diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index db1881fcbcd..9af07546d45 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -45,3 +45,9 @@ d827ed21adc7b36047e247cbb0dc6388d048a7f9 # `frappe.flags.in_test` => `frappe.in_test` 7a482a69985c952de0e8193c9d4e086aee65ee6d + +# these commits actually changed something valuable +# but they have a lot of whitespace changes that make blame noisy +# PR: https://github.com/frappe/erpnext/pull/49816 +3ffd50c772735877b330d010c1058f623da8721d +0e8f8677b8eb31e7834f72d1c6314d3c3f392ca6 diff --git a/.github/workflows/backport.yml b/.github/workflows/backport.yml index 3dda201454a..9c97552385c 100644 --- a/.github/workflows/backport.yml +++ b/.github/workflows/backport.yml @@ -14,7 +14,7 @@ jobs: timeout-minutes: 60 steps: - name: Checkout Actions - uses: actions/checkout@v2 + uses: actions/checkout@v6 with: repository: "frappe/backport" path: ./actions diff --git a/.github/workflows/docs-checker.yml b/.github/workflows/docs-checker.yml index a6201cb50e6..c081b86aa0e 100644 --- a/.github/workflows/docs-checker.yml +++ b/.github/workflows/docs-checker.yml @@ -13,12 +13,12 @@ jobs: steps: - name: 'Setup Environment' - uses: actions/setup-python@v2 + uses: actions/setup-python@v6 with: python-version: '3.10' - name: 'Clone repo' - uses: actions/checkout@v2 + uses: actions/checkout@v6 - name: Validate Docs env: diff --git a/.github/workflows/generate-pot-file.yml b/.github/workflows/generate-pot-file.yml index 9e42f4e0439..134d43ad1f0 100644 --- a/.github/workflows/generate-pot-file.yml +++ b/.github/workflows/generate-pot-file.yml @@ -21,14 +21,14 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: ref: ${{ matrix.branch }} - name: Setup Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: - python-version: "3.12" + python-version: "3.14" - name: Run script to update POT file run: | diff --git a/.github/workflows/linters.yml b/.github/workflows/linters.yml index fc9744405d0..6701673cc7f 100644 --- a/.github/workflows/linters.yml +++ b/.github/workflows/linters.yml @@ -12,12 +12,12 @@ jobs: name: linters runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v6 - - name: Set up Python 3.10 - uses: actions/setup-python@v4 + - name: Set up Python 3.14 + uses: actions/setup-python@v6 with: - python-version: '3.10' + python-version: '3.14' cache: pip - name: Install and Run Pre-commit @@ -27,12 +27,12 @@ jobs: name: semgrep runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v6 - - name: Set up Python 3.10 - uses: actions/setup-python@v4 + - name: Set up Python 3.14 + uses: actions/setup-python@v6 with: - python-version: '3.10' + python-version: '3.14' cache: pip - name: Download Semgrep rules diff --git a/.github/workflows/patch.yml b/.github/workflows/patch.yml index 45d405b0c0e..fac11c071db 100644 --- a/.github/workflows/patch.yml +++ b/.github/workflows/patch.yml @@ -29,7 +29,7 @@ jobs: services: mysql: - image: mariadb:10.6 + image: mariadb:11.8 env: MARIADB_ROOT_PASSWORD: 'root' ports: @@ -38,7 +38,7 @@ jobs: steps: - name: Clone - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Check for valid Python & Merge Conflicts run: | @@ -49,14 +49,17 @@ jobs: fi - name: Setup Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: - python-version: '3.11' + python-version: | + 3.11 + 3.13 + 3.14 - name: Setup Node - uses: actions/setup-node@v4 + uses: actions/setup-node@v6 with: - node-version: 18 + node-version: 24 check-latest: true - name: Add to Hosts @@ -132,15 +135,15 @@ jobs: # Resetup env and install apps pgrep honcho | xargs kill rm -rf ~/frappe-bench/env - bench -v setup env + bench -v setup env --python python$2 bench pip install -e ./apps/erpnext bench start &>> ~/frappe-bench/bench_start.log & bench --site test_site migrate } - update_to_version 14 - update_to_version 15 + update_to_version 14 3.11 + update_to_version 15 3.13 echo "Updating to latest version" git -C "apps/frappe" fetch --depth 1 upstream "${GITHUB_BASE_REF:-${GITHUB_REF##*/}}" diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 0affbd557dd..740d7489ed5 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -13,12 +13,12 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout Entire Repository - uses: actions/checkout@v2 + uses: actions/checkout@v6 with: fetch-depth: 0 persist-credentials: false - name: Setup Node.js - uses: actions/setup-node@v2 + uses: actions/setup-node@v6 with: node-version: 20 - name: Setup dependencies diff --git a/.github/workflows/run-indinvidual-tests.yml b/.github/workflows/run-indinvidual-tests.yml index 3b2857753d1..3e4b8371f8a 100644 --- a/.github/workflows/run-indinvidual-tests.yml +++ b/.github/workflows/run-indinvidual-tests.yml @@ -17,7 +17,7 @@ jobs: matrix: ${{ steps.set-matrix.outputs.matrix }} steps: - name: Clone - uses: actions/checkout@v4 + uses: actions/checkout@v6 - id: set-matrix run: | # Use grep and find to get the list of test files @@ -72,17 +72,17 @@ jobs: steps: - name: Clone - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Setup Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: - python-version: '3.12' + python-version: '3.14' - name: Setup Node - uses: actions/setup-node@v4 + uses: actions/setup-node@v6 with: - node-version: 18 + node-version: 24 check-latest: true - name: Add to Hosts diff --git a/.github/workflows/semantic-commits.yml b/.github/workflows/semantic-commits.yml index 0e478d551d9..f021b77eef8 100644 --- a/.github/workflows/semantic-commits.yml +++ b/.github/workflows/semantic-commits.yml @@ -15,11 +15,11 @@ jobs: name: Check Commit Titles runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v6 with: fetch-depth: 200 - - uses: actions/setup-node@v3 + - uses: actions/setup-node@v6 with: node-version: 18 check-latest: true diff --git a/.github/workflows/server-tests-mariadb.yml b/.github/workflows/server-tests-mariadb.yml index c24c647a8cf..036f587dbf9 100644 --- a/.github/workflows/server-tests-mariadb.yml +++ b/.github/workflows/server-tests-mariadb.yml @@ -62,12 +62,12 @@ jobs: steps: - name: Clone - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Setup Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: - python-version: '3.12' + python-version: '3.14' - name: Check for valid Python & Merge Conflicts run: | @@ -78,9 +78,9 @@ jobs: fi - name: Setup Node - uses: actions/setup-node@v4 + uses: actions/setup-node@v6 with: - node-version: 18 + node-version: 24 check-latest: true - name: Add to Hosts @@ -128,10 +128,9 @@ jobs: FRAPPE_BRANCH: ${{ github.event.client_payload.sha || github.event.inputs.branch }} - name: Run Tests - run: 'cd ~/frappe-bench/ && bench --site test_site run-parallel-tests --app erpnext --total-builds ${{ strategy.job-total }} --build-number ${{ matrix.container }}' + run: 'cd ~/frappe-bench/ && bench --site test_site run-parallel-tests --app erpnext --total-builds ${{ strategy.job-total }} --build-number ${{ matrix.container }} --with-coverage' env: TYPE: server - CAPTURE_COVERAGE: ${{ github.event_name != 'pull_request' }} - name: Show bench output @@ -140,7 +139,6 @@ jobs: - name: Upload coverage data uses: actions/upload-artifact@v4 - if: github.event_name != 'pull_request' with: name: coverage-${{ matrix.container }} path: /home/runner/frappe-bench/sites/coverage.xml @@ -149,10 +147,9 @@ jobs: name: Coverage Wrap Up needs: test runs-on: ubuntu-latest - if: ${{ github.event_name != 'pull_request' }} steps: - name: Clone - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Download artifacts uses: actions/download-artifact@v4 diff --git a/.github/workflows/server-tests-postgres.yml b/.github/workflows/server-tests-postgres.yml index 6bcfa4478ae..da5a4b60c3c 100644 --- a/.github/workflows/server-tests-postgres.yml +++ b/.github/workflows/server-tests-postgres.yml @@ -47,12 +47,12 @@ jobs: steps: - name: Clone - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Setup Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: - python-version: '3.12' + python-version: '3.14' - name: Check for valid Python & Merge Conflicts run: | @@ -63,9 +63,9 @@ jobs: fi - name: Setup Node - uses: actions/setup-node@v4 + uses: actions/setup-node@v6 with: - node-version: 18 + node-version: 24 check-latest: true - name: Add to Hosts diff --git a/erpnext/accounts/deferred_revenue.py b/erpnext/accounts/deferred_revenue.py index cb34b172ab4..be723915951 100644 --- a/erpnext/accounts/deferred_revenue.py +++ b/erpnext/accounts/deferred_revenue.py @@ -7,6 +7,7 @@ from frappe.utils import ( cint, date_diff, flt, + formatdate, get_first_day, get_last_day, get_link_to_form, @@ -318,7 +319,7 @@ def get_already_booked_amount(doc, item): def book_deferred_income_or_expense(doc, deferred_process, posting_date=None): enable_check = "enable_deferred_revenue" if doc.doctype == "Sales Invoice" else "enable_deferred_expense" - accounts_frozen_upto = frappe.get_single_value("Accounts Settings", "acc_frozen_upto") + accounts_frozen_upto = frappe.db.get_value("Company", doc.company, "accounts_frozen_till_date") def _book_deferred_revenue_or_expense( item, diff --git a/erpnext/accounts/doctype/account/account.py b/erpnext/accounts/doctype/account/account.py index 1e6467e502f..3e32f6b8817 100644 --- a/erpnext/accounts/doctype/account/account.py +++ b/erpnext/accounts/doctype/account/account.py @@ -93,8 +93,10 @@ class Account(NestedSet): super().on_update() def onload(self): - frozen_accounts_modifier = frappe.get_single_value("Accounts Settings", "frozen_accounts_modifier") - if not frozen_accounts_modifier or frozen_accounts_modifier in frappe.get_roles(): + role_allowed_for_frozen_entries = frappe.db.get_value( + "Company", self.company, "role_allowed_for_frozen_entries" + ) + if not role_allowed_for_frozen_entries or role_allowed_for_frozen_entries in frappe.get_roles(): self.set_onload("can_freeze_account", True) def autoname(self): @@ -303,10 +305,10 @@ class Account(NestedSet): if not doc_before_save or doc_before_save.freeze_account == self.freeze_account: return - frozen_accounts_modifier = frappe.get_cached_value( - "Accounts Settings", "Accounts Settings", "frozen_accounts_modifier" + role_allowed_for_frozen_entries = frappe.get_cached_value( + "Company", self.company, "role_allowed_for_frozen_entries" ) - if not frozen_accounts_modifier or frozen_accounts_modifier not in frappe.get_roles(): + if not role_allowed_for_frozen_entries or role_allowed_for_frozen_entries not in frappe.get_roles(): throw(_("You are not authorized to set Frozen value")) def validate_balance_must_be_debit_or_credit(self): diff --git a/erpnext/accounts/doctype/account/account_tree.js b/erpnext/accounts/doctype/account/account_tree.js index 804cb473305..315b41560ce 100644 --- a/erpnext/accounts/doctype/account/account_tree.js +++ b/erpnext/accounts/doctype/account/account_tree.js @@ -70,6 +70,7 @@ frappe.treeview_settings["Account"] = { args: { accounts: accounts, company: cur_tree.args.company, + include_default_fb_balances: true, }, }); diff --git a/erpnext/accounts/doctype/accounts_settings/accounts_settings.json b/erpnext/accounts/doctype/accounts_settings/accounts_settings.json index 64b8b27cd76..dc657945544 100644 --- a/erpnext/accounts/doctype/accounts_settings/accounts_settings.json +++ b/erpnext/accounts/doctype/accounts_settings/accounts_settings.json @@ -73,13 +73,12 @@ "calculate_depr_using_total_days", "column_break_gjcc", "book_asset_depreciation_entry_automatically", + "role_to_notify_on_depreciation_failure", "closing_settings_tab", "period_closing_settings_section", - "acc_frozen_upto", "ignore_account_closing_balance", "use_legacy_controller_for_pcv", "column_break_25", - "frozen_accounts_modifier", "tab_break_dpet", "show_balance_in_coa", "banking_tab", @@ -102,21 +101,6 @@ "use_legacy_budget_controller" ], "fields": [ - { - "description": "Accounting entries are frozen up to this date. Nobody can create or modify entries except users with the role specified below", - "fieldname": "acc_frozen_upto", - "fieldtype": "Date", - "in_list_view": 1, - "label": "Accounts Frozen Till Date" - }, - { - "description": "Users with this role are allowed to set frozen accounts and create / modify accounting entries against frozen accounts", - "fieldname": "frozen_accounts_modifier", - "fieldtype": "Link", - "in_list_view": 1, - "label": "Role Allowed to Set Frozen Accounts and Edit Frozen Entries", - "options": "Role" - }, { "default": "Billing Address", "description": "Address used to determine Tax Category in transactions", @@ -658,6 +642,13 @@ "fieldname": "use_legacy_controller_for_pcv", "fieldtype": "Check", "label": "Use Legacy Controller For Period Closing Voucher" + }, + { + "description": "Users with this role will be notified if the asset depreciation gets failed", + "fieldname": "role_to_notify_on_depreciation_failure", + "fieldtype": "Link", + "label": "Role to Notify on Depreciation Failure", + "options": "Role" } ], "grid_page_length": 50, @@ -666,7 +657,7 @@ "index_web_pages_for_search": 1, "issingle": 1, "links": [], - "modified": "2025-10-20 14:06:08.870427", + "modified": "2025-12-03 20:42:13.238050", "modified_by": "Administrator", "module": "Accounts", "name": "Accounts Settings", diff --git a/erpnext/accounts/doctype/accounts_settings/accounts_settings.py b/erpnext/accounts/doctype/accounts_settings/accounts_settings.py index bef862d85e0..557afd02a48 100644 --- a/erpnext/accounts/doctype/accounts_settings/accounts_settings.py +++ b/erpnext/accounts/doctype/accounts_settings/accounts_settings.py @@ -11,7 +11,6 @@ from frappe.model.document import Document from frappe.utils import cint from erpnext.accounts.utils import sync_auto_reconcile_config -from erpnext.stock.utils import check_pending_reposting class AccountsSettings(Document): @@ -23,7 +22,6 @@ class AccountsSettings(Document): if TYPE_CHECKING: from frappe.types import DF - acc_frozen_upto: DF.Date | None add_taxes_from_item_tax_template: DF.Check add_taxes_from_taxes_and_charges_template: DF.Check allow_multi_currency_invoices_against_single_party_account: DF.Check @@ -50,7 +48,6 @@ class AccountsSettings(Document): enable_party_matching: DF.Check exchange_gain_loss_posting_date: DF.Literal["Invoice", "Payment", "Reconciliation Date"] fetch_valuation_rate_for_internal_transaction: DF.Check - frozen_accounts_modifier: DF.Link | None general_ledger_remarks_length: DF.Int ignore_account_closing_balance: DF.Check ignore_is_opening_check_for_reporting: DF.Check @@ -64,6 +61,7 @@ class AccountsSettings(Document): receivable_payable_remarks_length: DF.Int reconciliation_queue_size: DF.Int role_allowed_to_over_bill: DF.Link | None + role_to_notify_on_depreciation_failure: DF.Link | None role_to_override_stop_action: DF.Link | None round_row_wise_tax: DF.Check show_balance_in_coa: DF.Check @@ -100,9 +98,6 @@ class AccountsSettings(Document): if old_doc.show_payment_schedule_in_print != self.show_payment_schedule_in_print: self.enable_payment_schedule_in_print() - if old_doc.acc_frozen_upto != self.acc_frozen_upto: - self.validate_pending_reposts() - if clear_cache: frappe.clear_cache() @@ -129,10 +124,6 @@ class AccountsSettings(Document): validate_fields_for_doctype=False, ) - def validate_pending_reposts(self): - if self.acc_frozen_upto: - check_pending_reposting(self.acc_frozen_upto) - def validate_and_sync_auto_reconcile_config(self): if self.has_value_changed("auto_reconciliation_job_trigger"): if ( @@ -161,6 +152,5 @@ class AccountsSettings(Document): def drop_ar_sql_procedures(self): from erpnext.accounts.report.accounts_receivable.accounts_receivable import InitSQLProceduresForAR - frappe.db.sql(f"drop function if exists {InitSQLProceduresForAR.genkey_function_name}") frappe.db.sql(f"drop procedure if exists {InitSQLProceduresForAR.init_procedure_name}") frappe.db.sql(f"drop procedure if exists {InitSQLProceduresForAR.allocate_procedure_name}") diff --git a/erpnext/accounts/doctype/accounts_settings/regional/united_states.js b/erpnext/accounts/doctype/accounts_settings/regional/united_states.js index a522de9da75..06e1e3ba3b8 100644 --- a/erpnext/accounts/doctype/accounts_settings/regional/united_states.js +++ b/erpnext/accounts/doctype/accounts_settings/regional/united_states.js @@ -1,11 +1,16 @@ frappe.ui.form.on("Accounts Settings", { refresh: function (frm) { - frm.set_df_property("acc_frozen_upto", "label", "Books Closed Through"); - frm.set_df_property( - "frozen_accounts_modifier", - "label", - "Role Allowed to Close Books & Make Changes to Closed Periods" - ); frm.set_df_property("credit_controller", "label", "Credit Manager"); }, }); + +frappe.ui.form.on("Company", { + refresh: function (frm) { + frm.set_df_property("accounts_frozen_till_date", "label", "Books Closed Through"); + frm.set_df_property( + "role_allowed_for_frozen_entries", + "label", + "Role Allowed to Close Books & Make Changes to Closed Periods" + ); + }, +}); diff --git a/erpnext/accounts/doctype/advance_tax/advance_tax.json b/erpnext/accounts/doctype/advance_tax/advance_tax.json deleted file mode 100644 index f030d7f47a2..00000000000 --- a/erpnext/accounts/doctype/advance_tax/advance_tax.json +++ /dev/null @@ -1,57 +0,0 @@ -{ - "actions": [], - "allow_rename": 1, - "creation": "2021-11-25 10:24:39.836195", - "doctype": "DocType", - "engine": "InnoDB", - "field_order": [ - "reference_type", - "reference_name", - "reference_detail", - "account_head", - "allocated_amount" - ], - "fields": [ - { - "fieldname": "reference_type", - "fieldtype": "Link", - "label": "Reference Type", - "options": "DocType" - }, - { - "fieldname": "reference_name", - "fieldtype": "Dynamic Link", - "label": "Reference Name", - "options": "reference_type" - }, - { - "fieldname": "reference_detail", - "fieldtype": "Data", - "label": "Reference Detail" - }, - { - "fieldname": "account_head", - "fieldtype": "Link", - "label": "Account Head", - "options": "Account" - }, - { - "fieldname": "allocated_amount", - "fieldtype": "Currency", - "label": "Allocated Amount", - "options": "party_account_currency" - } - ], - "index_web_pages_for_search": 1, - "istable": 1, - "links": [], - "modified": "2024-03-27 13:05:58.308002", - "modified_by": "Administrator", - "module": "Accounts", - "name": "Advance Tax", - "owner": "Administrator", - "permissions": [], - "sort_field": "creation", - "sort_order": "DESC", - "states": [] -} \ No newline at end of file diff --git a/erpnext/accounts/doctype/advance_tax/advance_tax.py b/erpnext/accounts/doctype/advance_tax/advance_tax.py deleted file mode 100644 index 59bdac7bc5a..00000000000 --- a/erpnext/accounts/doctype/advance_tax/advance_tax.py +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and contributors -# For license information, please see license.txt - -# import frappe -from frappe.model.document import Document - - -class AdvanceTax(Document): - # begin: auto-generated types - # This code is auto-generated. Do not modify anything in this block. - - from typing import TYPE_CHECKING - - if TYPE_CHECKING: - from frappe.types import DF - - account_head: DF.Link | None - allocated_amount: DF.Currency - parent: DF.Data - parentfield: DF.Data - parenttype: DF.Data - reference_detail: DF.Data | None - reference_name: DF.DynamicLink | None - reference_type: DF.Link | None - # end: auto-generated types - - pass diff --git a/erpnext/accounts/doctype/advance_taxes_and_charges/advance_taxes_and_charges.json b/erpnext/accounts/doctype/advance_taxes_and_charges/advance_taxes_and_charges.json index ddc9b573c78..7850637a5e8 100644 --- a/erpnext/accounts/doctype/advance_taxes_and_charges/advance_taxes_and_charges.json +++ b/erpnext/accounts/doctype/advance_taxes_and_charges/advance_taxes_and_charges.json @@ -14,6 +14,7 @@ "description", "included_in_paid_amount", "set_by_item_tax_template", + "is_tax_withholding_account", "accounting_dimensions_section", "cost_center", "dimension_col_break", @@ -25,7 +26,6 @@ "net_amount", "tax_amount", "total", - "allocated_amount", "column_break_13", "base_tax_amount", "base_net_amount", @@ -97,11 +97,11 @@ "fieldtype": "Column Break" }, { - "allow_on_submit": 1, - "fieldname": "project", - "fieldtype": "Link", - "label": "Project", - "options": "Project" + "allow_on_submit": 1, + "fieldname": "project", + "fieldtype": "Link", + "label": "Project", + "options": "Project" }, { "fieldname": "section_break_8", @@ -172,12 +172,6 @@ "fieldtype": "Check", "label": "Considered In Paid Amount" }, - { - "fieldname": "allocated_amount", - "fieldtype": "Currency", - "label": "Allocated Amount", - "options": "currency" - }, { "fetch_from": "account_head.account_currency", "fieldname": "currency", @@ -213,18 +207,26 @@ "print_hide": 1, "read_only": 1, "report_hide": 1 + }, + { + "default": "0", + "fieldname": "is_tax_withholding_account", + "fieldtype": "Check", + "label": "Is Tax Withholding Account", + "read_only": 1 } ], "index_web_pages_for_search": 1, "istable": 1, "links": [], - "modified": "2024-11-22 19:16:22.346267", + "modified": "2025-12-15 06:42:18.707671", "modified_by": "Administrator", "module": "Accounts", "name": "Advance Taxes and Charges", "owner": "Administrator", "permissions": [], + "row_format": "Dynamic", "sort_field": "creation", "sort_order": "ASC", "states": [] -} \ No newline at end of file +} diff --git a/erpnext/accounts/doctype/advance_taxes_and_charges/advance_taxes_and_charges.py b/erpnext/accounts/doctype/advance_taxes_and_charges/advance_taxes_and_charges.py index 70012da76c3..e214bdfa0ba 100644 --- a/erpnext/accounts/doctype/advance_taxes_and_charges/advance_taxes_and_charges.py +++ b/erpnext/accounts/doctype/advance_taxes_and_charges/advance_taxes_and_charges.py @@ -17,7 +17,6 @@ class AdvanceTaxesandCharges(Document): account_head: DF.Link add_deduct_tax: DF.Literal["Add", "Deduct"] - allocated_amount: DF.Currency base_net_amount: DF.Currency base_tax_amount: DF.Currency base_total: DF.Currency @@ -28,10 +27,12 @@ class AdvanceTaxesandCharges(Document): currency: DF.Link | None description: DF.SmallText included_in_paid_amount: DF.Check + is_tax_withholding_account: DF.Check net_amount: DF.Currency parent: DF.Data parentfield: DF.Data parenttype: DF.Data + project: DF.Link | None rate: DF.Float row_id: DF.Data | None set_by_item_tax_template: DF.Check diff --git a/erpnext/accounts/doctype/bank_transaction/bank_transaction.json b/erpnext/accounts/doctype/bank_transaction/bank_transaction.json index 599a0604755..99622314532 100644 --- a/erpnext/accounts/doctype/bank_transaction/bank_transaction.json +++ b/erpnext/accounts/doctype/bank_transaction/bank_transaction.json @@ -38,7 +38,10 @@ "column_break_3czf", "bank_party_name", "bank_party_account_number", - "bank_party_iban" + "bank_party_iban", + "extended_bank_statement_section", + "included_fee", + "excluded_fee" ], "fields": [ { @@ -233,12 +236,32 @@ { "fieldname": "column_break_oufv", "fieldtype": "Column Break" + }, + { + "fieldname": "extended_bank_statement_section", + "fieldtype": "Section Break", + "label": "Extended Bank Statement" + }, + { + "fieldname": "included_fee", + "fieldtype": "Currency", + "label": "Included Fee", + "non_negative": 1, + "options": "currency" + }, + { + "description": "On save, the Excluded Fee will be converted to an Included Fee.", + "fieldname": "excluded_fee", + "fieldtype": "Currency", + "label": "Excluded Fee", + "non_negative": 1, + "options": "currency" } ], "grid_page_length": 50, "is_submittable": 1, "links": [], - "modified": "2025-10-23 17:32:58.514807", + "modified": "2025-12-07 20:49:18.600757", "modified_by": "Administrator", "module": "Accounts", "name": "Bank Transaction", diff --git a/erpnext/accounts/doctype/bank_transaction/bank_transaction.py b/erpnext/accounts/doctype/bank_transaction/bank_transaction.py index 8afe07343a5..e40749fdd5d 100644 --- a/erpnext/accounts/doctype/bank_transaction/bank_transaction.py +++ b/erpnext/accounts/doctype/bank_transaction/bank_transaction.py @@ -32,6 +32,8 @@ class BankTransaction(Document): date: DF.Date | None deposit: DF.Currency description: DF.SmallText | None + excluded_fee: DF.Currency + included_fee: DF.Currency naming_series: DF.Literal["ACC-BTN-.YYYY.-"] party: DF.DynamicLink | None party_type: DF.Link | None @@ -45,9 +47,11 @@ class BankTransaction(Document): # end: auto-generated types def before_validate(self): + self.handle_excluded_fee() self.update_allocated_amount() def validate(self): + self.validate_included_fee() self.validate_duplicate_references() self.validate_currency() @@ -307,6 +311,40 @@ class BankTransaction(Document): self.party_type, self.party = result + def validate_included_fee(self): + """ + The included_fee is only handled for withdrawals. An included_fee for a deposit, is not credited to the account and is + therefore outside of the deposit value and can be larger than the deposit itself. + """ + + if self.included_fee and self.withdrawal: + if self.included_fee > self.withdrawal: + frappe.throw(_("Included fee is bigger than the withdrawal itself.")) + + def handle_excluded_fee(self): + # Include the excluded fee on validate to handle all further processing the same + excluded_fee = flt(self.excluded_fee) + if excluded_fee <= 0: + return + + # Suppress a negative deposit (aka withdrawal), likely not intendend + if flt(self.deposit) > 0 and (flt(self.deposit) - excluded_fee) < 0: + frappe.throw(_("The Excluded Fee is bigger than the Deposit it is deducted from.")) + + # Enforce directionality + if flt(self.deposit) > 0 and flt(self.withdrawal) > 0: + frappe.throw( + _("Only one of Deposit or Withdrawal should be non-zero when applying an Excluded Fee.") + ) + + if flt(self.deposit) > 0: + self.deposit = flt(self.deposit) - excluded_fee + # A fee applied to deposit and withdrawal equal 0 become a withdrawal + elif flt(self.withdrawal) >= 0: + self.withdrawal = flt(self.withdrawal) + excluded_fee + self.included_fee = flt(self.included_fee) + excluded_fee + self.excluded_fee = 0 + @frappe.whitelist() def get_doctypes_for_bank_reconciliation(): diff --git a/erpnext/accounts/doctype/bank_transaction/test_bank_transaction_fees.py b/erpnext/accounts/doctype/bank_transaction/test_bank_transaction_fees.py new file mode 100644 index 00000000000..95fc615d91d --- /dev/null +++ b/erpnext/accounts/doctype/bank_transaction/test_bank_transaction_fees.py @@ -0,0 +1,133 @@ +# Copyright (c) 2025, Frappe Technologies Pvt. Ltd. and Contributors +# See license.txt + +import frappe +from frappe.tests import UnitTestCase + + +class TestBankTransactionFees(UnitTestCase): + def test_included_fee_throws(self): + """A fee that's part of a withdrawal cannot be bigger than the + withdrawal itself.""" + bt = frappe.new_doc("Bank Transaction") + bt.withdrawal = 100 + bt.included_fee = 101 + + self.assertRaises(frappe.ValidationError, bt.validate_included_fee) + + def test_included_fee_allows_equal(self): + """A fee that's part of a withdrawal may be equal to the withdrawal + amount (only the fee was deducted from the account).""" + bt = frappe.new_doc("Bank Transaction") + bt.withdrawal = 100 + bt.included_fee = 100 + + bt.validate_included_fee() + + def test_included_fee_allows_for_deposit(self): + """For deposits, a fee may be recorded separately without limiting the + received amount.""" + bt = frappe.new_doc("Bank Transaction") + bt.deposit = 10 + bt.included_fee = 999 + + bt.validate_included_fee() + + def test_excluded_fee_noop_when_zero(self): + """When there is no excluded fee to apply, the amounts should remain + unchanged.""" + bt = frappe.new_doc("Bank Transaction") + bt.deposit = 100 + bt.withdrawal = 0 + bt.included_fee = 5 + bt.excluded_fee = 0 + + bt.handle_excluded_fee() + + self.assertEqual(bt.deposit, 100) + self.assertEqual(bt.withdrawal, 0) + self.assertEqual(bt.included_fee, 5) + self.assertEqual(bt.excluded_fee, 0) + + def test_excluded_fee_throws_when_exceeds_deposit(self): + """A fee deducted from an incoming payment must not exceed the incoming + amount (else it would be a withdrawal, a conversion we don't support).""" + bt = frappe.new_doc("Bank Transaction") + bt.deposit = 10 + bt.excluded_fee = 11 + + self.assertRaises(frappe.ValidationError, bt.handle_excluded_fee) + + def test_excluded_fee_throws_when_both_deposit_and_withdrawal_are_set(self): + """A transaction must be either incoming or outgoing when applying a + fee, not both.""" + bt = frappe.new_doc("Bank Transaction") + bt.deposit = 10 + bt.withdrawal = 10 + bt.excluded_fee = 1 + + self.assertRaises(frappe.ValidationError, bt.handle_excluded_fee) + + def test_excluded_fee_deducts_from_deposit(self): + """When a fee is deducted from an incoming payment, the net received + amount decreases and the fee is tracked as included.""" + bt = frappe.new_doc("Bank Transaction") + bt.deposit = 100 + bt.withdrawal = 0 + bt.included_fee = 2 + bt.excluded_fee = 5 + + bt.handle_excluded_fee() + + self.assertEqual(bt.deposit, 95) + self.assertEqual(bt.withdrawal, 0) + self.assertEqual(bt.included_fee, 7) + self.assertEqual(bt.excluded_fee, 0) + + def test_excluded_fee_can_reduce_an_incoming_payment_to_zero(self): + """A separately-deducted fee may reduce an incoming payment to zero, + while still tracking the fee.""" + bt = frappe.new_doc("Bank Transaction") + bt.deposit = 5 + bt.withdrawal = 0 + bt.included_fee = 0 + bt.excluded_fee = 5 + + bt.handle_excluded_fee() + + self.assertEqual(bt.deposit, 0) + self.assertEqual(bt.withdrawal, 0) + self.assertEqual(bt.included_fee, 5) + self.assertEqual(bt.excluded_fee, 0) + + def test_excluded_fee_increases_outgoing_payment(self): + """When a separately-deducted fee is provided for an outgoing payment, + the total money leaving increases and the fee is tracked.""" + bt = frappe.new_doc("Bank Transaction") + bt.deposit = 0 + bt.withdrawal = 100 + bt.included_fee = 2 + bt.excluded_fee = 5 + + bt.handle_excluded_fee() + + self.assertEqual(bt.deposit, 0) + self.assertEqual(bt.withdrawal, 105) + self.assertEqual(bt.included_fee, 7) + self.assertEqual(bt.excluded_fee, 0) + + def test_excluded_fee_turns_zero_amount_into_withdrawal(self): + """If only an excluded fee is provided, it should be treated as an + outgoing payment and the fee is then tracked as included.""" + bt = frappe.new_doc("Bank Transaction") + bt.deposit = 0 + bt.withdrawal = 0 + bt.included_fee = 0 + bt.excluded_fee = 5 + + bt.handle_excluded_fee() + + self.assertEqual(bt.deposit, 0) + self.assertEqual(bt.withdrawal, 5) + self.assertEqual(bt.included_fee, 5) + self.assertEqual(bt.excluded_fee, 0) diff --git a/erpnext/accounts/doctype/currency_exchange_settings/currency_exchange_settings.js b/erpnext/accounts/doctype/currency_exchange_settings/currency_exchange_settings.js index ad68352c2a4..40f0938ee1c 100644 --- a/erpnext/accounts/doctype/currency_exchange_settings/currency_exchange_settings.js +++ b/erpnext/accounts/doctype/currency_exchange_settings/currency_exchange_settings.js @@ -19,7 +19,7 @@ frappe.ui.form.on("Currency Exchange Settings", { to: "{to_currency}", }; add_param(frm, r.message, params, result); - } else if (frm.doc.service_provider == "frankfurter.app") { + } else if (["frankfurter.app", "frankfurter.dev"].includes(frm.doc.service_provider)) { let result = ["rates", "{to_currency}"]; let params = { base: "{from_currency}", diff --git a/erpnext/accounts/doctype/currency_exchange_settings/currency_exchange_settings.json b/erpnext/accounts/doctype/currency_exchange_settings/currency_exchange_settings.json index 992d96167e5..614f4e6d3e5 100644 --- a/erpnext/accounts/doctype/currency_exchange_settings/currency_exchange_settings.json +++ b/erpnext/accounts/doctype/currency_exchange_settings/currency_exchange_settings.json @@ -78,7 +78,7 @@ "fieldname": "service_provider", "fieldtype": "Select", "label": "Service Provider", - "options": "frankfurter.app\nexchangerate.host\nCustom", + "options": "frankfurter.dev\nexchangerate.host\nCustom", "reqd": 1 }, { @@ -104,7 +104,7 @@ "index_web_pages_for_search": 1, "issingle": 1, "links": [], - "modified": "2024-03-27 13:06:47.653110", + "modified": "2025-11-25 13:03:41.896424", "modified_by": "Administrator", "module": "Accounts", "name": "Currency Exchange Settings", @@ -141,8 +141,9 @@ "write": 1 } ], + "row_format": "Dynamic", "sort_field": "creation", "sort_order": "DESC", "states": [], "track_changes": 1 -} \ No newline at end of file +} diff --git a/erpnext/accounts/doctype/currency_exchange_settings/currency_exchange_settings.py b/erpnext/accounts/doctype/currency_exchange_settings/currency_exchange_settings.py index f5889510732..55f967fc788 100644 --- a/erpnext/accounts/doctype/currency_exchange_settings/currency_exchange_settings.py +++ b/erpnext/accounts/doctype/currency_exchange_settings/currency_exchange_settings.py @@ -29,7 +29,7 @@ class CurrencyExchangeSettings(Document): disabled: DF.Check req_params: DF.Table[CurrencyExchangeSettingsDetails] result_key: DF.Table[CurrencyExchangeSettingsResult] - service_provider: DF.Literal["frankfurter.app", "exchangerate.host", "Custom"] + service_provider: DF.Literal["frankfurter.dev", "exchangerate.host", "Custom"] url: DF.Data | None use_http: DF.Check # end: auto-generated types @@ -60,7 +60,7 @@ class CurrencyExchangeSettings(Document): self.append("req_params", {"key": "date", "value": "{transaction_date}"}) self.append("req_params", {"key": "from", "value": "{from_currency}"}) self.append("req_params", {"key": "to", "value": "{to_currency}"}) - elif self.service_provider == "frankfurter.app": + elif self.service_provider in ("frankfurter.dev", "frankfurter.app"): self.set("result_key", []) self.set("req_params", []) @@ -105,11 +105,13 @@ class CurrencyExchangeSettings(Document): @frappe.whitelist() def get_api_endpoint(service_provider: str | None = None, use_http: bool = False): - if service_provider and service_provider in ["exchangerate.host", "frankfurter.app"]: + if service_provider and service_provider in ["exchangerate.host", "frankfurter.dev", "frankfurter.app"]: if service_provider == "exchangerate.host": api = "api.exchangerate.host/convert" elif service_provider == "frankfurter.app": api = "api.frankfurter.app/{transaction_date}" + elif service_provider == "frankfurter.dev": + api = "api.frankfurter.dev/v1/{transaction_date}" protocol = "https://" if use_http: diff --git a/erpnext/accounts/doctype/gl_entry/gl_entry.py b/erpnext/accounts/doctype/gl_entry/gl_entry.py index aefe293157b..c52c86528fd 100644 --- a/erpnext/accounts/doctype/gl_entry/gl_entry.py +++ b/erpnext/accounts/doctype/gl_entry/gl_entry.py @@ -100,7 +100,7 @@ class GLEntry(Document): self.validate_account_details(adv_adj) self.validate_dimensions_for_pl_and_bs() validate_balance_type(self.account, adv_adj) - validate_frozen_account(self.account, adv_adj) + validate_frozen_account(self.company, self.account, adv_adj) if ( self.voucher_type == "Journal Entry" @@ -276,7 +276,7 @@ class GLEntry(Document): ) def validate_party(self): - validate_party_frozen_disabled(self.party_type, self.party) + validate_party_frozen_disabled(self.company, self.party_type, self.party) validate_account_party_type(self) def validate_currency(self): @@ -419,16 +419,16 @@ def update_outstanding_amt( ref_doc.set_status(update=True) -def validate_frozen_account(account, adv_adj=None): +def validate_frozen_account(company, account, adv_adj=None): frozen_account = frappe.get_cached_value("Account", account, "freeze_account") if frozen_account == "Yes" and not adv_adj: - frozen_accounts_modifier = frappe.get_cached_value( - "Accounts Settings", None, "frozen_accounts_modifier" + role_allowed_for_frozen_entries = frappe.get_cached_value( + "Company", company, "role_allowed_for_frozen_entries" ) - if not frozen_accounts_modifier: + if not role_allowed_for_frozen_entries: frappe.throw(_("Account {0} is frozen").format(account)) - elif frozen_accounts_modifier not in frappe.get_roles(): + elif role_allowed_for_frozen_entries not in frappe.get_roles(): frappe.throw(_("Not authorized to edit frozen Account {0}").format(account)) diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.js b/erpnext/accounts/doctype/journal_entry/journal_entry.js index c81acb57865..3f772264d78 100644 --- a/erpnext/accounts/doctype/journal_entry/journal_entry.js +++ b/erpnext/accounts/doctype/journal_entry/journal_entry.js @@ -201,6 +201,7 @@ frappe.ui.form.on("Journal Entry", { erpnext.accounts.dimensions.update_dimension(frm, frm.doctype); erpnext.utils.set_letter_head(frm); + frm.clear_table("tax_withholding_entries"); }, voucher_type: function (frm) { @@ -251,6 +252,10 @@ frappe.ui.form.on("Journal Entry", { }); } }, + + apply_tds: function (frm) { + frm.clear_table("tax_withholding_entries"); + }, }); var update_jv_details = function (doc, r) { @@ -720,6 +725,8 @@ $.extend(erpnext.journal_entry, { } }, }); + } else { + erpnext.journal_entry.clear_fields(frm, dt, dn); } }, set_amount_on_last_row: function (frm, dt, dn) { @@ -744,4 +751,13 @@ $.extend(erpnext.journal_entry, { } refresh_field("accounts"); }, + clear_fields: function (frm, dt, dn) { + let row = locals[dt][dn]; + + row.party_type = null; + row.party = null; + row.bank_account = null; + + frm.refresh_field("accounts"); + }, }); diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.json b/erpnext/accounts/doctype/journal_entry/journal_entry.json index 7058cd90461..2465948c5ef 100644 --- a/erpnext/accounts/doctype/journal_entry/journal_entry.json +++ b/erpnext/accounts/doctype/journal_entry/journal_entry.json @@ -43,6 +43,11 @@ "total_amount_currency", "total_amount", "total_amount_in_words", + "section_tax_withholding_entry", + "tax_withholding_group", + "ignore_tax_withholding_threshold", + "override_tax_withholding_entries", + "tax_withholding_entries", "reference", "clearance_date", "remark", @@ -517,7 +522,7 @@ "depends_on": "eval:['Credit Note', 'Debit Note'].includes(doc.voucher_type)", "fieldname": "apply_tds", "fieldtype": "Check", - "label": "Apply Tax Withholding Amount " + "label": "Consider for Tax Withholding " }, { "depends_on": "eval:doc.docstatus", @@ -586,6 +591,39 @@ "hidden": 1, "label": "Party Not Required", "no_copy": 1 + }, + { + "collapsible": 1, + "collapsible_depends_on": "eval: doc.apply_tds && doc.docstatus == 0", + "depends_on": "eval: doc.apply_tds", + "fieldname": "section_tax_withholding_entry", + "fieldtype": "Section Break", + "label": "Tax Withholding Entry" + }, + { + "fieldname": "tax_withholding_group", + "fieldtype": "Link", + "label": "Tax Withholding Group", + "options": "Tax Withholding Group" + }, + { + "default": "0", + "fieldname": "ignore_tax_withholding_threshold", + "fieldtype": "Check", + "label": "Ignore Tax Withholding Threshold" + }, + { + "default": "0", + "fieldname": "override_tax_withholding_entries", + "fieldtype": "Check", + "label": "Edit Tax Withholding Entries" + }, + { + "fieldname": "tax_withholding_entries", + "fieldtype": "Table", + "label": "Tax Withholding Entries", + "options": "Tax Withholding Entry", + "read_only_depends_on": "eval: !doc.override_tax_withholding_entries" } ], "icon": "fa fa-file-text", @@ -600,7 +638,7 @@ "table_fieldname": "payment_entries" } ], - "modified": "2025-09-29 13:05:46.982277", + "modified": "2025-11-13 17:54:14.542903", "modified_by": "Administrator", "module": "Accounts", "name": "Journal Entry", diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.py b/erpnext/accounts/doctype/journal_entry/journal_entry.py index e4aaf4e7a5a..6bf739c6b5a 100644 --- a/erpnext/accounts/doctype/journal_entry/journal_entry.py +++ b/erpnext/accounts/doctype/journal_entry/journal_entry.py @@ -17,9 +17,7 @@ from erpnext.accounts.doctype.repost_accounting_ledger.repost_accounting_ledger validate_docs_for_deferred_accounting, validate_docs_for_voucher_types, ) -from erpnext.accounts.doctype.tax_withholding_category.tax_withholding_category import ( - get_party_tax_withholding_details, -) +from erpnext.accounts.doctype.tax_withholding_entry.tax_withholding_entry import JournalTaxWithholding from erpnext.accounts.party import get_party_account from erpnext.accounts.utils import ( cancel_exchange_gain_loss_journal, @@ -33,6 +31,7 @@ from erpnext.assets.doctype.asset_depreciation_schedule.asset_depreciation_sched get_depr_schedule, ) from erpnext.controllers.accounts_controller import AccountsController +from erpnext.setup.utils import get_exchange_rate as _get_exchange_rate class StockAccountInvalidTransaction(frappe.ValidationError): @@ -49,6 +48,7 @@ class JournalEntry(AccountsController): from frappe.types import DF from erpnext.accounts.doctype.journal_entry_account.journal_entry_account import JournalEntryAccount + from erpnext.accounts.doctype.tax_withholding_entry.tax_withholding_entry import TaxWithholdingEntry accounts: DF.Table[JournalEntryAccount] amended_from: DF.Link | None @@ -65,6 +65,7 @@ class JournalEntry(AccountsController): finance_book: DF.Link | None for_all_stock_asset_accounts: DF.Check from_template: DF.Link | None + ignore_tax_withholding_threshold: DF.Check inter_company_journal_entry_reference: DF.Link | None is_opening: DF.Literal["No", "Yes"] is_system_generated: DF.Check @@ -73,6 +74,7 @@ class JournalEntry(AccountsController): multi_currency: DF.Check naming_series: DF.Literal["ACC-JV-.YYYY.-"] party_not_required: DF.Check + override_tax_withholding_entries: DF.Check pay_to_recd_from: DF.Data | None payment_order: DF.Link | None periodic_entry_difference_account: DF.Link | None @@ -84,6 +86,8 @@ class JournalEntry(AccountsController): stock_asset_account: DF.Link | None stock_entry: DF.Link | None tax_withholding_category: DF.Link | None + tax_withholding_entries: DF.Table[TaxWithholdingEntry] + tax_withholding_group: DF.Link | None title: DF.Data | None total_amount: DF.Currency total_amount_currency: DF.Link | None @@ -150,8 +154,8 @@ class JournalEntry(AccountsController): self.validate_company_in_accounting_dimension() self.validate_advance_accounts() - if self.docstatus == 0: - self.apply_tax_withholding() + JournalTaxWithholding(self).on_validate() + if self.is_new() or not self.title: self.title = self.get_title() @@ -199,6 +203,7 @@ class JournalEntry(AccountsController): self.update_asset_value() self.update_inter_company_jv() self.update_invoice_discounting() + JournalTaxWithholding(self).on_submit() @frappe.whitelist() def get_balance_for_periodic_accounting(self): @@ -282,6 +287,8 @@ class JournalEntry(AccountsController): self.repost_accounting_entries() def on_cancel(self): + # Cancel tax withholding entries + # References for this Journal are removed on the `on_cancel` event in accounts_controller super().on_cancel() self.ignore_linked_doctypes = ( @@ -295,8 +302,10 @@ class JournalEntry(AccountsController): "Unreconcile Payment", "Unreconcile Payment Entries", "Advance Payment Ledger Entry", + "Tax Withholding Entry", ) self.make_gl_entries(1) + JournalTaxWithholding(self).on_cancel() self.unlink_advance_entry_reference() self.unlink_asset_reference() self.unlink_inter_company_jv() @@ -352,95 +361,6 @@ class JournalEntry(AccountsController): StockAccountInvalidTransaction, ) - def apply_tax_withholding(self): - from erpnext.accounts.report.general_ledger.general_ledger import get_account_type_map - - if not self.apply_tds or self.voucher_type not in ("Debit Note", "Credit Note"): - return - - parties = [d.party for d in self.get("accounts") if d.party] - parties = list(set(parties)) - - if len(parties) > 1: - frappe.throw(_("Cannot apply TDS against multiple parties in one entry")) - - account_type_map = get_account_type_map(self.company) - party_type = "supplier" if self.voucher_type == "Credit Note" else "customer" - doctype = "Purchase Invoice" if self.voucher_type == "Credit Note" else "Sales Invoice" - debit_or_credit = ( - "debit_in_account_currency" - if self.voucher_type == "Credit Note" - else "credit_in_account_currency" - ) - rev_debit_or_credit = ( - "credit_in_account_currency" - if debit_or_credit == "debit_in_account_currency" - else "debit_in_account_currency" - ) - - party_account = get_party_account(party_type.title(), parties[0], self.company) - - net_total = sum( - d.get(debit_or_credit) - for d in self.get("accounts") - if account_type_map.get(d.account) not in ("Tax", "Chargeable") - ) - - party_amount = sum( - d.get(rev_debit_or_credit) for d in self.get("accounts") if d.account == party_account - ) - - inv = frappe._dict( - { - party_type: parties[0], - "doctype": doctype, - "company": self.company, - "posting_date": self.posting_date, - "net_total": net_total, - } - ) - - tax_withholding_details, advance_taxes, voucher_wise_amount = get_party_tax_withholding_details( - inv, self.tax_withholding_category - ) - - if not tax_withholding_details: - return - - accounts = [] - for d in self.get("accounts"): - if d.get("account") == tax_withholding_details.get("account_head"): - d.update( - { - "account": tax_withholding_details.get("account_head"), - debit_or_credit: tax_withholding_details.get("tax_amount"), - } - ) - - accounts.append(d.get("account")) - - if d.get("account") == party_account: - d.update({rev_debit_or_credit: party_amount - tax_withholding_details.get("tax_amount")}) - - if not accounts or tax_withholding_details.get("account_head") not in accounts: - self.append( - "accounts", - { - "account": tax_withholding_details.get("account_head"), - rev_debit_or_credit: tax_withholding_details.get("tax_amount"), - "against_account": parties[0], - }, - ) - - to_remove = [ - d - for d in self.get("accounts") - if not d.get(rev_debit_or_credit) and d.account == tax_withholding_details.get("account_head") - ] - - for d in to_remove: - self.remove(d) - def update_asset_value(self): self.update_asset_on_depreciation() self.update_asset_on_disposal() @@ -1719,6 +1639,9 @@ def get_account_details_and_party_type(account, date, company, debit=None, credi "party_type": party_type, "account_type": account_details.account_type, "account_currency": account_details.account_currency or company_currency, + "bank_account": ( + frappe.db.get_value("Bank Account", {"account": account, "company": company}) or None + ), # The date used to retreive the exchange rate here is the date passed in # as an argument to this function. It is assumed to be the date on which the balance is sought "exchange_rate": get_exchange_rate( @@ -1751,8 +1674,6 @@ def get_exchange_rate( credit=None, exchange_rate=None, ): - from erpnext.setup.utils import get_exchange_rate - account_details = frappe.get_cached_value( "Account", account, ["account_type", "root_type", "account_currency", "company"], as_dict=1 ) @@ -1775,7 +1696,7 @@ def get_exchange_rate( # The date used to retreive the exchange rate here is the date passed # in as an argument to this function. elif (not flt(exchange_rate) or flt(exchange_rate) == 1) and account_currency and posting_date: - exchange_rate = get_exchange_rate(account_currency, company_currency, posting_date) + exchange_rate = _get_exchange_rate(account_currency, company_currency, posting_date) else: exchange_rate = 1 diff --git a/erpnext/accounts/doctype/journal_entry_account/journal_entry_account.json b/erpnext/accounts/doctype/journal_entry_account/journal_entry_account.json index f1832255122..675bfcf86c8 100644 --- a/erpnext/accounts/doctype/journal_entry_account/journal_entry_account.json +++ b/erpnext/accounts/doctype/journal_entry_account/journal_entry_account.json @@ -34,6 +34,7 @@ "reference_detail_no", "advance_voucher_type", "advance_voucher_no", + "is_tax_withholding_account", "col_break3", "is_advance", "user_remark", @@ -281,12 +282,19 @@ "options": "advance_voucher_type", "read_only": 1, "search_index": 1 + }, + { + "default": "0", + "fieldname": "is_tax_withholding_account", + "fieldtype": "Check", + "label": "Is Tax Withholding Account", + "read_only": 1 } ], "idx": 1, "istable": 1, "links": [], - "modified": "2025-10-27 13:48:32.805100", + "modified": "2025-11-27 12:23:33.157655", "modified_by": "Administrator", "module": "Accounts", "name": "Journal Entry Account", diff --git a/erpnext/accounts/doctype/journal_entry_account/journal_entry_account.py b/erpnext/accounts/doctype/journal_entry_account/journal_entry_account.py index b801ac8c9a5..d26224103c0 100644 --- a/erpnext/accounts/doctype/journal_entry_account/journal_entry_account.py +++ b/erpnext/accounts/doctype/journal_entry_account/journal_entry_account.py @@ -28,6 +28,7 @@ class JournalEntryAccount(Document): debit_in_account_currency: DF.Currency exchange_rate: DF.Float is_advance: DF.Literal["No", "Yes"] + is_tax_withholding_account: DF.Check parent: DF.Data parentfield: DF.Data parenttype: DF.Data diff --git a/erpnext/accounts/doctype/opening_invoice_creation_tool/opening_invoice_creation_tool.py b/erpnext/accounts/doctype/opening_invoice_creation_tool/opening_invoice_creation_tool.py index 7555e6d957f..2f3a893a73f 100644 --- a/erpnext/accounts/doctype/opening_invoice_creation_tool/opening_invoice_creation_tool.py +++ b/erpnext/accounts/doctype/opening_invoice_creation_tool/opening_invoice_creation_tool.py @@ -214,6 +214,9 @@ class OpeningInvoiceCreationTool(Document): } ) + if self.invoice_type == "Purchase" and row.supplier_invoice_date: + invoice.update({"bill_date": row.supplier_invoice_date}) + accounting_dimension = get_accounting_dimensions() for dimension in accounting_dimension: invoice.update({dimension: self.get(dimension) or item.get(dimension)}) diff --git a/erpnext/accounts/doctype/opening_invoice_creation_tool_item/opening_invoice_creation_tool_item.json b/erpnext/accounts/doctype/opening_invoice_creation_tool_item/opening_invoice_creation_tool_item.json index bc9229d0701..29daab42439 100644 --- a/erpnext/accounts/doctype/opening_invoice_creation_tool_item/opening_invoice_creation_tool_item.json +++ b/erpnext/accounts/doctype/opening_invoice_creation_tool_item/opening_invoice_creation_tool_item.json @@ -12,6 +12,7 @@ "column_break_3", "posting_date", "due_date", + "supplier_invoice_date", "section_break_5", "item_name", "outstanding_amount", @@ -111,19 +112,26 @@ "fieldname": "invoice_number", "fieldtype": "Data", "label": "Invoice Number" + }, + { + "depends_on": "eval: parent.invoice_type == \"Purchase\"", + "fieldname": "supplier_invoice_date", + "fieldtype": "Date", + "label": "Supplier Invoice Date" } ], "istable": 1, "links": [], - "modified": "2024-03-27 13:10:06.703006", + "modified": "2025-12-01 16:18:07.997594", "modified_by": "Administrator", "module": "Accounts", "name": "Opening Invoice Creation Tool Item", "owner": "Administrator", "permissions": [], "quick_entry": 1, + "row_format": "Dynamic", "sort_field": "creation", "sort_order": "DESC", "states": [], "track_changes": 1 -} \ No newline at end of file +} diff --git a/erpnext/accounts/doctype/opening_invoice_creation_tool_item/opening_invoice_creation_tool_item.py b/erpnext/accounts/doctype/opening_invoice_creation_tool_item/opening_invoice_creation_tool_item.py index bc48300286f..1ea025322b4 100644 --- a/erpnext/accounts/doctype/opening_invoice_creation_tool_item/opening_invoice_creation_tool_item.py +++ b/erpnext/accounts/doctype/opening_invoice_creation_tool_item/opening_invoice_creation_tool_item.py @@ -26,6 +26,7 @@ class OpeningInvoiceCreationToolItem(Document): party_type: DF.Link | None posting_date: DF.Date | None qty: DF.Data | None + supplier_invoice_date: DF.Date | None temporary_opening_account: DF.Link | None # end: auto-generated types diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.js b/erpnext/accounts/doctype/payment_entry/payment_entry.js index 939cd0d113d..40544fe6159 100644 --- a/erpnext/accounts/doctype/payment_entry/payment_entry.js +++ b/erpnext/accounts/doctype/payment_entry/payment_entry.js @@ -41,6 +41,7 @@ frappe.ui.form.on("Payment Entry", { if (frm.is_new()) { set_default_party_type(frm); + frm.clear_table("tax_withholding_entries"); } }, @@ -532,6 +533,7 @@ frappe.ui.form.on("Payment Entry", { }, () => frm.set_value("party_name", r.message.party_name), () => frm.clear_table("references"), + () => frm.clear_table("tax_withholding_entries"), () => frm.events.hide_unhide_fields(frm), () => frm.events.set_dynamic_labels(frm), () => { @@ -564,14 +566,15 @@ frappe.ui.form.on("Payment Entry", { } }, - apply_tax_withholding_amount: function (frm) { - if (!frm.doc.apply_tax_withholding_amount) { + apply_tds: function (frm) { + if (!frm.doc.apply_tds) { frm.set_value("tax_withholding_category", ""); - } else { - frappe.db.get_value("Supplier", frm.doc.party, "tax_withholding_category", (values) => { + } else if (["Customer", "Supplier"].includes(frm.doc.party_type)) { + frappe.db.get_value(frm.doc.party_type, frm.doc.party, "tax_withholding_category", (values) => { frm.set_value("tax_withholding_category", values.tax_withholding_category); }); } + frm.clear_table("tax_withholding_entries"); }, paid_from: function (frm) { @@ -1277,15 +1280,14 @@ frappe.ui.form.on("Payment Entry", { let row = (frm.doc.deductions || []).find((t) => t.is_exchange_gain_loss); if (!row) { - const response = await get_company_defaults(frm.doc.company); - + const company_defaults = frappe.get_doc(":Company", frm.doc.company); const account = - response.message?.[account_fieldname] || + company_defaults?.[account_fieldname] || (await prompt_for_missing_account(frm, account_fieldname)); row = frm.add_child("deductions"); row.account = account; - row.cost_center = response.message?.cost_center; + row.cost_center = company_defaults?.cost_center; row.is_exchange_gain_loss = 1; } @@ -1495,18 +1497,14 @@ frappe.ui.form.on("Payment Entry", { "Can refer row only if the charge type is 'On Previous Row Amount' or 'Previous Row Total'" ); d.row_id = ""; - } else if ( - (d.charge_type == "On Previous Row Amount" || d.charge_type == "On Previous Row Total") && - d.row_id - ) { + } else if (d.charge_type == "On Previous Row Amount" || d.charge_type == "On Previous Row Total") { if (d.idx == 1) { msg = __( "Cannot select charge type as 'On Previous Row Amount' or 'On Previous Row Total' for first row" ); d.charge_type = ""; } else if (!d.row_id) { - msg = __("Please specify a valid Row ID for row {0} in table {1}", [d.idx, __(d.doctype)]); - d.row_id = ""; + d.row_id = d.idx - 1; } else if (d.row_id && d.row_id >= d.idx) { msg = __( "Cannot refer row number greater than or equal to current row number for this Charge type" diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.json b/erpnext/accounts/doctype/payment_entry/payment_entry.json index 551c70cab38..2a2494127f4 100644 --- a/erpnext/accounts/doctype/payment_entry/payment_entry.json +++ b/erpnext/accounts/doctype/payment_entry/payment_entry.json @@ -21,6 +21,8 @@ "party_name", "book_advance_payments_in_separate_party_account", "reconcile_on_advance_payment_date", + "apply_tds", + "tax_withholding_category", "column_break_11", "bank_account", "party_bank_account", @@ -60,10 +62,6 @@ "taxes_and_charges_section", "purchase_taxes_and_charges_template", "sales_taxes_and_charges_template", - "column_break_55", - "apply_tax_withholding_amount", - "tax_withholding_category", - "section_break_56", "taxes", "section_break_60", "base_total_taxes_and_charges", @@ -71,6 +69,11 @@ "total_taxes_and_charges", "deductions_or_loss_section", "deductions", + "section_tax_withholding_entry", + "tax_withholding_group", + "ignore_tax_withholding_threshold", + "override_tax_withholding_entries", + "tax_withholding_entries", "transaction_references", "reference_no", "column_break_23", @@ -578,24 +581,17 @@ "label": "Custom Remarks" }, { - "depends_on": "eval:doc.apply_tax_withholding_amount", + "depends_on": "eval:doc.apply_tds", "fieldname": "tax_withholding_category", "fieldtype": "Link", "label": "Tax Withholding Category", - "mandatory_depends_on": "eval:doc.apply_tax_withholding_amount", + "mandatory_depends_on": "eval:doc.apply_tds", "options": "Tax Withholding Category" }, { - "default": "0", - "depends_on": "eval:doc.party_type == 'Supplier'", - "fieldname": "apply_tax_withholding_amount", - "fieldtype": "Check", - "label": "Apply Tax Withholding Amount" - }, - { - "collapsible": 1, "fieldname": "taxes_and_charges_section", "fieldtype": "Section Break", + "hide_border": 1, "label": "Taxes and Charges" }, { @@ -648,15 +644,6 @@ "options": "Company:company:default_currency", "read_only": 1 }, - { - "fieldname": "column_break_55", - "fieldtype": "Column Break" - }, - { - "fieldname": "section_break_56", - "fieldtype": "Section Break", - "hide_border": 1 - }, { "depends_on": "eval:doc.received_amount && doc.payment_type != 'Internal Transfer'", "fieldname": "received_amount_after_tax", @@ -695,8 +682,7 @@ }, { "fieldname": "section_break_60", - "fieldtype": "Section Break", - "hide_border": 1 + "fieldtype": "Section Break" }, { "depends_on": "eval:doc.docstatus==0", @@ -753,6 +739,46 @@ "options": "No\nYes", "print_hide": 1, "search_index": 1 + }, + { + "default": "0", + "depends_on": "eval:doc.party_type == 'Supplier'", + "fieldname": "apply_tds", + "fieldtype": "Check", + "label": "Consider for Tax Withholding" + }, + { + "collapsible": 1, + "collapsible_depends_on": "eval: doc.apply_tds && doc.docstatus == 0", + "depends_on": "eval: doc.apply_tds", + "fieldname": "section_tax_withholding_entry", + "fieldtype": "Section Break", + "label": "Tax Withholding Entry" + }, + { + "fieldname": "tax_withholding_group", + "fieldtype": "Link", + "label": "Tax Withholding Group", + "options": "Tax Withholding Group" + }, + { + "default": "0", + "fieldname": "ignore_tax_withholding_threshold", + "fieldtype": "Check", + "label": "Ignore Tax Withholding Threshold" + }, + { + "fieldname": "tax_withholding_entries", + "fieldtype": "Table", + "label": "Tax Withholding Entries", + "options": "Tax Withholding Entry", + "read_only_depends_on": "eval: !doc.override_tax_withholding_entries" + }, + { + "default": "0", + "fieldname": "override_tax_withholding_entries", + "fieldtype": "Check", + "label": "Edit Tax Withholding Entries" } ], "grid_page_length": 50, @@ -767,7 +793,7 @@ "table_fieldname": "payment_entries" } ], - "modified": "2025-05-08 11:18:10.238085", + "modified": "2025-12-18 13:56:40.206038", "modified_by": "Administrator", "module": "Accounts", "name": "Payment Entry", diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.py b/erpnext/accounts/doctype/payment_entry/payment_entry.py index 4737e22e91a..eb1673a8798 100644 --- a/erpnext/accounts/doctype/payment_entry/payment_entry.py +++ b/erpnext/accounts/doctype/payment_entry/payment_entry.py @@ -30,9 +30,7 @@ from erpnext.accounts.doctype.repost_accounting_ledger.repost_accounting_ledger validate_docs_for_deferred_accounting, validate_docs_for_voucher_types, ) -from erpnext.accounts.doctype.tax_withholding_category.tax_withholding_category import ( - get_party_tax_withholding_details, -) +from erpnext.accounts.doctype.tax_withholding_entry.tax_withholding_entry import PaymentTaxWithholding from erpnext.accounts.general_ledger import ( make_gl_entries, make_reverse_gl_entries, @@ -80,9 +78,10 @@ class PaymentEntry(AccountsController): from erpnext.accounts.doctype.payment_entry_reference.payment_entry_reference import ( PaymentEntryReference, ) + from erpnext.accounts.doctype.tax_withholding_entry.tax_withholding_entry import TaxWithholdingEntry amended_from: DF.Link | None - apply_tax_withholding_amount: DF.Check + apply_tds: DF.Check auto_repeat: DF.Link | None bank: DF.ReadOnly | None bank_account: DF.Link | None @@ -103,11 +102,13 @@ class PaymentEntry(AccountsController): custom_remarks: DF.Check deductions: DF.Table[PaymentEntryDeduction] difference_amount: DF.Currency + ignore_tax_withholding_threshold: DF.Check in_words: DF.SmallText | None is_opening: DF.Literal["No", "Yes"] letter_head: DF.Link | None mode_of_payment: DF.Link | None naming_series: DF.Literal["ACC-PAY-.YYYY.-"] + override_tax_withholding_entries: DF.Check paid_amount: DF.Currency paid_amount_after_tax: DF.Currency paid_from: DF.Link @@ -139,6 +140,8 @@ class PaymentEntry(AccountsController): status: DF.Literal["", "Draft", "Submitted", "Cancelled"] target_exchange_rate: DF.Float tax_withholding_category: DF.Link | None + tax_withholding_entries: DF.Table[TaxWithholdingEntry] + tax_withholding_group: DF.Link | None taxes: DF.Table[AdvanceTaxesandCharges] title: DF.Data | None total_allocated_amount: DF.Currency @@ -189,7 +192,7 @@ class PaymentEntry(AccountsController): self.validate_allocated_amount() self.validate_paid_invoices() self.ensure_supplier_is_not_blocked() - self.set_tax_withholding() + PaymentTaxWithholding(self).on_validate() self.set_status() self.set_total_in_words() @@ -199,6 +202,7 @@ class PaymentEntry(AccountsController): def on_submit(self): if self.difference_amount: frappe.throw(_("Difference Amount must be zero")) + PaymentTaxWithholding(self).on_submit() self.update_payment_requests() self.update_payment_schedule() self.make_gl_entries() @@ -300,8 +304,10 @@ class PaymentEntry(AccountsController): "Unreconcile Payment", "Unreconcile Payment Entries", "Advance Payment Ledger Entry", + "Tax Withholding Entry", ) super().on_cancel() + PaymentTaxWithholding(self).on_cancel() self.update_payment_requests(cancel=True) self.update_payment_schedule(cancel=1) self.make_gl_entries(cancel=1) @@ -937,93 +943,6 @@ class PaymentEntry(AccountsController): self.base_in_words = money_in_words(base_amount, self.company_currency) self.in_words = money_in_words(amount, currency) - def set_tax_withholding(self): - if self.party_type != "Supplier": - return - - if not self.apply_tax_withholding_amount: - return - - net_total = self.calculate_tax_withholding_net_total() - - # Adding args as purchase invoice to get TDS amount - args = frappe._dict( - { - "company": self.company, - "doctype": "Payment Entry", - "supplier": self.party, - "posting_date": self.posting_date, - "net_total": net_total, - } - ) - - tax_withholding_details = get_party_tax_withholding_details(args, self.tax_withholding_category) - - if not tax_withholding_details: - return - - tax_withholding_details.update( - {"cost_center": self.cost_center or erpnext.get_default_cost_center(self.company)} - ) - - accounts = [] - for d in self.taxes: - if d.account_head == tax_withholding_details.get("account_head"): - # Preserve user updated included in paid amount - if d.included_in_paid_amount: - tax_withholding_details.update({"included_in_paid_amount": d.included_in_paid_amount}) - - d.update(tax_withholding_details) - accounts.append(d.account_head) - - if not accounts or tax_withholding_details.get("account_head") not in accounts: - self.append("taxes", tax_withholding_details) - - to_remove = [ - d - for d in self.taxes - if not d.tax_amount and d.account_head == tax_withholding_details.get("account_head") - ] - - for d in to_remove: - self.remove(d) - - def calculate_tax_withholding_net_total(self): - net_total = 0 - order_details = self.get_order_wise_tax_withholding_net_total() - - for d in self.references: - tax_withholding_net_total = order_details.get(d.reference_name) - if not tax_withholding_net_total: - continue - - net_taxable_outstanding = max( - 0, d.outstanding_amount - (d.total_amount - tax_withholding_net_total) - ) - - net_total += min(net_taxable_outstanding, d.allocated_amount) - - net_total += self.unallocated_amount - - return net_total - - def get_order_wise_tax_withholding_net_total(self): - if self.party_type == "Supplier": - doctype = "Purchase Order" - else: - doctype = "Sales Order" - - docnames = [d.reference_name for d in self.references if d.reference_doctype == doctype] - - return frappe._dict( - frappe.db.get_all( - doctype, - filters={"name": ["in", docnames]}, - fields=["name", "base_tax_withholding_net_total"], - as_list=True, - ) - ) - def apply_taxes(self): self.initialize_taxes() self.determine_exclusive_rate() @@ -1874,7 +1793,7 @@ class PaymentEntry(AccountsController): else: self.total_taxes_and_charges += current_tax_amount - self.base_total_taxes_and_charges += tax.base_tax_amount + self.base_total_taxes_and_charges += current_tax_amount if self.get("taxes"): self.paid_amount_after_tax = self.get("taxes")[-1].base_total diff --git a/erpnext/accounts/doctype/payment_entry_deduction/payment_entry_deduction.json b/erpnext/accounts/doctype/payment_entry_deduction/payment_entry_deduction.json index 42ed2130890..59a01bc84ef 100644 --- a/erpnext/accounts/doctype/payment_entry_deduction/payment_entry_deduction.json +++ b/erpnext/accounts/doctype/payment_entry_deduction/payment_entry_deduction.json @@ -59,14 +59,15 @@ "index_web_pages_for_search": 1, "istable": 1, "links": [], - "modified": "2024-11-05 16:07:47.307971", + "modified": "2025-08-13 06:52:46.130142", "modified_by": "Administrator", "module": "Accounts", "name": "Payment Entry Deduction", "owner": "Administrator", "permissions": [], "quick_entry": 1, + "row_format": "Dynamic", "sort_field": "creation", "sort_order": "DESC", "states": [] -} \ No newline at end of file +} diff --git a/erpnext/accounts/doctype/payment_entry_reference/payment_entry_reference.json b/erpnext/accounts/doctype/payment_entry_reference/payment_entry_reference.json index 77abc195ebc..4eeb9a1746b 100644 --- a/erpnext/accounts/doctype/payment_entry_reference/payment_entry_reference.json +++ b/erpnext/accounts/doctype/payment_entry_reference/payment_entry_reference.json @@ -38,7 +38,7 @@ "search_index": 1 }, { - "columns": 2, + "columns": 4, "fieldname": "reference_name", "fieldtype": "Dynamic Link", "in_global_search": 1, @@ -49,8 +49,10 @@ "search_index": 1 }, { + "columns": 2, "fieldname": "due_date", "fieldtype": "Date", + "in_list_view": 1, "label": "Due Date", "read_only": 1 }, @@ -174,7 +176,7 @@ "index_web_pages_for_search": 1, "istable": 1, "links": [], - "modified": "2025-07-25 04:32:11.040025", + "modified": "2025-12-08 13:57:30.098239", "modified_by": "Administrator", "module": "Accounts", "name": "Payment Entry Reference", diff --git a/erpnext/accounts/doctype/payment_ledger_entry/payment_ledger_entry.py b/erpnext/accounts/doctype/payment_ledger_entry/payment_ledger_entry.py index 30e885adacc..c1a28d12350 100644 --- a/erpnext/accounts/doctype/payment_ledger_entry/payment_ledger_entry.py +++ b/erpnext/accounts/doctype/payment_ledger_entry/payment_ledger_entry.py @@ -159,7 +159,7 @@ class PaymentLedgerEntry(Document): def on_update(self): adv_adj = self.flags.adv_adj if not self.flags.from_repost: - validate_frozen_account(self.account, adv_adj) + validate_frozen_account(self.company, self.account, adv_adj) if not self.delinked: self.validate_account_details() self.validate_dimensions_for_pl_and_bs() diff --git a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.js b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.js index 74a9f709caa..0732e2a7f0e 100644 --- a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.js +++ b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.js @@ -334,7 +334,9 @@ erpnext.accounts.PaymentReconciliationController = class PaymentReconciliationCo }, { fieldtype: "HTML", - options: " New Journal Entry will be posted for the difference amount ", + options: __( + "New Journal Entry will be posted for the difference amount. The Posting Date can be modified." + ).bold(), }, ], primary_action: () => { diff --git a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py index 4d0888f078e..e03db121473 100644 --- a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py +++ b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py @@ -765,6 +765,14 @@ class PaymentReconciliation(Document): def reconcile_dr_cr_note(dr_cr_notes, company, active_dimensions=None): for inv in dr_cr_notes: + if ( + abs(frappe.db.get_value(inv.voucher_type, inv.voucher_no, "outstanding_amount")) + < inv.allocated_amount + ): + frappe.throw( + _("{0} has been modified after you pulled it. Please pull it again.").format(inv.voucher_type) + ) + voucher_type = "Credit Note" if inv.voucher_type == "Sales Invoice" else "Debit Note" reconcile_dr_or_cr = ( diff --git a/erpnext/accounts/doctype/payment_request/payment_request.py b/erpnext/accounts/doctype/payment_request/payment_request.py index f970690016f..1de9ff936e5 100644 --- a/erpnext/accounts/doctype/payment_request/payment_request.py +++ b/erpnext/accounts/doctype/payment_request/payment_request.py @@ -427,6 +427,7 @@ class PaymentRequest(Document): context = { "doc": frappe.get_doc(self.reference_doctype, self.reference_name), "payment_url": self.payment_url, + "payment_request": self, } if self.message: @@ -539,6 +540,9 @@ def make_payment_request(**args): if args.dt not in ALLOWED_DOCTYPES_FOR_PAYMENT_REQUEST: frappe.throw(_("Payment Requests cannot be created against: {0}").format(frappe.bold(args.dt))) + if args.dn and not isinstance(args.dn, str): + frappe.throw(_("Invalid parameter. 'dn' should be of type str")) + ref_doc = args.ref_doc or frappe.get_doc(args.dt, args.dn) if not args.get("company"): args.company = ref_doc.company @@ -843,6 +847,7 @@ def update_payment_requests_as_per_pe_references(references=None, cancel=False): ) referenced_payment_requests = {pr.name: pr for pr in referenced_payment_requests} + doc_updates = {} for ref in references: if not ref.payment_request: @@ -868,7 +873,7 @@ def update_payment_requests_as_per_pe_references(references=None, cancel=False): title=_("Invalid Allocated Amount"), ) - # update status + # determine status if new_outstanding_amount == payment_request["grand_total"]: status = "Initiated" if payment_request["payment_request_type"] == "Outward" else "Requested" elif new_outstanding_amount == 0: @@ -876,31 +881,37 @@ def update_payment_requests_as_per_pe_references(references=None, cancel=False): elif new_outstanding_amount > 0: status = "Partially Paid" - # update database - frappe.db.set_value( - "Payment Request", - ref.payment_request, - {"outstanding_amount": new_outstanding_amount, "status": status}, - ) + # prepare bulk update data + doc_updates[ref.payment_request] = { + "outstanding_amount": new_outstanding_amount, + "status": status, + } + + # bulk update all payment requests + if doc_updates: + frappe.db.bulk_update("Payment Request", doc_updates) def get_dummy_message(doc): - return frappe.render_template( - """{% if doc.contact_person -%} -

Dear {{ doc.contact_person }},

-{%- else %}

Hello,

{% endif %} + return """ + {% if doc.contact_person -%} +

Dear {{ doc.contact_person }},

+ {%- else %}

Hello,

{% endif %} -

{{ _("Requesting payment against {0} {1} for amount {2}").format(doc.doctype, - doc.name, doc.get_formatted("grand_total")) }}

+

+ {{ _("Requesting payment against {0} {1} for amount {2}").format( + doc.doctype, + doc.name, + payment_request.get_formatted("grand_total") + ) }} +

-{{ _("Make Payment") }} + {{ _("Make Payment") }} -

{{ _("If you have any questions, please get back to us.") }}

+

{{ _("If you have any questions, please get back to us.") }}

-

{{ _("Thank you for your business!") }}

-""", - dict(doc=doc, payment_url="{{ payment_url }}"), - ) +

{{ _("Thank you for your business!") }}

+ """ @frappe.whitelist() diff --git a/erpnext/accounts/doctype/pos_invoice/pos_invoice.py b/erpnext/accounts/doctype/pos_invoice/pos_invoice.py index d4825b87212..503c19c7ff8 100644 --- a/erpnext/accounts/doctype/pos_invoice/pos_invoice.py +++ b/erpnext/accounts/doctype/pos_invoice/pos_invoice.py @@ -20,6 +20,11 @@ from erpnext.accounts.party import get_due_date, get_party_account from erpnext.controllers.queries import item_query as _item_query from erpnext.controllers.sales_and_purchase_return import get_sales_invoice_item_from_consolidated_invoice from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos +from erpnext.stock.stock_ledger import is_negative_stock_allowed + + +class ProductBundleStockValidationError(frappe.ValidationError): + pass class POSInvoice(SalesInvoice): @@ -395,32 +400,67 @@ class POSInvoice(SalesInvoice): for d in self.get("items"): if not d.serial_and_batch_bundle: - available_stock, is_stock_item, is_negative_stock_allowed = get_stock_availability( - d.item_code, d.warehouse - ) + if frappe.db.exists("Product Bundle", d.item_code): + ( + availability, + is_stock_item, + is_negative_stock_allowed, + ) = get_product_bundle_stock_availability(d.item_code, d.warehouse, d.stock_qty) + + else: + availability, is_stock_item, is_negative_stock_allowed = get_stock_availability( + d.item_code, d.warehouse + ) if is_negative_stock_allowed: continue - item_code, warehouse, _qty = ( - frappe.bold(d.item_code), - frappe.bold(d.warehouse), - frappe.bold(d.qty), - ) - if is_stock_item and flt(available_stock) <= 0: - frappe.throw( - _("Row #{}: Item Code: {} is not available under warehouse {}.").format( - d.idx, item_code, warehouse - ), - title=_("Item Unavailable"), - ) - elif is_stock_item and flt(available_stock) < flt(d.stock_qty): - frappe.throw( - _("Row #{}: Stock quantity not enough for Item Code: {} under warehouse {}.").format( - d.idx, item_code, warehouse - ), - title=_("Item Unavailable"), - ) + if isinstance(availability, list): + error_msgs = [] + for item in availability: + if flt(item["available"]) < flt(item["required"]): + error_msgs.append( + _("
  • Packed Item {0}: Required {1}, Available {2}
  • ").format( + frappe.bold(item["item_code"]), + frappe.bold(flt(item["required"], 2)), + frappe.bold(flt(item["available"], 2)), + ) + ) + + if error_msgs: + frappe.throw( + _( + "Row #{0}: Bundle {1} in warehouse {2} has insufficient packed items:
    " + ).format( + d.idx, + frappe.bold(d.item_code), + frappe.bold(d.warehouse), + "
    ".join(error_msgs), + ), + title=_("Insufficient Stock for Product Bundle Items"), + exc=ProductBundleStockValidationError, + ) + + else: + item_code, warehouse = frappe.bold(d.item_code), frappe.bold(d.warehouse) + if is_stock_item and flt(availability) <= 0: + frappe.throw( + _("Row #{0}: Item {1} has no stock in warehouse {2}.").format( + d.idx, item_code, warehouse + ), + title=_("Item Out of Stock"), + ) + elif is_stock_item and flt(availability) < flt(d.stock_qty): + frappe.throw( + _("Row #{0}: Item {1} in warehouse {2}: Available {3}, Needed {4}.").format( + d.idx, + item_code, + warehouse, + frappe.bold(flt(availability, 2)), + frappe.bold(flt(d.stock_qty, 2)), + ), + title=_("Insufficient Stock"), + ) def validate_is_pos_using_sales_invoice(self): self.invoice_type_in_pos = frappe.db.get_single_value("POS Settings", "invoice_type") @@ -858,8 +898,6 @@ class POSInvoice(SalesInvoice): @frappe.whitelist() def get_stock_availability(item_code, warehouse): - from erpnext.stock.stock_ledger import is_negative_stock_allowed - if frappe.db.get_value("Item", item_code, "is_stock_item"): is_stock_item = True bin_qty = get_bin_qty(item_code, warehouse) @@ -876,6 +914,26 @@ def get_stock_availability(item_code, warehouse): return 0, is_stock_item, False +def get_product_bundle_stock_availability(item_code, warehouse, item_qty): + is_stock_item = True + bundle = frappe.get_doc("Product Bundle", item_code) + availabilities = [] + for bundle_item in bundle.items: + if frappe.get_value("Item", bundle_item.item_code, "is_stock_item"): + bin_qty = get_bin_qty(bundle_item.item_code, warehouse) + reserved_qty = get_pos_reserved_qty(bundle_item.item_code, warehouse) + available = bin_qty - reserved_qty + availabilities.append( + { + "item_code": bundle_item.item_code, + "required": bundle_item.qty * item_qty, + "available": available, + } + ) + + return availabilities, is_stock_item, is_negative_stock_allowed(item_code=item_code) + + def get_bundle_availability(bundle_item_code, warehouse): product_bundle = frappe.get_doc("Product Bundle", bundle_item_code) diff --git a/erpnext/accounts/doctype/pos_invoice/test_pos_invoice.py b/erpnext/accounts/doctype/pos_invoice/test_pos_invoice.py index a1282f07717..58985195867 100644 --- a/erpnext/accounts/doctype/pos_invoice/test_pos_invoice.py +++ b/erpnext/accounts/doctype/pos_invoice/test_pos_invoice.py @@ -1024,6 +1024,84 @@ class TestPOSInvoice(IntegrationTestCase): frappe.db.rollback(save_point="before_test_delivered_serial_no_case") frappe.set_user("Administrator") + def test_bundle_stock_availability_validation(self): + from erpnext.accounts.doctype.pos_invoice.pos_invoice import ProductBundleStockValidationError + from erpnext.accounts.doctype.pos_invoice_merge_log.test_pos_invoice_merge_log import ( + init_user_and_profile, + ) + from erpnext.selling.doctype.product_bundle.test_product_bundle import make_product_bundle + from erpnext.stock.doctype.item.test_item import create_item + + init_user_and_profile() + + frappe.set_user("Administrator") + + warehouse = "_Test Warehouse - _TC" + company = "_Test Company" + + # Create stock sub-items + sub_item_a = "_Test Bundle SubA" + if not frappe.db.exists("Item", sub_item_a): + create_item( + item_code=sub_item_a, + is_stock_item=1, + ) + + sub_item_b = "_Test Bundle SubB" + if not frappe.db.exists("Item", sub_item_b): + create_item( + item_code=sub_item_b, + is_stock_item=1, + ) + + # Add initial stock: SubA=5, SubB=2 + make_stock_entry(item_code=sub_item_a, target=warehouse, qty=5, company=company) + make_stock_entry(item_code=sub_item_b, target=warehouse, qty=2, company=company) + + # Create Product Bundle: Test Bundle (SubA x2 + SubB x1) + bundle_item = "_Test Bundle" + if not frappe.db.exists("Item", bundle_item): + create_item( + item_code=bundle_item, + is_stock_item=0, + ) + + if not frappe.db.exists("Product Bundle", bundle_item): + make_product_bundle(parent=bundle_item, items=[sub_item_a, sub_item_b]) + + # Test Case 1: Sufficient stock (bundle qty=1: requires SubA=2 (<=5), SubB=1 (<=2)) -> No error + pos_inv_sufficient = create_pos_invoice( + item=bundle_item, + qty=1, + rate=100, + warehouse=warehouse, + pos_profile=self.pos_profile.name, + do_not_save=1, + ) + pos_inv_sufficient.append("payments", {"mode_of_payment": "Cash", "amount": 100, "default": 1}) + pos_inv_sufficient.insert() + pos_inv_sufficient.submit() + + pos_inv_sufficient.cancel() + pos_inv_sufficient.delete() + + # Test Case 2: Insufficient stock (reduce SubB to 1, bundle qty=2: requires SubB=2 >1) -> Error with details + make_stock_entry(item_code=sub_item_b, from_warehouse=warehouse, qty=1, company=company) + + pos_inv_insufficient = create_pos_invoice( + item=bundle_item, + qty=2, + rate=100, + warehouse=warehouse, + pos_profile=self.pos_profile.name, + do_not_save=1, + ) + pos_inv_insufficient.append("payments", {"mode_of_payment": "Cash", "amount": 200, "default": 1}) + pos_inv_insufficient.save() + self.assertRaises(ProductBundleStockValidationError, pos_inv_insufficient.submit) + + frappe.set_user("test@example.com") + def create_pos_invoice(**args): args = frappe._dict(args) diff --git a/erpnext/accounts/doctype/pricing_rule/utils.py b/erpnext/accounts/doctype/pricing_rule/utils.py index f276235d402..efbd0ce5fae 100644 --- a/erpnext/accounts/doctype/pricing_rule/utils.py +++ b/erpnext/accounts/doctype/pricing_rule/utils.py @@ -244,7 +244,7 @@ def get_other_conditions(conditions, values, args): conditions += " and " + group_condition date = args.get("transaction_date") or frappe.get_value( - args.get("doctype"), args.get("name"), "posting_date" + args.get("doctype"), args.get("name"), "posting_date", ignore=True ) if date: conditions += """ and %(transaction_date)s between ifnull(`tabPricing Rule`.valid_from, '2000-01-01') diff --git a/erpnext/accounts/doctype/process_deferred_accounting/test_process_deferred_accounting.py b/erpnext/accounts/doctype/process_deferred_accounting/test_process_deferred_accounting.py index 97fc47b01b9..b987d1579e8 100644 --- a/erpnext/accounts/doctype/process_deferred_accounting/test_process_deferred_accounting.py +++ b/erpnext/accounts/doctype/process_deferred_accounting/test_process_deferred_accounting.py @@ -16,7 +16,7 @@ from erpnext.stock.doctype.item.test_item import create_item class TestProcessDeferredAccounting(IntegrationTestCase): def test_creation_of_ledger_entry_on_submit(self): """test creation of gl entries on submission of document""" - change_acc_settings(acc_frozen_upto="2023-05-31", book_deferred_entries_based_on="Months") + change_acc_settings(acc_frozen_till_date="2023-05-31", book_deferred_entries_based_on="Months") deferred_account = create_account( account_name="Deferred Revenue for Accounts Frozen", @@ -92,8 +92,10 @@ class TestProcessDeferredAccounting(IntegrationTestCase): pda.cancel() -def change_acc_settings(acc_frozen_upto="", book_deferred_entries_based_on="Days"): +def change_acc_settings( + company="_Test Company", acc_frozen_till_date=None, book_deferred_entries_based_on="Days" +): acc_settings = frappe.get_doc("Accounts Settings", "Accounts Settings") - acc_settings.acc_frozen_upto = acc_frozen_upto acc_settings.book_deferred_entries_based_on = book_deferred_entries_based_on + frappe.db.set_value("Company", company, "accounts_frozen_till_date", acc_frozen_till_date) acc_settings.save() diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js index 0cda42a6ca2..0aa6fa85605 100644 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js @@ -12,6 +12,7 @@ erpnext.buying.setup_buying_controller(); erpnext.accounts.PurchaseInvoice = class PurchaseInvoice extends erpnext.buying.BuyingController { setup(doc) { + this.setup_accounting_dimension_triggers(); this.setup_posting_date_time_check(); super.setup(doc); @@ -129,7 +130,7 @@ erpnext.accounts.PurchaseInvoice = class PurchaseInvoice extends erpnext.buying. } } - if (doc.outstanding_amount > 0 && !cint(doc.is_return) && !doc.on_hold) { + if (doc.docstatus == 1 && doc.outstanding_amount > 0 && !cint(doc.is_return) && !doc.on_hold) { this.frm.add_custom_button( __("Payment Request"), function () { @@ -223,7 +224,6 @@ erpnext.accounts.PurchaseInvoice = class PurchaseInvoice extends erpnext.buying. }); } - this.frm.set_df_property("tax_withholding_category", "hidden", doc.apply_tds ? 0 : 1); erpnext.accounts.unreconcile_payment.add_unreconcile_btn(me.frm); } @@ -363,10 +363,9 @@ erpnext.accounts.PurchaseInvoice = class PurchaseInvoice extends erpnext.buying. }, function () { me.apply_pricing_rule(); - me.frm.doc.apply_tds = me.frm.supplier_tds ? 1 : 0; - me.frm.doc.tax_withholding_category = me.frm.supplier_tds; - me.frm.set_df_property("apply_tds", "read_only", me.frm.supplier_tds ? 0 : 1); - me.frm.set_df_property("tax_withholding_category", "hidden", me.frm.supplier_tds ? 0 : 1); + me.frm.doc.apply_tds = + me.frm.tax_withholding_category || me.frm.tax_withholding_group ? 1 : 0; + me.frm.clear_table("tax_withholding_entries"); // while duplicating, don't change payment terms if (me.frm.doc.__run_link_triggers === false) { @@ -379,26 +378,7 @@ erpnext.accounts.PurchaseInvoice = class PurchaseInvoice extends erpnext.buying. apply_tds(frm) { var me = this; - me.frm.set_value("tax_withheld_vouchers", []); - if (!me.frm.doc.apply_tds) { - me.frm.set_value("tax_withholding_category", ""); - me.frm.set_df_property("tax_withholding_category", "hidden", 1); - } else { - me.frm.set_value("tax_withholding_category", me.frm.supplier_tds); - me.frm.set_df_property("tax_withholding_category", "hidden", 0); - } - } - - tax_withholding_category(frm) { - var me = this; - let filtered_taxes = (me.frm.doc.taxes || []).filter((row) => !row.is_tax_withholding_account); - me.frm.clear_table("taxes"); - - filtered_taxes.forEach((row) => { - me.frm.add_child("taxes", row); - }); - - me.frm.refresh_field("taxes"); + me.frm.clear_table("tax_withholding_entries"); } credit_to() { @@ -578,17 +558,6 @@ cur_frm.fields_dict["items"].grid.get_field("cost_center").get_query = function }; }; -cur_frm.cscript.cost_center = function (doc, cdt, cdn) { - var d = locals[cdt][cdn]; - if (d.cost_center) { - var cl = doc.items || []; - for (var i = 0; i < cl.length; i++) { - if (!cl[i].cost_center) cl[i].cost_center = d.cost_center; - } - } - refresh_field("items"); -}; - cur_frm.fields_dict["items"].grid.get_field("project").get_query = function (doc, cdt, cdn) { return { filters: [["Project", "status", "not in", "Completed, Cancelled"]], @@ -702,10 +671,7 @@ frappe.ui.form.on("Purchase Invoice", { onload: function (frm) { if (frm.doc.__onload && frm.doc.supplier) { if (frm.is_new()) { - frm.doc.apply_tds = frm.doc.__onload.supplier_tds ? 1 : 0; - } - if (!frm.doc.__onload.supplier_tds) { - frm.set_df_property("apply_tds", "read_only", 1); + frm.doc.apply_tds = frm.doc.__onload.apply_tds ? 1 : 0; } } @@ -714,7 +680,7 @@ frappe.ui.form.on("Purchase Invoice", { }); if (frm.is_new()) { - frm.clear_table("tax_withheld_vouchers"); + frm.clear_table("tax_withholding_entries"); } }, @@ -741,6 +707,7 @@ frappe.ui.form.on("Purchase Invoice", { company: function (frm) { erpnext.accounts.dimensions.update_dimension(frm, frm.doctype); + frm.clear_table("tax_withholding_entries"); if (frm.doc.company) { frappe.call({ diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json index d2efe60e459..bd86928766c 100644 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json @@ -27,7 +27,6 @@ "update_billed_amount_in_purchase_order", "update_billed_amount_in_purchase_receipt", "apply_tds", - "tax_withholding_category", "amended_from", "supplier_invoice_details", "bill_no", @@ -68,8 +67,6 @@ "column_break_28", "total", "net_total", - "tax_withholding_net_total", - "base_tax_withholding_net_total", "taxes_section", "tax_category", "taxes_and_charges", @@ -102,14 +99,17 @@ "total_advance", "outstanding_amount", "disable_rounded_total", + "section_tax_withholding_entry", + "tax_withholding_group", + "ignore_tax_withholding_threshold", + "override_tax_withholding_entries", + "tax_withholding_entries", "section_break_44", "apply_discount_on", "base_discount_amount", "column_break_46", "additional_discount_percentage", "discount_amount", - "tax_withheld_vouchers_section", - "tax_withheld_vouchers", "sec_tax_breakup", "other_charges_calculation", "item_wise_tax_details", @@ -130,7 +130,6 @@ "only_include_allocated_payments", "get_advances", "advances", - "advance_tax", "write_off", "write_off_amount", "base_write_off_amount", @@ -286,7 +285,7 @@ "default": "0", "fieldname": "apply_tds", "fieldtype": "Check", - "label": "Apply Tax Withholding Amount", + "label": "Consider for Tax Withholding", "print_hide": 1 }, { @@ -1358,14 +1357,6 @@ "fieldname": "dimension_col_break", "fieldtype": "Column Break" }, - { - "fieldname": "tax_withholding_category", - "fieldtype": "Link", - "hidden": 1, - "label": "Tax Withholding Category", - "options": "Tax Withholding Category", - "print_hide": 1 - }, { "fieldname": "billing_address", "fieldtype": "Link", @@ -1455,14 +1446,6 @@ "fieldname": "column_break_147", "fieldtype": "Column Break" }, - { - "fieldname": "advance_tax", - "fieldtype": "Table", - "hidden": 1, - "label": "Advance Tax", - "options": "Advance Tax", - "read_only": 1 - }, { "fieldname": "subscription", "fieldtype": "Link", @@ -1477,42 +1460,6 @@ "label": "Is Old Subcontracting Flow", "read_only": 1 }, - { - "default": "0", - "depends_on": "apply_tds", - "fieldname": "tax_withholding_net_total", - "fieldtype": "Currency", - "hidden": 1, - "label": "Tax Withholding Net Total", - "no_copy": 1, - "options": "currency", - "read_only": 1 - }, - { - "depends_on": "apply_tds", - "fieldname": "base_tax_withholding_net_total", - "fieldtype": "Currency", - "hidden": 1, - "label": "Base Tax Withholding Net Total", - "no_copy": 1, - "options": "Company:company:default_currency", - "print_hide": 1, - "read_only": 1 - }, - { - "collapsible_depends_on": "tax_withheld_vouchers", - "fieldname": "tax_withheld_vouchers_section", - "fieldtype": "Section Break", - "label": "Tax Withheld Vouchers" - }, - { - "fieldname": "tax_withheld_vouchers", - "fieldtype": "Table", - "label": "Tax Withheld Vouchers", - "no_copy": 1, - "options": "Tax Withheld Vouchers", - "read_only": 1 - }, { "fieldname": "payments_tab", "fieldtype": "Tab Break", @@ -1662,7 +1609,7 @@ "fieldtype": "Data", "is_virtual": 1, "label": "Last Scanned Warehouse" - }, + }, { "fieldname": "claimed_landed_cost_amount", "fieldtype": "Currency", @@ -1679,6 +1626,40 @@ "label": "Item Wise Tax Details", "no_copy": 1, "options": "Item Wise Tax Detail" + }, + { + "collapsible": 1, + "collapsible_depends_on": "eval: doc.apply_tds && doc.docstatus == 0", + "depends_on": "eval: doc.apply_tds", + "fieldname": "section_tax_withholding_entry", + "fieldtype": "Section Break", + "label": "Tax Withholding Entry" + }, + { + "fieldname": "tax_withholding_group", + "fieldtype": "Link", + "label": "Tax Withholding Group", + "options": "Tax Withholding Group", + "print_hide": 1 + }, + { + "fieldname": "tax_withholding_entries", + "fieldtype": "Table", + "label": "Tax Withholding Entries", + "options": "Tax Withholding Entry", + "read_only_depends_on": "eval: !doc.override_tax_withholding_entries" + }, + { + "default": "0", + "fieldname": "ignore_tax_withholding_threshold", + "fieldtype": "Check", + "label": "Ignore Tax Withholding Threshold" + }, + { + "default": "0", + "fieldname": "override_tax_withholding_entries", + "fieldtype": "Check", + "label": "Edit Tax Withholding Entries" } ], "grid_page_length": 50, @@ -1686,7 +1667,7 @@ "idx": 204, "is_submittable": 1, "links": [], - "modified": "2025-08-04 19:19:11.380664", + "modified": "2025-12-15 06:41:38.237728", "modified_by": "Administrator", "module": "Accounts", "name": "Purchase Invoice", diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py index bdd936a520b..888dbd59438 100644 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py @@ -24,9 +24,7 @@ from erpnext.accounts.doctype.sales_invoice.sales_invoice import ( update_linked_doc, validate_inter_company_party, ) -from erpnext.accounts.doctype.tax_withholding_category.tax_withholding_category import ( - get_party_tax_withholding_details, -) +from erpnext.accounts.doctype.tax_withholding_entry.tax_withholding_entry import PurchaseTaxWithholding from erpnext.accounts.general_ledger import ( get_round_off_account_and_cost_center, make_gl_entries, @@ -61,7 +59,6 @@ class PurchaseInvoice(BuyingController): if TYPE_CHECKING: from frappe.types import DF - from erpnext.accounts.doctype.advance_tax.advance_tax import AdvanceTax from erpnext.accounts.doctype.item_wise_tax_detail.item_wise_tax_detail import ItemWiseTaxDetail from erpnext.accounts.doctype.payment_schedule.payment_schedule import PaymentSchedule from erpnext.accounts.doctype.pricing_rule_detail.pricing_rule_detail import PricingRuleDetail @@ -72,14 +69,13 @@ class PurchaseInvoice(BuyingController): from erpnext.accounts.doctype.purchase_taxes_and_charges.purchase_taxes_and_charges import ( PurchaseTaxesandCharges, ) - from erpnext.accounts.doctype.tax_withheld_vouchers.tax_withheld_vouchers import TaxWithheldVouchers + from erpnext.accounts.doctype.tax_withholding_entry.tax_withholding_entry import TaxWithholdingEntry from erpnext.buying.doctype.purchase_receipt_item_supplied.purchase_receipt_item_supplied import ( PurchaseReceiptItemSupplied, ) additional_discount_percentage: DF.Float address_display: DF.TextEditor | None - advance_tax: DF.Table[AdvanceTax] advances: DF.Table[PurchaseInvoiceAdvance] against_expense_account: DF.SmallText | None allocate_advances_automatically: DF.Check @@ -94,7 +90,6 @@ class PurchaseInvoice(BuyingController): base_paid_amount: DF.Currency base_rounded_total: DF.Currency base_rounding_adjustment: DF.Currency - base_tax_withholding_net_total: DF.Currency base_taxes_and_charges_added: DF.Currency base_taxes_and_charges_deducted: DF.Currency base_total: DF.Currency @@ -128,6 +123,7 @@ class PurchaseInvoice(BuyingController): hold_comment: DF.SmallText | None ignore_default_payment_terms_template: DF.Check ignore_pricing_rule: DF.Check + ignore_tax_withholding_threshold: DF.Check in_words: DF.Data | None incoterm: DF.Link | None inter_company_invoice_reference: DF.Link | None @@ -149,6 +145,7 @@ class PurchaseInvoice(BuyingController): only_include_allocated_payments: DF.Check other_charges_calculation: DF.TextEditor | None outstanding_amount: DF.Currency + override_tax_withholding_entries: DF.Check paid_amount: DF.Currency party_account_currency: DF.Link | None payment_schedule: DF.Table[PaymentSchedule] @@ -198,9 +195,8 @@ class PurchaseInvoice(BuyingController): supplier_warehouse: DF.Link | None tax_category: DF.Link | None tax_id: DF.ReadOnly | None - tax_withheld_vouchers: DF.Table[TaxWithheldVouchers] - tax_withholding_category: DF.Link | None - tax_withholding_net_total: DF.Currency + tax_withholding_entries: DF.Table[TaxWithholdingEntry] + tax_withholding_group: DF.Link | None taxes: DF.Table[PurchaseTaxesandCharges] taxes_and_charges: DF.Link | None taxes_and_charges_added: DF.Currency @@ -245,11 +241,14 @@ class PurchaseInvoice(BuyingController): def onload(self): super().onload() - supplier_tds = frappe.db.get_value("Supplier", self.supplier, "tax_withholding_category") - self.set_onload("supplier_tds", supplier_tds) + if self.supplier: + tax_withholding_category, tax_withholding_group = frappe.get_cached_value( + "Supplier", self.supplier, ["tax_withholding_category", "tax_withholding_group"] + ) + self.set_onload("apply_tds", tax_withholding_category or tax_withholding_group) if self.is_new(): - self.set("tax_withheld_vouchers", []) + self.set("tax_withholding_entries", []) def before_save(self): if not self.on_hold: @@ -300,6 +299,7 @@ class PurchaseInvoice(BuyingController): self.reset_default_field_value("set_warehouse", "items", "warehouse") self.reset_default_field_value("rejected_warehouse", "items", "rejected_warehouse") self.reset_default_field_value("set_from_warehouse", "items", "from_warehouse") + PurchaseTaxWithholding(self).on_validate() self.set_percentage_received() def set_percentage_received(self): @@ -352,11 +352,13 @@ class PurchaseInvoice(BuyingController): template_name=self.payment_terms_template, ) - tds_category = frappe.db.get_value("Supplier", self.supplier, "tax_withholding_category") - if tds_category and not for_validate: - self.apply_tds = 1 - self.tax_withholding_category = tds_category - self.set_onload("supplier_tds", tds_category) + if self.supplier: + tax_withholding_category, tax_withholding_group = frappe.get_cached_value( + "Supplier", self.supplier, ["tax_withholding_category", "tax_withholding_group"] + ) + if not for_validate: + if tax_withholding_category or tax_withholding_group: + self.apply_tds = 1 super().set_missing_values(for_validate) @@ -747,6 +749,7 @@ class PurchaseInvoice(BuyingController): def on_submit(self): super().on_submit() + PurchaseTaxWithholding(self).on_submit() self.check_prev_docstatus() @@ -788,7 +791,6 @@ class PurchaseInvoice(BuyingController): self.update_project() update_linked_doc(self.doctype, self.name, self.inter_company_invoice_reference) - self.update_advance_tax_references() self.process_common_party_accounting() @@ -1672,6 +1674,7 @@ class PurchaseInvoice(BuyingController): check_if_return_invoice_linked_with_payment_entry(self) super().on_cancel() + PurchaseTaxWithholding(self).on_cancel() self.check_on_hold_or_closed_status() @@ -1718,10 +1721,9 @@ class PurchaseInvoice(BuyingController): "Unreconcile Payment", "Unreconcile Payment Entries", "Payment Ledger Entry", - "Tax Withheld Vouchers", "Serial and Batch Bundle", + "Tax Withholding Entry", ) - self.update_advance_tax_references(cancel=1) def update_project(self): projects = frappe._dict() @@ -1844,102 +1846,6 @@ class PurchaseInvoice(BuyingController): self.db_set("on_hold", 0) self.db_set("release_date", None) - def set_tax_withholding(self): - self.set("advance_tax", []) - self.set("tax_withheld_vouchers", []) - - if not self.apply_tds: - return - - if self.apply_tds and not self.get("tax_withholding_category"): - self.tax_withholding_category = frappe.db.get_value( - "Supplier", self.supplier, "tax_withholding_category" - ) - - if not self.tax_withholding_category: - return - - tax_withholding_details, advance_taxes, voucher_wise_amount = get_party_tax_withholding_details( - self, self.tax_withholding_category - ) - - # Adjust TDS paid on advances - self.allocate_advance_tds(tax_withholding_details, advance_taxes) - - if not tax_withholding_details: - return - - accounts = [] - for d in self.taxes: - if d.account_head == tax_withholding_details.get("account_head"): - d.update(tax_withholding_details) - - accounts.append(d.account_head) - - if not accounts or tax_withholding_details.get("account_head") not in accounts: - self.append("taxes", tax_withholding_details) - - to_remove = [ - d - for d in self.taxes - if not d.tax_amount and d.account_head == tax_withholding_details.get("account_head") - ] - - for d in to_remove: - self.remove(d) - - ## Add pending vouchers on which tax was withheld - for row in voucher_wise_amount: - self.append( - "tax_withheld_vouchers", - { - "voucher_name": row.voucher_name, - "voucher_type": row.voucher_type, - "taxable_amount": row.taxable_amount, - }, - ) - - # calculate totals again after applying TDS - self.calculate_taxes_and_totals() - - def allocate_advance_tds(self, tax_withholding_details, advance_taxes): - for tax in advance_taxes: - allocated_amount = 0 - pending_amount = flt(tax.tax_amount - tax.allocated_amount) - if flt(tax_withholding_details.get("tax_amount")) >= pending_amount: - tax_withholding_details["tax_amount"] -= pending_amount - allocated_amount = pending_amount - elif ( - flt(tax_withholding_details.get("tax_amount")) - and flt(tax_withholding_details.get("tax_amount")) < pending_amount - ): - allocated_amount = tax_withholding_details["tax_amount"] - tax_withholding_details["tax_amount"] = 0 - - self.append( - "advance_tax", - { - "reference_type": "Payment Entry", - "reference_name": tax.parent, - "reference_detail": tax.name, - "account_head": tax.account_head, - "allocated_amount": allocated_amount, - }, - ) - - def update_advance_tax_references(self, cancel=0): - for tax in self.get("advance_tax"): - at = frappe.qb.DocType("Advance Taxes and Charges").as_("at") - - if cancel: - frappe.qb.update(at).set( - at.allocated_amount, at.allocated_amount - tax.allocated_amount - ).where(at.name == tax.reference_detail).run() - else: - frappe.qb.update(at).set( - at.allocated_amount, at.allocated_amount + tax.allocated_amount - ).where(at.name == tax.reference_detail).run() - def set_status(self, update=False, status=None, update_modified=True): if self.is_new(): if self.get("amended_from"): @@ -2027,6 +1933,7 @@ def get_list_context(context=None): "show_search": True, "no_breadcrumbs": True, "title": _("Purchase Invoices"), + "list_template": "templates/includes/list/list.html", } ) return list_context @@ -2097,10 +2004,26 @@ def make_purchase_receipt(source_name, target_doc=None, args=None): if isinstance(args, str): args = json.loads(args) + def post_parent_process(source_parent, target_parent): + for row in target_parent.get("items"): + if row.get("qty") == 0: + target_parent.remove(row) + def update_item(obj, target, source_parent): - target.qty = flt(obj.qty) - flt(obj.received_qty) + from erpnext.controllers.sales_and_purchase_return import get_returned_qty_map_for_row + + returned_qty_map = ( + get_returned_qty_map_for_row( + source_parent.name, source_parent.supplier, obj.name, "Purchase Invoice" + ) + or {} + ) + + target.qty = flt(obj.qty) - flt(obj.received_qty) - flt(returned_qty_map.get("qty")) target.received_qty = flt(obj.qty) - flt(obj.received_qty) - target.stock_qty = (flt(obj.qty) - flt(obj.received_qty)) * flt(obj.conversion_factor) + target.stock_qty = (flt(obj.qty) - flt(obj.received_qty) - flt(returned_qty_map.get("qty"))) * flt( + obj.conversion_factor + ) target.amount = (flt(obj.qty) - flt(obj.received_qty)) * flt(obj.rate) target.base_amount = ( (flt(obj.qty) - flt(obj.received_qty)) * flt(obj.rate) * flt(source_parent.conversion_rate) @@ -2139,6 +2062,7 @@ def make_purchase_receipt(source_name, target_doc=None, args=None): "Purchase Taxes and Charges": {"doctype": "Purchase Taxes and Charges"}, }, target_doc, + post_parent_process, ) return doc diff --git a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py index c6324c10373..9392a0e3220 100644 --- a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py +++ b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py @@ -1538,7 +1538,7 @@ class TestPurchaseInvoice(IntegrationTestCase, StockTestMixin): # Create Payment Entry Against the order payment_entry = get_payment_entry(dt="Purchase Order", dn=po.name) payment_entry.paid_from = "Cash - _TC" - payment_entry.apply_tax_withholding_amount = 1 + payment_entry.apply_tds = 1 payment_entry.tax_withholding_category = tax_withholding_category payment_entry.save() payment_entry.submit() @@ -1591,12 +1591,26 @@ class TestPurchaseInvoice(IntegrationTestCase, StockTestMixin): self.assertEqual(expected_gle[i][1], gle.amount) payment_entry.load_from_db() - self.assertEqual(payment_entry.taxes[0].allocated_amount, 3000) + tax_allocated = sum( + [ + entry.withholding_amount + for entry in payment_entry.get("tax_withholding_entries", []) + if entry.taxable_name + ] + ) + self.assertEqual(tax_allocated, 3000) purchase_invoice.cancel() payment_entry.load_from_db() - self.assertEqual(payment_entry.taxes[0].allocated_amount, 0) + tax_allocated = sum( + [ + entry.withholding_amount + for entry in payment_entry.get("tax_withholding_entries", []) + if entry.taxable_name + ] + ) + self.assertEqual(tax_allocated, 0) def test_purchase_gl_with_tax_withholding_tax(self): company = "_Test Company" @@ -1631,7 +1645,6 @@ class TestPurchaseInvoice(IntegrationTestCase, StockTestMixin): do_not_submit=1, ) pi.apply_tds = 1 - pi.tax_withholding_category = tax_withholding_category pi.save() pi.submit() @@ -2931,6 +2944,29 @@ class TestPurchaseInvoice(IntegrationTestCase, StockTestMixin): pi.save() self.assertEqual(pi.discount_amount, discount_amount) + def test_returned_item_purchase_receipt(self): + from erpnext.accounts.doctype.purchase_invoice.purchase_invoice import ( + make_purchase_receipt as make_purchase_receipt_from_pi, + ) + + item = create_item("_Test Returned Item Purchase Receipt", is_stock_item=1) + + pi = make_purchase_invoice(item_code=item.name, qty=5, rate=100) + + return_pi = make_purchase_invoice( + item_code=item.name, + is_return=1, + return_against=pi.name, + qty=-5, + do_not_submit=True, + ) + + return_pi.items[0].purchase_invoice_item = pi.items[0].name + return_pi.submit() + + pr = make_purchase_receipt_from_pi(pi.name) + self.assertFalse(pr.items) + def set_advance_flag(company, flag, default_account): frappe.db.set_value( diff --git a/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json b/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json index 19990719d9e..d007f4bf8cd 100644 --- a/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json +++ b/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json @@ -44,6 +44,7 @@ "rate", "amount", "item_tax_template", + "tax_withholding_category", "col_break4", "base_rate", "base_amount", @@ -228,7 +229,6 @@ "reqd": 1 }, { - "default": "1", "depends_on": "eval:doc.uom != doc.stock_uom", "fieldname": "conversion_factor", "fieldtype": "Float", @@ -893,7 +893,7 @@ "default": "1", "fieldname": "apply_tds", "fieldtype": "Check", - "label": "Apply TDS" + "label": "Consider for Tax Withholding" }, { "depends_on": "eval:parent.update_stock == 1 && (doc.use_serial_batch_fields === 0 || doc.docstatus === 1)", @@ -979,13 +979,20 @@ "fieldtype": "Currency", "label": "Distributed Discount Amount", "options": "currency" + }, + { + "fieldname": "tax_withholding_category", + "fieldtype": "Link", + "label": "Tax Withholding Category", + "options": "Tax Withholding Category", + "print_hide": 1 } ], "grid_page_length": 50, "idx": 1, "istable": 1, "links": [], - "modified": "2025-10-14 13:00:54.441511", + "modified": "2025-12-13 14:10:02.379392", "modified_by": "Administrator", "module": "Accounts", "name": "Purchase Invoice Item", diff --git a/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.py b/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.py index 96db9d66f05..0256e6fbd23 100644 --- a/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.py +++ b/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.py @@ -90,6 +90,7 @@ class PurchaseInvoiceItem(Document): stock_qty: DF.Float stock_uom: DF.Link | None stock_uom_rate: DF.Currency + tax_withholding_category: DF.Link | None total_weight: DF.Float uom: DF.Link use_serial_batch_fields: DF.Check diff --git a/erpnext/accounts/doctype/purchase_taxes_and_charges/purchase_taxes_and_charges.json b/erpnext/accounts/doctype/purchase_taxes_and_charges/purchase_taxes_and_charges.json index fab5b6f6a21..44c3d2719e6 100644 --- a/erpnext/accounts/doctype/purchase_taxes_and_charges/purchase_taxes_and_charges.json +++ b/erpnext/accounts/doctype/purchase_taxes_and_charges/purchase_taxes_and_charges.json @@ -34,7 +34,8 @@ "base_net_amount", "base_tax_amount", "base_total", - "base_tax_amount_after_discount_amount" + "base_tax_amount_after_discount_amount", + "dont_recompute_tax" ], "fields": [ { @@ -205,11 +206,11 @@ "fieldtype": "Column Break" }, { - "allow_on_submit": 1, - "fieldname": "project", - "fieldtype": "Link", - "label": "Project", - "options": "Project" + "allow_on_submit": 1, + "fieldname": "project", + "fieldtype": "Link", + "label": "Project", + "options": "Project" }, { "default": "0", @@ -262,13 +263,22 @@ "print_hide": 1, "read_only": 1, "report_hide": 1 + }, + { + "default": "0", + "fieldname": "dont_recompute_tax", + "fieldtype": "Check", + "hidden": 1, + "label": "Don't Recompute Tax", + "print_hide": 1, + "read_only": 1 } ], "grid_page_length": 50, "idx": 1, "istable": 1, "links": [], - "modified": "2025-07-24 15:08:44.433022", + "modified": "2025-11-24 18:22:56.886010", "modified_by": "Administrator", "module": "Accounts", "name": "Purchase Taxes and Charges", diff --git a/erpnext/accounts/doctype/purchase_taxes_and_charges/purchase_taxes_and_charges.py b/erpnext/accounts/doctype/purchase_taxes_and_charges/purchase_taxes_and_charges.py index 4a198e001bc..4e054593455 100644 --- a/erpnext/accounts/doctype/purchase_taxes_and_charges/purchase_taxes_and_charges.py +++ b/erpnext/accounts/doctype/purchase_taxes_and_charges/purchase_taxes_and_charges.py @@ -32,6 +32,7 @@ class PurchaseTaxesandCharges(Document): ] cost_center: DF.Link | None description: DF.SmallText + dont_recompute_tax: DF.Check included_in_paid_amount: DF.Check included_in_print_rate: DF.Check is_tax_withholding_account: DF.Check @@ -39,6 +40,7 @@ class PurchaseTaxesandCharges(Document): parent: DF.Data parentfield: DF.Data parenttype: DF.Data + project: DF.Link | None rate: DF.Float row_id: DF.Data | None set_by_item_tax_template: DF.Check diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js index 2c86981a8a4..c50eaa69a9f 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js @@ -14,6 +14,7 @@ erpnext.accounts.SalesInvoiceController = class SalesInvoiceController extends ( erpnext.selling.SellingController ) { setup(doc) { + this.setup_accounting_dimension_triggers(); this.setup_posting_date_time_check(); super.setup(doc); this.frm.make_methods = { @@ -24,6 +25,7 @@ erpnext.accounts.SalesInvoiceController = class SalesInvoiceController extends ( company() { super.company(); erpnext.accounts.dimensions.update_dimension(this.frm, this.frm.doctype); + this.frm.clear_table("tax_withholding_entries"); } onload() { var me = this; @@ -381,6 +383,9 @@ erpnext.accounts.SalesInvoiceController = class SalesInvoiceController extends ( ), }, function () { + me.frm.doc.apply_tds = + me.frm.tax_withholding_category || me.frm.tax_withholding_group ? 1 : 0; + me.frm.clear_table("tax_withholding_entries"); me.apply_pricing_rule(); } ); @@ -597,6 +602,10 @@ erpnext.accounts.SalesInvoiceController = class SalesInvoiceController extends ( this.calculate_taxes_and_totals(); } + + apply_tds(frm) { + this.frm.clear_table("tax_withholding_entries"); + } }; // for backward compatibility: combine new and previous states @@ -617,10 +626,6 @@ cur_frm.cscript.expense_account = function (doc, cdt, cdn) { erpnext.utils.copy_value_in_all_rows(doc, cdt, cdn, "items", "expense_account"); }; -cur_frm.cscript.cost_center = function (doc, cdt, cdn) { - erpnext.utils.copy_value_in_all_rows(doc, cdt, cdn, "items", "cost_center"); -}; - frappe.ui.form.on("Sales Invoice", { setup: function (frm) { frm.add_fetch("customer", "tax_id", "tax_id"); @@ -817,6 +822,16 @@ frappe.ui.form.on("Sales Invoice", { }, onload: function (frm) { frm.redemption_conversion_factor = null; + + if (frm.doc.__onload && frm.doc.customer) { + if (frm.is_new()) { + frm.doc.apply_tds = frm.doc.__onload.apply_tds ? 1 : 0; + } + } + + if (frm.is_new()) { + frm.clear_table("tax_withholding_entries"); + } }, update_stock: function (frm, dt, dn) { diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json index a889ca3c2ed..ebf2d2f4b00 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json @@ -28,6 +28,7 @@ "update_billed_amount_in_sales_order", "update_billed_amount_in_delivery_note", "is_debit_note", + "apply_tds", "amended_from", "is_created_using_pos", "pos_closing_entry", @@ -90,6 +91,11 @@ "total_advance", "outstanding_amount", "disable_rounded_total", + "section_tax_withholding_entry", + "tax_withholding_group", + "ignore_tax_withholding_threshold", + "override_tax_withholding_entries", + "tax_withholding_entries", "section_break_49", "apply_discount_on", "base_discount_amount", @@ -2247,6 +2253,46 @@ "label": "Item Wise Tax Details", "no_copy": 1, "options": "Item Wise Tax Detail" + }, + { + "default": "0", + "fieldname": "apply_tds", + "fieldtype": "Check", + "label": "Consider for Tax Withholding", + "print_hide": 1 + }, + { + "collapsible": 1, + "collapsible_depends_on": "eval: doc.apply_tds && doc.docstatus == 0", + "depends_on": "eval: doc.apply_tds", + "fieldname": "section_tax_withholding_entry", + "fieldtype": "Section Break", + "label": "Tax Withholding Entry" + }, + { + "fieldname": "tax_withholding_group", + "fieldtype": "Link", + "label": "Tax Withholding Group", + "options": "Tax Withholding Group" + }, + { + "fieldname": "tax_withholding_entries", + "fieldtype": "Table", + "label": "Tax Withholding Entries", + "options": "Tax Withholding Entry", + "read_only_depends_on": "eval: !doc.override_tax_withholding_entries" + }, + { + "default": "0", + "fieldname": "ignore_tax_withholding_threshold", + "fieldtype": "Check", + "label": "Ignore Tax Withholding Threshold" + }, + { + "default": "0", + "fieldname": "override_tax_withholding_entries", + "fieldtype": "Check", + "label": "Edit Tax Withholding Entries" } ], "grid_page_length": 50, diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py index fdea1b2d29e..18a86434ef9 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py @@ -26,9 +26,7 @@ from erpnext.accounts.doctype.repost_accounting_ledger.repost_accounting_ledger validate_docs_for_deferred_accounting, validate_docs_for_voucher_types, ) -from erpnext.accounts.doctype.tax_withholding_category.tax_withholding_category import ( - get_party_tax_withholding_details, -) +from erpnext.accounts.doctype.tax_withholding_entry.tax_withholding_entry import SalesTaxWithholding from erpnext.accounts.general_ledger import get_round_off_account_and_cost_center from erpnext.accounts.party import get_due_date, get_party_account, get_party_details from erpnext.accounts.utils import ( @@ -77,6 +75,7 @@ class SalesInvoice(SellingController): from erpnext.accounts.doctype.sales_taxes_and_charges.sales_taxes_and_charges import ( SalesTaxesandCharges, ) + from erpnext.accounts.doctype.tax_withholding_entry.tax_withholding_entry import TaxWithholdingEntry from erpnext.selling.doctype.sales_team.sales_team import SalesTeam from erpnext.stock.doctype.packed_item.packed_item import PackedItem @@ -90,6 +89,7 @@ class SalesInvoice(SellingController): amended_from: DF.Link | None amount_eligible_for_commission: DF.Currency apply_discount_on: DF.Literal["", "Grand Total", "Net Total"] + apply_tds: DF.Check auto_repeat: DF.Link | None base_change_amount: DF.Currency base_discount_amount: DF.Currency @@ -135,6 +135,7 @@ class SalesInvoice(SellingController): has_subcontracted: DF.Check ignore_default_payment_terms_template: DF.Check ignore_pricing_rule: DF.Check + ignore_tax_withholding_threshold: DF.Check in_words: DF.SmallText | None incoterm: DF.Link | None inter_company_invoice_reference: DF.Link | None @@ -162,6 +163,7 @@ class SalesInvoice(SellingController): only_include_allocated_payments: DF.Check other_charges_calculation: DF.TextEditor | None outstanding_amount: DF.Currency + override_tax_withholding_entries: DF.Check packed_items: DF.Table[PackedItem] paid_amount: DF.Currency party_account_currency: DF.Link | None @@ -214,6 +216,8 @@ class SalesInvoice(SellingController): subscription: DF.Link | None tax_category: DF.Link | None tax_id: DF.Data | None + tax_withholding_entries: DF.Table[TaxWithholdingEntry] + tax_withholding_group: DF.Link | None taxes: DF.Table[SalesTaxesandCharges] taxes_and_charges: DF.Link | None tc_name: DF.Link | None @@ -282,58 +286,13 @@ class SalesInvoice(SellingController): self.indicator_color = "green" self.indicator_title = _("Paid") - def before_print(self, settings=None): - from frappe.contacts.doctype.address.address import get_address_display_list - - super().before_print(settings) - - company_details = frappe.get_value( - "Company", self.company, ["company_logo", "website", "phone_no", "email"], as_dict=True - ) - - required_fields = [ - company_details.get("company_logo"), - company_details.get("phone_no"), - company_details.get("email"), - ] - - if not all(required_fields) and not frappe.has_permission("Company", "write", throw=False): - frappe.msgprint( - _( - "Some required Company details are missing. You don't have permission to update them. Please contact your System Manager." - ) - ) - return - - if not self.company_address and not frappe.has_permission("Sales Invoice", "write", throw=False): - frappe.msgprint( - _( - "Company Address is missing. You don't have permission to update it. Please contact your System Manager." - ) - ) - return - - address_display_list = get_address_display_list("Company", self.company) - address_line = address_display_list[0].get("address_line1") if address_display_list else "" - - required_fields.append(self.company_address) - required_fields.append(address_line) - - if not all(required_fields): - frappe.publish_realtime( - "sales_invoice_before_print", - { - "company_logo": company_details.get("company_logo"), - "website": company_details.get("website"), - "phone_no": company_details.get("phone_no"), - "email": company_details.get("email"), - "address_line": address_line, - "company": self.company, - "company_address": self.company_address, - "name": self.name, - }, - user=frappe.session.user, + def onload(self): + super().onload() + if self.customer: + tax_withholding_category, tax_withholding_group = frappe.get_cached_value( + "Customer", self.customer, ["tax_withholding_category", "tax_withholding_group"] ) + self.set_onload("apply_tds", tax_withholding_category or tax_withholding_group) def validate(self): self.validate_auto_set_posting_time() @@ -344,7 +303,7 @@ class SalesInvoice(SellingController): if not (self.is_pos or self.is_debit_note): self.so_dn_required() - self.set_tax_withholding() + SalesTaxWithholding(self).on_validate() self.validate_proj_cust() self.validate_pos_return() @@ -466,38 +425,6 @@ class SalesInvoice(SellingController): for item in self.get("items"): validate_account_head(item.idx, item.income_account, self.company, _("Income")) - def set_tax_withholding(self): - if self.get("is_opening") == "Yes": - return - - tax_withholding_details = get_party_tax_withholding_details(self) - - if not tax_withholding_details: - return - - accounts = [] - tax_withholding_account = tax_withholding_details.get("account_head") - - for d in self.taxes: - if d.account_head == tax_withholding_account: - d.update(tax_withholding_details) - accounts.append(d.account_head) - - if not accounts or tax_withholding_account not in accounts: - self.append("taxes", tax_withholding_details) - - to_remove = [ - d - for d in self.taxes - if not d.tax_amount and d.charge_type == "Actual" and d.account_head == tax_withholding_account - ] - - for d in to_remove: - self.remove(d) - - # calculate totals again after applying TDS - self.calculate_taxes_and_totals() - def before_save(self): self.set_account_for_mode_of_payment() self.set_paid_amount() @@ -519,6 +446,8 @@ class SalesInvoice(SellingController): # NOTE status updating bypassed for is_return self.status_updater = [] + SalesTaxWithholding(self).on_submit() + self.update_status_updater_args() self.update_prevdoc_status() @@ -658,6 +587,7 @@ class SalesInvoice(SellingController): # Updating stock ledger should always be called after updating prevdoc status, # because updating reserved qty in bin depends upon updated delivered qty in SO + SalesTaxWithholding(self).on_cancel() if self.update_stock == 1: self.update_stock_ledger() @@ -699,6 +629,7 @@ class SalesInvoice(SellingController): "Unreconcile Payment Entries", "Payment Ledger Entry", "Serial and Batch Bundle", + "Tax Withholding Entry", ) self.delete_auto_created_batches() @@ -1678,7 +1609,11 @@ class SalesInvoice(SellingController): ) for item in self.get("items"): - if flt(item.base_net_amount, item.precision("base_net_amount")) or item.is_fixed_asset: + if ( + flt(item.base_net_amount, item.precision("base_net_amount")) + or item.is_fixed_asset + or enable_discount_accounting + ): # Do not book income for transfer within same company if self.is_internal_transfer(): continue @@ -2375,6 +2310,7 @@ def get_list_context(context=None): "show_search": True, "no_breadcrumbs": True, "title": _("Invoices"), + "list_template": "templates/includes/list/list.html", } ) return list_context @@ -2948,59 +2884,6 @@ def get_loyalty_programs(customer): return lp_details -@frappe.whitelist() -def save_company_master_details(name, company, details): - from frappe.utils import validate_email_address - - if isinstance(details, str): - details = frappe.parse_json(details) - - if details.get("email"): - validate_email_address(details.get("email"), throw=True) - - company_fields = ["company_logo", "website", "phone_no", "email"] - company_fields_to_update = {field: details.get(field) for field in company_fields if details.get(field)} - - if company_fields_to_update: - frappe.db.set_value("Company", company, company_fields_to_update) - - company_address = details.get("company_address") - if details.get("address_line1"): - address_doc = frappe.get_doc( - { - "doctype": "Address", - "address_title": details.get("address_title"), - "address_type": details.get("address_type"), - "address_line1": details.get("address_line1"), - "address_line2": details.get("address_line2"), - "city": details.get("city"), - "state": details.get("state"), - "pincode": details.get("pincode"), - "country": details.get("country"), - "is_your_company_address": 1, - "links": [{"link_doctype": "Company", "link_name": company}], - } - ) - address_doc.insert() - company_address = address_doc.name - - if company_address: - company_address_display = frappe.db.get_value("Sales Invoice", name, "company_address_display") - if not company_address_display or details.get("address_line1"): - from frappe.query_builder import DocType - - SalesInvoice = DocType("Sales Invoice") - - ( - frappe.qb.update(SalesInvoice) - .set(SalesInvoice.company_address, company_address) - .set(SalesInvoice.company_address_display, get_address_display(company_address)) - .where(SalesInvoice.name == name) - ).run() - - return True - - @frappe.whitelist() def create_invoice_discounting(source_name, target_doc=None): invoice = frappe.get_doc("Sales Invoice", source_name) diff --git a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py index a2983e4555b..1b98556f0c6 100644 --- a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py @@ -63,7 +63,8 @@ class TestSalesInvoice(ERPNextTestSuite): set_default_account_for_mode_of_payment( mode_of_payment, "_Test Company with perpetual inventory", "_Test Bank - TCP1" ) - frappe.db.set_single_value("Accounts Settings", "acc_frozen_upto", None) + for company in frappe.get_all("Company", pluck="name"): + frappe.db.set_value("Company", company, "accounts_frozen_till_date", None) @change_settings( "Accounts Settings", @@ -3398,8 +3399,8 @@ class TestSalesInvoice(ERPNextTestSuite): si.commission_rate = commission_rate self.assertRaises(frappe.ValidationError, si.save) - @IntegrationTestCase.change_settings("Accounts Settings", {"acc_frozen_upto": add_days(getdate(), 1)}) def test_sales_invoice_submission_post_account_freezing_date(self): + frappe.db.set_value("Company", "_Test Company", "accounts_frozen_till_date", add_days(getdate(), 1)) si = create_sales_invoice(do_not_save=True) si.posting_date = add_days(getdate(), 1) si.save() @@ -3407,6 +3408,7 @@ class TestSalesInvoice(ERPNextTestSuite): self.assertRaises(frappe.ValidationError, si.submit) si.posting_date = getdate() si.submit() + frappe.db.set_value("Company", "_Test Company", "accounts_frozen_till_date", None) @IntegrationTestCase.change_settings("Accounts Settings", {"over_billing_allowance": 0}) def test_over_billing_case_against_delivery_note(self): @@ -3473,7 +3475,7 @@ class TestSalesInvoice(ERPNextTestSuite): si.save() si.submit() - frappe.db.set_single_value("Accounts Settings", "acc_frozen_upto", getdate("2019-01-31")) + frappe.db.set_value("Company", "_Test Company", "accounts_frozen_till_date", getdate("2019-01-31")) pda1 = frappe.get_doc( dict( diff --git a/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json b/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json index e5283ea8103..7608ea87de8 100644 --- a/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json +++ b/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json @@ -43,12 +43,14 @@ "rate", "amount", "item_tax_template", + "tax_withholding_category", "col_break3", "base_rate", "base_amount", "pricing_rules", "stock_uom_rate", "is_free_item", + "apply_tds", "grant_commission", "section_break_21", "net_rate", @@ -986,6 +988,21 @@ "hidden": 1, "label": "SCIO Detail", "read_only": 1 + }, + { + "fieldname": "tax_withholding_category", + "fieldtype": "Link", + "label": "Tax Withholding Category", + "options": "Tax Withholding Category", + "print_hide": 1 + }, + { + "default": "1", + "fieldname": "apply_tds", + "fieldtype": "Check", + "label": "Consider for Tax Withholding", + "print_hide": 1, + "read_only": 1 } ], "grid_page_length": 50, diff --git a/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.py b/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.py index 3d3e92f3fd4..2b444d760b7 100644 --- a/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.py +++ b/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.py @@ -24,6 +24,7 @@ class SalesInvoiceItem(Document): actual_qty: DF.Float allow_zero_valuation_rate: DF.Check amount: DF.Currency + apply_tds: DF.Check asset: DF.Link | None barcode: DF.Data | None base_amount: DF.Currency @@ -95,6 +96,7 @@ class SalesInvoiceItem(Document): stock_uom: DF.Link | None stock_uom_rate: DF.Currency target_warehouse: DF.Link | None + tax_withholding_category: DF.Link | None total_weight: DF.Float uom: DF.Link use_serial_batch_fields: DF.Check diff --git a/erpnext/accounts/doctype/sales_taxes_and_charges/sales_taxes_and_charges.json b/erpnext/accounts/doctype/sales_taxes_and_charges/sales_taxes_and_charges.json index 429bf759743..f499963d92e 100644 --- a/erpnext/accounts/doctype/sales_taxes_and_charges/sales_taxes_and_charges.json +++ b/erpnext/accounts/doctype/sales_taxes_and_charges/sales_taxes_and_charges.json @@ -14,6 +14,7 @@ "included_in_print_rate", "included_in_paid_amount", "set_by_item_tax_template", + "is_tax_withholding_account", "accounting_dimensions_section", "cost_center", "dimension_col_break", @@ -202,7 +203,7 @@ "fieldname": "dont_recompute_tax", "fieldtype": "Check", "hidden": 1, - "label": "Dont Recompute tax", + "label": "Don't Recompute Tax", "print_hide": 1, "read_only": 1 }, @@ -241,6 +242,13 @@ "print_hide": 1, "read_only": 1, "report_hide": 1 + }, + { + "default": "0", + "fieldname": "is_tax_withholding_account", + "fieldtype": "Check", + "label": "Is Tax Withholding Account", + "read_only": 1 } ], "idx": 1, diff --git a/erpnext/accounts/doctype/sales_taxes_and_charges/sales_taxes_and_charges.py b/erpnext/accounts/doctype/sales_taxes_and_charges/sales_taxes_and_charges.py index 329511c2651..c9382b036b8 100644 --- a/erpnext/accounts/doctype/sales_taxes_and_charges/sales_taxes_and_charges.py +++ b/erpnext/accounts/doctype/sales_taxes_and_charges/sales_taxes_and_charges.py @@ -33,6 +33,8 @@ class SalesTaxesandCharges(Document): dont_recompute_tax: DF.Check included_in_paid_amount: DF.Check included_in_print_rate: DF.Check + is_tax_withholding_account: DF.Check + item_wise_tax_detail: DF.Code | None net_amount: DF.Currency parent: DF.Data parentfield: DF.Data diff --git a/erpnext/accounts/doctype/share_balance/share_balance.json b/erpnext/accounts/doctype/share_balance/share_balance.json index 48a8cd6f4a7..dc54d07690d 100644 --- a/erpnext/accounts/doctype/share_balance/share_balance.json +++ b/erpnext/accounts/doctype/share_balance/share_balance.json @@ -35,7 +35,7 @@ }, { "fieldname": "rate", - "fieldtype": "Int", + "fieldtype": "Currency", "in_list_view": 1, "label": "Rate", "read_only": 1, @@ -62,7 +62,7 @@ }, { "fieldname": "amount", - "fieldtype": "Int", + "fieldtype": "Currency", "in_list_view": 1, "label": "Amount", "read_only": 1, @@ -91,15 +91,16 @@ ], "istable": 1, "links": [], - "modified": "2024-03-27 13:10:39.866399", + "modified": "2025-12-10 08:06:40.611761", "modified_by": "Administrator", "module": "Accounts", "name": "Share Balance", "owner": "Administrator", "permissions": [], "quick_entry": 1, + "row_format": "Dynamic", "sort_field": "creation", "sort_order": "DESC", "states": [], "track_changes": 1 -} \ No newline at end of file +} diff --git a/erpnext/accounts/doctype/share_balance/share_balance.py b/erpnext/accounts/doctype/share_balance/share_balance.py index 7a77ce9b871..2eff8a9a9be 100644 --- a/erpnext/accounts/doctype/share_balance/share_balance.py +++ b/erpnext/accounts/doctype/share_balance/share_balance.py @@ -14,7 +14,7 @@ class ShareBalance(Document): if TYPE_CHECKING: from frappe.types import DF - amount: DF.Int + amount: DF.Currency current_state: DF.Literal["", "Issued", "Purchased"] from_no: DF.Int is_company: DF.Check @@ -22,7 +22,7 @@ class ShareBalance(Document): parent: DF.Data parentfield: DF.Data parenttype: DF.Data - rate: DF.Int + rate: DF.Currency share_type: DF.Link to_no: DF.Int # end: auto-generated types diff --git a/erpnext/accounts/doctype/subscription/subscription.py b/erpnext/accounts/doctype/subscription/subscription.py index c96a95ec1e7..e2cd4127049 100644 --- a/erpnext/accounts/doctype/subscription/subscription.py +++ b/erpnext/accounts/doctype/subscription/subscription.py @@ -411,7 +411,10 @@ class Subscription(Document): invoice.customer = self.party else: invoice.supplier = self.party - if frappe.db.get_value("Supplier", self.party, "tax_withholding_category"): + tax_withholding_category, tax_withholding_group = frappe.get_cached_value( + "Supplier", self.party, ["tax_withholding_category", "tax_withholding_group"] + ) + if tax_withholding_category or tax_withholding_group: invoice.apply_tds = 1 # Add currency to invoice diff --git a/erpnext/accounts/doctype/subscription/test_subscription.py b/erpnext/accounts/doctype/subscription/test_subscription.py index a121db20634..7bb72a1dcd7 100644 --- a/erpnext/accounts/doctype/subscription/test_subscription.py +++ b/erpnext/accounts/doctype/subscription/test_subscription.py @@ -27,7 +27,7 @@ class TestSubscription(IntegrationTestCase): make_plans() create_parties() reset_settings() - frappe.db.set_single_value("Accounts Settings", "acc_frozen_upto", None) + frappe.db.set_value("Company", "_Test Company", "accounts_frozen_till_date", None) def tearDown(self): frappe.db.rollback() diff --git a/erpnext/accounts/doctype/tax_withheld_vouchers/tax_withheld_vouchers.json b/erpnext/accounts/doctype/tax_withheld_vouchers/tax_withheld_vouchers.json deleted file mode 100644 index 667da42bb8a..00000000000 --- a/erpnext/accounts/doctype/tax_withheld_vouchers/tax_withheld_vouchers.json +++ /dev/null @@ -1,47 +0,0 @@ -{ - "actions": [], - "autoname": "hash", - "creation": "2022-09-13 16:18:59.404842", - "doctype": "DocType", - "editable_grid": 1, - "engine": "InnoDB", - "field_order": [ - "voucher_type", - "voucher_name", - "taxable_amount" - ], - "fields": [ - { - "fieldname": "voucher_type", - "fieldtype": "Data", - "in_list_view": 1, - "label": "Voucher Type" - }, - { - "fieldname": "voucher_name", - "fieldtype": "Data", - "in_list_view": 1, - "label": "Voucher Name" - }, - { - "fieldname": "taxable_amount", - "fieldtype": "Currency", - "in_list_view": 1, - "label": "Taxable Amount", - "options": "Company:company:default_currency" - } - ], - "index_web_pages_for_search": 1, - "istable": 1, - "links": [], - "modified": "2025-02-05 16:39:14.863698", - "modified_by": "Administrator", - "module": "Accounts", - "name": "Tax Withheld Vouchers", - "naming_rule": "Random", - "owner": "Administrator", - "permissions": [], - "sort_field": "creation", - "sort_order": "DESC", - "states": [] -} \ No newline at end of file diff --git a/erpnext/accounts/doctype/tax_withholding_category/tax_withholding_category.js b/erpnext/accounts/doctype/tax_withholding_category/tax_withholding_category.js index 042831c8080..83a2348f792 100644 --- a/erpnext/accounts/doctype/tax_withholding_category/tax_withholding_category.js +++ b/erpnext/accounts/doctype/tax_withholding_category/tax_withholding_category.js @@ -16,4 +16,54 @@ frappe.ui.form.on("Tax Withholding Category", { } }); }, + + refresh: function (frm) { + update_rates_read_only_state(frm); + }, + + disable_cumulative_threshold: function (frm) { + toggle_threshold_settings(frm, "disable_cumulative_threshold"); + if (frm.doc.disable_cumulative_threshold) { + reset_rates_column(frm, "cumulative_threshold"); + } + update_rates_read_only_state(frm); + }, + + disable_transaction_threshold: function (frm) { + toggle_threshold_settings(frm, "disable_transaction_threshold"); + if (frm.doc.disable_transaction_threshold) { + reset_rates_column(frm, "single_threshold"); + } + update_rates_read_only_state(frm); + }, }); + +function toggle_threshold_settings(frm, field_name) { + if (frm.doc[field_name]) { + const other_field = + field_name === "disable_cumulative_threshold" + ? "disable_transaction_threshold" + : "disable_cumulative_threshold"; + frm.set_value(other_field, 0); + } +} + +function update_rates_read_only_state(frm) { + frm.fields_dict["rates"].grid.update_docfield_property( + "cumulative_threshold", + "read_only", + frm.doc.disable_cumulative_threshold + ); + frm.fields_dict["rates"].grid.update_docfield_property( + "single_threshold", + "read_only", + frm.doc.disable_transaction_threshold + ); +} + +function reset_rates_column(frm, field_name) { + $.each(frm.doc.rates || [], function (i, row) { + row[field_name] = 0; + }); + frm.refresh_field("rates"); +} diff --git a/erpnext/accounts/doctype/tax_withholding_category/tax_withholding_category.json b/erpnext/accounts/doctype/tax_withholding_category/tax_withholding_category.json index 7463e07db30..cff8fea5858 100644 --- a/erpnext/accounts/doctype/tax_withholding_category/tax_withholding_category.json +++ b/erpnext/accounts/doctype/tax_withholding_category/tax_withholding_category.json @@ -10,10 +10,12 @@ "field_order": [ "category_details_section", "category_name", - "round_off_tax_amount", + "tax_deduction_basis", "column_break_2", - "consider_party_ledger_amount", + "round_off_tax_amount", "tax_on_excess_amount", + "disable_cumulative_threshold", + "disable_transaction_threshold", "section_break_8", "rates", "section_break_7", @@ -61,14 +63,7 @@ }, { "default": "0", - "description": "Only payment entries with apply tax withholding unchecked will be considered for checking cumulative threshold breach", - "fieldname": "consider_party_ledger_amount", - "fieldtype": "Check", - "label": "Consider Entire Party Ledger Amount" - }, - { - "default": "0", - "description": "Tax will be withheld only for amount exceeding the cumulative threshold", + "description": "Tax withheld only for amount exceeding cumulative threshold", "fieldname": "tax_on_excess_amount", "fieldtype": "Check", "label": "Only Deduct Tax On Excess Amount " @@ -79,6 +74,28 @@ "fieldname": "round_off_tax_amount", "fieldtype": "Check", "label": "Round Off Tax Amount" + }, + { + "default": "Net Total", + "fieldname": "tax_deduction_basis", + "fieldtype": "Select", + "label": "Deduct Tax On Basis", + "options": "\nGross Total\nNet Total", + "reqd": 1 + }, + { + "default": "0", + "description": "When checked, only transaction threshold will be applied for transaction individually", + "fieldname": "disable_cumulative_threshold", + "fieldtype": "Check", + "label": "Disable Cumulative Threshold" + }, + { + "default": "0", + "description": "When checked, only cumulative threshold will be applied", + "fieldname": "disable_transaction_threshold", + "fieldtype": "Check", + "label": "Disable Transaction Threshold" } ], "index_web_pages_for_search": 1, diff --git a/erpnext/accounts/doctype/tax_withholding_category/tax_withholding_category.py b/erpnext/accounts/doctype/tax_withholding_category/tax_withholding_category.py index 2c6d13b3147..c78b026c227 100644 --- a/erpnext/accounts/doctype/tax_withholding_category/tax_withholding_category.py +++ b/erpnext/accounts/doctype/tax_withholding_category/tax_withholding_category.py @@ -1,14 +1,15 @@ # Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors # For license information, please see license.txt +from collections import defaultdict import frappe -from frappe import _, qb +from frappe import _ from frappe.model.document import Document -from frappe.query_builder import Criterion -from frappe.query_builder.functions import Abs, Sum -from frappe.utils import cint, flt, getdate +from frappe.query_builder.functions import Sum +from frappe.utils import getdate +from erpnext import allow_regional from erpnext.controllers.accounts_controller import validate_account_head @@ -28,30 +29,41 @@ class TaxWithholdingCategory(Document): accounts: DF.Table[TaxWithholdingAccount] category_name: DF.Data | None - consider_party_ledger_amount: DF.Check + disable_cumulative_threshold: DF.Check + disable_transaction_threshold: DF.Check rates: DF.Table[TaxWithholdingRate] round_off_tax_amount: DF.Check + tax_deduction_basis: DF.Literal["", "Gross Total", "Net Total"] tax_on_excess_amount: DF.Check # end: auto-generated types def validate(self): + # TODO: Disable single threshold if tax on excess is enabled self.validate_dates() self.validate_companies_and_accounts() self.validate_thresholds() def validate_dates(self): - last_to_date = None - rates = sorted(self.get("rates"), key=lambda d: getdate(d.from_date)) - - for d in rates: + group_rates = defaultdict(list) + for d in self.get("rates"): if getdate(d.from_date) >= getdate(d.to_date): frappe.throw(_("Row #{0}: From Date cannot be before To Date").format(d.idx)) + group_rates[d.tax_withholding_group].append(d) - # validate overlapping of dates - if last_to_date and getdate(d.from_date) < getdate(last_to_date): - frappe.throw(_("Row #{0}: Dates overlapping with other row").format(d.idx)) + # Validate overlapping dates within each group + for group, rates in group_rates.items(): + rates = sorted(rates, key=lambda d: getdate(d.from_date)) + last_to_date = None - last_to_date = d.to_date + for d in rates: + if last_to_date and getdate(d.from_date) < getdate(last_to_date): + frappe.throw( + _("Row #{0}: Dates overlapping with other row in group {1}").format( + d.idx, group or "Default" + ) + ) + + last_to_date = d.to_date def validate_companies_and_accounts(self): existing_accounts = set() @@ -78,699 +90,168 @@ class TaxWithholdingCategory(Document): ).format(d.idx) ) + def get_applicable_tax_row(self, posting_date, tax_withholding_group): + for row in self.rates: + if ( + getdate(row.from_date) <= getdate(posting_date) <= getdate(row.to_date) + and row.tax_withholding_group == tax_withholding_group + ): + return row -def get_party_details(inv): - party_type, party = "", "" + frappe.throw(_("No Tax Withholding data found for the current posting date.")) - if inv.doctype == "Sales Invoice": - party_type = "Customer" - party = inv.customer - else: - party_type = "Supplier" - party = inv.supplier + def get_company_account(self, company): + for row in self.accounts: + if company == row.company: + return row.account - if not party: - frappe.throw(_("Please select {0} first").format(party_type)) - - return party_type, party - - -def get_party_tax_withholding_details(inv, tax_withholding_category=None): - if inv.doctype == "Payment Entry": - inv.tax_withholding_net_total = inv.net_total - inv.base_tax_withholding_net_total = inv.net_total - - pan_no = "" - parties = [] - party_type, party = get_party_details(inv) - has_pan_field = frappe.get_meta(party_type).has_field("pan") - - if not tax_withholding_category: - if has_pan_field: - fields = ["tax_withholding_category", "pan"] - else: - fields = ["tax_withholding_category"] - - tax_withholding_details = frappe.db.get_value(party_type, party, fields, as_dict=1) - - tax_withholding_category = tax_withholding_details.get("tax_withholding_category") - pan_no = tax_withholding_details.get("pan") - - if not tax_withholding_category: - return - - # if tax_withholding_category passed as an argument but not pan_no - if not pan_no and has_pan_field: - pan_no = frappe.db.get_value(party_type, party, "pan") - - # Get others suppliers with the same PAN No - if pan_no: - parties = frappe.get_all(party_type, filters={"pan": pan_no}, pluck="name") - - if not parties: - parties.append(party) - - posting_date = inv.get("posting_date") or inv.get("transaction_date") - tax_details = get_tax_withholding_details(tax_withholding_category, posting_date, inv.company) - - if not tax_details: - frappe.msgprint( - _( - "Skipping Tax Withholding Category {0} as there is no associated account set for Company {1} in it." - ).format(tax_withholding_category, inv.company) - ) - if inv.doctype == "Purchase Invoice": - return {}, [], {} - return {} - - if party_type == "Customer" and not tax_details.cumulative_threshold: - # TCS is only chargeable on sum of invoiced value frappe.throw( - _( - "Tax Withholding Category {} against Company {} for Customer {} should have Cumulative Threshold value." - ).format(tax_withholding_category, inv.company, party) - ) - - tax_amount, tax_deducted, tax_deducted_on_advances, voucher_wise_amount = get_tax_amount( - party_type, parties, inv, tax_details, posting_date, pan_no - ) - - if party_type == "Supplier": - tax_row = get_tax_row_for_tds(tax_details, tax_amount) - else: - tax_row = get_tax_row_for_tcs(inv, tax_details, tax_amount, tax_deducted) - - cost_center = get_cost_center(inv) - tax_row.update( - { - "cost_center": cost_center, - "is_tax_withholding_account": 1, - } - ) - - if cint(tax_details.round_off_tax_amount): - inv.round_off_applicable_accounts_for_tax_withholding = tax_details.account_head - - if inv.doctype == "Purchase Invoice": - return tax_row, tax_deducted_on_advances, voucher_wise_amount - else: - return tax_row - - -def get_cost_center(inv): - cost_center = frappe.get_cached_value("Company", inv.company, "cost_center") - - if len(inv.get("taxes", [])) > 0: - cost_center = inv.get("taxes")[0].cost_center - - return cost_center - - -def get_tax_withholding_details(tax_withholding_category, posting_date, company): - tax_withholding = frappe.get_doc("Tax Withholding Category", tax_withholding_category) - - tax_rate_detail = get_tax_withholding_rates(tax_withholding, posting_date) - - for account_detail in tax_withholding.accounts: - if company == account_detail.company: - return frappe._dict( - { - "tax_withholding_category": tax_withholding_category, - "account_head": account_detail.account, - "rate": tax_rate_detail.tax_withholding_rate, - "from_date": tax_rate_detail.from_date, - "to_date": tax_rate_detail.to_date, - "threshold": tax_rate_detail.single_threshold, - "cumulative_threshold": tax_rate_detail.cumulative_threshold, - "description": tax_withholding.category_name - if tax_withholding.category_name - else tax_withholding_category, - "consider_party_ledger_amount": tax_withholding.consider_party_ledger_amount, - "tax_on_excess_amount": tax_withholding.tax_on_excess_amount, - "round_off_tax_amount": tax_withholding.round_off_tax_amount, - } + _("No Tax withholding account set for Company {0} in Tax Withholding Category {1}.").format( + frappe.bold(company), frappe.bold(self.name) ) - - -def get_tax_withholding_rates(tax_withholding, posting_date): - # returns the row that matches with the fiscal year from posting date - for rate in tax_withholding.rates: - if getdate(rate.from_date) <= getdate(posting_date) <= getdate(rate.to_date): - return rate - - frappe.throw(_("No Tax Withholding data found for the current posting date.")) - - -def get_tax_row_for_tcs(inv, tax_details, tax_amount, tax_deducted): - row = { - "category": "Total", - "charge_type": "Actual", - "tax_amount": tax_amount, - "description": tax_details.description, - "account_head": tax_details.account_head, - } - - if tax_deducted: - # TCS already deducted on previous invoices - # So, TCS will be calculated by 'Previous Row Total' - - taxes_excluding_tcs = [d for d in inv.taxes if d.account_head != tax_details.account_head] - if taxes_excluding_tcs: - # chargeable amount is the total amount after other charges are applied - row.update( - { - "charge_type": "On Previous Row Total", - "row_id": len(taxes_excluding_tcs), - "rate": tax_details.rate, - } - ) - else: - # if only TCS is to be charged, then net total is chargeable amount - row.update({"charge_type": "On Net Total", "rate": tax_details.rate}) - - return row - - -def get_tax_row_for_tds(tax_details, tax_amount): - return { - "category": "Total", - "charge_type": "Actual", - "tax_amount": tax_amount, - "add_deduct_tax": "Deduct", - "description": tax_details.description, - "account_head": tax_details.account_head, - } - - -def get_lower_deduction_certificate(company, posting_date, tax_details, pan_no): - ldc_name = frappe.db.get_value( - "Lower Deduction Certificate", - { - "pan_no": pan_no, - "tax_withholding_category": tax_details.tax_withholding_category, - "valid_from": ("<=", posting_date), - "valid_upto": (">=", posting_date), - "company": company, - }, - "name", - ) - - if ldc_name: - return frappe.get_doc("Lower Deduction Certificate", ldc_name) - - -def get_tax_amount(party_type, parties, inv, tax_details, posting_date, pan_no=None): - vouchers, voucher_wise_amount = get_invoice_vouchers( - parties, - tax_details, - inv.company, - party_type=party_type, - ) - - payment_entry_vouchers = get_payment_entry_vouchers( - parties, tax_details, inv.company, party_type=party_type - ) - - advance_vouchers = get_advance_vouchers( - parties, - company=inv.company, - from_date=tax_details.from_date, - to_date=tax_details.to_date, - party_type=party_type, - ) - - taxable_vouchers = vouchers + advance_vouchers + payment_entry_vouchers - tax_deducted_on_advances = 0 - - if inv.doctype == "Purchase Invoice": - tax_deducted_on_advances = get_taxes_deducted_on_advances_allocated(inv, tax_details) - - tax_deducted = 0 - if taxable_vouchers: - tax_deducted = get_deducted_tax(taxable_vouchers, tax_details) - - # If advance is outside the current tax withholding period (usually a fiscal year), `get_deducted_tax` won't fetch it. - # updating `tax_deducted` with correct advance tax value (from current and previous previous withholding periods), will allow the - # rest of the below logic to function properly - # ---FY 2023-------------||---------------------FY 2024-----------------------||-- - # ---Advance-------------||---------Inv_1--------Inv_2------------------------||-- - if tax_deducted_on_advances: - tax_deducted += get_advance_tax_across_fiscal_year(tax_deducted_on_advances, tax_details) - - tax_amount = 0 - - if party_type == "Supplier": - # if tds account is changed. - if not tax_deducted: - tax_deducted = is_tax_deducted_on_the_basis_of_inv(vouchers) - - ldc = get_lower_deduction_certificate(inv.company, posting_date, tax_details, pan_no) - if tax_deducted: - net_total = inv.tax_withholding_net_total - if ldc: - limit_consumed = get_limit_consumed(ldc, parties) - if is_valid_certificate(ldc, posting_date, limit_consumed): - tax_amount = get_lower_deduction_amount( - net_total, limit_consumed, ldc.certificate_limit, ldc.rate, tax_details - ) - else: - tax_amount = net_total * tax_details.rate / 100 - else: - tax_amount = net_total * tax_details.rate / 100 - - # once tds is deducted, not need to add vouchers in the invoice - voucher_wise_amount = {} - else: - tax_amount = get_tds_amount(ldc, parties, inv, tax_details, voucher_wise_amount) - - elif party_type == "Customer": - if tax_deducted: - # if already TCS is charged, then amount will be calculated based on 'Previous Row Total' - tax_amount = 0 - else: - # if no TCS has been charged in FY, - # then chargeable value is "prev invoices + advances - advance_adjusted" value which cross the threshold - tax_amount = get_tcs_amount(parties, inv, tax_details, vouchers, advance_vouchers) - - if cint(tax_details.round_off_tax_amount): - tax_amount = normal_round(tax_amount) - - return tax_amount, tax_deducted, tax_deducted_on_advances, voucher_wise_amount - - -def is_tax_deducted_on_the_basis_of_inv(vouchers): - return frappe.db.exists( - "Purchase Taxes and Charges", - { - "parent": ["in", vouchers], - "is_tax_withholding_account": 1, - "parenttype": "Purchase Invoice", - "base_tax_amount_after_discount_amount": [">", 0], - }, - ) - - -def get_invoice_vouchers(parties, tax_details, company, party_type="Supplier"): - voucher_wise_amount = [] - vouchers = [] - - ldcs = frappe.db.get_all( - "Lower Deduction Certificate", - filters={ - "valid_from": [">=", tax_details.from_date], - "valid_upto": ["<=", tax_details.to_date], - "company": company, - "supplier": ["in", parties], - }, - fields=["supplier", "valid_from", "valid_upto", "rate"], - ) - - doctype = "Purchase Invoice" if party_type == "Supplier" else "Sales Invoice" - field = [ - "base_tax_withholding_net_total as base_net_total" if party_type == "Supplier" else "base_net_total", - "name", - "grand_total", - "posting_date", - ] - - filters = { - "company": company, - frappe.scrub(party_type): ["in", parties], - "posting_date": ["between", (tax_details.from_date, tax_details.to_date)], - "is_opening": "No", - "docstatus": 1, - } - - if doctype != "Sales Invoice": - filters.update( - {"apply_tds": 1, "tax_withholding_category": tax_details.get("tax_withholding_category")} ) - invoices_details = frappe.get_all(doctype, filters=filters, fields=field) - for d in invoices_details: - d = frappe._dict( - { - "voucher_name": d.name, - "voucher_type": doctype, - "taxable_amount": d.base_net_total, - "grand_total": d.grand_total, - "posting_date": d.posting_date, - } - ) +class TaxWithholdingDetails: + def __init__( + self, + tax_withholding_categories: list[str], + tax_withholding_group: str, + posting_date: str, + party_type: str, + party: str, + company: str, + ): + self.tax_withholding_categories = tax_withholding_categories + self.tax_withholding_group = tax_withholding_group + self.posting_date = posting_date + self.party_type = party_type + self.party = party + self.company = company - if ldc := [x for x in ldcs if d.posting_date >= x.valid_from and d.posting_date <= x.valid_upto]: - if ldc[0].supplier in parties and ldc[0].rate == 0: - d.update({"taxable_amount": 0}) - - vouchers.append(d.voucher_name) - voucher_wise_amount.append(d) - - journal_entries_details = frappe.db.sql( + def get(self) -> list: """ - SELECT j.name, ja.credit - ja.debit AS amount, ja.reference_type - FROM `tabJournal Entry` j, `tabJournal Entry Account` ja - WHERE - j.name = ja.parent - AND j.docstatus = 1 - AND j.is_opening = 'No' - AND j.posting_date between %s and %s - AND ja.party in %s - AND j.apply_tds = 1 - AND j.tax_withholding_category = %s - AND j.company = %s - """, - ( - tax_details.from_date, - tax_details.to_date, - tuple(parties), - tax_details.get("tax_withholding_category"), - company, - ), - as_dict=1, - ) + Fetches tax withholding categories based on the provided parameters. + """ + category_details = frappe._dict() + if not self.tax_withholding_categories: + return category_details - for d in journal_entries_details: - vouchers.append(d.name) - voucher_wise_amount.append( - frappe._dict( - { - "voucher_name": d.name, - "voucher_type": "Journal Entry", - "taxable_amount": d.amount, - "reference_type": d.reference_type, - } + ldc_details = self.get_ldc_details() + + for category_name in self.tax_withholding_categories: + doc: TaxWithholdingCategory = frappe.get_cached_doc("Tax Withholding Category", category_name) + row = doc.get_applicable_tax_row(self.posting_date, self.tax_withholding_group) + account_head = doc.get_company_account(self.company) + + category_detail = frappe._dict( + name=category_name, + description=doc.category_name, + account_head=account_head, + # rates + tax_rate=row.tax_withholding_rate, + from_date=row.from_date, + to_date=row.to_date, + single_threshold=row.single_threshold, + cumulative_threshold=row.cumulative_threshold, + # settings + tax_deduction_basis=doc.tax_deduction_basis, + round_off_tax_amount=doc.round_off_tax_amount, + tax_on_excess_amount=doc.tax_on_excess_amount, + disable_cumulative_threshold=doc.disable_cumulative_threshold, + disable_transaction_threshold=doc.disable_transaction_threshold, + taxable_amount=0, + ) + + # ldc (only if valid based on posting date) + if ldc_detail := ldc_details.get(category_name): + category_detail.update(ldc_detail) + + category_details[category_name] = category_detail + + return category_details + + def get_ldc_details(self): + """ + Fetches the Lower Deduction Certificate (LDC) details for the given party. + Assumes that only one LDC per category can be valid at a time. + """ + ldc_details = {} + + if self.party_type != "Supplier": + return ldc_details + + # NOTE: This can be a configurable option + # To check if filter by tax_id is needed + tax_id = get_tax_id_for_party(self.party_type, self.party) + + # ldc details + ldc_records = self.get_valid_ldc_records(tax_id) + if not ldc_records: + return ldc_details + + ldc_names = [ldc.name for ldc in ldc_records] + ldc_utilization_map = self.get_ldc_utilization_by_category(ldc_names, tax_id) + + # map + for ldc in ldc_records: + category_name = ldc.tax_withholding_category + + unutilized_amount = ldc.certificate_limit - (ldc_utilization_map.get(ldc.name) or 0) + if not unutilized_amount: + continue + + ldc_details[category_name] = dict( + ldc_certificate=ldc.name, + ldc_unutilized_amount=unutilized_amount, + ldc_rate=ldc.rate, + ) + + return ldc_details + + def get_valid_ldc_records(self, tax_id): + ldc = frappe.qb.DocType("Lower Deduction Certificate") + query = ( + frappe.qb.from_(ldc) + .select( + ldc.name, + ldc.tax_withholding_category, + ldc.rate, + ldc.certificate_limit, + ) + .where( + (ldc.valid_from <= self.posting_date) + & (ldc.valid_upto >= self.posting_date) + & (ldc.company == self.company) + & ldc.tax_withholding_category.isin(self.tax_withholding_categories) ) ) - return vouchers, voucher_wise_amount + query = query.where(ldc.pan_no == tax_id) if tax_id else query.where(ldc.supplier == self.party) + return query.run(as_dict=True) -def get_payment_entry_vouchers(parties, tax_details, company, party_type="Supplier"): - payment_entry_filters = { - "party_type": party_type, - "party": ("in", parties), - "docstatus": 1, - "apply_tax_withholding_amount": 1, - "posting_date": ["between", (tax_details.from_date, tax_details.to_date)], - "tax_withholding_category": tax_details.get("tax_withholding_category"), - "company": company, - } - - return frappe.db.get_all("Payment Entry", filters=payment_entry_filters, pluck="name") - - -def get_advance_vouchers(parties, company=None, from_date=None, to_date=None, party_type="Supplier"): - """ - Use Payment Ledger to fetch unallocated Advance Payments - """ - - if party_type == "Supplier": - return [] - - ple = qb.DocType("Payment Ledger Entry") - - conditions = [] - - conditions.append(ple.amount.lt(0)) - conditions.append(ple.delinked == 0) - conditions.append(ple.party_type == party_type) - conditions.append(ple.party.isin(parties)) - conditions.append(ple.voucher_no == ple.against_voucher_no) - - if company: - conditions.append(ple.company == company) - - if from_date and to_date: - conditions.append(ple.posting_date[from_date:to_date]) - - advances = qb.from_(ple).select(ple.voucher_no).distinct().where(Criterion.all(conditions)).run(as_list=1) - if advances: - advances = [x[0] for x in advances] - - return advances - - -def get_taxes_deducted_on_advances_allocated(inv, tax_details): - tax_info = [] - - if inv.get("advances"): - advances = [d.reference_name for d in inv.get("advances")] - - if advances: - pe = frappe.qb.DocType("Payment Entry").as_("pe") - at = frappe.qb.DocType("Advance Taxes and Charges").as_("at") - - tax_info = ( - frappe.qb.from_(at) - .inner_join(pe) - .on(pe.name == at.parent) - .select(pe.posting_date, at.parent, at.name, at.tax_amount, at.allocated_amount) - .where(pe.tax_withholding_category == tax_details.get("tax_withholding_category")) - .where(at.parent.isin(advances)) - .where(at.account_head == tax_details.account_head) - .run(as_dict=True) - ) - - return tax_info - - -def get_deducted_tax(taxable_vouchers, tax_details): - # check if TDS / TCS account is already charged on taxable vouchers - filters = { - "is_cancelled": 0, - "credit": [">", 0], - "posting_date": ["between", (tax_details.from_date, tax_details.to_date)], - "account": tax_details.account_head, - "voucher_no": ["in", taxable_vouchers], - } - field = "credit" - - entries = frappe.db.get_all("GL Entry", filters, pluck=field) - return sum(entries) - - -def get_advance_tax_across_fiscal_year(tax_deducted_on_advances, tax_details): - """ - Only applies for Taxes deducted on Advance Payments - """ - advance_tax_from_across_fiscal_year = sum( - [adv.tax_amount for adv in tax_deducted_on_advances if adv.posting_date < tax_details.from_date] - ) - return advance_tax_from_across_fiscal_year - - -def get_tds_amount(ldc, parties, inv, tax_details, voucher_wise_amount): - tds_amount = 0 - - pi_grand_total = 0 - pi_base_net_total = 0 - jv_credit_amt = 0 - pe_credit_amt = 0 - - for row in voucher_wise_amount: - if row.voucher_type == "Purchase Invoice": - pi_grand_total += row.get("grand_total", 0) - pi_base_net_total += row.get("taxable_amount", 0) - - if row.voucher_type == "Journal Entry" and row.reference_type != "Purchase Invoice": - jv_credit_amt += row.get("taxable_amount", 0) - - ## for TDS to be deducted on advances - pe_filters = { - "party_type": "Supplier", - "party": ("in", parties), - "docstatus": 1, - "apply_tax_withholding_amount": 1, - "unallocated_amount": (">", 0), - "posting_date": ["between", (tax_details.from_date, tax_details.to_date)], - "tax_withholding_category": tax_details.get("tax_withholding_category"), - "company": inv.company, - } - - consider_party_ledger_amt = cint(tax_details.consider_party_ledger_amount) - - if consider_party_ledger_amt: - pe_filters.pop("apply_tax_withholding_amount", None) - pe_filters.pop("tax_withholding_category", None) - - # Get Amount via payment entry - payment_entries = frappe.db.get_all( - "Payment Entry", - filters=pe_filters, - fields=["name", "unallocated_amount as taxable_amount", "payment_type"], - ) - - for row in payment_entries: - value = row.taxable_amount if row.payment_type == "Pay" else -1 * row.taxable_amount - pe_credit_amt += value - voucher_wise_amount.append( - frappe._dict( - { - "voucher_name": row.name, - "voucher_type": "Payment Entry", - "taxable_amount": value, - } + def get_ldc_utilization_by_category(self, ldc_names, tax_id): + twe = frappe.qb.DocType("Tax Withholding Entry") + query = ( + frappe.qb.from_(twe) + .select(twe.lower_deduction_certificate, Sum(twe.taxable_amount).as_("limit_consumed")) + .where( + (twe.company == self.company) + & (twe.party_type == self.party_type) + & (twe.tax_withholding_category.isin(self.tax_withholding_categories)) + & (twe.lower_deduction_certificate.isin(ldc_names)) + & (twe.docstatus == 1) + & (twe.status.isin(["Settled", "Over Withheld"])) ) + .groupby(twe.lower_deduction_certificate) ) - threshold = tax_details.get("threshold", 0) - cumulative_threshold = tax_details.get("cumulative_threshold", 0) - supp_credit_amt = jv_credit_amt + pe_credit_amt + inv.get("tax_withholding_net_total", 0) - tax_withholding_net_total = inv.get("base_tax_withholding_net_total", 0) + query = query.where(twe.tax_id == tax_id) if tax_id else query.where(twe.party == self.party) - # if consider_party_ledger_amount is checked, then threshold will be based on grand total - amt_for_threshold = pi_grand_total if consider_party_ledger_amt else pi_base_net_total - - cumulative_threshold_breached = ( - cumulative_threshold and (supp_credit_amt + amt_for_threshold) >= cumulative_threshold - ) - - if (threshold and tax_withholding_net_total >= threshold) or (cumulative_threshold_breached): - supp_credit_amt += pi_base_net_total - - if cumulative_threshold_breached and cint(tax_details.tax_on_excess_amount): - supp_credit_amt = pi_base_net_total + tax_withholding_net_total - cumulative_threshold - - if ldc and is_valid_certificate(ldc, inv.get("posting_date") or inv.get("transaction_date"), 0): - tds_amount = get_lower_deduction_amount( - supp_credit_amt, 0, ldc.certificate_limit, ldc.rate, tax_details - ) - else: - tds_amount = supp_credit_amt * tax_details.rate / 100 if supp_credit_amt > 0 else 0 - - return tds_amount + return frappe._dict(query.run()) -def get_tcs_amount(parties, inv, tax_details, vouchers, adv_vouchers): - tcs_amount = 0 - ple = qb.DocType("Payment Ledger Entry") - - # sum of debit entries made from sales invoices - invoiced_amt = ( - frappe.db.get_value( - "GL Entry", - { - "is_cancelled": 0, - "party_type": "Customer", - "party": ["in", parties], - "company": inv.company, - "voucher_no": ["in", vouchers], - }, - [{"SUM": "debit"}], - ) - or 0.0 - ) - - # sum of credit entries made from PE / JV with unset 'against voucher' - - conditions = [] - conditions.append(ple.amount.lt(0)) - conditions.append(ple.delinked == 0) - conditions.append(ple.party_type == "Customer") - conditions.append(ple.party.isin(parties)) - conditions.append(ple.voucher_no == ple.against_voucher_no) - conditions.append(ple.company == inv.company) - conditions.append(ple.posting_date[tax_details.from_date : tax_details.to_date]) - - advance_amt = ( - qb.from_(ple).select(Abs(Sum(ple.amount))).where(Criterion.all(conditions)).run()[0][0] or 0.0 - ) - - # sum of credit entries made from sales invoice - credit_note_amt = sum( - frappe.db.get_all( - "GL Entry", - { - "is_cancelled": 0, - "credit": [">", 0], - "party_type": "Customer", - "party": ["in", parties], - "posting_date": ["between", (tax_details.from_date, tax_details.to_date)], - "company": inv.company, - "voucher_type": "Sales Invoice", - }, - pluck="credit", - ) - ) - - cumulative_threshold = tax_details.get("cumulative_threshold", 0) - advance_adjusted = get_advance_adjusted_in_invoice(inv) - - current_invoice_total = get_invoice_total_without_tcs(inv, tax_details) - total_invoiced_amt = ( - current_invoice_total + invoiced_amt + advance_amt - credit_note_amt - advance_adjusted - ) - - if cumulative_threshold and total_invoiced_amt >= cumulative_threshold: - chargeable_amt = total_invoiced_amt - cumulative_threshold - tcs_amount = chargeable_amt * tax_details.rate / 100 if chargeable_amt > 0 else 0 - - return tcs_amount - - -def get_advance_adjusted_in_invoice(inv): - advances_adjusted = 0 - for row in inv.get("advances", []): - advances_adjusted += row.allocated_amount - - return advances_adjusted - - -def get_invoice_total_without_tcs(inv, tax_details): - tcs_tax_row = [d for d in inv.taxes if d.account_head == tax_details.account_head] - tcs_tax_row_amount = tcs_tax_row[0].base_tax_amount if tcs_tax_row else 0 - - return inv.grand_total - tcs_tax_row_amount - - -def get_limit_consumed(ldc, parties): - limit_consumed = frappe.db.get_value( - "Purchase Invoice", - { - "supplier": ("in", parties), - "apply_tds": 1, - "docstatus": 1, - "tax_withholding_category": ldc.tax_withholding_category, - "posting_date": ("between", (ldc.valid_from, ldc.valid_upto)), - "company": ldc.company, - }, - [{"SUM": "tax_withholding_net_total"}], - ) - - return limit_consumed - - -def get_lower_deduction_amount(current_amount, limit_consumed, certificate_limit, rate, tax_details): - if certificate_limit - flt(limit_consumed) - flt(current_amount) >= 0: - return current_amount * rate / 100 - else: - ltds_amount = certificate_limit - flt(limit_consumed) - tds_amount = current_amount - ltds_amount - - return ltds_amount * rate / 100 + tds_amount * tax_details.rate / 100 - - -def is_valid_certificate(ldc, posting_date, limit_consumed): - available_amount = flt(ldc.certificate_limit) - flt(limit_consumed) - if (getdate(ldc.valid_from) <= getdate(posting_date) <= getdate(ldc.valid_upto)) and available_amount > 0: - return True - - return False - - -def normal_round(number): - """ - Rounds a number to the nearest integer. - :param number: The number to round. - """ - decimal_part = number - int(number) - - if decimal_part >= 0.5: - decimal_part = 1 - else: - decimal_part = 0 - - number = int(number) + decimal_part - - return number +@allow_regional +def get_tax_id_for_party(party_type, party): + return None diff --git a/erpnext/accounts/doctype/tax_withholding_category/test_tax_withholding_category.py b/erpnext/accounts/doctype/tax_withholding_category/test_tax_withholding_category.py index 4aa0dccc65f..38561815d65 100644 --- a/erpnext/accounts/doctype/tax_withholding_category/test_tax_withholding_category.py +++ b/erpnext/accounts/doctype/tax_withholding_category/test_tax_withholding_category.py @@ -2,7 +2,6 @@ # See license.txt import datetime -import unittest import frappe from frappe.custom.doctype.custom_field.custom_field import create_custom_fields @@ -28,10 +27,240 @@ class TestTaxWithholdingCategory(IntegrationTestCase): def tearDown(self): frappe.db.rollback() + def validate_tax_withholding_entries(self, doctype, docname, expected_entries): + """Validate tax withholding entries for a document""" + entries = frappe.get_all( + "Tax Withholding Entry", + filters={"parenttype": doctype, "parent": docname}, + fields=[ + "tax_withholding_category", + "party_type", + "party", + "tax_rate", + "withholding_amount", + "taxable_amount", + "status", + "taxable_doctype", + "taxable_name", + "withholding_doctype", + "withholding_name", + "under_withheld_reason", + "lower_deduction_certificate", + ], + ) + + self.assertEqual(len(entries), len(expected_entries), "Number of entries mismatch") + + # Sort both actual and expected entries for consistent comparison + def sort_key(entry): + return ( + entry.get("taxable_doctype", ""), + entry.get("taxable_name", ""), + entry.get("withholding_doctype", ""), + entry.get("withholding_name", ""), + entry.get("tax_withholding_category", ""), + entry.get("taxable_amount", 0), + entry.get("withholding_amount", 0), + entry.get("under_withheld_reason", "") or "", + entry.get("lower_deduction_certificate", "") or "", + ) + + sorted_entries = sorted(entries, key=sort_key) + sorted_expected = sorted(expected_entries, key=sort_key) + + # Normalize empty strings and None values for comparison + def normalize_entry(entry): + normalized = entry.copy() + # Convert None to empty string and empty string to None for consistent comparison + for field in ["under_withheld_reason", "lower_deduction_certificate"]: + if field in normalized: + if normalized[field] == "" or normalized[field] is None: + normalized[field] = None + return normalized + + normalized_entries = [normalize_entry(entry) for entry in sorted_entries] + normalized_expected = [normalize_entry(entry) for entry in sorted_expected] + + self.assertEqual( + normalized_entries, normalized_expected, "Tax withholding entries do not match expected values" + ) + + def get_tax_withholding_entry(self, **kwargs): + """ + Create a tax withholding entry with consistent field ordering + """ + entry = { + "tax_withholding_category": kwargs.get("tax_withholding_category"), + "party_type": kwargs.get("party_type"), + "party": kwargs.get("party"), + "tax_rate": kwargs.get("tax_rate") or 0.0, + "withholding_amount": kwargs.get("withholding_amount") or 0.0, + "taxable_amount": kwargs.get("taxable_amount") or 0.0, + "status": kwargs.get("status"), + "taxable_doctype": kwargs.get("taxable_doctype") or "", + "taxable_name": kwargs.get("taxable_name") or "", + "withholding_doctype": kwargs.get("withholding_doctype") or "", + "withholding_name": kwargs.get("withholding_name") or "", + "under_withheld_reason": kwargs.get("under_withheld_reason"), + "lower_deduction_certificate": kwargs.get("lower_deduction_certificate"), + } + return entry + + def setup_party_with_category(self, party_type, party_name, category_name): + """Setup party with tax withholding category""" + frappe.db.set_value( + party_type, + party_name, + "tax_withholding_category", + category_name, + ) + + def validate_tax_deduction(self, invoice, expected_amount): + """Validate invoice tax deduction and grand total""" + actual_amount = sum([d.base_tax_amount for d in invoice.taxes if d.is_tax_withholding_account]) + self.assertEqual( + actual_amount, expected_amount, f"Expected TCS charged: {expected_amount}, got: {actual_amount}" + ) + + def cleanup_invoices(self, invoice_list): + """Clean up invoices in reverse order to avoid dependency issues""" + for invoice in reversed(invoice_list): + invoice.reload() + if invoice.docstatus == 1: + invoice.cancel() + def test_cumulative_threshold_tds(self): - frappe.db.set_value( - "Supplier", "Test TDS Supplier", "tax_withholding_category", "Cumulative Threshold TDS" - ) + "Tax withholding entries for cumulative threshold TDS with Tax on excess without single threshold" + self.setup_party_with_category("Supplier", "Test TDS Supplier", "Cumulative Threshold TDS") + invoices = [] + + # First invoice - should be under withheld + pi1 = create_purchase_invoice(supplier="Test TDS Supplier") + pi1.submit() + + expected_entries = [ + self.get_tax_withholding_entry( + tax_withholding_category="Cumulative Threshold TDS", + party_type="Supplier", + party="Test TDS Supplier", + taxable_doctype="Purchase Invoice", + taxable_name=pi1.name, + tax_rate=10.0, + taxable_amount=10000.0, + withholding_amount=0.0, + status="Under Withheld", + withholding_doctype=None, + withholding_name=None, + under_withheld_reason=None, + ) + ] + self.validate_tax_withholding_entries("Purchase Invoice", pi1.name, expected_entries) + + # Second invoice - should also be under withheld + pi2 = create_purchase_invoice(supplier="Test TDS Supplier") + pi2.submit() + + expected_entries = [ + self.get_tax_withholding_entry( + tax_withholding_category="Cumulative Threshold TDS", + party_type="Supplier", + party="Test TDS Supplier", + taxable_doctype="Purchase Invoice", + taxable_name=pi2.name, + tax_rate=10.0, + taxable_amount=10000.0, + withholding_amount=0.0, + status="Under Withheld", + withholding_doctype=None, + withholding_name=None, + under_withheld_reason=None, + ) + ] + self.validate_tax_withholding_entries("Purchase Invoice", pi2.name, expected_entries) + + # Third invoice - surpasses cumulative threshold, all should be settled + pi3 = create_purchase_invoice(supplier="Test TDS Supplier") + pi3.submit() + + expected_entries = [ + self.get_tax_withholding_entry( + tax_withholding_category="Cumulative Threshold TDS", + party_type="Supplier", + party="Test TDS Supplier", + taxable_doctype="Purchase Invoice", + taxable_name=pi1.name, + withholding_amount=1000.0, + tax_rate=10.0, + taxable_amount=10000.0, + status="Settled", + withholding_doctype="Purchase Invoice", + withholding_name=pi3.name, + under_withheld_reason=None, + ), + self.get_tax_withholding_entry( + tax_withholding_category="Cumulative Threshold TDS", + party_type="Supplier", + party="Test TDS Supplier", + taxable_doctype="Purchase Invoice", + taxable_name=pi2.name, + withholding_amount=1000.0, + tax_rate=10.0, + taxable_amount=10000.0, + status="Settled", + withholding_doctype="Purchase Invoice", + withholding_name=pi3.name, + under_withheld_reason=None, + ), + self.get_tax_withholding_entry( + tax_withholding_category="Cumulative Threshold TDS", + party_type="Supplier", + party="Test TDS Supplier", + taxable_doctype="Purchase Invoice", + taxable_name=pi3.name, + tax_rate=10.0, + taxable_amount=10000.0, + withholding_amount=1000.0, + status="Settled", + withholding_doctype="Purchase Invoice", + withholding_name=pi3.name, + under_withheld_reason=None, + ), + ] + + # Validate invoice totals and tax withholding entries + self.validate_tax_deduction(pi3, 3000) + self.validate_tax_withholding_entries("Purchase Invoice", pi3.name, expected_entries) + invoices.append(pi3) + + # Fourth invoice - TDS deducted on every invoice from now on + pi4 = create_purchase_invoice(supplier="Test TDS Supplier", rate=5000) + pi4.submit() + + expected_entries = [ + self.get_tax_withholding_entry( + tax_withholding_category="Cumulative Threshold TDS", + party_type="Supplier", + party="Test TDS Supplier", + taxable_doctype="Purchase Invoice", + taxable_name=pi4.name, + tax_rate=10.0, + taxable_amount=5000.0, + withholding_amount=500.0, + status="Settled", + withholding_doctype="Purchase Invoice", + withholding_name=pi4.name, + under_withheld_reason=None, + ) + ] + + # Validate invoice totals and tax withholding entries + self.validate_tax_deduction(pi4, 500) + self.validate_tax_withholding_entries("Purchase Invoice", pi4.name, expected_entries) + invoices.append(pi4) + + def test_cumulative_threshold_tds_with_account_change(self): + "Cumulative threshold TDS without tax_on_excess, with account change in the middle of the year" + self.setup_party_with_category("Supplier", "Test TDS Supplier", "Multi Account TDS Category") invoices = [] # create invoices for lower than single threshold tax rate @@ -41,7 +270,7 @@ class TestTaxWithholdingCategory(IntegrationTestCase): invoices.append(pi) # create another invoice whose total when added to previously created invoice, - # surpasses cumulative threshhold + # surpasses cumulative threshold pi = create_purchase_invoice(supplier="Test TDS Supplier") pi.submit() @@ -50,42 +279,7 @@ class TestTaxWithholdingCategory(IntegrationTestCase): self.assertEqual(pi.grand_total, 7000) invoices.append(pi) - # TDS is already deducted, so from onward system will deduct the TDS on every invoice - pi = create_purchase_invoice(supplier="Test TDS Supplier", rate=5000) - pi.submit() - - # assert equal tax deduction on total invoice amount until now - self.assertEqual(pi.taxes_and_charges_deducted, 500) - invoices.append(pi) - - # delete invoices to avoid clashing - for d in reversed(invoices): - d.cancel() - - def test_tds_with_account_changed(self): - frappe.db.set_value( - "Supplier", "Test TDS Supplier", "tax_withholding_category", "Multi Account TDS Category" - ) - invoices = [] - - # create invoices for lower than single threshold tax rate - for _ in range(2): - pi = create_purchase_invoice(supplier="Test TDS Supplier") - pi.submit() - invoices.append(pi) - - # create another invoice whose total when added to previously created invoice, - # surpasses cumulative threshhold - pi = create_purchase_invoice(supplier="Test TDS Supplier") - pi.submit() - - # assert equal tax deduction on total invoice amount until now - self.assertEqual(pi.taxes_and_charges_deducted, 3000) - self.assertEqual(pi.grand_total, 7000) - invoices.append(pi) - - # account changed - + # Change account in the middle of the year frappe.db.set_value( "Tax Withholding Account", {"parent": "Multi Account TDS Category"}, @@ -101,9 +295,8 @@ class TestTaxWithholdingCategory(IntegrationTestCase): self.assertEqual(pi.taxes_and_charges_deducted, 500) invoices.append(pi) - # delete invoices to avoid clashing - for d in reversed(invoices): - d.cancel() + # Clean up invoices to avoid clashing + self.cleanup_invoices(invoices) def test_single_threshold_tds(self): invoices = [] @@ -143,13 +336,11 @@ class TestTaxWithholdingCategory(IntegrationTestCase): # TDS amount is 1000 because in previous invoices it's already deducted self.assertEqual(pi.taxes_and_charges_deducted, 1000) - # delete invoices to avoid clashing - for d in reversed(invoices): - d.cancel() + self.cleanup_invoices(invoices) def test_tax_withholding_category_checks(self): invoices = [] - frappe.db.set_value("Supplier", "Test TDS Supplier3", "tax_withholding_category", "New TDS Category") + self.setup_party_with_category("Supplier", "Test TDS Supplier3", "New TDS Category") # First Invoice with no tds check pi = create_purchase_invoice(supplier="Test TDS Supplier3", rate=20000, do_not_save=True) @@ -168,14 +359,11 @@ class TestTaxWithholdingCategory(IntegrationTestCase): # Second didn't breach, no TDS should be applied self.assertEqual(pi1.taxes, []) - for d in reversed(invoices): - d.cancel() + self.cleanup_invoices(invoices) def test_cumulative_threshold_with_party_ledger_amount_on_net_total(self): invoices = [] - frappe.db.set_value( - "Supplier", "Test TDS Supplier3", "tax_withholding_category", "Advance TDS Category" - ) + self.setup_party_with_category("Supplier", "Test TDS Supplier3", "Advance TDS Category") # Invoice with tax and without exceeding single and cumulative thresholds for _ in range(2): @@ -208,12 +396,11 @@ class TestTaxWithholdingCategory(IntegrationTestCase): # Threshold calculation should be only on the third invoice self.assertEqual(pi1.taxes[0].tax_amount, 800) - for d in reversed(invoices): - d.cancel() + self.cleanup_invoices(invoices) def test_cumulative_threshold_with_tax_on_excess_amount(self): invoices = [] - frappe.db.set_value("Supplier", "Test TDS Supplier3", "tax_withholding_category", "New TDS Category") + self.setup_party_with_category("Supplier", "Test TDS Supplier3", "New TDS Category") # Invoice with tax and without exceeding single and cumulative thresholds for _ in range(2): @@ -235,126 +422,209 @@ class TestTaxWithholdingCategory(IntegrationTestCase): pi.submit() invoices.append(pi) - # Third Invoice exceeds single threshold and not exceeding cumulative threshold + # Validate tax withholding entry for each invoice (should be settled with exemption reason) + expected_entries = [ + self.get_tax_withholding_entry( + tax_withholding_category="New TDS Category", + party_type="Supplier", + party="Test TDS Supplier3", + tax_rate=10.0, + taxable_amount=10000.0, + withholding_amount=0.0, + status="Settled", + taxable_doctype="Purchase Invoice", + taxable_name=pi.name, + withholding_doctype="Purchase Invoice", + withholding_name=pi.name, + under_withheld_reason="Threshold Exemption", + ) + ] + self.validate_tax_withholding_entries("Purchase Invoice", pi.name, expected_entries) + + # Third Invoice breaches cumulative threshold pi1 = create_purchase_invoice(supplier="Test TDS Supplier3", rate=20000) pi1.apply_tds = 1 pi1.save() pi1.submit() invoices.append(pi1) + # Validate tax withholding entries for current invoice only + # For amount before threshold (first 10000): TDS entry with amount zero + # For amount above threshold (next 10000): TDS entry with TDS applied + expected_entries = [ + self.get_tax_withholding_entry( + tax_withholding_category="New TDS Category", + party_type="Supplier", + party="Test TDS Supplier3", + tax_rate=10.0, + taxable_amount=10000.0, + withholding_amount=0.0, + status="Settled", + taxable_doctype="Purchase Invoice", + taxable_name=pi1.name, + withholding_doctype="Purchase Invoice", + withholding_name=pi1.name, + under_withheld_reason="Threshold Exemption", + ), + self.get_tax_withholding_entry( + tax_withholding_category="New TDS Category", + party_type="Supplier", + party="Test TDS Supplier3", + tax_rate=10.0, + taxable_amount=10000.0, + withholding_amount=1000.0, + status="Settled", + taxable_doctype="Purchase Invoice", + taxable_name=pi1.name, + withholding_doctype="Purchase Invoice", + withholding_name=pi1.name, + under_withheld_reason=None, + ), + ] + self.validate_tax_withholding_entries("Purchase Invoice", pi1.name, expected_entries) + # Cumulative threshold is 10,000 # Threshold calculation should be only on the third invoice self.assertTrue(len(pi1.taxes) > 0) self.assertEqual(pi1.taxes[0].tax_amount, 1000) - for d in reversed(invoices): - d.cancel() + self.cleanup_invoices(invoices) - def test_cumulative_threshold_tcs(self): - frappe.db.set_value( - "Customer", "Test TCS Customer", "tax_withholding_category", "Cumulative Threshold TCS" - ) + def test_cumulative_threshold_tcs_on_gross_amount(self): + self.setup_party_with_category("Customer", "Test TCS Customer", "Cumulative Threshold TCS") invoices = [] - # create invoices for lower than single threshold tax rate + # First two invoices - below threshold, should be settled with zero TCS for _ in range(2): si = create_sales_invoice(customer="Test TCS Customer") + si.append( + "taxes", + { + "category": "Total", + "charge_type": "Actual", + "account_head": "TCS - _TC", + "cost_center": "Main - _TC", + "tax_amount": 200, + "description": "Test Gross Tax", + "add_deduct_tax": "Add", + }, + ) + si.save() si.submit() invoices.append(si) + expected_entries = [ + self.get_tax_withholding_entry( + tax_withholding_category="Cumulative Threshold TCS", + party_type="Customer", + party="Test TCS Customer", + tax_rate=10.0, + taxable_amount=10200.0, # including vat amount + withholding_amount=0.0, + status="Settled", + taxable_doctype="Sales Invoice", + taxable_name=si.name, + withholding_doctype="Sales Invoice", + withholding_name=si.name, + under_withheld_reason="Threshold Exemption", + ) + ] + self.validate_tax_withholding_entries("Sales Invoice", si.name, expected_entries) - # create another invoice whose total when added to previously created invoice, - # surpasses cumulative threshold + # Third invoice - breaches threshold, TCS applied only on excess si = create_sales_invoice(customer="Test TCS Customer", rate=12000) + si.append( + "taxes", + { + "category": "Total", + "charge_type": "Actual", + "account_head": "TCS - _TC", + "cost_center": "Main - _TC", + "tax_amount": 400, + "description": "Test Gross Tax", + "add_deduct_tax": "Add", + }, + ) + si.save() si.submit() - - # assert tax collection on total invoice amount created until now - tcs_charged = sum([d.base_tax_amount for d in si.taxes if d.account_head == "TCS - _TC"]) - self.assertEqual(tcs_charged, 200) - self.assertEqual(si.grand_total, 12200) invoices.append(si) + # For amount before threshold (first 8000 + VAT): TCS entry with amount zero + # For amount above threshold (next 4000): TCS entry with TCS applied + expected_entries = [ + self.get_tax_withholding_entry( + tax_withholding_category="Cumulative Threshold TCS", + party_type="Customer", + party="Test TCS Customer", + tax_rate=10.0, + taxable_amount=9600.0, + withholding_amount=0.0, + status="Settled", + taxable_doctype="Sales Invoice", + taxable_name=si.name, + withholding_doctype="Sales Invoice", + withholding_name=si.name, + under_withheld_reason="Threshold Exemption", + ), + self.get_tax_withholding_entry( + tax_withholding_category="Cumulative Threshold TCS", + party_type="Customer", + party="Test TCS Customer", + tax_rate=10.0, + taxable_amount=2800.0, + withholding_amount=280.0, + status="Settled", + taxable_doctype="Sales Invoice", + taxable_name=si.name, + withholding_doctype="Sales Invoice", + withholding_name=si.name, + under_withheld_reason=None, + ), + ] + self.validate_tax_withholding_entries("Sales Invoice", si.name, expected_entries) + self.validate_tax_deduction(si, 280) + self.assertEqual(si.grand_total, 12680) - # TCS is already collected once, so going forward system will collect TCS on every invoice + # Fourth invoice - TCS applied on full amount si = create_sales_invoice(customer="Test TCS Customer", rate=5000) + si.append( + "taxes", + { + "category": "Total", + "charge_type": "Actual", + "account_head": "_Test Account VAT - _TC", + "cost_center": "Main - _TC", + "tax_amount": 500, + "description": "VAT added to test TDS calculation on gross amount", + "add_deduct_tax": "Add", + }, + ) + si.save() si.submit() - - tcs_charged = sum(d.base_tax_amount for d in si.taxes if d.account_head == "TCS - _TC") - self.assertEqual(tcs_charged, 500) invoices.append(si) + expected_entries = [ + self.get_tax_withholding_entry( + tax_withholding_category="Cumulative Threshold TCS", + party_type="Customer", + party="Test TCS Customer", + tax_rate=10.0, + taxable_amount=5500.0, + withholding_amount=550.0, + status="Settled", + taxable_doctype="Sales Invoice", + taxable_name=si.name, + withholding_doctype="Sales Invoice", + withholding_name=si.name, + under_withheld_reason=None, + ) + ] + self.validate_tax_withholding_entries("Sales Invoice", si.name, expected_entries) + self.validate_tax_deduction(si, 550) + self.assertEqual(si.grand_total, 6050) # cancel invoices to avoid clashing - for d in reversed(invoices): - d.cancel() - - def test_tcs_on_unallocated_advance_payments(self): - frappe.db.set_value( - "Customer", "Test TCS Customer", "tax_withholding_category", "Cumulative Threshold TCS" - ) - fiscal_year = get_fiscal_year(today(), company="_Test Company") - - vouchers = [] - - # create advance payment - pe1 = create_payment_entry( - payment_type="Receive", party_type="Customer", party="Test TCS Customer", paid_amount=20000 - ) - pe1.paid_from = "Debtors - _TC" - pe1.paid_to = "Cash - _TC" - pe1.submit() - vouchers.append(pe1) - - # create invoice - si1 = create_sales_invoice(customer="Test TCS Customer", rate=5000) - si1.submit() - vouchers.append(si1) - - # reconcile - pr = frappe.get_doc("Payment Reconciliation") - pr.company = "_Test Company" - pr.party_type = "Customer" - pr.party = "Test TCS Customer" - pr.receivable_payable_account = "Debtors - _TC" - pr.get_unreconciled_entries() - invoices = [x.as_dict() for x in pr.get("invoices")] - payments = [x.as_dict() for x in pr.get("payments")] - pr.allocate_entries(frappe._dict({"invoices": invoices, "payments": payments})) - pr.reconcile() - - # make another invoice - # sum of unallocated amount from payment entry and this sales invoice will breach cumulative threashold - # TDS should be calculated - - # this payment should not be considered for TCS calculation as it is outside of fiscal year - pe2 = create_payment_entry( - payment_type="Receive", party_type="Customer", party="Test TCS Customer", paid_amount=10000 - ) - pe2.paid_from = "Debtors - _TC" - pe2.paid_to = "Cash - _TC" - pe2.posting_date = add_days(fiscal_year[1], -10) - pe2.submit() - vouchers.append(pe2) - - si2 = create_sales_invoice(customer="Test TCS Customer", rate=15000) - si2.submit() - vouchers.append(si2) - - si3 = create_sales_invoice(customer="Test TCS Customer", rate=10000) - si3.submit() - vouchers.append(si3) - - # assert tax collection on total invoice amount created until now - tcs_charged = sum([d.base_tax_amount for d in si2.taxes if d.account_head == "TCS - _TC"]) - tcs_charged += sum([d.base_tax_amount for d in si3.taxes if d.account_head == "TCS - _TC"]) - self.assertEqual(tcs_charged, 1500) - - # cancel invoice and payments to avoid clashing - for d in reversed(vouchers): - d.reload() - d.cancel() + self.cleanup_invoices(invoices) def test_tcs_on_allocated_advance_payments(self): - frappe.db.set_value( - "Customer", "Test TCS Customer", "tax_withholding_category", "Cumulative Threshold TCS" - ) + self.setup_party_with_category("Customer", "Test TCS Customer", "Cumulative Threshold TCS") vouchers = [] @@ -364,9 +634,29 @@ class TestTaxWithholdingCategory(IntegrationTestCase): ) pe.paid_from = "Debtors - _TC" pe.paid_to = "Cash - _TC" + pe.apply_tds = 1 + pe.tax_withholding_category = "Cumulative Threshold TCS" pe.submit() vouchers.append(pe) + # Validate payment entry tax withholding entries + payment_expected_entries = [ + self.get_tax_withholding_entry( + tax_withholding_category="Cumulative Threshold TCS", + party_type="Customer", + party="Test TCS Customer", + tax_rate=10.0, + taxable_amount=30000.0, + withholding_amount=3000.0, + status="Over Withheld", + taxable_doctype="", + taxable_name="", + withholding_doctype="Payment Entry", + withholding_name=pe.name, + ) + ] + self.validate_tax_withholding_entries("Payment Entry", pe.name, payment_expected_entries) + si = create_sales_invoice(customer="Test TCS Customer", rate=50000) advances = si.get_advance_entries() si.append( @@ -381,20 +671,347 @@ class TestTaxWithholdingCategory(IntegrationTestCase): si.submit() vouchers.append(si) - # assert tax collection on total invoice ,advance payment adjusted should be excluded. + # Validate TCS charged on Sales Invoice + # Since PE already collected 3000 TCS (over-withheld), and total required is 5000, + # the remaining 2000 is settled from PE's over-withheld amount. + # No new TCS is deducted on SI - the taxes row should be 0. tcs_charged = sum([d.base_tax_amount for d in si.taxes if d.account_head == "TCS - _TC"]) - # tcs = (inv amt)50000+(adv amt)30000-(adv adj) 30000 - threshold(30000) * rate 10% - self.assertEqual(tcs_charged, 2000) + self.assertEqual(tcs_charged, 0) - # cancel invoice and payments to avoid clashing - for d in reversed(vouchers): - d.reload() - d.cancel() + # Validate invoice tax withholding entries + invoice_expected_entries = [ + # Main invoice entry + self.get_tax_withholding_entry( + tax_withholding_category="Cumulative Threshold TCS", + party_type="Customer", + party="Test TCS Customer", + tax_rate=10.0, + taxable_amount=30000, # Net amount after advance adjustment (50000-30000) + withholding_amount=0, # Tax on net amount: 30000 * 10% + status="Settled", + taxable_doctype="Sales Invoice", + taxable_name=si.name, + withholding_doctype="Sales Invoice", + withholding_name=si.name, + under_withheld_reason="Threshold Exemption", + ), + # Advance allocation adjustment entry + self.get_tax_withholding_entry( + tax_withholding_category="Cumulative Threshold TCS", + party_type="Customer", + party="Test TCS Customer", + tax_rate=10.0, + taxable_amount=20000.0, # Positive amount that's allocated + withholding_amount=2000.0, # No tax on allocated advance + status="Settled", + taxable_doctype="Sales Invoice", + taxable_name=si.name, + withholding_doctype="Payment Entry", + withholding_name=pe.name, + ), + ] + self.validate_tax_withholding_entries("Sales Invoice", si.name, invoice_expected_entries) + + self.cleanup_invoices(vouchers) + + def test_tds_multiple_payments_adjust_only_linked(self): + """ + Test that when multiple advance payment entries exist for the same supplier, + only the payment entry that is linked/allocated to the invoice is adjusted. + """ + self.setup_party_with_category("Supplier", "Test TDS Supplier", "Cumulative Threshold TDS") + + vouchers = [] + + pe1 = create_payment_entry( + payment_type="Pay", party_type="Supplier", party="Test TDS Supplier", paid_amount=5000 + ) + pe1.apply_tds = 1 + pe1.tax_withholding_category = "Cumulative Threshold TDS" + pe1.save() + pe1.submit() + vouchers.append(pe1) + + pe1_expected_entries = [ + self.get_tax_withholding_entry( + tax_withholding_category="Cumulative Threshold TDS", + party_type="Supplier", + party="Test TDS Supplier", + tax_rate=10.0, + taxable_amount=5000.0, + withholding_amount=500.0, + status="Over Withheld", + taxable_doctype="", + taxable_name="", + withholding_doctype="Payment Entry", + withholding_name=pe1.name, + ) + ] + self.validate_tax_withholding_entries("Payment Entry", pe1.name, pe1_expected_entries) + + pe2 = create_payment_entry( + payment_type="Pay", party_type="Supplier", party="Test TDS Supplier", paid_amount=3000 + ) + pe2.apply_tds = 1 + pe2.tax_withholding_category = "Cumulative Threshold TDS" + pe2.save() + pe2.submit() + vouchers.append(pe2) + + pe2_expected_entries = [ + self.get_tax_withholding_entry( + tax_withholding_category="Cumulative Threshold TDS", + party_type="Supplier", + party="Test TDS Supplier", + tax_rate=10.0, + taxable_amount=3000.0, + withholding_amount=300.0, + status="Over Withheld", + taxable_doctype="", + taxable_name="", + withholding_doctype="Payment Entry", + withholding_name=pe2.name, + ) + ] + self.validate_tax_withholding_entries("Payment Entry", pe2.name, pe2_expected_entries) + + pi = create_purchase_invoice(supplier="Test TDS Supplier", rate=40000) + pi.append( + "advances", + { + "reference_type": pe1.doctype, + "reference_name": pe1.name, + "advance_amount": 5000, + "allocated_amount": 5000, + }, + ) + pi.submit() + vouchers.append(pi) + + invoice_expected_entries = [ + self.get_tax_withholding_entry( + tax_withholding_category="Cumulative Threshold TDS", + party_type="Supplier", + party="Test TDS Supplier", + tax_rate=10.0, + taxable_amount=35000.0, + withholding_amount=3500.0, + status="Settled", + taxable_doctype="Purchase Invoice", + taxable_name=pi.name, + withholding_doctype="Purchase Invoice", + withholding_name=pi.name, + ), + self.get_tax_withholding_entry( + tax_withholding_category="Cumulative Threshold TDS", + party_type="Supplier", + party="Test TDS Supplier", + tax_rate=10.0, + taxable_amount=5000.0, + withholding_amount=500.0, + status="Settled", + taxable_doctype="Purchase Invoice", + taxable_name=pi.name, + withholding_doctype="Payment Entry", + withholding_name=pe1.name, + ), + ] + self.validate_tax_withholding_entries("Purchase Invoice", pi.name, invoice_expected_entries) + self.cleanup_invoices(vouchers) + + def test_tds_multiple_payments_with_unused_threshold(self): + """ + Test multiple payment entries with unused threshold (tax_on_excess_amount enabled). + Only the linked payment entry should be adjusted, and threshold exemption should apply. + """ + self.setup_party_with_category("Supplier", "Test TDS Supplier3", "New TDS Category") + + vouchers = [] + + pe1 = create_payment_entry( + payment_type="Pay", party_type="Supplier", party="Test TDS Supplier3", paid_amount=5000 + ) + pe1.apply_tds = 1 + pe1.tax_withholding_category = "New TDS Category" + pe1.save() + pe1.submit() + vouchers.append(pe1) + + pe1_expected_entries = [ + self.get_tax_withholding_entry( + tax_withholding_category="New TDS Category", + party_type="Supplier", + party="Test TDS Supplier3", + tax_rate=10.0, + taxable_amount=5000.0, + withholding_amount=500.0, + status="Over Withheld", + taxable_doctype="", + taxable_name="", + withholding_doctype="Payment Entry", + withholding_name=pe1.name, + ) + ] + self.validate_tax_withholding_entries("Payment Entry", pe1.name, pe1_expected_entries) + + pe2 = create_payment_entry( + payment_type="Pay", party_type="Supplier", party="Test TDS Supplier3", paid_amount=3000 + ) + pe2.apply_tds = 1 + pe2.tax_withholding_category = "New TDS Category" + pe2.save() + pe2.submit() + vouchers.append(pe2) + + pe2_expected_entries = [ + self.get_tax_withholding_entry( + tax_withholding_category="New TDS Category", + party_type="Supplier", + party="Test TDS Supplier3", + tax_rate=10.0, + taxable_amount=3000.0, + withholding_amount=300.0, + status="Over Withheld", + taxable_doctype="", + taxable_name="", + withholding_doctype="Payment Entry", + withholding_name=pe2.name, + ) + ] + self.validate_tax_withholding_entries("Payment Entry", pe2.name, pe2_expected_entries) + + pi = create_purchase_invoice(supplier="Test TDS Supplier3", rate=40000) + pi.append( + "advances", + { + "reference_type": pe1.doctype, + "reference_name": pe1.name, + "advance_amount": 5000, + "allocated_amount": 5000, + }, + ) + pi.submit() + vouchers.append(pi) + + # Expected entries: + # 1. Threshold Exemption for first 30000 (no TDS) + # 2. Remaining 5000 (40000-30000-5000 from PE1) from invoice + # 3. PE1's 5000 adjusted + invoice_expected_entries = [ + # Threshold exemption for first 30000 + self.get_tax_withholding_entry( + tax_withholding_category="New TDS Category", + party_type="Supplier", + party="Test TDS Supplier3", + tax_rate=10.0, + taxable_amount=30000.0, + withholding_amount=0.0, + status="Settled", + taxable_doctype="Purchase Invoice", + taxable_name=pi.name, + withholding_doctype="Purchase Invoice", + withholding_name=pi.name, + under_withheld_reason="Threshold Exemption", + ), + # Remaining 5000 from invoice (40000 - 30000 threshold - 5000 PE1) + self.get_tax_withholding_entry( + tax_withholding_category="New TDS Category", + party_type="Supplier", + party="Test TDS Supplier3", + tax_rate=10.0, + taxable_amount=5000.0, + withholding_amount=500.0, + status="Settled", + taxable_doctype="Purchase Invoice", + taxable_name=pi.name, + withholding_doctype="Purchase Invoice", + withholding_name=pi.name, + ), + # PE1's over-withheld adjustment (5000) + self.get_tax_withholding_entry( + tax_withholding_category="New TDS Category", + party_type="Supplier", + party="Test TDS Supplier3", + tax_rate=10.0, + taxable_amount=5000.0, + withholding_amount=500.0, + status="Settled", + taxable_doctype="Purchase Invoice", + taxable_name=pi.name, + withholding_doctype="Payment Entry", + withholding_name=pe1.name, + ), + ] + self.validate_tax_withholding_entries("Purchase Invoice", pi.name, invoice_expected_entries) + self.cleanup_invoices(vouchers) + + def test_tds_withholding_group_different_rates(self): + """ + Test that Tax Withholding Group applies different rates for different groups + within the same Tax Withholding Category. + """ + for group_name in ["Individual", "Company"]: + if not frappe.db.exists("Tax Withholding Group", group_name): + frappe.get_doc({"doctype": "Tax Withholding Group", "group_name": group_name}).insert() + + fiscal_year = get_fiscal_year(today(), company="_Test Company") + from_date = fiscal_year[1] + to_date = fiscal_year[2] + + # Single category with BOTH groups at different rates + if not frappe.db.exists("Tax Withholding Category", "TDS Group Rate Category"): + frappe.get_doc( + { + "doctype": "Tax Withholding Category", + "name": "TDS Group Rate Category", + "category_name": "TDS Group Rate Category", + "tax_deduction_basis": "Net Total", + "rates": [ + { + "from_date": from_date, + "to_date": to_date, + "tax_withholding_group": "Individual", + "tax_withholding_rate": 1, # 1% for Individual + "single_threshold": 0, + "cumulative_threshold": 0, + }, + { + "from_date": from_date, + "to_date": to_date, + "tax_withholding_group": "Company", + "tax_withholding_rate": 2, # 2% for Company + "single_threshold": 0, + "cumulative_threshold": 0, + }, + ], + "accounts": [{"company": "_Test Company", "account": "TDS - _TC"}], + } + ).insert() + + invoices = [] + + self.setup_party_with_category("Supplier", "Test TDS Supplier5", "TDS Group Rate Category") + frappe.db.set_value("Supplier", "Test TDS Supplier5", "tax_withholding_group", "Individual") + pi1 = create_purchase_invoice(supplier="Test TDS Supplier5", rate=100000) + pi1.submit() + invoices.append(pi1) + + total = sum([d.base_tax_amount for d in pi1.taxes if d.account_head == "TDS - _TC"]) + self.assertEqual(abs(total), 1000, "Individual rate should be 1% (1000 on 100000)") + + self.setup_party_with_category("Supplier", "Test TDS Supplier6", "TDS Group Rate Category") + frappe.db.set_value("Supplier", "Test TDS Supplier6", "tax_withholding_group", "Company") + pi2 = create_purchase_invoice(supplier="Test TDS Supplier6", rate=100000) + pi2.submit() + invoices.append(pi2) + + total = sum([d.base_tax_amount for d in pi2.taxes if d.account_head == "TDS - _TC"]) + self.assertEqual(abs(total), 2000, "Company rate should be 2% (2000 on 100000)") + + self.cleanup_invoices(invoices) def test_tds_calculation_on_net_total(self): - frappe.db.set_value( - "Supplier", "Test TDS Supplier4", "tax_withholding_category", "Cumulative Threshold TDS" - ) + self.setup_party_with_category("Supplier", "Test TDS Supplier4", "Cumulative Threshold TDS") invoices = [] pi = create_purchase_invoice(supplier="Test TDS Supplier4", rate=20000, do_not_save=True) @@ -406,7 +1023,7 @@ class TestTaxWithholdingCategory(IntegrationTestCase): "account_head": "_Test Account VAT - _TC", "cost_center": "Main - _TC", "tax_amount": 1000, - "description": "Test", + "description": "VAT added to test TDS calculation on gross amount", "add_deduct_tax": "Add", }, ) @@ -421,37 +1038,50 @@ class TestTaxWithholdingCategory(IntegrationTestCase): self.assertEqual(pi1.taxes[0].tax_amount, 4000) - # cancel invoices to avoid clashing - for d in reversed(invoices): - d.cancel() + self.cleanup_invoices(invoices) def test_tds_calculation_on_net_total_partial_tds(self): - frappe.db.set_value( - "Supplier", "Test TDS Supplier4", "tax_withholding_category", "Cumulative Threshold TDS" - ) + self.setup_party_with_category("Supplier", "Test TDS Supplier4", "Cumulative Threshold TDS") invoices = [] - pi = create_purchase_invoice(supplier="Test TDS Supplier4", rate=20000, do_not_save=True) + # Create purchase invoice with 3 items: + # 1. No TDS (apply_tds = 0) + # 2. TDS with Test Service Category (rate 10%, single_threshold=2000, cumulative_threshold=2000, no tax on excess) + # 3. TDS with New TDS Category (rate 10%, cumulative_threshold=30000, tax on excess enabled) + item_code = frappe.db.get_value("Item", {"item_name": "TDS Item"}, "name") + pi = create_purchase_invoice(supplier="Test TDS Supplier4", rate=0, do_not_save=True) + pi.items = [] pi.extend( "items", [ { "doctype": "Purchase Invoice Item", - "item_code": frappe.db.get_value("Item", {"item_name": "TDS Item"}, "name"), + "item_code": item_code, "qty": 1, - "rate": 20000, + "rate": 10000, "cost_center": "Main - _TC", "expense_account": "Stock Received But Not Billed - _TC", - "apply_tds": 0, + "apply_tds": 0, # No TDS for this item }, { "doctype": "Purchase Invoice Item", - "item_code": frappe.db.get_value("Item", {"item_name": "TDS Item"}, "name"), + "item_code": item_code, "qty": 1, - "rate": 35000, + "rate": 5000, # Above single threshold of 2000 for Test Service Category "cost_center": "Main - _TC", "expense_account": "Stock Received But Not Billed - _TC", "apply_tds": 1, + "tax_withholding_category": "Test Service Category", + }, + { + "doctype": "Purchase Invoice Item", + "item_code": item_code, + "qty": 1, + "rate": 35000, # Above cumulative threshold for New TDS Category with tax on excess + "cost_center": "Main - _TC", + "expense_account": "Stock Received But Not Billed - _TC", + "apply_tds": 1, + "tax_withholding_category": "New TDS Category", }, ], ) @@ -459,55 +1089,70 @@ class TestTaxWithholdingCategory(IntegrationTestCase): pi.submit() invoices.append(pi) - self.assertEqual(pi.taxes[0].tax_amount, 5500) + # Expected behavior: + # Item 1: No TDS - no tax withholding entry + # Item 2: Test Service Category - TDS applies as amount (5000) > single threshold (2000) + # Item 3: New TDS Category - TDS applies with tax on excess logic as amount (35000) > cumulative threshold (30000) - # cancel invoices to avoid clashing - for d in reversed(invoices): - d.cancel() + # Validate tax withholding entries + expected_entries = [ + # Item 2: Test Service Category - TDS deducted on full amount since it exceeds single threshold + self.get_tax_withholding_entry( + tax_withholding_category="Test Service Category", + party_type="Supplier", + party="Test TDS Supplier4", # Same supplier for all items + tax_rate=10.0, + taxable_amount=5000.0, + withholding_amount=500.0, # 10% of 5000 + status="Settled", + taxable_doctype="Purchase Invoice", + taxable_name=pi.name, + withholding_doctype="Purchase Invoice", + withholding_name=pi.name, + under_withheld_reason=None, + ), + # Item 3: New TDS Category - TDS with tax on excess logic + # First 30000 (threshold) - no TDS + self.get_tax_withholding_entry( + tax_withholding_category="New TDS Category", + party_type="Supplier", + party="Test TDS Supplier4", + tax_rate=10.0, + taxable_amount=30000.0, + withholding_amount=0.0, # No TDS on threshold amount + status="Settled", + taxable_doctype="Purchase Invoice", + taxable_name=pi.name, + withholding_doctype="Purchase Invoice", + withholding_name=pi.name, + under_withheld_reason="Threshold Exemption", + ), + # Remaining 5000 (35000-30000) - TDS applies + self.get_tax_withholding_entry( + tax_withholding_category="New TDS Category", + party_type="Supplier", + party="Test TDS Supplier4", + tax_rate=10.0, + taxable_amount=5000.0, + withholding_amount=500.0, # 10% of excess amount (5000) + status="Settled", + taxable_doctype="Purchase Invoice", + taxable_name=pi.name, + withholding_doctype="Purchase Invoice", + withholding_name=pi.name, + under_withheld_reason=None, + ), + ] - orders = [] + self.validate_tax_withholding_entries("Purchase Invoice", pi.name, expected_entries) - po = create_purchase_order(supplier="Test TDS Supplier4", rate=20000, do_not_save=True) - po.extend( - "items", - [ - { - "doctype": "Purchase Order Item", - "item_code": frappe.db.get_value("Item", {"item_name": "TDS Item"}, "name"), - "qty": 1, - "rate": 20000, - "cost_center": "Main - _TC", - "expense_account": "Stock Received But Not Billed - _TC", - "apply_tds": 0, - }, - { - "doctype": "Purchase Order Item", - "item_code": frappe.db.get_value("Item", {"item_name": "TDS Item"}, "name"), - "qty": 1, - "rate": 35000, - "cost_center": "Main - _TC", - "expense_account": "Stock Received But Not Billed - _TC", - "apply_tds": 1, - }, - ], - ) - po.save() - po.submit() - orders.append(po) + self.validate_tax_deduction(pi, 1000) - self.assertEqual(po.taxes[0].tax_amount, 5500) - - # cancel orders to avoid clashing - for d in reversed(orders): - d.cancel() + self.cleanup_invoices(invoices) def test_tds_deduction_for_po_via_payment_entry(self): - frappe.db.set_value( - "Supplier", "Test TDS Supplier8", "tax_withholding_category", "Cumulative Threshold TDS" - ) + self.setup_party_with_category("Supplier", "Test TDS Supplier8", "Cumulative Threshold TDS") order = create_purchase_order(supplier="Test TDS Supplier8", rate=40000, do_not_save=True) - - # Add some tax on the order order.append( "taxes", { @@ -522,50 +1167,51 @@ class TestTaxWithholdingCategory(IntegrationTestCase): ) order.save() - - order.apply_tds = 1 - order.tax_withholding_category = "Cumulative Threshold TDS" order.submit() - - self.assertEqual(order.taxes[0].tax_amount, 4000) + self.assertEqual(order.taxes[0].tax_amount, 8000) payment = get_payment_entry(order.doctype, order.name) - payment.apply_tax_withholding_amount = 1 + payment.apply_tds = 1 payment.tax_withholding_category = "Cumulative Threshold TDS" payment.save().submit() - self.assertEqual(payment.taxes[0].tax_amount, 4000) + self.assertEqual(payment.taxes[0].tax_amount, 4800) def test_multi_category_single_supplier(self): - frappe.db.set_value( - "Supplier", "Test TDS Supplier5", "tax_withholding_category", "Test Service Category" - ) + self.setup_party_with_category("Supplier", "Test TDS Supplier5", "Test Service Category") invoices = [] pi = create_purchase_invoice(supplier="Test TDS Supplier5", rate=500, do_not_save=True) - pi.tax_withholding_category = "Test Service Category" pi.save() pi.submit() invoices.append(pi) + self.assertEqual(pi.items[0].tax_withholding_category, "Test Service Category") # Second Invoice will apply TDS checked pi1 = create_purchase_invoice(supplier="Test TDS Supplier5", rate=2500, do_not_save=True) - pi1.tax_withholding_category = "Test Goods Category" + for item in pi1.items: + item.apply_tds = 1 + item.tax_withholding_category = "Test Goods Category" pi1.save() pi1.submit() invoices.append(pi1) self.assertEqual(pi1.taxes[0].tax_amount, 250) - # cancel invoices to avoid clashing - for d in reversed(invoices): - d.cancel() + self.cleanup_invoices(invoices) - def test_tax_withholding_category_voucher_display(self): - frappe.db.set_value( - "Supplier", "Test TDS Supplier6", "tax_withholding_category", "Test Multi Invoice Category" - ) + def test_tds_deductions_with_payment_entries(self): + """ + Test tax withholding entries across different voucher types and statuses: + - Purchase Invoice: Regular invoice (Under Withheld - below threshold) + - Return Invoice: Negative amount (Under Withheld - return, no TDS) + - Payment Entry: Over Withheld (always) + - Payment Entry2: Over Withheld (always) + - Final Invoice: Settlement invoice that settles all previous entries (Settled status) + """ + self.setup_party_with_category("Supplier", "Test TDS Supplier6", "Test Multi Invoice Category") invoices = [] + # First invoice - below threshold, should be under withheld pi = create_purchase_invoice(supplier="Test TDS Supplier6", rate=4000, do_not_save=True) pi.apply_tds = 1 pi.tax_withholding_category = "Test Multi Invoice Category" @@ -573,77 +1219,345 @@ class TestTaxWithholdingCategory(IntegrationTestCase): pi.submit() invoices.append(pi) - pi1 = create_purchase_invoice(supplier="Test TDS Supplier6", rate=2000, do_not_save=True) - pi1.apply_tds = 1 - pi1.is_return = 1 - pi1.items[0].qty = -1 - pi1.tax_withholding_category = "Test Multi Invoice Category" - pi1.save() - pi1.submit() - invoices.append(pi1) + # Validate tax withholding entry for first invoice + expected_entries = [ + self.get_tax_withholding_entry( + tax_withholding_category="Test Multi Invoice Category", + party_type="Supplier", + party="Test TDS Supplier6", + tax_rate=10.0, + taxable_amount=4000.0, + withholding_amount=0.0, + status="Under Withheld", + taxable_doctype="Purchase Invoice", + taxable_name=pi.name, + withholding_doctype="", + withholding_name="", + under_withheld_reason=None, + ) + ] + self.validate_tax_withholding_entries("Purchase Invoice", pi.name, expected_entries) + + pe1 = create_payment_entry( + payment_type="Pay", party_type="Supplier", party="Test TDS Supplier6", paid_amount=3000 + ) + pe1.apply_tds = 1 + pe1.tax_withholding_category = "Test Multi Invoice Category" + pe1.save() + pe1.submit() + invoices.append(pe1) + + expected_entries = [ + self.get_tax_withholding_entry( + tax_withholding_category="Test Multi Invoice Category", + party_type="Supplier", + party="Test TDS Supplier6", + tax_rate=10.0, + taxable_amount=3000.0, + withholding_amount=300.0, + status="Over Withheld", + taxable_doctype="", + taxable_name="", + withholding_doctype="Payment Entry", + withholding_name=pe1.name, + ) + ] + self.validate_tax_withholding_entries("Payment Entry", pe1.name, expected_entries) + + pe2 = create_payment_entry( + payment_type="Pay", party_type="Supplier", party="Test TDS Supplier6", paid_amount=6000 + ) + pe2.apply_tds = 1 + pe2.tax_withholding_category = "Test Multi Invoice Category" + pe2.save() + pe2.submit() + invoices.append(pe2) + + # Validate tax withholding entry for larger payment entry (over withheld) + expected_entries = [ + self.get_tax_withholding_entry( + tax_withholding_category="Test Multi Invoice Category", + party_type="Supplier", + party="Test TDS Supplier6", + tax_rate=10.0, + taxable_amount=6000.0, + withholding_amount=600.0, + status="Over Withheld", + taxable_doctype="", + taxable_name="", + withholding_doctype="Payment Entry", + withholding_name=pe2.name, + under_withheld_reason=None, + ) + ] + self.validate_tax_withholding_entries("Payment Entry", pe2.name, expected_entries) + + # Final invoice - should breach cumulative threshold and settle all previous entries + pi2 = create_purchase_invoice(supplier="Test TDS Supplier6", rate=12000, do_not_save=True) + pi2.apply_tds = 1 + pi2.tax_withholding_category = "Test Multi Invoice Category" + advances = pi2.get_advance_entries() + pi2.append( + "advances", + { + "reference_type": advances[0].reference_type, + "reference_name": advances[0].reference_name, + "advance_amount": advances[0].amount, + "allocated_amount": advances[0].amount, + }, + ) + pi2.append( + "advances", + { + "reference_type": advances[1].reference_type, + "reference_name": advances[1].reference_name, + "advance_amount": advances[1].amount, + "allocated_amount": advances[1].amount, + }, + ) + pi2.save() + pi2.submit() + invoices.append(pi2) + + # Validate tax withholding entries for final invoice (should settle previous entries) + # Based on actual system behavior, this creates 2 settlement entries: + # 1. Settlement for first invoice (4000, status: Settled) + # 2. Entry for final invoice itself (9000, status: Settled) + expected_entries = [ + # Settlement for first invoice + self.get_tax_withholding_entry( + tax_withholding_category="Test Multi Invoice Category", + party_type="Supplier", + party="Test TDS Supplier6", + tax_rate=10.0, + taxable_amount=4000.0, + withholding_amount=400.0, # 10% of 4000 + status="Settled", + taxable_doctype="Purchase Invoice", + taxable_name=pi.name, # First invoice + withholding_doctype="Purchase Invoice", + withholding_name=pi2.name, # Final invoice settles it + under_withheld_reason=None, + ), + # against first payment entry + self.get_tax_withholding_entry( + tax_withholding_category="Test Multi Invoice Category", + party_type="Supplier", + party="Test TDS Supplier6", + tax_rate=10.0, + taxable_amount=3000.0, # Final invoice amount + withholding_amount=300.0, # TDS on final invoice + status="Settled", + taxable_doctype="Purchase Invoice", + taxable_name=pi2.name, # Final invoice itself + withholding_doctype="Payment Entry", + withholding_name=pe1.name, + under_withheld_reason=None, + ), + # against second payment entry + self.get_tax_withholding_entry( + tax_withholding_category="Test Multi Invoice Category", + party_type="Supplier", + party="Test TDS Supplier6", + tax_rate=10.0, + taxable_amount=6000.0, # Final invoice amount + withholding_amount=600.0, # TDS on final invoice + status="Settled", + taxable_doctype="Purchase Invoice", + taxable_name=pi2.name, # Final invoice itself + withholding_doctype="Payment Entry", + withholding_name=pe2.name, + under_withheld_reason=None, + ), + # against second payment entry + self.get_tax_withholding_entry( + tax_withholding_category="Test Multi Invoice Category", + party_type="Supplier", + party="Test TDS Supplier6", + tax_rate=10.0, + taxable_amount=3000.0, # Final invoice amount + withholding_amount=300.0, # TDS on final invoice + status="Settled", + taxable_doctype="Purchase Invoice", + taxable_name=pi2.name, # Final invoice itself + withholding_doctype="Purchase Invoice", + withholding_name=pi2.name, + under_withheld_reason=None, + ), + ] + self.validate_tax_withholding_entries("Purchase Invoice", pi2.name, expected_entries) + + # validate duplicate entries in Purchase Invoice 1 + expected_entries = [ + self.get_tax_withholding_entry( + tax_withholding_category="Test Multi Invoice Category", + party_type="Supplier", + party="Test TDS Supplier6", + tax_rate=10.0, + taxable_amount=4000.0, + withholding_amount=400.0, + status="Duplicate", + taxable_doctype="Purchase Invoice", + taxable_name=pi.name, + withholding_doctype="Purchase Invoice", + withholding_name=pi2.name, + under_withheld_reason=None, + ), + ] + + self.validate_tax_withholding_entries("Purchase Invoice", pi.name, expected_entries) + # validate duplicate entries in payment entry 1 + expected_entries = [ + self.get_tax_withholding_entry( + tax_withholding_category="Test Multi Invoice Category", + party_type="Supplier", + party="Test TDS Supplier6", + tax_rate=10.0, + taxable_amount=3000.0, # Final invoice amount + withholding_amount=300.0, # TDS on final invoice + status="Duplicate", + taxable_doctype="Purchase Invoice", + taxable_name=pi2.name, # Final invoice itself + withholding_doctype="Payment Entry", + withholding_name=pe1.name, + under_withheld_reason=None, + ), + ] + self.validate_tax_withholding_entries("Payment Entry", pe1.name, expected_entries) + + # Validate duplicate entries in payment entry 2 + expected_entries = [ + self.get_tax_withholding_entry( + tax_withholding_category="Test Multi Invoice Category", + party_type="Supplier", + party="Test TDS Supplier6", + tax_rate=10.0, + taxable_amount=6000.0, # Final invoice amount + withholding_amount=600.0, # TDS on final invoice + status="Duplicate", + taxable_doctype="Purchase Invoice", + taxable_name=pi2.name, # Final invoice itself + withholding_doctype="Payment Entry", + withholding_name=pe2.name, + under_withheld_reason=None, + ), + ] + self.validate_tax_withholding_entries("Payment Entry", pe2.name, expected_entries) + + self.cleanup_invoices(invoices) + + def test_tds_deduction_with_partial_payment_adjustment(self): + invoices = [] + self.setup_party_with_category("Supplier", "Test TDS Supplier6", "Test Multi Invoice Category") pe = create_payment_entry( - payment_type="Pay", party_type="Supplier", party="Test TDS Supplier6", paid_amount=1000 + payment_type="Pay", party_type="Supplier", party="Test TDS Supplier6", paid_amount=6000 ) - pe.apply_tax_withholding_amount = 1 + pe.apply_tds = 1 pe.tax_withholding_category = "Test Multi Invoice Category" pe.save() pe.submit() invoices.append(pe) - pi2 = create_purchase_invoice(supplier="Test TDS Supplier6", rate=9000, do_not_save=True) - pi2.apply_tds = 1 - pi2.tax_withholding_category = "Test Multi Invoice Category" - pi2.save() - pi2.submit() - invoices.append(pi2) + expected_entries = [ + self.get_tax_withholding_entry( + tax_withholding_category="Test Multi Invoice Category", + party_type="Supplier", + party="Test TDS Supplier6", + tax_rate=10.0, + taxable_amount=6000.0, + withholding_amount=600.0, + status="Over Withheld", + taxable_doctype="", + taxable_name="", + withholding_doctype="Payment Entry", + withholding_name=pe.name, + ) + ] + self.validate_tax_withholding_entries("Payment Entry", pe.name, expected_entries) - pi2.load_from_db() - - self.assertTrue(pi2.taxes[0].tax_amount, 1100) - - self.assertTrue(pi2.tax_withheld_vouchers[0].voucher_name == pi1.name) - self.assertTrue(pi2.tax_withheld_vouchers[0].taxable_amount == pi1.net_total) - self.assertTrue(pi2.tax_withheld_vouchers[1].voucher_name == pi.name) - self.assertTrue(pi2.tax_withheld_vouchers[1].taxable_amount == pi.net_total) - self.assertTrue(pi2.tax_withheld_vouchers[2].voucher_name == pe.name) - self.assertTrue(pi2.tax_withheld_vouchers[2].taxable_amount == pe.paid_amount) - - # cancel invoices to avoid clashing - for d in reversed(invoices): - d.cancel() - - def test_tax_withholding_via_payment_entry_for_advances(self): - frappe.db.set_value( - "Supplier", "Test TDS Supplier7", "tax_withholding_category", "Advance TDS Category" + pi = create_purchase_invoice(supplier="Test TDS Supplier6", rate=12000, do_not_save=True) + pi.apply_tds = 1 + pi.tax_withholding_category = "Test Multi Invoice Category" + advances = pi.get_advance_entries() + pi.append( + "advances", + { + "reference_type": advances[0].reference_type, + "reference_name": advances[0].reference_name, + "advance_amount": advances[0].amount, + "allocated_amount": 3600, + }, ) + pi.save() + pi.submit() + invoices.append(pi) - # create payment entry - pe1 = create_payment_entry( - payment_type="Pay", party_type="Supplier", party="Test TDS Supplier7", paid_amount=4000 - ) - pe1.submit() - - self.assertFalse(pe1.get("taxes")) - - pe2 = create_payment_entry( - payment_type="Pay", party_type="Supplier", party="Test TDS Supplier7", paid_amount=4000 - ) - pe2.submit() - - self.assertFalse(pe2.get("taxes")) - - pe3 = create_payment_entry( - payment_type="Pay", party_type="Supplier", party="Test TDS Supplier7", paid_amount=4000 - ) - pe3.apply_tax_withholding_amount = 1 - pe3.save() - pe3.submit() - - self.assertEqual(pe3.get("taxes")[0].tax_amount, 1200) - pe1.cancel() - pe2.cancel() - pe3.cancel() + expected_entries = [ + # against first payment entry + self.get_tax_withholding_entry( + tax_withholding_category="Test Multi Invoice Category", + party_type="Supplier", + party="Test TDS Supplier6", + tax_rate=10.0, + taxable_amount=4000.0, + withholding_amount=400.0, # 600 * 6000/(6000-5400) + status="Settled", + taxable_doctype="Purchase Invoice", + taxable_name=pi.name, # Final invoice itself + withholding_doctype="Payment Entry", + withholding_name=pe.name, + under_withheld_reason=None, + ), + # against remaining invoice + self.get_tax_withholding_entry( + tax_withholding_category="Test Multi Invoice Category", + party_type="Supplier", + party="Test TDS Supplier6", + tax_rate=10.0, + taxable_amount=8000.0, # Final invoice amount + withholding_amount=800.0, # TDS on final invoice + status="Settled", + taxable_doctype="Purchase Invoice", + taxable_name=pi.name, # Final invoice itself + withholding_doctype="Purchase Invoice", + withholding_name=pi.name, + under_withheld_reason=None, + ), + ] + self.validate_tax_withholding_entries("Purchase Invoice", pi.name, expected_entries) + # validate duplicate entries + expected_entries = [ + self.get_tax_withholding_entry( + tax_withholding_category="Test Multi Invoice Category", + party_type="Supplier", + party="Test TDS Supplier6", + tax_rate=10.0, + taxable_amount=4000.0, + withholding_amount=400.0, # 600 * 6000/(6000-5400) + status="Duplicate", + taxable_doctype="Purchase Invoice", + taxable_name=pi.name, # Final invoice itself + withholding_doctype="Payment Entry", + withholding_name=pe.name, + under_withheld_reason=None, + ), + self.get_tax_withholding_entry( + tax_withholding_category="Test Multi Invoice Category", + party_type="Supplier", + party="Test TDS Supplier6", + tax_rate=10.0, + taxable_amount=2000.0, + withholding_amount=200.0, + status="Over Withheld", + taxable_doctype="", + taxable_name="", + withholding_doctype="Payment Entry", + withholding_name=pe.name, + ), + ] + self.validate_tax_withholding_entries("Payment Entry", pe.name, expected_entries) + self.cleanup_invoices(invoices) def test_lower_deduction_certificate_application(self): frappe.db.set_value( @@ -675,9 +1589,7 @@ class TestTaxWithholdingCategory(IntegrationTestCase): pi3.submit() self.assertEqual(pi3.taxes[0].tax_amount, 3500) - pi1.cancel() - pi2.cancel() - pi3.cancel() + self.cleanup_invoices([pi1, pi2, pi3]) def test_ldc_at_0_rate(self): frappe.db.set_value( @@ -718,9 +1630,309 @@ class TestTaxWithholdingCategory(IntegrationTestCase): self.assertEqual(len(pi2.taxes), 1) # pi1 net total shouldn't be included as it lies within LDC at rate of '0' self.assertEqual(pi2.taxes[0].tax_amount, 3500) + self.cleanup_invoices([pi1, pi2]) - pi1.cancel() - pi2.cancel() + def test_payment_entry_with_ldc_and_invoice_adjustment(self): + """ + Test: Payment Entry with LDC, then Invoice, with correct tax adjustment. + - Payment Entry (advance) is made and tax is deducted at LDC rate + - Purchase Invoice is created for a higher amount + - For the portion of invoice covered by advance, tax is adjusted at LDC rate + - For the remaining invoice amount, tax is deducted at normal rate + """ + + invoices = [] + pan = "ABCTY1234D" + supplier = "Test LDC Supplier" + category = "Test Service Category" + ldc_no = "TEST-1" + + frappe.db.set_value( + "Supplier", + supplier, + { + "tax_withholding_category": category, + "pan": pan, + }, + ) + + create_lower_deduction_certificate( + supplier=supplier, + certificate_no=ldc_no, + tax_withholding_category=category, + tax_rate=0, + limit=10000, + ) + + # Payment Entry (advance) with LDC + advance_amount = 6000.0 + pe = create_payment_entry( + payment_type="Pay", party_type="Supplier", party=supplier, paid_amount=advance_amount + ) + pe.apply_tds = 1 + pe.tax_withholding_category = category + pe.save() + pe.submit() + invoices.append(pe) + + # Validate payment entry tax withholding entries (LDC rate) + expected_pe_entries = [ + self.get_tax_withholding_entry( + tax_withholding_category=category, + party_type="Supplier", + party=supplier, + tax_rate=0.0, + taxable_amount=advance_amount, + withholding_amount=0.0, + status="Over Withheld", + taxable_doctype="", + taxable_name="", + withholding_doctype="Payment Entry", + withholding_name=pe.name, + under_withheld_reason="Lower Deduction Certificate", + lower_deduction_certificate=ldc_no, + ) + ] + self.validate_tax_withholding_entries("Payment Entry", pe.name, expected_pe_entries) + + # Now create and link the invoice (do not update PE after this point) + invoice_amount = 15000 + pi = create_purchase_invoice( + supplier=supplier, + rate=invoice_amount, + ) + + advances = pi.get_advance_entries() + pi.append( + "advances", + { + "reference_type": advances[0].reference_type, + "reference_name": advances[0].reference_name, + "advance_amount": advances[0].amount, + "allocated_amount": advance_amount, + }, + ) + pi.save() + pi.submit() + invoices.append(pi) + + # Validate invoice tax withholding entries + expected_pi_entries = [ + # LDC portion (settled) + self.get_tax_withholding_entry( + tax_withholding_category=category, + party_type="Supplier", + party=supplier, + tax_rate=0.0, + taxable_amount=advance_amount, + withholding_amount=0.0, + taxable_doctype="Purchase Invoice", + taxable_name=pi.name, + withholding_doctype="Payment Entry", + withholding_name=pe.name, + under_withheld_reason="Lower Deduction Certificate", + lower_deduction_certificate=ldc_no, + status="Settled", + ), + # Balance LDC portion (settled) + self.get_tax_withholding_entry( + tax_withholding_category=category, + party_type="Supplier", + party=supplier, + tax_rate=0.0, + taxable_amount=4000.0, + withholding_amount=0.0, + status="Settled", + taxable_doctype="Purchase Invoice", + taxable_name=pi.name, + withholding_doctype="Purchase Invoice", + withholding_name=pi.name, + under_withheld_reason="Lower Deduction Certificate", + lower_deduction_certificate=ldc_no, + ), + # Balance LDC portion (settled) + self.get_tax_withholding_entry( + tax_withholding_category=category, + party_type="Supplier", + party=supplier, + tax_rate=10.0, + taxable_amount=5000.0, + withholding_amount=500.0, + status="Settled", + taxable_doctype="Purchase Invoice", + taxable_name=pi.name, + withholding_doctype="Purchase Invoice", + withholding_name=pi.name, + under_withheld_reason=None, + lower_deduction_certificate=None, + ), + ] + self.validate_tax_withholding_entries("Purchase Invoice", pi.name, expected_pi_entries) + + # validate duplicate entries in payment entry + expected_entries = [ + self.get_tax_withholding_entry( + tax_withholding_category=category, + party_type="Supplier", + party=supplier, + tax_rate=0.0, + taxable_amount=advance_amount, + withholding_amount=0.0, + status="Duplicate", + taxable_doctype="Purchase Invoice", + taxable_name=pi.name, + withholding_doctype="Payment Entry", + withholding_name=pe.name, + under_withheld_reason="Lower Deduction Certificate", + lower_deduction_certificate=ldc_no, + ) + ] + + self.validate_tax_withholding_entries("Payment Entry", pe.name, expected_entries) + + self.cleanup_invoices(invoices) + + def test_payment_entry_with_ldc_and_partial_invoice_adjustment(self): + """ + Test: Payment Entry with LDC, then Invoice, with correct tax adjustment. + - Payment Entry (advance) is made and tax is deducted at LDC rate + - Purchase Invoice is created for a higher amount + - For the portion of invoice covered by advance, tax is adjusted at LDC rate + - For the remaining invoice amount, tax is deducted at normal rate + """ + + invoices = [] + pan = "ABCTY1234D" + supplier = "Test LDC Supplier" + category = "Test Service Category" + ldc_no = "TEST-1" + + frappe.db.set_value( + "Supplier", + supplier, + { + "tax_withholding_category": category, + "pan": pan, + }, + ) + + create_lower_deduction_certificate( + supplier=supplier, + certificate_no=ldc_no, + tax_withholding_category=category, + tax_rate=0, + limit=15000, + ) + + # Payment Entry (advance) with LDC + advance_amount = 6000.0 + pe = create_payment_entry( + payment_type="Pay", party_type="Supplier", party=supplier, paid_amount=advance_amount + ) + pe.apply_tds = 1 + pe.tax_withholding_category = category + pe.save() + pe.submit() + invoices.append(pe) + + # Validate payment entry tax withholding entries (LDC rate) + expected_pe_entries = [ + self.get_tax_withholding_entry( + tax_withholding_category=category, + party_type="Supplier", + party=supplier, + tax_rate=0.0, + taxable_amount=advance_amount, + withholding_amount=0.0, + status="Over Withheld", + taxable_doctype="", + taxable_name="", + withholding_doctype="Payment Entry", + withholding_name=pe.name, + under_withheld_reason="Lower Deduction Certificate", + lower_deduction_certificate=ldc_no, + ) + ] + self.validate_tax_withholding_entries("Payment Entry", pe.name, expected_pe_entries) + + # Now create and link the invoice (do not update PE after this point) + invoice_amount = 3000.0 + pi = create_purchase_invoice( + supplier=supplier, + rate=invoice_amount, + ) + + advances = pi.get_advance_entries() + pi.append( + "advances", + { + "reference_type": advances[0].reference_type, + "reference_name": advances[0].reference_name, + "advance_amount": advances[0].amount, + "allocated_amount": invoice_amount, + }, + ) + pi.save() + pi.submit() + invoices.append(pi) + + # Validate invoice tax withholding entries + expected_pi_entries = [ + # LDC portion (settled) + self.get_tax_withholding_entry( + tax_withholding_category=category, + party_type="Supplier", + party=supplier, + tax_rate=0.0, + taxable_amount=invoice_amount, + withholding_amount=0.0, + taxable_doctype="Purchase Invoice", + taxable_name=pi.name, + withholding_doctype="Payment Entry", + withholding_name=pe.name, + under_withheld_reason="Lower Deduction Certificate", + lower_deduction_certificate=ldc_no, + status="Settled", + ), + ] + self.validate_tax_withholding_entries("Purchase Invoice", pi.name, expected_pi_entries) + + # validate duplicate entries in payment entry + expected_entries = [ + self.get_tax_withholding_entry( + tax_withholding_category=category, + party_type="Supplier", + party=supplier, + tax_rate=0.0, + taxable_amount=invoice_amount, # 3000 + withholding_amount=0.0, + status="Duplicate", + taxable_doctype="Purchase Invoice", + taxable_name=pi.name, + withholding_doctype="Payment Entry", + withholding_name=pe.name, + under_withheld_reason="Lower Deduction Certificate", + lower_deduction_certificate=ldc_no, + ), + self.get_tax_withholding_entry( + tax_withholding_category=category, + party_type="Supplier", + party=supplier, + tax_rate=0.0, + taxable_amount=advance_amount - invoice_amount, # 6000-3000 = 3000 + withholding_amount=0.0, + status="Over Withheld", + taxable_doctype="", + taxable_name="", + withholding_doctype="Payment Entry", + withholding_name=pe.name, + under_withheld_reason="Lower Deduction Certificate", + lower_deduction_certificate=ldc_no, + ), + ] + + self.validate_tax_withholding_entries("Payment Entry", pe.name, expected_entries) + self.cleanup_invoices(invoices) def set_previous_fy_and_tax_category(self): test_company = "_Test Company" @@ -786,15 +1998,13 @@ class TestTaxWithholdingCategory(IntegrationTestCase): po = create_purchase_order(supplier=supplier, qty=10, rate=10000) po.transaction_date = po_and_advance_posting_date po.taxes = [] - po.apply_tds = False - po.tax_withholding_category = None po.save().submit() # Partial advance payment = get_payment_entry(po.doctype, po.name) payment.posting_date = po_and_advance_posting_date payment.paid_amount = 60000 - payment.apply_tax_withholding_amount = 1 + payment.apply_tds = 1 payment.tax_withholding_category = category payment.references = [] payment.taxes = [] @@ -825,7 +2035,6 @@ class TestTaxWithholdingCategory(IntegrationTestCase): payment.reload() self.assertEqual(pi1.taxes, []) self.assertEqual(payment.taxes[0].tax_amount, 6000) - self.assertEqual(payment.taxes[0].allocated_amount, 3000) pi2 = make_purchase_invoice(source_name=po.name) pi2.apply_tds = True @@ -847,28 +2056,1508 @@ class TestTaxWithholdingCategory(IntegrationTestCase): payment.reload() self.assertEqual(pi2.taxes, []) self.assertEqual(payment.taxes[0].tax_amount, 6000) - self.assertEqual(payment.taxes[0].allocated_amount, 6000) + @IntegrationTestCase.change_settings("Accounts Settings", {"delete_linked_ledger_entries": 1}) + def test_tds_payment_entry_cancellation(self): + """ + Test payment entry cancellation clears withholding references from matched entries + """ + invoices = [] + self.setup_party_with_category("Supplier", "Test TDS Supplier6", "Test Multi Invoice Category") -def cancel_invoices(): - purchase_invoices = frappe.get_all( - "Purchase Invoice", - { - "supplier": ["in", ["Test TDS Supplier", "Test TDS Supplier1", "Test TDS Supplier2"]], - "docstatus": 1, - }, - pluck="name", - ) + # Create payment entry with tax withholding + pe = create_payment_entry( + payment_type="Pay", party_type="Supplier", party="Test TDS Supplier6", paid_amount=6000 + ) + pe.apply_tds = 1 + pe.tax_withholding_category = "Test Multi Invoice Category" + pe.save() + pe.submit() + invoices.append(pe) - sales_invoices = frappe.get_all( - "Sales Invoice", {"customer": "Test TCS Customer", "docstatus": 1}, pluck="name" - ) + # Verify initial "Over Withheld" entry + expected_entries = [ + self.get_tax_withholding_entry( + tax_withholding_category="Test Multi Invoice Category", + party_type="Supplier", + party="Test TDS Supplier6", + tax_rate=10.0, + taxable_amount=6000.0, + withholding_amount=600.0, + status="Over Withheld", + taxable_doctype="", + taxable_name="", + withholding_doctype="Payment Entry", + withholding_name=pe.name, + ) + ] + self.validate_tax_withholding_entries("Payment Entry", pe.name, expected_entries) - for d in purchase_invoices: - frappe.get_doc("Purchase Invoice", d).cancel() + # Create purchase invoice that settles the payment entry + pi = create_purchase_invoice(supplier="Test TDS Supplier6", rate=8000, do_not_save=True) + pi.apply_tds = 1 + pi.tax_withholding_category = "Test Multi Invoice Category" + advances = pi.get_advance_entries() + pi.append( + "advances", + { + "reference_type": advances[0].reference_type, + "reference_name": advances[0].reference_name, + "advance_amount": advances[0].amount, + "allocated_amount": 6000, + }, + ) + pi.save() + pi.submit() + invoices.append(pi) - for d in sales_invoices: - frappe.get_doc("Sales Invoice", d).cancel() + # Verify entries after invoice creation (should have Settled and Duplicate statuses) + expected_pi_entries = [ + self.get_tax_withholding_entry( + tax_withholding_category="Test Multi Invoice Category", + party_type="Supplier", + party="Test TDS Supplier6", + tax_rate=10.0, + taxable_amount=6000.0, + withholding_amount=600.0, + status="Settled", + taxable_doctype="Purchase Invoice", + taxable_name=pi.name, + withholding_doctype="Payment Entry", + withholding_name=pe.name, + ), + self.get_tax_withholding_entry( + tax_withholding_category="Test Multi Invoice Category", + party_type="Supplier", + party="Test TDS Supplier6", + tax_rate=10.0, + taxable_amount=2000.0, + withholding_amount=200.0, + status="Settled", + taxable_doctype="Purchase Invoice", + taxable_name=pi.name, + withholding_doctype="Purchase Invoice", + withholding_name=pi.name, + ), + ] + self.validate_tax_withholding_entries("Purchase Invoice", pi.name, expected_pi_entries) + + # Verify duplicate entry in payment entry + expected_pe_entries = [ + self.get_tax_withholding_entry( + tax_withholding_category="Test Multi Invoice Category", + party_type="Supplier", + party="Test TDS Supplier6", + tax_rate=10.0, + taxable_amount=6000.0, + withholding_amount=600.0, + status="Duplicate", + taxable_doctype="Purchase Invoice", + taxable_name=pi.name, + withholding_doctype="Payment Entry", + withholding_name=pe.name, + ) + ] + self.validate_tax_withholding_entries("Payment Entry", pe.name, expected_pe_entries) + + # Cancel the payment entry (reload first to avoid timestamp mismatch) + pe.reload() + pe.cancel() + + # After payment entry cancellation, the purchase invoice entries should have: + # - Withholding references cleared (empty doctype and name) + # - Status changed to "Under Withheld" + # - Withholding amounts set to 0 + expected_pi_entries_after_cancel = [ + self.get_tax_withholding_entry( + tax_withholding_category="Test Multi Invoice Category", + party_type="Supplier", + party="Test TDS Supplier6", + tax_rate=10.0, + taxable_amount=6000.0, + withholding_amount=0.0, # Cleared + status="Under Withheld", # Changed + taxable_doctype="Purchase Invoice", + taxable_name=pi.name, + withholding_doctype="", # Cleared + withholding_name="", # Cleared + ), + self.get_tax_withholding_entry( + tax_withholding_category="Test Multi Invoice Category", + party_type="Supplier", + party="Test TDS Supplier6", + tax_rate=10.0, + taxable_amount=2000.0, + withholding_amount=200.0, # Not cleared (same document) + status="Settled", # Unchanged (same document) + taxable_doctype="Purchase Invoice", + taxable_name=pi.name, + withholding_doctype="Purchase Invoice", + withholding_name=pi.name, + ), + ] + self.validate_tax_withholding_entries("Purchase Invoice", pi.name, expected_pi_entries_after_cancel) + + pi1 = create_purchase_invoice(supplier="Test TDS Supplier6", rate=8000, do_not_save=True) + pi1.apply_tds = 1 + pi1.tax_withholding_category = "Test Multi Invoice Category" + pi1.submit() + invoices.append(pi1) + + expected_entries = [ + # Adjust previous purchase invoice + self.get_tax_withholding_entry( + tax_withholding_category="Test Multi Invoice Category", + party_type="Supplier", + party="Test TDS Supplier6", + tax_rate=10.0, + taxable_amount=6000.0, + withholding_amount=600, # Cleared + status="Settled", # Changed + taxable_doctype="Purchase Invoice", + taxable_name=pi.name, + withholding_doctype="Purchase Invoice", + withholding_name=pi1.name, + ), + self.get_tax_withholding_entry( + tax_withholding_category="Test Multi Invoice Category", + party_type="Supplier", + party="Test TDS Supplier6", + tax_rate=10.0, + taxable_amount=8000.0, + withholding_amount=800, # Cleared + status="Settled", # Changed + taxable_doctype="Purchase Invoice", + taxable_name=pi1.name, + withholding_doctype="Purchase Invoice", + withholding_name=pi1.name, + ), + ] + self.validate_tax_withholding_entries("Purchase Invoice", pi1.name, expected_entries) + self.cleanup_invoices(invoices) + + @IntegrationTestCase.change_settings("Accounts Settings", {"delete_linked_ledger_entries": 1}) + def test_tds_purchase_invoice_cancellation(self): + """ + Test that after cancellation, new documents get automatically adjusted against remaining entries + """ + invoices = [] + self.setup_party_with_category("Supplier", "Test TDS Supplier8", "Test Multi Invoice Category") + + # Create payment entry with tax withholding + pe = create_payment_entry( + payment_type="Pay", party_type="Supplier", party="Test TDS Supplier8", paid_amount=10000 + ) + pe.apply_tds = 1 + pe.tax_withholding_category = "Test Multi Invoice Category" + pe.save() + pe.submit() + invoices.append(pe) + + # Create first purchase invoice + pi1 = create_purchase_invoice(supplier="Test TDS Supplier8", rate=10000, do_not_save=True) + pi1.apply_tds = 1 + pi1.tax_withholding_category = "Test Multi Invoice Category" + advances = pi1.get_advance_entries() + pi1.append( + "advances", + { + "reference_type": advances[0].reference_type, + "reference_name": advances[0].reference_name, + "advance_amount": advances[0].amount, + "allocated_amount": 4500, + }, + ) + pi1.save() + pi1.submit() + invoices.append(pi1) + + # Verify entries after first invoice + expected_pe_entries = [ + self.get_tax_withholding_entry( + tax_withholding_category="Test Multi Invoice Category", + party_type="Supplier", + party="Test TDS Supplier8", + tax_rate=10.0, + taxable_amount=5000.0, + withholding_amount=500.0, + status="Over Withheld", + taxable_doctype="", + taxable_name="", + withholding_doctype="Payment Entry", + withholding_name=pe.name, + ), + self.get_tax_withholding_entry( + tax_withholding_category="Test Multi Invoice Category", + party_type="Supplier", + party="Test TDS Supplier8", + tax_rate=10.0, + taxable_amount=5000.0, + withholding_amount=500.0, + status="Duplicate", + taxable_doctype="Purchase Invoice", + taxable_name=pi1.name, + withholding_doctype="Payment Entry", + withholding_name=pe.name, + ), + ] + self.validate_tax_withholding_entries("Payment Entry", pe.name, expected_pe_entries) + + # Cancel the first purchase invoice + pi1.cancel() + + # After cancellation, payment entry should be back to single "Over Withheld" entry + expected_pe_entries_after_cancel = [ + self.get_tax_withholding_entry( + tax_withholding_category="Test Multi Invoice Category", + party_type="Supplier", + party="Test TDS Supplier8", + tax_rate=10.0, + taxable_amount=5000.0, + withholding_amount=500.0, + status="Over Withheld", + taxable_doctype="", + taxable_name="", + withholding_doctype="Payment Entry", + withholding_name=pe.name, + ), + self.get_tax_withholding_entry( + tax_withholding_category="Test Multi Invoice Category", + party_type="Supplier", + party="Test TDS Supplier8", + tax_rate=10.0, + taxable_amount=5000.0, + withholding_amount=500.0, + status="Over Withheld", + taxable_doctype="", + taxable_name="", + withholding_doctype="Payment Entry", + withholding_name=pe.name, + ), + ] + self.validate_tax_withholding_entries("Payment Entry", pe.name, expected_pe_entries_after_cancel) + + # Create new purchase invoice - should automatically adjust against "Over Withheld" entries + pi2 = create_purchase_invoice(supplier="Test TDS Supplier8", rate=7000, do_not_save=True) + pi2.apply_tds = 1 + pi2.tax_withholding_category = "Test Multi Invoice Category" + advances = pi2.get_advance_entries() + pi2.append( + "advances", + { + "reference_type": advances[0].reference_type, + "reference_name": advances[0].reference_name, + "advance_amount": advances[0].amount, + "allocated_amount": 5500, + }, + ) + pi2.save() + pi2.submit() + invoices.append(pi2) + + # Verify automatic adjustment works correctly + expected_pi2_entries = [ + self.get_tax_withholding_entry( + tax_withholding_category="Test Multi Invoice Category", + party_type="Supplier", + party="Test TDS Supplier8", + tax_rate=10.0, + taxable_amount=2000.0, + withholding_amount=200.0, + status="Settled", + taxable_doctype="Purchase Invoice", + taxable_name=pi2.name, + withholding_doctype="Payment Entry", + withholding_name=pe.name, + ), + self.get_tax_withholding_entry( + tax_withholding_category="Test Multi Invoice Category", + party_type="Supplier", + party="Test TDS Supplier8", + tax_rate=10.0, + taxable_amount=5000.0, + withholding_amount=500.0, + status="Settled", + taxable_doctype="Purchase Invoice", + taxable_name=pi2.name, + withholding_doctype="Payment Entry", + withholding_name=pe.name, + ), + ] + self.validate_tax_withholding_entries("Purchase Invoice", pi2.name, expected_pi2_entries) + + # Payment entry should now have the remaining amount as "Over Withheld" + expected_pe_entries_after_pi2 = [ + self.get_tax_withholding_entry( + tax_withholding_category="Test Multi Invoice Category", + party_type="Supplier", + party="Test TDS Supplier8", + tax_rate=10.0, + taxable_amount=3000.0, + withholding_amount=300.0, + status="Over Withheld", + taxable_doctype="", + taxable_name="", + withholding_doctype="Payment Entry", + withholding_name=pe.name, + ), + self.get_tax_withholding_entry( + tax_withholding_category="Test Multi Invoice Category", + party_type="Supplier", + party="Test TDS Supplier8", + tax_rate=10.0, + taxable_amount=2000.0, + withholding_amount=200.0, + status="Duplicate", + taxable_doctype="Purchase Invoice", + taxable_name=pi2.name, + withholding_doctype="Payment Entry", + withholding_name=pe.name, + ), + self.get_tax_withholding_entry( + tax_withholding_category="Test Multi Invoice Category", + party_type="Supplier", + party="Test TDS Supplier8", + tax_rate=10.0, + taxable_amount=5000.0, + withholding_amount=500.0, + status="Duplicate", + taxable_doctype="Purchase Invoice", + taxable_name=pi2.name, + withholding_doctype="Payment Entry", + withholding_name=pe.name, + ), + ] + self.validate_tax_withholding_entries("Payment Entry", pe.name, expected_pe_entries_after_pi2) + + self.cleanup_invoices(invoices) + + def test_tds_deduction_in_purchase_return(self): + self.setup_party_with_category("Supplier", "Test TDS Supplier", "Cumulative Threshold TDS") + + pi = create_purchase_invoice(supplier="Test TDS Supplier", rate=40000) + pi.submit() + + self.assertEqual(pi.taxes_and_charges_deducted, 4000) + + pi_return = create_purchase_invoice(supplier="Test TDS Supplier", is_return=1, qty=-1, rate=40000) + pi_return.return_against = pi.name + pi_return.save() + pi_return.submit() + + self.assertEqual(pi_return.taxes_and_charges_deducted, -4000) + self.cleanup_invoices([pi, pi_return]) + + def test_tds_purchase_invoice_cancellation_and_adjustment(self): + invoices = [] + self.setup_party_with_category("Supplier", "Test TDS Supplier8", "Test Multi Invoice Category") + + pi1 = create_purchase_invoice(supplier="Test TDS Supplier8", rate=3000, do_not_save=True) + pi1.apply_tds = 1 + pi1.tax_withholding_category = "Test Multi Invoice Category" + pi1.save() + pi1.submit() + invoices.append(pi1) + + pi2 = create_purchase_invoice(supplier="Test TDS Supplier8", rate=10000, do_not_save=True) + pi2.apply_tds = 1 + pi2.tax_withholding_category = "Test Multi Invoice Category" + pi2.save() + pi2.submit() + invoices.append(pi2) + + pi1.reload() + pi1.cancel() + + pi3 = create_purchase_invoice(supplier="Test TDS Supplier8", rate=3000, do_not_save=True) + pi3.apply_tds = 1 + pi3.tax_withholding_category = "Test Multi Invoice Category" + pi3.save() + pi3.submit() + invoices.append(pi3) + + # Over-Withheld amount in pi2 will get adjusted + expected_entries = [ + self.get_tax_withholding_entry( + tax_withholding_category="Test Multi Invoice Category", + party_type="Supplier", + party="Test TDS Supplier8", + tax_rate=10.0, + taxable_amount=3000.0, + withholding_amount=300.0, + status="Settled", + taxable_doctype="Purchase Invoice", + taxable_name=pi3.name, + withholding_doctype="Purchase Invoice", + withholding_name=pi2.name, + ) + ] + + self.validate_tax_withholding_entries("Purchase Invoice", pi3.name, expected_entries) + self.cleanup_invoices(invoices) + + def test_tds_for_return_invoices(self): + """Test TDS handling for return invoices with 3-entry cancellation approach""" + invoices = [] + self.setup_party_with_category("Supplier", "Test TDS Supplier8", "Test Multi Invoice Category") + + # Create return invoice + pi1 = create_purchase_invoice( + supplier="Test TDS Supplier8", rate=3000, is_return=1, qty=-1, do_not_save=True + ) + pi1.apply_tds = 1 + pi1.tax_withholding_category = "Test Multi Invoice Category" + pi1.save() + pi1.submit() + invoices.append(pi1) + + # Create regular invoice that breaches threshold + pi2 = create_purchase_invoice(supplier="Test TDS Supplier8", rate=10000, do_not_save=True) + pi2.apply_tds = 1 + pi2.tax_withholding_category = "Test Multi Invoice Category" + pi2.save() + pi2.submit() + invoices.append(pi2) + + # Before cancellation: 2 entries (cross-referenced settlement) + expected_entries = [ + self.get_tax_withholding_entry( + tax_withholding_category="Test Multi Invoice Category", + party_type="Supplier", + party="Test TDS Supplier8", + tax_rate=10.0, + taxable_amount=-3000.0, + withholding_amount=-300.0, + status="Settled", + taxable_doctype="Purchase Invoice", + taxable_name=pi1.name, + withholding_doctype="Purchase Invoice", + withholding_name=pi2.name, + ), + self.get_tax_withholding_entry( + tax_withholding_category="Test Multi Invoice Category", + party_type="Supplier", + party="Test TDS Supplier8", + tax_rate=10.0, + taxable_amount=10000.0, + withholding_amount=1000.0, + status="Settled", + taxable_doctype="Purchase Invoice", + taxable_name=pi2.name, + withholding_doctype="Purchase Invoice", + withholding_name=pi2.name, # pi2 settles against itself after adjustment + ), + ] + + self.validate_tax_withholding_entries("Purchase Invoice", pi2.name, expected_entries) + + # Duplicate Entries in P1 before cancellation + expected_entries = [ + self.get_tax_withholding_entry( + tax_withholding_category="Test Multi Invoice Category", + party_type="Supplier", + party="Test TDS Supplier8", + tax_rate=10.0, + taxable_amount=-3000.0, + withholding_amount=-300.0, + status="Duplicate", + taxable_doctype="Purchase Invoice", + taxable_name=pi1.name, + withholding_doctype="Purchase Invoice", + withholding_name=pi2.name, + ) + ] + + self.validate_tax_withholding_entries("Purchase Invoice", pi1.name, expected_entries) + + pi1.reload() + pi1.cancel() + + expected_entries = [ + self.get_tax_withholding_entry( + tax_withholding_category="Test Multi Invoice Category", + party_type="Supplier", + party="Test TDS Supplier8", + tax_rate=10.0, + taxable_amount=10000.0, + withholding_amount=1000.0, + status="Settled", + taxable_doctype="Purchase Invoice", + taxable_name=pi2.name, + withholding_doctype="Purchase Invoice", + withholding_name=pi2.name, + ), + self.get_tax_withholding_entry( + tax_withholding_category="Test Multi Invoice Category", + party_type="Supplier", + party="Test TDS Supplier8", + tax_rate=10.0, + taxable_amount=-3000.0, + withholding_amount=-300.0, + status="Settled", + taxable_doctype="Purchase Invoice", + taxable_name=pi2.name, + withholding_doctype="Purchase Invoice", + withholding_name=pi2.name, + under_withheld_reason=None, + ), + self.get_tax_withholding_entry( + tax_withholding_category="Test Multi Invoice Category", + party_type="Supplier", + party="Test TDS Supplier8", + tax_rate=10.0, + taxable_amount=3000.0, + withholding_amount=0.0, + status="Under Withheld", + taxable_doctype="Purchase Invoice", + taxable_name=pi2.name, # Points to withholding document, not cancelled return + withholding_doctype="", + withholding_name="", + under_withheld_reason="", + ), + ] + + self.validate_tax_withholding_entries("Purchase Invoice", pi2.name, expected_entries) + + # Test future invoice adjustment against the under withheld credit + pi3 = create_purchase_invoice(supplier="Test TDS Supplier8", rate=5000, do_not_save=True) + pi3.apply_tds = 1 + pi3.tax_withholding_category = "Test Multi Invoice Category" + pi3.save() + pi3.submit() + invoices.append(pi3) + + # pi3 should adjust against the under withheld entry from pi1 cancellation + expected_entries = [ + # Settlement of the cancelled return invoice credit + self.get_tax_withholding_entry( + tax_withholding_category="Test Multi Invoice Category", + party_type="Supplier", + party="Test TDS Supplier8", + tax_rate=10.0, + taxable_amount=3000.0, + withholding_amount=300.0, + status="Settled", + taxable_doctype="Purchase Invoice", + taxable_name=pi2.name, # References the source of under withheld + withholding_doctype="Purchase Invoice", + withholding_name=pi3.name, + ), + # Remaining amount with normal tax + self.get_tax_withholding_entry( + tax_withholding_category="Test Multi Invoice Category", + party_type="Supplier", + party="Test TDS Supplier8", + tax_rate=10.0, + taxable_amount=5000.0, # 5000 - 3000 already adjusted + withholding_amount=500.0, # 2000 * 10% + status="Settled", + taxable_doctype="Purchase Invoice", + taxable_name=pi3.name, + withholding_doctype="Purchase Invoice", + withholding_name=pi3.name, + ), + ] + + self.validate_tax_withholding_entries("Purchase Invoice", pi3.name, expected_entries) + + # expected entries in pi2 + expected_entries = [ + # Original pi2 entry (unchanged) + self.get_tax_withholding_entry( + tax_withholding_category="Test Multi Invoice Category", + party_type="Supplier", + party="Test TDS Supplier8", + tax_rate=10.0, + taxable_amount=10000.0, + withholding_amount=1000.0, + status="Settled", + taxable_doctype="Purchase Invoice", + taxable_name=pi2.name, + withholding_doctype="Purchase Invoice", + withholding_name=pi2.name, + ), + # Entry 1: Original entry from pi1 made settled (self-settle) + self.get_tax_withholding_entry( + tax_withholding_category="Test Multi Invoice Category", + party_type="Supplier", + party="Test TDS Supplier8", + tax_rate=10.0, + taxable_amount=-3000.0, + withholding_amount=-300.0, + status="Settled", + taxable_doctype="Purchase Invoice", + taxable_name=pi2.name, + withholding_doctype="Purchase Invoice", + withholding_name=pi2.name, + under_withheld_reason=None, + ), + # Entry 2: Under withheld entry for future adjustment (taxable fields point to pi2) + self.get_tax_withholding_entry( + tax_withholding_category="Test Multi Invoice Category", + party_type="Supplier", + party="Test TDS Supplier8", + tax_rate=10.0, + taxable_amount=3000.0, + withholding_amount=300.0, + status="Duplicate", + taxable_doctype="Purchase Invoice", + taxable_name=pi2.name, # Points to withholding document, not cancelled return + withholding_doctype="Purchase Invoice", + withholding_name=pi3.name, + under_withheld_reason="", + ), + ] + self.validate_tax_withholding_entries("Purchase Invoice", pi2.name, expected_entries) + + self.cleanup_invoices(invoices) + + def test_manual_tax_withholding_validation(self): + """Test validation when user manually overrides tax withholding entries with incorrect amounts""" + self.setup_party_with_category("Supplier", "Test TDS Supplier6", "Test Multi Invoice Category") + + # Create purchase invoice with manual override + pi = create_purchase_invoice(supplier="Test TDS Supplier6", rate=20000, do_not_save=True) + pi.apply_tds = 1 + pi.tax_withholding_category = "Test Multi Invoice Category" + pi.ignore_tax_withholding_threshold = 1 + pi.save() + + pi.override_tax_withholding_entries = 1 # Enable manual override + pi.tax_withholding_entries[0].withholding_amount = 1500 # incorrect tax withheld + self.assertRaisesRegex( + frappe.ValidationError, + r"Row #\d+: Withholding Amount \d+(\.\d+)? does not match calculated amount \d+(\.\d+)?", + pi.save, + ) + + pi.reload() + pi.tax_withholding_entries[0].taxable_amount = 15000 # correct taxable amount + pi.save() + + def test_manual_tax_adjustment_with_partial_adjustment_and_rate_change(self): + """Test manual tax adjustment where tax rate is changed during adjustment between payment and invoice""" + self.setup_party_with_category("Supplier", "Test TDS Supplier8", "Test Multi Invoice Category") + + # Step 1: Create a Payment Entry with over withheld amount at 10% rate + pe = create_payment_entry( + payment_type="Pay", party_type="Supplier", party="Test TDS Supplier8", paid_amount=150000 + ) + pe.apply_tds = 1 + pe.tax_withholding_category = "Test Multi Invoice Category" + pe.save().submit() + + # Step 2: Create Purchase Invoice with partial adjustment and manual rate change + pi = create_purchase_invoice(supplier="Test TDS Supplier8", rate=80000, do_not_save=True) + pi.tax_withholding_category = "Test Multi Invoice Category" + pi.override_tax_withholding_entries = 1 # Enable manual override + pi.tax_withholding_entries = [] + + # Entry 1: Partial adjustment with new tax rate (12% instead of 10%) + pi.append( + "tax_withholding_entries", + { + "tax_withholding_category": "Test Multi Invoice Category", + "party_type": "Supplier", + "party": "Test TDS Supplier8", + "tax_rate": 12.0, # Changed rate from 10% to 12% + "taxable_amount": 50000.0, # Partial taxable amount + "withholding_amount": 6000.0, # 50000 * 12% = 6000 + "taxable_doctype": "Purchase Invoice", + "taxable_name": pi.name, + "withholding_doctype": "Payment Entry", + "withholding_name": pe.name, + "conversion_rate": 1.0, + }, + ) + + # Entry 2: Remaining taxable amount under withheld + pi.append( + "tax_withholding_entries", + { + "tax_withholding_category": "Test Multi Invoice Category", + "party_type": "Supplier", + "party": "Test TDS Supplier8", + "tax_rate": 12.0, # Same new rate + "taxable_amount": 30000.0, # Remaining taxable amount (80000 - 50000) + "withholding_amount": 3600.0, # 30000 * 12% = 3600 + "taxable_doctype": "Purchase Invoice", + "taxable_name": pi.name, + "withholding_doctype": "Purchase Invoice", + "withholding_name": pi.name, + "conversion_rate": 1.0, + }, + ) + + pi.save() + pi.submit() + + # Step 3: Verify the tax withholding entries + expected_entries = [ + self.get_tax_withholding_entry( + tax_withholding_category="Test Multi Invoice Category", + party_type="Supplier", + party="Test TDS Supplier8", + tax_rate=12.0, # Updated rate + taxable_amount=50000.0, + withholding_amount=6000.0, + status="Settled", + taxable_doctype="Purchase Invoice", + taxable_name=pi.name, + withholding_doctype="Payment Entry", + withholding_name=pe.name, + ), + self.get_tax_withholding_entry( + tax_withholding_category="Test Multi Invoice Category", + party_type="Supplier", + party="Test TDS Supplier8", + tax_rate=12.0, # Updated rate + taxable_amount=30000.0, + withholding_amount=3600.0, + status="Settled", + taxable_doctype="Purchase Invoice", + taxable_name=pi.name, + withholding_doctype="Purchase Invoice", + withholding_name=pi.name, + ), + ] + + self.validate_tax_withholding_entries("Purchase Invoice", pi.name, expected_entries) + + # expected_entries in pe + expected_entries = [ + self.get_tax_withholding_entry( + tax_withholding_category="Test Multi Invoice Category", + party_type="Supplier", + party="Test TDS Supplier8", + tax_rate=12.0, # Updated rate + taxable_amount=50000.0, + withholding_amount=6000.0, + status="Duplicate", + taxable_doctype="Purchase Invoice", + taxable_name=pi.name, + withholding_doctype="Payment Entry", + withholding_name=pe.name, + ), + self.get_tax_withholding_entry( + tax_withholding_category="Test Multi Invoice Category", + party_type="Supplier", + party="Test TDS Supplier8", + tax_rate=10.0, # Updated rate + taxable_amount=90000.0, + withholding_amount=9000.0, + status="Over Withheld", + taxable_doctype="", + taxable_name="", + withholding_doctype="Payment Entry", + withholding_name=pe.name, + ), + ] + + self.validate_tax_withholding_entries("Payment Entry", pe.name, expected_entries) + + def test_manual_tax_adjustment_with_rate_change(self): + """Test manual tax adjustment where tax rate is changed during adjustment between payment and invoice""" + self.setup_party_with_category("Supplier", "Test TDS Supplier8", "Test Multi Invoice Category") + + # Step 1: Create a Payment Entry with over withheld amount at 10% rate + pe = create_payment_entry( + payment_type="Pay", party_type="Supplier", party="Test TDS Supplier8", paid_amount=150000 + ) + pe.apply_tds = 1 + pe.tax_withholding_category = "Test Multi Invoice Category" + pe.save().submit() + + # Step 2: Create Purchase Invoice with partial adjustment and manual rate change + pi = create_purchase_invoice(supplier="Test TDS Supplier8", rate=80000, do_not_save=True) + pi.tax_withholding_category = "Test Multi Invoice Category" + pi.override_tax_withholding_entries = 1 # Enable manual override + pi.tax_withholding_entries = [] + + # Entry 1: Partial adjustment with new tax rate (12% instead of 10%) + pi.append( + "tax_withholding_entries", + { + "tax_withholding_category": "Test Multi Invoice Category", + "party_type": "Supplier", + "party": "Test TDS Supplier8", + "tax_rate": 30.0, # Changed rate from 10% to 12% + "taxable_amount": 50000.0, # Partial taxable amount + "withholding_amount": 15000.0, # 50000 * 12% = 6000 + "taxable_doctype": "Purchase Invoice", + "taxable_name": pi.name, + "withholding_doctype": "Payment Entry", + "withholding_name": pe.name, + "conversion_rate": 1.0, + }, + ) + + # Entry 2: Remaining taxable amount under withheld + pi.append( + "tax_withholding_entries", + { + "tax_withholding_category": "Test Multi Invoice Category", + "party_type": "Supplier", + "party": "Test TDS Supplier8", + "tax_rate": 12.0, # Same new rate + "taxable_amount": 30000.0, # Remaining taxable amount (80000 - 50000) + "withholding_amount": 3600.0, # 30000 * 12% = 3600 + "taxable_doctype": "Purchase Invoice", + "taxable_name": pi.name, + "withholding_doctype": "Purchase Invoice", + "withholding_name": pi.name, + "conversion_rate": 1.0, + }, + ) + + pi.save() + pi.submit() + + # Step 3: Verify the tax withholding entries + expected_entries = [ + self.get_tax_withholding_entry( + tax_withholding_category="Test Multi Invoice Category", + party_type="Supplier", + party="Test TDS Supplier8", + tax_rate=30.0, # Updated rate + taxable_amount=50000.0, + withholding_amount=15000.0, + status="Settled", + taxable_doctype="Purchase Invoice", + taxable_name=pi.name, + withholding_doctype="Payment Entry", + withholding_name=pe.name, + ), + self.get_tax_withholding_entry( + tax_withholding_category="Test Multi Invoice Category", + party_type="Supplier", + party="Test TDS Supplier8", + tax_rate=12.0, # Updated rate + taxable_amount=30000.0, + withholding_amount=3600.0, + status="Settled", + taxable_doctype="Purchase Invoice", + taxable_name=pi.name, + withholding_doctype="Purchase Invoice", + withholding_name=pi.name, + ), + ] + + self.validate_tax_withholding_entries("Purchase Invoice", pi.name, expected_entries) + + # expected_entries in pe + expected_entries = [ + self.get_tax_withholding_entry( + tax_withholding_category="Test Multi Invoice Category", + party_type="Supplier", + party="Test TDS Supplier8", + tax_rate=30.0, # Updated rate + taxable_amount=50000.0, + withholding_amount=15000.0, + status="Duplicate", + taxable_doctype="Purchase Invoice", + taxable_name=pi.name, + withholding_doctype="Payment Entry", + withholding_name=pe.name, + ) + ] + + self.validate_tax_withholding_entries("Payment Entry", pe.name, expected_entries) + + def test_manual_tax_adjustment_with_zero_rate(self): + """Test manual tax adjustment where tax rate is changed to zero during adjustment""" + self.setup_party_with_category("Supplier", "Test TDS Supplier8", "Test Multi Invoice Category") + + pe = create_payment_entry( + payment_type="Pay", party_type="Supplier", party="Test TDS Supplier8", paid_amount=100000 + ) + pe.apply_tds = 1 + pe.tax_withholding_category = "Test Multi Invoice Category" + pe.save().submit() + + pe_expected = [ + self.get_tax_withholding_entry( + tax_withholding_category="Test Multi Invoice Category", + party_type="Supplier", + party="Test TDS Supplier8", + tax_rate=10.0, + taxable_amount=100000.0, + withholding_amount=10000.0, + status="Over Withheld", + taxable_doctype="", + taxable_name="", + withholding_doctype="Payment Entry", + withholding_name=pe.name, + ) + ] + self.validate_tax_withholding_entries("Payment Entry", pe.name, pe_expected) + + pi = create_purchase_invoice(supplier="Test TDS Supplier8", rate=50000, do_not_save=True) + pi.tax_withholding_category = "Test Multi Invoice Category" + pi.override_tax_withholding_entries = 1 + pi.tax_withholding_entries = [] + + pi.append( + "tax_withholding_entries", + { + "tax_withholding_category": "Test Multi Invoice Category", + "party_type": "Supplier", + "party": "Test TDS Supplier8", + "tax_rate": 0.0, # Zero rate + "taxable_amount": 50000.0, + "withholding_amount": 0.0, # No withholding at zero rate + "taxable_doctype": "Purchase Invoice", + "taxable_name": pi.name, + "withholding_doctype": "Payment Entry", + "withholding_name": pe.name, + "conversion_rate": 1.0, + }, + ) + + pi.save() + pi.submit() + + # Step 3: Verify the tax withholding entries on invoice + pi_expected = [ + self.get_tax_withholding_entry( + tax_withholding_category="Test Multi Invoice Category", + party_type="Supplier", + party="Test TDS Supplier8", + tax_rate=0.0, + taxable_amount=50000.0, + withholding_amount=0.0, + status="Settled", + taxable_doctype="Purchase Invoice", + taxable_name=pi.name, + withholding_doctype="Payment Entry", + withholding_name=pe.name, + ) + ] + self.validate_tax_withholding_entries("Purchase Invoice", pi.name, pi_expected) + + # Verify Payment Entry entries after adjustment + # PE should have: + # 1. Duplicate entry (adjusted 50000 portion with zero rate) + # 2. Over Withheld entry (remaining 50000 portion at 10%) + pe_expected_after = [ + self.get_tax_withholding_entry( + tax_withholding_category="Test Multi Invoice Category", + party_type="Supplier", + party="Test TDS Supplier8", + tax_rate=0.0, # Updated to zero rate + taxable_amount=50000.0, # Preserved from manual entry + withholding_amount=0.0, # Zero because rate is zero + status="Duplicate", + taxable_doctype="Purchase Invoice", + taxable_name=pi.name, + withholding_doctype="Payment Entry", + withholding_name=pe.name, + ), + self.get_tax_withholding_entry( + tax_withholding_category="Test Multi Invoice Category", + party_type="Supplier", + party="Test TDS Supplier8", + tax_rate=10.0, # Original rate + taxable_amount=50000.0, # Adjusted taxable + withholding_amount=10000.0, # Original amount (not split) + status="Over Withheld", # Still over withheld + taxable_doctype="", + taxable_name="", + withholding_doctype="Payment Entry", + withholding_name=pe.name, + ), + ] + self.validate_tax_withholding_entries("Payment Entry", pe.name, pe_expected_after) + + self.cleanup_invoices([pe, pi]) + + def test_tds_on_journal_entry_for_supplier(self): + """Test TDS deduction for Supplier in Debit Note""" + self.setup_party_with_category("Supplier", "Test TDS Supplier", "Cumulative Threshold TDS") + + jv = make_journal_entry_with_tax_withholding( + party_type="Supplier", + party="Test TDS Supplier", + voucher_type="Debit Note", + amount=50000, + save=False, + ) + jv.apply_tds = 1 + jv.tax_withholding_category = "Cumulative Threshold TDS" + jv.save() + + # Again saving should not change tds amount + jv.user_remark = "Test TDS on Journal Entry for Supplier" + jv.save() + jv.submit() + + # TDS = 50000 * 10% = 5000 + self.assertEqual(len(jv.accounts), 3) + + # Find TDS account row + tds_row = None + supplier_row = None + for row in jv.accounts: + if row.get("is_tax_withholding_account"): + tds_row = row + elif row.party_type == "Supplier": + supplier_row = row + + self.assertIsNotNone(tds_row, "TDS account row should be created") + self.assertIsNotNone(supplier_row, "Supplier account row should exist") + + # TDS should be credited (liability to government) + self.assertEqual(tds_row.credit, 5000) + self.assertEqual(tds_row.debit, 0) + + # Supplier credit should be reduced by TDS amount + self.assertEqual(supplier_row.credit, 45000) # 50000 - 5000 + + # Validate tax withholding entries + expected_entries = [ + self.get_tax_withholding_entry( + tax_withholding_category="Cumulative Threshold TDS", + party_type="Supplier", + party="Test TDS Supplier", + tax_rate=10.0, + taxable_amount=50000.0, + withholding_amount=5000.0, + status="Settled", + taxable_doctype="Journal Entry", + taxable_name=jv.name, + withholding_doctype="Journal Entry", + withholding_name=jv.name, + ) + ] + self.validate_tax_withholding_entries("Journal Entry", jv.name, expected_entries) + + def test_tcs_on_journal_entry_for_customer(self): + """Test TCS collection for Customer in Credit Note""" + self.setup_party_with_category("Customer", "Test TCS Customer", "Cumulative Threshold TCS") + + # Create Credit Note with amount exceeding threshold + jv = make_journal_entry_with_tax_withholding( + party_type="Customer", + party="Test TCS Customer", + voucher_type="Credit Note", + amount=50000, + save=False, + ) + jv.apply_tds = 1 + jv.tax_withholding_category = "Cumulative Threshold TCS" + jv.save() + + # Again saving should not change tds amount + jv.user_remark = "Test TCS on Journal Entry for Customer" + jv.save() + jv.submit() + + # Assert TCS calculation (10% on amount above threshold of 30000) + self.assertEqual(len(jv.accounts), 3) + + # Find TCS account row + tcs_row = None + customer_row = None + for row in jv.accounts: + if row.get("is_tax_withholding_account"): + tcs_row = row + elif row.party_type == "Customer": + customer_row = row + + self.assertIsNotNone(tcs_row, "TCS account row should be created") + self.assertIsNotNone(customer_row, "Customer account row should exist") + + # TCS should be credited (liability to government) + self.assertEqual(tcs_row.credit, 2000) # (50000 - 30000) * 10% + self.assertEqual(tcs_row.debit, 0) + + # Customer debit should be increased by TCS amount + self.assertEqual(customer_row.debit, 52000) # 50000 + 2000 + + # Validate tax withholding entries - system creates two entries for threshold processing + expected_entries = [ + self.get_tax_withholding_entry( + tax_withholding_category="Cumulative Threshold TCS", + party_type="Customer", + party="Test TCS Customer", + tax_rate=10.0, + taxable_amount=20000.0, # Excess amount above threshold (50000 - 30000) + withholding_amount=2000.0, # 10% of 20000 + status="Settled", + taxable_doctype="Journal Entry", + taxable_name=jv.name, + withholding_doctype="Journal Entry", + withholding_name=jv.name, + ), + self.get_tax_withholding_entry( + tax_withholding_category="Cumulative Threshold TCS", + party_type="Customer", + party="Test TCS Customer", + tax_rate=10.0, + taxable_amount=30000.0, # Threshold exemption amount + withholding_amount=0.0, # No tax on threshold portion + status="Settled", + taxable_doctype="Journal Entry", + taxable_name=jv.name, + withholding_doctype="Journal Entry", + withholding_name=jv.name, + under_withheld_reason="Threshold Exemption", + ), + ] + self.validate_tax_withholding_entries("Journal Entry", jv.name, expected_entries) + + def test_tds_with_multi_currency_invoice(self): + """Test TDS calculation with multi-currency purchase invoice and payment""" + invoices = [] + + self.setup_party_with_category("Supplier", "_Test Supplier USD", "Cumulative Threshold TDS") + + pe = frappe.get_doc( + { + "doctype": "Payment Entry", + "posting_date": today(), + "payment_type": "Pay", + "party_type": "Supplier", + "party": "_Test Supplier USD", + "company": "_Test Company", + "paid_from": "Cash - _TC", + "paid_to": "_Test Payable USD - _TC", + "paid_amount": 40000, # INR + "received_amount": 500, # USD + "source_exchange_rate": 1, + "target_exchange_rate": 80, + "reference_no": "USD-TDS-001", + "reference_date": today(), + "paid_from_account_currency": "INR", + "paid_to_account_currency": "USD", + "apply_tds": 1, + "tax_withholding_category": "Cumulative Threshold TDS", + } + ) + pe.save() + pe.submit() + invoices.append(pe) + + pe_expected = [ + self.get_tax_withholding_entry( + tax_withholding_category="Cumulative Threshold TDS", + party_type="Supplier", + party="_Test Supplier USD", + tax_rate=10.0, + taxable_amount=40000.0, # Base currency: 500 USD * 80 = 40000 INR + withholding_amount=4000.0, # 10% of 40000 INR + status="Over Withheld", + taxable_doctype="", + taxable_name="", + withholding_doctype="Payment Entry", + withholding_name=pe.name, + ) + ] + self.validate_tax_withholding_entries("Payment Entry", pe.name, pe_expected) + + pi = frappe.get_doc( + { + "doctype": "Purchase Invoice", + "supplier": "_Test Supplier USD", + "company": "_Test Company", + "apply_tds": 1, + "currency": "USD", + "conversion_rate": 80, + "credit_to": "_Test Payable USD - _TC", + "taxes": [], + "items": [ + { + "doctype": "Purchase Invoice Item", + "item_code": frappe.db.get_value("Item", {"item_name": "TDS Item"}, "name"), + "qty": 1, + "rate": 500, # 500 USD = 40000 INR + "cost_center": "Main - _TC", + "expense_account": "_Test Account Cost for Goods Sold - _TC", + } + ], + "advances": [ + { + "doctype": "Purchase Invoice Advance", + "reference_type": "Payment Entry", + "reference_name": pe.name, + "advance_amount": 500, # USD + "allocated_amount": 500, # USD (full allocation) + "ref_exchange_rate": 80, + } + ], + } + ) + pi.save() + pi.submit() + invoices.append(pi) + + pi_expected = [ + self.get_tax_withholding_entry( + tax_withholding_category="Cumulative Threshold TDS", + party_type="Supplier", + party="_Test Supplier USD", + tax_rate=10.0, + taxable_amount=40000.0, # Base currency: 500 USD * 80 = 40000 INR + withholding_amount=4000.0, # 10% of 40000 INR (settled from PE) + status="Settled", + taxable_doctype="Purchase Invoice", + taxable_name=pi.name, + withholding_doctype="Payment Entry", + withholding_name=pe.name, + ), + ] + self.validate_tax_withholding_entries("Purchase Invoice", pi.name, pi_expected) + self.cleanup_invoices(invoices) + frappe.db.set_value("Supplier", "_Test Supplier USD", "tax_withholding_category", "") + + def test_journal_entry_with_adjustment_in_invoice(self): + """Test Journal Entry with amount below threshold creates Under Withheld entry + and gets settled when a new Purchase Invoice crosses the threshold""" + invoices = [] + self.setup_party_with_category("Supplier", "Test TDS Supplier", "Cumulative Threshold TDS") + + # Create Debit Note with amount below threshold (30000) + jv = make_journal_entry_with_tax_withholding( + party_type="Supplier", + party="Test TDS Supplier", + voucher_type="Debit Note", + amount=20000, # Below cumulative threshold of 30000 + save=False, + ) + jv.apply_tds = 1 + jv.tax_withholding_category = "Cumulative Threshold TDS" + jv.save() + jv.submit() + invoices.append(jv) + + # Validate tax withholding entries - should have Under Withheld status + jv_expected = [ + self.get_tax_withholding_entry( + tax_withholding_category="Cumulative Threshold TDS", + party_type="Supplier", + party="Test TDS Supplier", + tax_rate=10.0, + taxable_amount=20000.0, + withholding_amount=0.0, # No tax withheld + status="Under Withheld", + taxable_doctype="Journal Entry", + taxable_name=jv.name, + withholding_doctype="", + withholding_name="", + ) + ] + self.validate_tax_withholding_entries("Journal Entry", jv.name, jv_expected) + + pi = create_purchase_invoice(supplier="Test TDS Supplier", rate=20000) + pi.submit() + invoices.append(pi) + + pi_expected = [ + # Entry for JV's under-withheld amount (now settled via PI) + self.get_tax_withholding_entry( + tax_withholding_category="Cumulative Threshold TDS", + party_type="Supplier", + party="Test TDS Supplier", + tax_rate=10.0, + taxable_amount=20000.0, # JV's taxable amount + withholding_amount=2000.0, # TDS on JV's amount + status="Settled", + taxable_doctype="Journal Entry", + taxable_name=jv.name, + withholding_doctype="Purchase Invoice", + withholding_name=pi.name, + ), + # Entry for PI's own amount + self.get_tax_withholding_entry( + tax_withholding_category="Cumulative Threshold TDS", + party_type="Supplier", + party="Test TDS Supplier", + tax_rate=10.0, + taxable_amount=20000.0, # PI's taxable amount + withholding_amount=2000.0, # TDS on PI's amount + status="Settled", + taxable_doctype="Purchase Invoice", + taxable_name=pi.name, + withholding_doctype="Purchase Invoice", + withholding_name=pi.name, + ), + ] + self.validate_tax_withholding_entries("Purchase Invoice", pi.name, pi_expected) + + self.cleanup_invoices(invoices) + + def test_journal_entry_negative_amount_debit_note(self): + """Test Journal Entry with negative amount (reversal of Debit Note)""" + invoices = [] + self.setup_party_with_category("Supplier", "Test TDS Supplier", "Cumulative Threshold TDS") + + # First create a regular Debit Note to cross threshold + jv1 = make_journal_entry_with_tax_withholding( + party_type="Supplier", + party="Test TDS Supplier", + voucher_type="Debit Note", + amount=50000, + save=False, + ) + jv1.apply_tds = 1 + jv1.tax_withholding_category = "Cumulative Threshold TDS" + jv1.save() + jv1.submit() + invoices.append(jv1) + + # Validate first JV entries + jv1_expected = [ + self.get_tax_withholding_entry( + tax_withholding_category="Cumulative Threshold TDS", + party_type="Supplier", + party="Test TDS Supplier", + tax_rate=10.0, + taxable_amount=50000.0, + withholding_amount=5000.0, + status="Settled", + taxable_doctype="Journal Entry", + taxable_name=jv1.name, + withholding_doctype="Journal Entry", + withholding_name=jv1.name, + ) + ] + self.validate_tax_withholding_entries("Journal Entry", jv1.name, jv1_expected) + + jv2 = frappe.new_doc("Journal Entry") + jv2.posting_date = today() + jv2.company = "_Test Company" + jv2.voucher_type = "Debit Note" + jv2.multi_currency = 0 + jv2.apply_tds = 1 + jv2.tax_withholding_category = "Cumulative Threshold TDS" + + jv2.append( + "accounts", + { + "account": "Stock Received But Not Billed - _TC", + "cost_center": "_Test Cost Center - _TC", + "credit_in_account_currency": 50000, # Credit (reversal of expense) + "exchange_rate": 1, + }, + ) + + # Supplier account: Debit 50000 (instead of normal Credit) + # This reduces supplier liability (refund/reversal) + jv2.append( + "accounts", + { + "account": "Creditors - _TC", + "party_type": "Supplier", + "party": "Test TDS Supplier", + "cost_center": "_Test Cost Center - _TC", + "debit_in_account_currency": 50000, # Debit (reversal) + "exchange_rate": 1, + }, + ) + + jv2.save() + jv2.submit() + invoices.append(jv2) + + jv2_expected = [ + self.get_tax_withholding_entry( + tax_withholding_category="Cumulative Threshold TDS", + party_type="Supplier", + party="Test TDS Supplier", + tax_rate=10.0, + taxable_amount=-50000.0, # Negative taxable amount + withholding_amount=-5000.0, # Negative withholding (reversal) + status="Settled", + taxable_doctype="Journal Entry", + taxable_name=jv2.name, + withholding_doctype="Journal Entry", + withholding_name=jv2.name, + ) + ] + self.validate_tax_withholding_entries("Journal Entry", jv2.name, jv2_expected) + self.cleanup_invoices(invoices) + + def test_delete_draft_pi_with_tax_withholding_entries(self): + """ + Test that draft Purchase Invoice with Tax Withholding Entries can be deleted. + """ + self.setup_party_with_category("Supplier", "Test TDS Supplier", "Cumulative Threshold TDS") + + pi = create_purchase_invoice(supplier="Test TDS Supplier", rate=50000, do_not_save=True) + pi.save() + + self.assertTrue(len(pi.tax_withholding_entries) > 0) + pi.delete() + + def test_tds_rounding_with_decimal_amounts(self): + """Test TDS rounding when round_off_tax_amount is enabled in category""" + self.setup_party_with_category("Supplier", "Test TDS Supplier3", "New TDS Category") + + pi = create_purchase_invoice(supplier="Test TDS Supplier3", rate=35555) + pi.submit() + + tds_row = next(e for e in pi.tax_withholding_entries if e.withholding_amount > 0) + self.assertEqual(tds_row.withholding_amount, 556) + + self.cleanup_invoices([pi]) + + def test_tax_withholding_entry_status_determination(self): + """Test that Tax Withholding Entry status is correctly determined""" + from erpnext.accounts.doctype.tax_withholding_entry.tax_withholding_entry import ( + TaxWithholdingEntry, + ) + + # Entry with only taxable fields (Under Withheld) + entry = frappe._dict( + docstatus=1, + withholding_name="", + under_withheld_reason="", + taxable_name="PI-001", + ) + self.assertEqual(TaxWithholdingEntry.get_status(entry), "Under Withheld") + + # Entry with withholding but no taxable (Over Withheld) + entry = frappe._dict( + docstatus=1, + withholding_name="PE-001", + under_withheld_reason="", + taxable_name="", + ) + self.assertEqual(TaxWithholdingEntry.get_status(entry), "Over Withheld") + + # Entry with both (Settled) + entry = frappe._dict( + docstatus=1, + withholding_name="PE-001", + under_withheld_reason="", + taxable_name="PI-001", + ) + self.assertEqual(TaxWithholdingEntry.get_status(entry), "Settled") + + # Entry with under withheld reason (considered matched/settled) + entry = frappe._dict( + docstatus=1, + withholding_name="", + under_withheld_reason="Threshold Exemption", + taxable_name="PI-001", + ) + self.assertEqual(TaxWithholdingEntry.get_status(entry), "Settled") + + # Cancelled entry + entry = frappe._dict(docstatus=2, withholding_name="", under_withheld_reason="", taxable_name="") + self.assertEqual(TaxWithholdingEntry.get_status(entry), "Cancelled") + + def test_invalid_withholding_amount_validation(self): + """Test that mismatched withholding amounts throw validation error on save""" + self.setup_party_with_category("Supplier", "Test TDS Supplier", "Cumulative Threshold TDS") + pi = create_purchase_invoice(supplier="Test TDS Supplier", rate=50000) + + self.assertTrue(len(pi.tax_withholding_entries) > 0) + pi.override_tax_withholding_entries = 1 + + entry = pi.tax_withholding_entries[0] + entry.withholding_amount = 5001 # Should be 5000 (10% of 50000) + self.assertRaisesRegex(frappe.ValidationError, "Withholding Amount.*does not match", pi.save) def create_purchase_invoice(**args): @@ -882,6 +3571,7 @@ def create_purchase_invoice(**args): "set_posting_time": args.set_posting_time or False, "posting_date": args.posting_date or today(), "apply_tds": 0 if args.do_not_apply_tds else 1, + "is_return": args.is_return or 0, "supplier": args.supplier, "company": "_Test Company", "taxes_and_charges": "", @@ -949,6 +3639,7 @@ def create_sales_invoice(**args): "posting_date": today(), "customer": args.customer, "company": "_Test Company", + "apply_tds": 0 if args.do_not_apply_tds else 1, "taxes_and_charges": "", "currency": "INR", "debit_to": "Debtors - _TC", @@ -997,6 +3688,88 @@ def create_payment_entry(**args): return pe +def make_journal_entry_with_tax_withholding( + party_type, + party, + voucher_type, + amount, + cost_center=None, + posting_date=None, + save=True, + submit=False, +): + """Helper function to create Journal Entry for tax withholding""" + if not cost_center: + cost_center = "_Test Cost Center - _TC" + + jv = frappe.new_doc("Journal Entry") + jv.posting_date = posting_date or today() + jv.company = "_Test Company" + jv.voucher_type = voucher_type + jv.multi_currency = 0 + + if party_type == "Supplier": + # Debit Note: Expense Dr, Supplier Cr + expense_account = "Stock Received But Not Billed - _TC" + party_account = "Creditors - _TC" + + jv.append( + "accounts", + { + "account": expense_account, + "cost_center": cost_center, + "debit_in_account_currency": amount, + "exchange_rate": 1, + }, + ) + + jv.append( + "accounts", + { + "account": party_account, + "party_type": party_type, + "party": party, + "cost_center": cost_center, + "credit_in_account_currency": amount, + "exchange_rate": 1, + }, + ) + else: # Customer + # Credit Note: Customer Dr, Income Cr + party_account = "Debtors - _TC" + income_account = "Sales - _TC" + + jv.append( + "accounts", + { + "account": party_account, + "party_type": party_type, + "party": party, + "cost_center": cost_center, + "debit_in_account_currency": amount, + "exchange_rate": 1, + }, + ) + + jv.append( + "accounts", + { + "account": income_account, + "cost_center": cost_center, + "credit_in_account_currency": amount, + "exchange_rate": 1, + }, + ) + + if save or submit: + jv.insert() + + if submit: + jv.submit() + + return jv + + def create_records(): # create a new suppliers for name in [ @@ -1094,6 +3867,7 @@ def create_tax_withholding_category_records(): account="TDS - _TC", single_threshold=0, cumulative_threshold=30000.00, + disable_transaction_threshold=1, ) # Category for TCS @@ -1105,6 +3879,9 @@ def create_tax_withholding_category_records(): account="TCS - _TC", single_threshold=0, cumulative_threshold=30000.00, + disable_transaction_threshold=1, + tax_deduction_basis="Gross Total", + tax_on_excess_amount=1, ) # Single threshold @@ -1127,7 +3904,6 @@ def create_tax_withholding_category_records(): single_threshold=0, cumulative_threshold=30000, round_off_tax_amount=1, - consider_party_ledger_amount=1, tax_on_excess_amount=1, ) @@ -1169,7 +3945,6 @@ def create_tax_withholding_category_records(): account="TDS - _TC", single_threshold=5000, cumulative_threshold=10000, - consider_party_ledger_amount=1, ) create_tax_withholding_category( @@ -1180,6 +3955,7 @@ def create_tax_withholding_category_records(): account="TDS - _TC", single_threshold=0, cumulative_threshold=30000, + disable_transaction_threshold=1, ) @@ -1192,8 +3968,9 @@ def create_tax_withholding_category( single_threshold=0, cumulative_threshold=0, round_off_tax_amount=0, - consider_party_ledger_amount=0, tax_on_excess_amount=0, + disable_transaction_threshold=0, + tax_deduction_basis="Net Total", ): if not frappe.db.exists("Tax Withholding Category", category_name): frappe.get_doc( @@ -1202,8 +3979,9 @@ def create_tax_withholding_category( "name": category_name, "category_name": category_name, "round_off_tax_amount": round_off_tax_amount, - "consider_party_ledger_amount": consider_party_ledger_amount, "tax_on_excess_amount": tax_on_excess_amount, + "disable_transaction_threshold": disable_transaction_threshold, + "tax_deduction_basis": tax_deduction_basis, "rates": [ { "from_date": from_date, diff --git a/erpnext/accounts/doctype/advance_tax/__init__.py b/erpnext/accounts/doctype/tax_withholding_entry/__init__.py similarity index 100% rename from erpnext/accounts/doctype/advance_tax/__init__.py rename to erpnext/accounts/doctype/tax_withholding_entry/__init__.py diff --git a/erpnext/accounts/doctype/tax_withholding_entry/tax_withholding_entry.json b/erpnext/accounts/doctype/tax_withholding_entry/tax_withholding_entry.json new file mode 100644 index 00000000000..76109669216 --- /dev/null +++ b/erpnext/accounts/doctype/tax_withholding_entry/tax_withholding_entry.json @@ -0,0 +1,237 @@ +{ + "actions": [], + "allow_rename": 1, + "creation": "2025-06-20 04:55:28.583171", + "doctype": "DocType", + "engine": "InnoDB", + "field_order": [ + "section_break_krko", + "company", + "party_type", + "party", + "tax_id", + "column_break_egzm", + "tax_withholding_category", + "tax_withholding_group", + "taxable_amount", + "tax_rate", + "withholding_amount", + "target_section", + "taxable_doctype", + "taxable_name", + "taxable_date", + "currency", + "conversion_rate", + "column_break_fqoe", + "under_withheld_reason", + "lower_deduction_certificate", + "source_section", + "withholding_doctype", + "withholding_name", + "withholding_date", + "column_break_dahw", + "section_break_ggna", + "status", + "column_break_jfjf", + "created_by_migration" + ], + "fields": [ + { + "fieldname": "section_break_krko", + "fieldtype": "Section Break" + }, + { + "fieldname": "party_type", + "fieldtype": "Link", + "label": "Party Type", + "options": "DocType", + "read_only": 1 + }, + { + "fieldname": "party", + "fieldtype": "Dynamic Link", + "label": "Party", + "options": "party_type", + "read_only": 1 + }, + { + "fieldname": "tax_id", + "fieldtype": "Data", + "label": "Tax ID", + "read_only": 1 + }, + { + "fieldname": "tax_withholding_category", + "fieldtype": "Link", + "in_list_view": 1, + "label": "Tax Withholding Category", + "options": "Tax Withholding Category", + "read_only": 1 + }, + { + "fieldname": "column_break_egzm", + "fieldtype": "Column Break" + }, + { + "columns": 1, + "fieldname": "tax_rate", + "fieldtype": "Percent", + "in_list_view": 1, + "label": "Tax Rate" + }, + { + "columns": 1, + "fieldname": "taxable_amount", + "fieldtype": "Currency", + "in_list_view": 1, + "label": "Base Taxable Amount", + "options": "Company:company:default_currency" + }, + { + "description": "Transaction from which tax is withheld", + "fieldname": "source_section", + "fieldtype": "Section Break", + "label": "Deducted From" + }, + { + "fieldname": "column_break_dahw", + "fieldtype": "Column Break" + }, + { + "description": "Transaction for which tax is withheld", + "fieldname": "target_section", + "fieldtype": "Section Break", + "label": "Applicable For" + }, + { + "fieldname": "column_break_fqoe", + "fieldtype": "Column Break" + }, + { + "fieldname": "section_break_ggna", + "fieldtype": "Section Break" + }, + { + "fieldname": "column_break_jfjf", + "fieldtype": "Column Break" + }, + { + "fieldname": "lower_deduction_certificate", + "fieldtype": "Link", + "label": "Lower Deduction Certificate", + "options": "Lower Deduction Certificate", + "read_only": 1 + }, + { + "fieldname": "status", + "fieldtype": "Select", + "label": "Status", + "options": "\nSettled\nUnder Withheld\nOver Withheld\nDuplicate\nCancelled", + "read_only": 1 + }, + { + "fieldname": "currency", + "fieldtype": "Link", + "label": "Currency", + "options": "Currency", + "read_only": 1 + }, + { + "fieldname": "conversion_rate", + "fieldtype": "Float", + "label": "Exchange Rate", + "precision": "9", + "read_only": 1 + }, + { + "fieldname": "withholding_doctype", + "fieldtype": "Link", + "label": "Withholding Document Type", + "options": "DocType" + }, + { + "fieldname": "withholding_name", + "fieldtype": "Dynamic Link", + "label": "Withholding Document Name", + "options": "withholding_doctype" + }, + { + "fieldname": "taxable_doctype", + "fieldtype": "Link", + "label": "Taxable Document Type", + "options": "DocType" + }, + { + "fieldname": "taxable_name", + "fieldtype": "Dynamic Link", + "in_list_view": 1, + "label": "Taxable Document Name", + "options": "taxable_doctype" + }, + { + "fieldname": "taxable_date", + "fieldtype": "Date", + "label": "Taxable Date", + "read_only": 1 + }, + { + "fieldname": "withholding_date", + "fieldtype": "Date", + "label": "Withholding Date", + "read_only": 1 + }, + { + "fieldname": "under_withheld_reason", + "fieldtype": "Select", + "label": "Under Withheld Reason", + "options": "\nThreshold Exemption\nLower Deduction Certificate", + "read_only": 1 + }, + { + "columns": 1, + "fieldname": "withholding_amount", + "fieldtype": "Currency", + "in_list_view": 1, + "label": "Base Tax Withheld", + "options": "Company:company:default_currency", + "read_only": 1 + }, + { + "columns": 1, + "fieldname": "tax_withholding_group", + "fieldtype": "Link", + "in_list_view": 1, + "label": "Tax Withholding Group", + "options": "Tax Withholding Group", + "read_only": 1 + }, + { + "fieldname": "company", + "fieldtype": "Link", + "label": "Company", + "options": "Company" + }, + { + "default": "0", + "fieldname": "created_by_migration", + "fieldtype": "Check", + "hidden": 1, + "label": "Created By Migration", + "read_only": 1 + } + ], + "grid_page_length": 50, + "index_web_pages_for_search": 1, + "istable": 1, + "links": [], + "modified": "2025-12-22 09:07:26.701207", + "modified_by": "Administrator", + "module": "Accounts", + "name": "Tax Withholding Entry", + "owner": "Administrator", + "permissions": [], + "row_format": "Dynamic", + "sort_field": "creation", + "sort_order": "DESC", + "states": [] +} diff --git a/erpnext/accounts/doctype/tax_withholding_entry/tax_withholding_entry.py b/erpnext/accounts/doctype/tax_withholding_entry/tax_withholding_entry.py new file mode 100644 index 00000000000..96a2768e68c --- /dev/null +++ b/erpnext/accounts/doctype/tax_withholding_entry/tax_withholding_entry.py @@ -0,0 +1,1460 @@ +# Copyright (c) 2025, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +from collections import defaultdict, deque +from math import inf + +import frappe +from frappe import _ +from frappe.model.document import Document +from frappe.query_builder.functions import IfNull, Sum +from frappe.utils import flt + +import erpnext +from erpnext.accounts.utils import get_advance_payment_doctypes + +DOCTYPE = "Tax Withholding Entry" + + +class TaxWithholdingEntry(Document): + # begin: auto-generated types + # This code is auto-generated. Do not modify anything in this block. + + from typing import TYPE_CHECKING + + if TYPE_CHECKING: + from frappe.types import DF + + company: DF.Link | None + conversion_rate: DF.Float + created_by_migration: DF.Check + currency: DF.Link | None + lower_deduction_certificate: DF.Link | None + parent: DF.Data + parentfield: DF.Data + parenttype: DF.Data + party: DF.DynamicLink | None + party_type: DF.Link | None + status: DF.Literal["", "Settled", "Under Withheld", "Over Withheld", "Duplicate", "Cancelled"] + tax_id: DF.Data | None + tax_rate: DF.Percent + tax_withholding_category: DF.Link | None + tax_withholding_group: DF.Link | None + taxable_amount: DF.Currency + taxable_date: DF.Date | None + taxable_doctype: DF.Link | None + taxable_name: DF.DynamicLink | None + under_withheld_reason: DF.Literal["", "Threshold Exemption", "Lower Deduction Certificate"] + withholding_amount: DF.Currency + withholding_date: DF.Date | None + withholding_doctype: DF.Link | None + withholding_name: DF.DynamicLink | None + # end: auto-generated types + + def set_status(self, status=None): + if not status: + status = self.get_status() + + self.status = status + + def get_status(self): + if self.docstatus == 2: + return "Cancelled" + + # Reasons are genuine allowed reasons for under deduction. + # Hence if a reason is provided, consider it as matched. + if not self.withholding_name and not self.under_withheld_reason: + return "Under Withheld" + + elif not self.taxable_name: + return "Over Withheld" + + else: + return "Settled" + + def validate_adjustments(self): + if self.is_taxable_different and self.is_withholding_different: + frappe.throw( + _( + "Row #{0}: Cannot create entry with different taxable AND withholding document links." + ).format(self.idx) + ) + + def validate_tax_withheld_amount(self): + if not self.withholding_name or self.under_withheld_reason: + return + + precision = self.precision("withholding_amount") + allowance = 0.5 + + tax_to_withheld = flt(self.taxable_amount * (self.tax_rate / 100), precision) + diff = abs(tax_to_withheld - self.withholding_amount) + if diff > allowance: + frappe.throw( + _("Row #{0}: Withholding Amount {1} does not match calculated amount {2}.").format( + self.idx, self.withholding_amount, tax_to_withheld + ) + ) + + @property + def is_taxable_different(self): + return self.taxable_doctype != self.parenttype or self.taxable_name != self.parent + + @property + def is_withholding_different(self): + return self.withholding_doctype != self.parenttype or self.withholding_name != self.parent + + def _process_tax_withholding_adjustments(self): + if self.status != "Settled": + return + # adjust old taxable (under-withheld) + if self.is_taxable_different: + self._adjust_against_old_entries(field_type="taxable") + + # adjust old withholding (over-withheld) + elif self.is_withholding_different: + self._adjust_against_old_entries(field_type="withholding") + + def _adjust_against_old_entries(self, field_type: str) -> set: + """ + Find old entries that need adjustment and update them. + The logic reads like: "Match up old incomplete entries with this new entry" + + Args: + field_type: Either "taxable" or "withholding" - determines which fields to use + """ + + doctype_field = f"{field_type}_doctype" + docname_field = f"{field_type}_name" + amount_field = f"{field_type}_amount" + status_to_find = "Under Withheld" if field_type == "taxable" else "Over Withheld" + + if not self.tax_rate: + amount_field = "taxable_amount" + + # old entries + old_entries = frappe.get_all( + DOCTYPE, + filters={ + # NOTE: Allow offsetting across different categories + # Change Filters + "tax_withholding_category": self.tax_withholding_category, + "status": status_to_find, + doctype_field: self.get(doctype_field), + docname_field: self.get(docname_field), + "docstatus": 1, + }, + fields="*", + ) + + value_direction = -1 if self.get(amount_field) < 0 else 1 + remaining_amount = abs(self.get(amount_field)) + docs_needing_reindex = set() + precision = self.precision("taxable_amount") + + # update + for old_entry_data in old_entries: + old_entry = frappe.get_doc(DOCTYPE, **old_entry_data) + old_amount = abs(old_entry.get(amount_field)) + + if old_entry.get(amount_field) * value_direction < 0: + # sign of old entry's amount is different + continue + + amount_we_can_match = min(old_amount, remaining_amount) + proportion = amount_we_can_match / old_amount if old_amount else 0 + values_to_update = self._get_values_to_update(old_entry, proportion, field_type) + + if old_amount <= amount_we_can_match: + # complete adjustment + frappe.db.set_value(DOCTYPE, old_entry.name, values_to_update) + + else: + # partial adjustment + # Calculate balance values for both taxable and withholding amounts + balance_amount = (old_amount - amount_we_can_match) * value_direction + + balance_values = self._get_balance_values_to_update(old_entry, proportion, field_type) + balance_values[amount_field] = balance_amount + + frappe.db.set_value(DOCTYPE, old_entry.name, balance_values) + + # new entry + # For partial adjustments, we need to proportionally adjust both taxable and withholding amounts + values_to_update["withholding_amount"] = old_entry.withholding_amount * proportion + values_to_update["taxable_amount"] = old_entry.taxable_amount * proportion + + # If tax rate has changed, recalculate based on new rate + if self.tax_rate != old_entry.tax_rate: + if not self.tax_rate: + # Zero rate means no withholding + values_to_update["withholding_amount"] = 0 + else: + values_to_update["taxable_amount"] = flt( + values_to_update["withholding_amount"] * 100 / self.tax_rate, + precision, + ) + + new_entry = frappe.copy_doc(old_entry) + new_entry.update(values_to_update) + new_entry.insert() + + docs_needing_reindex.add((old_entry.parenttype, old_entry.parent)) + + remaining_amount -= amount_we_can_match + + if remaining_amount <= 0: + break + + else: + frappe.throw( + _("Row #{0}: Could not find enough {1} entries to match. Remaining amount: {2}").format( + self.idx, status_to_find, remaining_amount + ) + ) + _reset_idx(docs_needing_reindex) + + def _get_values_to_update(self, old_entry, proportion: float, field_type: str): + field_to_update = "withholding" if field_type == "taxable" else "taxable" + + values = { + f"{field_to_update}_amount": self.get(f"{field_to_update}_amount") * proportion, + f"{field_to_update}_doctype": self.get(f"{field_to_update}_doctype"), + f"{field_to_update}_name": self.get(f"{field_to_update}_name"), + f"{field_to_update}_date": self.get(f"{field_to_update}_date"), + "tax_rate": self.tax_rate, + "status": "Duplicate", + "under_withheld_reason": None, + } + + if field_to_update == "taxable": + values.update( + currency=self.currency, + conversion_rate=self.conversion_rate, + under_withheld_reason=self.under_withheld_reason, + lower_deduction_certificate=self.lower_deduction_certificate, + ) + + # NOTE: Allow offsetting across different categories + # Update Tax Withholding Category values + + return values + + def _get_balance_values_to_update(self, old_entry, proportion: float, field_type: str): + """Calculate the balance amounts for both taxable and withholding fields for partial adjustments""" + field_to_update = "withholding" if field_type == "taxable" else "taxable" + field = f"{field_to_update}_amount" + proportion = 1 - proportion + + amount = flt(old_entry.get(field) * proportion, self.precision(field)) + + return {field: amount} + + # CANCEL + def _clear_old_references(self): + if self.status not in ["Settled", "Duplicate"]: + return + + filters = { + "tax_withholding_category": self.tax_withholding_category, + "taxable_doctype": self.taxable_doctype, + "taxable_name": self.taxable_name, + "withholding_doctype": self.withholding_doctype, + "withholding_name": self.withholding_name, + "name": ["!=", self.name], + "docstatus": 1, + } + + if self.is_taxable_different: + frappe.db.set_value( + DOCTYPE, + filters, + { + "withholding_name": "", + "withholding_doctype": "", + "withholding_amount": 0, + "withholding_date": None, + "under_withheld_reason": "", + "lower_deduction_certificate": "", + "status": "Under Withheld", + }, + ) + + elif self.is_withholding_different: + if self.taxable_amount < 0: + # Special handling for return invoice cancellation + self._handle_return_invoice_cancellation(filters) + else: + frappe.db.set_value( + DOCTYPE, + filters, + { + "taxable_name": "", + "taxable_doctype": "", + "taxable_date": None, + "status": "Over Withheld", + }, + ) + + def _handle_return_invoice_cancellation(self, filters): + # Get old entries that need adjustment - inspired by _adjust_against_old_entries + old_entries = frappe.get_all( + DOCTYPE, + filters=filters, + fields="*", + ) + + docs_needing_reindex = set() + + for entry in old_entries: + frappe.db.set_value( + DOCTYPE, + entry.name, + { + "taxable_doctype": entry.withholding_doctype, + "taxable_name": entry.withholding_name, + "taxable_date": entry.withholding_date, + }, + ) + + # cases where withholding amount is zero + if entry.withholding_amount == 0: + continue + + new_entry = frappe.copy_doc(frappe.get_doc(DOCTYPE, **entry)) + values_to_update = { + "taxable_amount": abs(entry.taxable_amount), + "withholding_amount": 0, + "status": "Under Withheld", + "under_withheld_reason": "", + "taxable_doctype": entry.withholding_doctype, + "taxable_name": entry.withholding_name, + "taxable_date": entry.withholding_date, + "withholding_doctype": "", + "withholding_name": "", + "withholding_date": None, + } + new_entry.update(values_to_update) + new_entry.insert() + + docs_needing_reindex.add((entry.parenttype, entry.parent)) + + _reset_idx(docs_needing_reindex) + + +from erpnext.accounts.doctype.tax_withholding_category.tax_withholding_category import ( + TaxWithholdingDetails, + get_tax_id_for_party, +) + + +class TaxWithholdingController: + def __init__(self, doc): + self.doc = doc + self.entries = [] + self.precision = self.doc.precision("withholding_amount", "tax_withholding_entries") + + def _get_category_details(self): + """Get tax withholding category details for the current document""" + category_names = self._get_category_names() + + return TaxWithholdingDetails( + category_names, + self.doc.tax_withholding_group, + self.doc.posting_date, + self.party_type, + self.party, + self.doc.company, + ).get() + + def _get_category_names(self): + category_names = set( + item.tax_withholding_category + for item in self.doc.items + if item.tax_withholding_category and item.apply_tds + ) + + return category_names + + def calculate(self): + # Always get category details first for account mapping + self.category_details = self._get_category_details() + + if not self.doc.override_tax_withholding_entries: + self._generate_withholding_entries() + + # Final processing - entry status and tax_update + self._process_withholding_entries() + + def _generate_withholding_entries(self): + # Clear existing entries + self.doc.tax_withholding_entries = [] + + # Calculate taxable amounts for each category + self._update_taxable_amounts() + + # Apply threshold rules + self._evaluate_thresholds() + + # Generate entries for each category + for category in self.category_details.values(): + self.entries += self._create_entries_for_category(category) + + # Add all generated entries to the document + self.doc.extend("tax_withholding_entries", self.entries) + + def _create_entries_for_category(self, category): + entries = [] + + if not category.taxable_amount: + return entries + + # Case 1: Threshold not crossed - create under withheld entry + if not category.threshold_crossed: + entries.append(self._create_under_withheld_entry(category)) + category.taxable_amount = 0 + return entries + + # Case 2: Tax on excess amount - handle threshold exemption first + if category.unused_threshold: + entries.append(self._create_threshold_exemption_entry(category)) + if category.taxable_amount <= 0: + return entries + + # Case 3: Process remaining amount with historical entries + open_entries = self._get_open_entries_for_category(category) + under_entries = open_entries["under_withheld"] + over_entries = open_entries["over_withheld"] + + # Case 4: Adjust Under and Over Withheld Entries + entries.extend(self._adjust_under_over_withheld(under_entries, over_entries, category)) + + # Case 4: Lower Deduction Certificate processing + if category.ldc_unutilized_amount: + entries.extend(self._process_ldc_entries(under_entries, over_entries, category)) + + # Case 5: Regular tax withholding processing + entries.extend(self._merge_entries(under_entries, over_entries, category)) + + return entries + + def _create_under_withheld_entry(self, category): + """Create an under withheld entry when threshold is not crossed""" + return { + **self._create_default_entry(category), + "taxable_amount": category.taxable_amount, + "withholding_doctype": "", + "withholding_name": "", + "withholding_date": "", + "withholding_amount": 0, + } + + def _create_threshold_exemption_entry(self, category): + """Create entry for amount below threshold (tax on excess)""" + taxable_amount = min(category.unused_threshold, category.taxable_amount) + category.taxable_amount -= taxable_amount + + return { + **self._create_default_entry(category), + "taxable_amount": taxable_amount, + "under_withheld_reason": "Threshold Exemption", + } + + def _get_open_entries_for_category(self, category): + """Get historical under withheld and over withheld entries for processing""" + entries = self._get_historical_entries(category) + linked_payments = self._get_linked_payments() + + open_entries = {"under_withheld": deque(), "over_withheld": deque()} + + # Process historical entries + self._categorize_historical_entries(entries, linked_payments, open_entries) + + # Add current document as under withheld + current_entry = self._create_default_entry(category) + current_entry.update( + { + "taxable_amount": category.taxable_amount, + "withholding_doctype": "", + "withholding_name": "", + "withholding_date": "", + } + ) + open_entries["under_withheld"].appendleft(current_entry) + + return open_entries + + def _categorize_historical_entries(self, entries, linked_payments, open_entries): + """Categorize historical entries into under withheld and over withheld""" + for entry in entries: + if entry.status == "Under Withheld": + open_entries["under_withheld"].append(entry) + continue + + # Handle over withheld entries + key = (entry.withholding_doctype, entry.withholding_name) + if key in linked_payments: + # Calculate proportion for linked payments + # TODO: whether it should be entry.taxable_amount only or do we need proportion + total_value = entry.taxable_amount - entry.withholding_amount + if not total_value: + continue + proportion = linked_payments[key] / total_value + + # for handling rounding adjustments + proportion = min(proportion, 1) + entry.withholding_amount *= proportion + open_entries["over_withheld"].appendleft(entry) + continue + + # only linked payment entries are allowed + if entry.withholding_doctype in ["Payment Entry", "Journal Entry"]: + continue + + open_entries["over_withheld"].append(entry) + + def _process_ldc_entries(self, under_entries, over_entries, category): + ldc_config = { + "under_withheld_reason": "Lower Deduction Certificate", + "lower_deduction_certificate": category.ldc_certificate, + } + + return self._merge_entries( + under_entries, + over_entries, + category, + tax_rate=category.ldc_rate, + constraint=category.ldc_unutilized_amount, + default_obj=ldc_config, + ) + + def _update_taxable_amounts(self): + if not self.doc.base_net_total: + return + + self._update_amount_for_item() + + def _update_amount_for_item(self): + precision = self.doc.precision("base_net_rate", "items") + self._update_item_wise_tax_amount() + + for item in self.doc.get("items"): + if not (item.apply_tds and item.tax_withholding_category): + continue + + category = self.category_details.get(item.tax_withholding_category) + + if category.tax_deduction_basis != "Gross Total": + taxable_amount = item.base_net_amount + else: + taxable_amount = item.base_net_amount + item._item_total_tax_amount + + taxable_amount = flt(taxable_amount, precision) + + item._base_tax_withholding_net_total = taxable_amount + + category["taxable_amount"] += flt(taxable_amount, precision) + + def _update_item_wise_tax_amount(self): + for item in self.doc.get("items"): + item._item_total_tax_amount = 0 + + precision = self.doc.precision("tax_amount", "taxes") + for row in self.doc.get("_item_wise_tax_details", []): + item = row.item + + if not (item.apply_tds and item.tax_withholding_category): + continue + + if row.tax.is_tax_withholding_account: + continue + + item._item_total_tax_amount = flt(item._item_total_tax_amount + row.amount, precision) + + def _evaluate_thresholds(self): + """ + Evaluate if thresholds are crossed for each category + + Thresholds are crossed when: + - Single transaction threshold is exceeded + - Cumulative threshold is exceeded + - Threshold check is manually overridden + """ + for category in self.category_details.values(): + category.threshold_crossed = self._is_threshold_crossed_for_category(category) + category.unused_threshold = self._get_unused_threshold(category) + + def _is_threshold_crossed_for_category(self, category): + # Manual override - always cross threshold + if self.doc.ignore_tax_withholding_threshold: + return True + + # Transaction threshold only mode + if category.disable_cumulative_threshold: + return category.taxable_amount >= category.single_threshold + + # No cumulative threshold set + if category.cumulative_threshold == 0: + return True + + # Tax on excess amount - always process + if category.tax_on_excess_amount: + return True + + # Standard cumulative/transaction threshold check + return self._check_historical_threshold_status(category) + + def _check_historical_threshold_status(self, category): + entry = frappe.qb.DocType(DOCTYPE) + result = frappe._dict( + self._base_threshold_query(category).where(entry.status.isin(["Settled", "Under Withheld"])).run() + ) + + # NOTE: Once deducted, always deducted. Not checking cumulative threshold again purposefully. + # conservative approach to avoid tax disputes as it can have conflicting views + # https://www.taxtmi.com/forum/issue?id=118627 + + if result.get("Settled", 0) > 0: + return True + + # Check remaining threshold + remaining_threshold = category.cumulative_threshold - result.get("Under Withheld", 0) + + if not category.disable_transaction_threshold: + remaining_threshold = min(remaining_threshold, category.single_threshold) + + return category.taxable_amount >= remaining_threshold + + def _get_unused_threshold(self, category): + """Calculate unused threshold amount for tax on excess scenarios""" + if not category.tax_on_excess_amount: + return 0 + + entry = frappe.qb.DocType(DOCTYPE) + result = frappe._dict( + self._base_threshold_query(category) + .where(IfNull(entry.under_withheld_reason, "") == "Threshold Exemption") + .run() + ) + + return category.cumulative_threshold - result.get("Settled", 0) + + def _base_threshold_query(self, category): + entry = frappe.qb.DocType(DOCTYPE) + query = ( + frappe.qb.from_(entry) + .select(entry.status, Sum(entry.taxable_amount).as_("taxable_amount")) + .where(entry.party_type == self.party_type) + .where(entry.tax_withholding_category == category.name) + .where(entry.company == self.doc.company) + .where(entry.docstatus == 1) + .groupby(entry.status) + ) + + # NOTE: This can be a configurable option + # To check if filter by tax_id is needed + tax_id = get_tax_id_for_party(self.party_type, self.party) + query = query.where(entry.tax_id == tax_id) if tax_id else query.where(entry.party == self.party) + + return query + + def _get_historical_entries(self, category): + entry = frappe.qb.DocType(DOCTYPE) + base_query = ( + frappe.qb.from_(entry) + .select("*") + .where(entry.tax_withholding_category == category.name) + .where(entry.party_type == self.party_type) + .where(entry.party == self.party) + .where(entry.company == self.doc.company) + .where(entry.docstatus == 1) + ) + + over_withheld_query = base_query.where(entry.status == "Over Withheld") + + return ( + base_query.where(entry.status == "Under Withheld") + .where(entry.taxable_date.between(category.from_date, category.to_date)) + .union(over_withheld_query) + .run(as_dict=True) + ) + + def _get_linked_payments(self): + references = frappe._dict() + for ref in self.doc.advances: + key = (ref.reference_type, ref.reference_name) + references[key] = ref.allocated_amount * self.doc.conversion_rate + + return references + + def _create_default_entry(self, category): + return frappe._dict( + { + "company": self.doc.company, + "party_type": self.party_type, + "party": self.party, + "tax_withholding_category": category.name, + "tax_withholding_group": category.tax_withholding_group, + "tax_rate": category.tax_rate, + "conversion_rate": self.get_conversion_rate(), + "taxable_doctype": self.doc.doctype, + "taxable_name": self.doc.name, + "taxable_date": self.doc.posting_date, + "taxable_amount": 0, + "withholding_doctype": self.doc.doctype, + "withholding_name": self.doc.name, + "withholding_date": self.doc.posting_date, + "withholding_amount": 0, # Will be computed later + } + ) + + def update_tax_rows(self): + """Update tax rows in the parent document based on withholding entries""" + account_amount_map = self._calculate_account_wise_amount() + category_withholding_map = self._get_category_withholding_map() + existing_taxes = {row.account_head: row for row in self.doc.taxes if row.is_tax_withholding_account} + precision = self.doc.precision("tax_amount", "taxes") + conversion_rate = self.get_conversion_rate() + + for account_head, base_amount in account_amount_map.items(): + tax_amount = flt(base_amount / conversion_rate, precision) + if not tax_amount: + continue + + # Update existing tax row or create new one + if existing_tax := existing_taxes.get(account_head): + existing_tax.tax_amount = tax_amount + existing_tax.dont_recompute_tax = 1 + tax_row = existing_tax + for_update = True + else: + tax_row = self._create_tax_row(account_head, tax_amount) + for_update = False + + # Set item-wise tax breakup for this tax row + self._set_item_wise_tax_for_tds( + tax_row, account_head, category_withholding_map, for_update=for_update + ) + + self._remove_zero_tax_rows() + self.calculate_taxes_and_totals() + + def _create_tax_row(self, account_head, tax_amount): + cost_center = self.doc.cost_center or erpnext.get_default_cost_center(self.doc.company) + return self.doc.append( + "taxes", + { + "is_tax_withholding_account": 1, + "category": "Total", + "charge_type": "Actual", + "account_head": account_head, + "description": account_head, + "cost_center": cost_center, + "add_deduct_tax": "Deduct", + "tax_amount": tax_amount, + "dont_recompute_tax": 1, + }, + ) + + def _set_item_wise_tax_for_tds(self, tax_row, account_head, category_withholding_map, for_update=False): + # Get all categories for this account (multiple categories can share same account) + categories_for_account = [ + cat for cat in self.category_details.values() if cat.account_head == account_head + ] + + if not categories_for_account: + return + + if not hasattr(self.doc, "_item_wise_tax_details"): + self.doc._item_wise_tax_details = [] + + if for_update: + self.doc._item_wise_tax_details = [ + d for d in self.doc._item_wise_tax_details if d.get("tax") != tax_row + ] + + items = self.doc.get("items") or [] + category_totals = {} + for item in items: + if item.apply_tds and item.tax_withholding_category: + item_taxable = item.get("_base_tax_withholding_net_total", 0) + category_totals[item.tax_withholding_category] = ( + category_totals.get(item.tax_withholding_category, 0) + item_taxable + ) + + precision = self.doc.precision("tax_amount", "taxes") + for item in items: + if not (item.apply_tds and item.tax_withholding_category): + continue + + category = self.category_details.get(item.tax_withholding_category) + if not category or category.account_head != account_head: + continue + + item_base_taxable = item.get("_base_tax_withholding_net_total") or 0 + + if not category.taxable_amount or not item_base_taxable: + continue + + total_taxable_amount = category_totals.get(category.name, 0) + + if category.unused_threshold and total_taxable_amount: + # Proportionately deduct unused threshold from item's base taxable + item_threshold_deduction = ( + item_base_taxable / total_taxable_amount + ) * category.unused_threshold + item_effective_taxable = max(0, item_base_taxable - item_threshold_deduction) + else: + item_effective_taxable = item_base_taxable + + withholding_amount = category_withholding_map.get(category.name, 0) + if withholding_amount and category.taxable_amount: + item_proportion = item_effective_taxable / category.taxable_amount + item_tax_amount = flt(withholding_amount * item_proportion, precision) + else: + item_tax_amount = 0 + + self.doc._item_wise_tax_details.append( + frappe._dict( + item=item, + tax=tax_row, + rate=category.tax_rate, + amount=item_tax_amount * -1, # Negative because it's a deduction + taxable_amount=item_base_taxable, + ) + ) + + def _get_category_withholding_map(self): + category_withholding_map = defaultdict(float) + + for entry in self.doc.tax_withholding_entries: + if entry.withholding_name != self.doc.name: + continue + category_withholding_map[entry.tax_withholding_category] += entry.withholding_amount + + return category_withholding_map + + def _calculate_account_wise_amount(self): + account_amount_map = defaultdict(float) + + for entry in self.doc.tax_withholding_entries: + if entry.withholding_name != self.doc.name: + continue + category = self.category_details.get(entry.tax_withholding_category) + account_amount_map[category.account_head] += entry.withholding_amount + + return account_amount_map + + def _remove_zero_tax_rows(self): + self.doc.taxes = [ + row for row in self.doc.taxes if not (row.is_tax_withholding_account and not row.tax_amount) + ] + + def _adjust_under_over_withheld( + self, + under_entries: deque, + over_entries: deque, + category: dict, + ): + """ + Merge under withheld and over withheld entries based on the tax rate and constraint. + If only under and over entries are available, they will be processed against current document. + """ + if not (under_entries and over_entries): + return [] + + merged_entries = [] + + while under_entries and over_entries: + under = under_entries[0] + over = over_entries[0] + tax_rate = over.tax_rate + + # Calculate tax amount for this taxable amount + tax_amount = self.compute_withheld_amount( + under.taxable_amount, + tax_rate, + round_off_tax_amount=category.round_off_tax_amount, + ) + + tax_amount = flt(min(tax_amount, over.withholding_amount), self.precision) + + if tax_rate == 0: + taxable_amount = min(under.taxable_amount, over.taxable_amount) + else: + taxable_amount = flt(100 / tax_rate * tax_amount, self.precision) + + # Create merged entry + merged_entry = under.copy() + merged_entry.update( + { + "taxable_amount": taxable_amount, + "withholding_amount": tax_amount, + "withholding_doctype": over.withholding_doctype, + "withholding_name": over.withholding_name, + "withholding_date": over.withholding_date, + "under_withheld_reason": over.under_withheld_reason, + "tax_rate": tax_rate, + "lower_deduction_certificate": over.lower_deduction_certificate, + } + ) + + # Consolidate entries by document combination + if self._should_include_entry(merged_entry): + merged_entries.append(merged_entry) + + under.taxable_amount -= taxable_amount + over.withholding_amount -= tax_amount + + if flt(under.taxable_amount, self.precision) <= 0: + under_entries.popleft() + if flt(over.withholding_amount, self.precision) <= 0: + over_entries.popleft() + + return merged_entries + + def _merge_entries( + self, + under_entries: deque, + over_entries: deque, + category: dict, + tax_rate: float | None = None, + constraint: float = inf, + default_obj: dict | None = None, + ): + """ + Merge under withheld and over withheld entries based on the tax rate and constraint. + If only under and over entries are available, they will be processed against current document. + """ + merged_entries = [] + if not ((under_entries or over_entries) and constraint > 0): + return merged_entries + + if tax_rate is None: + tax_rate = category.tax_rate + + # Process remaining under entries + constraint = self._process_under_withheld_entries( + under_entries, category, tax_rate, constraint, default_obj, merged_entries + ) + + # Process remaining over entries + self._process_over_withheld_entries( + over_entries, category, tax_rate, constraint, default_obj, merged_entries + ) + + return merged_entries + + def _process_under_withheld_entries( + self, under_entries, category, tax_rate, constraint, default_obj, merged_entries + ): + """ + Process remaining Under Withheld Entries - adjust against current document + """ + while under_entries and constraint > 0: + entry = under_entries[0] + + value_direction = -1 if entry.taxable_amount < 0 else 1 + amount_to_process = min(entry.taxable_amount, constraint) + + if amount_to_process * value_direction <= 0: + break + + # Create base entry and calculate withholding amount + merged_entry = self._create_base_entry(entry, category, tax_rate, default_obj) + merged_entry.update( + { + "taxable_amount": flt(amount_to_process, self.precision), + "withholding_amount": self.compute_withheld_amount( + amount_to_process, + tax_rate, + round_off_tax_amount=category.round_off_tax_amount, + ), + "withholding_doctype": self.doc.doctype, + "withholding_name": self.doc.name, + "withholding_date": self.doc.posting_date, + } + ) + + # Always include under entries + merged_entries.append(merged_entry) + + # Update entry amounts + entry.taxable_amount -= amount_to_process + if flt(entry.taxable_amount * value_direction, self.precision) <= 0: + under_entries.popleft() + + # Update constraint + constraint -= amount_to_process + + return constraint + + def _process_over_withheld_entries( + self, over_entries, category, tax_rate, constraint, default_obj, merged_entries + ): + """ + Process remaining Over Withheld Entries - adjust existing over-withheld amounts + """ + while over_entries and constraint > 0: + entry = over_entries[0] + + value_direction = -1 if entry.taxable_amount < 0 else 1 + amount_to_process = min(entry.taxable_amount, constraint) + + if amount_to_process * value_direction <= 0: + break + + # Create base entry and calculate withholding amount + merged_entry = self._create_base_entry(entry, category, tax_rate, default_obj) + merged_entry.update( + { + "taxable_amount": flt(amount_to_process, self.precision), + "withholding_amount": self.compute_withheld_amount( + amount_to_process, + tax_rate, + round_off_tax_amount=category.round_off_tax_amount, + ), + "withholding_doctype": entry.withholding_doctype, + "withholding_name": entry.withholding_name, + "withholding_date": entry.withholding_date, + "taxable_doctype": "", + "taxable_name": "", + "taxable_date": "", + "conversion_rate": self.get_conversion_rate(), + } + ) + + # Only include over entries related to current document + if self._should_include_entry(merged_entry): + merged_entries.append(merged_entry) + + # Update entry amounts + entry.taxable_amount -= amount_to_process + if flt(entry.taxable_amount * value_direction, self.precision) <= 0: + over_entries.popleft() + + # Update constraint + constraint -= amount_to_process + + return constraint + + def _create_base_entry(self, source_entry, category, tax_rate, default_obj): + entry = {} + if default_obj: + entry.update(default_obj) + + entry.update( + { + "taxable_doctype": source_entry.taxable_doctype, + "taxable_name": source_entry.taxable_name, + "taxable_date": source_entry.taxable_date, + "tax_withholding_category": category.name, + "tax_rate": tax_rate, + "party_type": self.party_type, + "party": self.party, + "company": self.doc.company, + } + ) + return entry + + def _should_include_entry(self, entry): + return entry.get("taxable_name") == self.doc.name or entry.get("withholding_name") == self.doc.name + + def compute_withheld_amount(self, taxable_amount, tax_rate, round_off_tax_amount=False): + """Calculate the withholding amount based on taxable amount and rate""" + amount = taxable_amount * tax_rate / 100 + if round_off_tax_amount: + return flt(amount, 0) + return flt(amount, self.precision) + + def _process_withholding_entries(self): + """Final processing - update tax rows and validate""" + self.update_tax_rows() + for entry in self.doc.tax_withholding_entries: + entry: TaxWithholdingEntry + entry.set_status(entry.status) + entry.validate_adjustments() + entry.validate_tax_withheld_amount() + + def on_submit(self): + for entry in self.doc.tax_withholding_entries: + entry: TaxWithholdingEntry + entry._process_tax_withholding_adjustments() + + def on_cancel(self): + for entry in self.doc.tax_withholding_entries: + entry: TaxWithholdingEntry + entry._clear_old_references() + entry.set_status() + + def _is_tax_withholding_applicable(self): + # Clear existing tax withholding amounts before recalculation + self._clear_existing_tax_amounts() + + if not self.doc.apply_tds or self.doc.get("is_opening") == "Yes" or not self._get_category_names(): + self.doc.tax_withholding_entries = [] + return False + + return True + + def _clear_existing_tax_amounts(self): + for row in self.doc.taxes: + if row.is_tax_withholding_account and row.tax_amount: + row.tax_amount = 0 + row.base_tax_amount_after_discount_amount = 0 + + def calculate_taxes_and_totals(self): + self.doc.calculate_taxes_and_totals() + + def get_conversion_rate(self): + return self.doc.get("conversion_rate") or 1 + + def on_validate(self): + if self._is_tax_withholding_applicable(): + self.calculate() + + +class PurchaseTaxWithholding(TaxWithholdingController): + """Tax withholding controller for Purchase Invoices""" + + def __init__(self, doc): + super().__init__(doc) + self.party_type = "Supplier" + self.party = doc.supplier + + +class SalesTaxWithholding(TaxWithholdingController): + """Tax withholding controller for Sales Invoices (TCS)""" + + def __init__(self, doc): + super().__init__(doc) + self.party_type = "Customer" + self.party = doc.customer + + +class PaymentTaxWithholding(TaxWithholdingController): + """Tax withholding controller for Payment Entries""" + + def __init__(self, doc): + super().__init__(doc) + self.party_type = doc.party_type + self.party = doc.party + + def _get_category_names(self): + if not self.doc.tax_withholding_category: + return [] + + return [self.doc.tax_withholding_category] + + def _update_taxable_amounts(self): + category = next(iter(self.category_details.values())) + + taxable_amount_in_party_currency = self.doc.unallocated_amount + taxable_amount_in_party_currency += sum( + flt(d.allocated_amount) + for d in self.doc.references + if d.reference_doctype in get_advance_payment_doctypes() + ) + + exchange_rate = self.get_conversion_rate() + taxable_amount = flt(taxable_amount_in_party_currency * exchange_rate, self.precision) + + category["taxable_amount"] = taxable_amount + + def get_conversion_rate(self): + if self.doc.payment_type == "Receive": + return self.doc.source_exchange_rate or 1 + else: + return self.doc.target_exchange_rate or 1 + + def calculate_taxes_and_totals(self): + self.doc.apply_taxes() + + def _get_open_entries_for_category(self, category): + # for payment only over withheld + open_entries = {"under_withheld": deque(), "over_withheld": deque()} + + current_entry = frappe._dict( + { + **self._create_default_entry(category), + "taxable_amount": category.taxable_amount, + "taxable_doctype": "", + "taxable_name": "", + "taxable_date": "", + } + ) + + open_entries["over_withheld"].append(current_entry) + + return open_entries + + def _is_threshold_crossed_for_category(self, category): + """For payment entries if apply_tds is checked, return True""" + return True + + def _get_unused_threshold(self, category): + """Always withhold Tax and whenever tax gets deducted adjust it""" + return 0 + + +class JournalTaxWithholding(TaxWithholdingController): + """Tax withholding controller for Journal Entries""" + + def __init__(self, doc): + super().__init__(doc) + self.party = None + self.party_type = None + self.party_account = None + self.party_row = None + self.existing_tds_rows = [] + self.precision = None + self.has_multiple_parties = False + + self.party_field = None + self.reverse_field = None + + self._setup_party_info() + + def _setup_party_info(self): + for row in self.doc.get("accounts"): + if row.party_type in ("Customer", "Supplier") and row.party: + if self.party and row.party != self.party: + self.has_multiple_parties = True + + if not self.party: + self.party = row.party + self.party_type = row.party_type + self.party_account = row.account + self.party_row = row + + if row.get("is_tax_withholding_account"): + self.existing_tds_rows.append(row) + + if self.party_type: + self._setup_direction_fields() + + def _setup_direction_fields(self): + """ + For Supplier (TDS): party has credit, TDS reduces credit + For Customer (TCS): party has debit, TCS increases debit + """ + if self.party_type == "Supplier": + self.party_field = "credit" + self.reverse_field = "debit" + else: # Customer + self.party_field = "debit" + self.reverse_field = "credit" + + self.precision = self.doc.precision(self.party_field, self.party_row) + + def _get_category_names(self): + if not self.doc.tax_withholding_category: + return [] + + return [self.doc.tax_withholding_category] + + def _update_taxable_amounts(self): + if not self.category_details: + return + + net_amount = self._calculate_net_total() + category = next(iter(self.category_details.values())) + category["taxable_amount"] = net_amount + + def _calculate_net_total(self): + from erpnext.accounts.report.general_ledger.general_ledger import get_account_type_map + + account_type_map = get_account_type_map(self.doc.company) + + return flt( + sum( + d.get(self.reverse_field) - d.get(self.party_field) + for d in self.doc.get("accounts") + if account_type_map.get(d.account) not in ("Tax", "Chargeable") + and d.account != self.party_account + and not d.get("is_tax_withholding_account") + ), + self.precision, + ) + + def get_conversion_rate(self): + return self.party_row.get("exchange_rate", 1.0) + + def calculate_taxes_and_totals(self): + self.doc.set_amounts_in_company_currency() + self.doc.set_total_debit_credit() + self.doc.set_against_account() + + def update_tax_rows(self): + if not self._should_apply_tds(): + self._cleanup_duplicate_tds_rows(None) + return + + if self.has_multiple_parties: + frappe.throw(_("Cannot apply TDS against multiple parties in one entry")) + + account_amount_map = self._calculate_account_wise_amount() + + if not account_amount_map: + return + + self._reset_existing_tds() + + for account_head, tax_amount in account_amount_map.items(): + if not tax_amount: + continue + + self._create_or_update_tds_row(account_head, tax_amount) + self._update_party_amount(tax_amount, is_reversal=False) + + self._recalculate_totals() + + def _should_apply_tds(self): + return self.doc.apply_tds and self.doc.voucher_type in ("Debit Note", "Credit Note") + + def _reset_existing_tds(self): + for row in self.existing_tds_rows: + # TDS amount is always in credit (liability to government) + tds_amount = flt(row.get("credit") - row.get("debit"), self.precision) + if not tds_amount: + continue + + self._update_party_amount(tds_amount, is_reversal=True) + + # zero_out_tds_row + row.update( + { + "credit": 0, + "credit_in_account_currency": 0, + "debit": 0, + "debit_in_account_currency": 0, + } + ) + + def _update_party_amount(self, amount, is_reversal=False): + amount = flt(amount, self.precision) + amount_in_party_currency = flt(amount / self.party_row.get("exchange_rate", 1), self.precision) + + # Determine which field the party amount is in + active_field = self.party_field if self.party_row.get(self.party_field) else self.reverse_field + + # If amount is in reverse field, flip the signs + if active_field == self.reverse_field: + amount = -amount + amount_in_party_currency = -amount_in_party_currency + + # Direction multiplier based on party type: + # Customer (TCS): +1 (add to debit) + # Supplier (TDS): -1 (subtract from credit) + direction = 1 if self.party_type == "Customer" else -1 + + # Reversal inverts the direction + if is_reversal: + direction = -direction + + adjustment = amount * direction + adjustment_in_party_currency = amount_in_party_currency * direction + + active_field_account_currency = f"{active_field}_in_account_currency" + + self.party_row.update( + { + active_field: flt(self.party_row.get(active_field) + adjustment, self.precision), + active_field_account_currency: flt( + self.party_row.get(active_field_account_currency) + adjustment_in_party_currency, + self.precision, + ), + } + ) + + def _create_or_update_tds_row(self, account_head, tax_amount): + from erpnext.accounts.utils import get_account_currency + from erpnext.setup.utils import get_exchange_rate as _get_exchange_rate + + account_currency = get_account_currency(account_head) + company_currency = frappe.get_cached_value("Company", self.doc.company, "default_currency") + exchange_rate = _get_exchange_rate(account_currency, company_currency, self.doc.posting_date) + + tax_amount = flt(tax_amount, self.precision) + tax_amount_in_account_currency = flt(tax_amount / exchange_rate, self.precision) + + tax_row = None + for row in self.doc.get("accounts"): + if row.account == account_head and row.get("is_tax_withholding_account"): + tax_row = row + break + + if not tax_row: + tax_row = self.doc.append( + "accounts", + { + "account": account_head, + "account_currency": account_currency, + "exchange_rate": exchange_rate, + "cost_center": self.doc.get("cost_center") + or erpnext.get_default_cost_center(self.doc.company), + "credit": 0, + "credit_in_account_currency": 0, + "debit": 0, + "debit_in_account_currency": 0, + "is_tax_withholding_account": 1, + }, + ) + + # TDS/TCS is always credited (liability to government) + tax_row.update( + { + "credit": tax_amount, + "credit_in_account_currency": tax_amount_in_account_currency, + "debit": 0, + "debit_in_account_currency": 0, + } + ) + + self._cleanup_duplicate_tds_rows(tax_row) + + def _cleanup_duplicate_tds_rows(self, current_tax_row): + rows_to_remove = [ + row + for row in self.doc.get("accounts") + if row.get("is_tax_withholding_account") and row != current_tax_row + ] + + for row in rows_to_remove: + self.doc.remove(row) + + def _recalculate_totals(self): + self.doc.set_amounts_in_company_currency() + self.doc.set_total_debit_credit() + self.doc.set_against_account() + + def _is_tax_withholding_applicable(self): + if not self._should_apply_tds(): + self.doc.tax_withholding_entries = [] + return False + + if not self.doc.tax_withholding_category: + self.doc.tax_withholding_entries = [] + return False + + return True + + def _get_linked_payments(self): + """Journal Entry doesn't have advances like invoices""" + return frappe._dict() + + +def _reset_idx(docs_to_reset_idx): + updates = {} + for doctype, docname in docs_to_reset_idx: + names = frappe.get_all( + DOCTYPE, + filters={"parent": docname, "parenttype": doctype, "docstatus": 1}, + pluck="name", + ) + + for idx, name in enumerate(names, start=1): + updates[name] = {"idx": idx} + + if updates: + frappe.db.bulk_update(DOCTYPE, updates, update_modified=False) diff --git a/erpnext/accounts/doctype/tax_withholding_entry/test_tax_withholding_entry.py b/erpnext/accounts/doctype/tax_withholding_entry/test_tax_withholding_entry.py new file mode 100644 index 00000000000..8a09f46e079 --- /dev/null +++ b/erpnext/accounts/doctype/tax_withholding_entry/test_tax_withholding_entry.py @@ -0,0 +1,20 @@ +# Copyright (c) 2025, Frappe Technologies Pvt. Ltd. and Contributors +# See license.txt + +# import frappe +from frappe.tests import IntegrationTestCase + +# On IntegrationTestCase, the doctype test records and all +# link-field test record dependencies are recursively loaded +# Use these module variables to add/remove to/from that list +EXTRA_TEST_RECORD_DEPENDENCIES = [] # eg. ["User"] +IGNORE_TEST_RECORD_DEPENDENCIES = [] # eg. ["User"] + + +class IntegrationTestTaxWithholdingEntry(IntegrationTestCase): + """ + Integration tests for TaxWithholdingEntry. + Use this class for testing interactions between multiple components. + """ + + pass diff --git a/erpnext/accounts/doctype/tax_withheld_vouchers/__init__.py b/erpnext/accounts/doctype/tax_withholding_group/__init__.py similarity index 100% rename from erpnext/accounts/doctype/tax_withheld_vouchers/__init__.py rename to erpnext/accounts/doctype/tax_withholding_group/__init__.py diff --git a/erpnext/accounts/doctype/tax_withholding_group/tax_withholding_group.js b/erpnext/accounts/doctype/tax_withholding_group/tax_withholding_group.js new file mode 100644 index 00000000000..a1b889489bd --- /dev/null +++ b/erpnext/accounts/doctype/tax_withholding_group/tax_withholding_group.js @@ -0,0 +1,8 @@ +// Copyright (c) 2025, Frappe Technologies Pvt. Ltd. and contributors +// For license information, please see license.txt + +// frappe.ui.form.on("Tax Withholding Group", { +// refresh(frm) { + +// }, +// }); diff --git a/erpnext/accounts/doctype/tax_withholding_group/tax_withholding_group.json b/erpnext/accounts/doctype/tax_withholding_group/tax_withholding_group.json new file mode 100644 index 00000000000..d2700f1eaeb --- /dev/null +++ b/erpnext/accounts/doctype/tax_withholding_group/tax_withholding_group.json @@ -0,0 +1,48 @@ +{ + "actions": [], + "allow_rename": 1, + "autoname": "field:group_name", + "creation": "2025-06-29 05:24:51.819891", + "doctype": "DocType", + "engine": "InnoDB", + "field_order": [ + "group_name" + ], + "fields": [ + { + "fieldname": "group_name", + "fieldtype": "Data", + "in_list_view": 1, + "label": "Group Name", + "reqd": 1, + "unique": 1 + } + ], + "grid_page_length": 50, + "index_web_pages_for_search": 1, + "links": [], + "modified": "2025-06-29 05:25:50.243710", + "modified_by": "Administrator", + "module": "Accounts", + "name": "Tax Withholding Group", + "naming_rule": "By fieldname", + "owner": "Administrator", + "permissions": [ + { + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "System Manager", + "share": 1, + "write": 1 + } + ], + "row_format": "Dynamic", + "sort_field": "creation", + "sort_order": "DESC", + "states": [] +} diff --git a/erpnext/accounts/doctype/tax_withheld_vouchers/tax_withheld_vouchers.py b/erpnext/accounts/doctype/tax_withholding_group/tax_withholding_group.py similarity index 57% rename from erpnext/accounts/doctype/tax_withheld_vouchers/tax_withheld_vouchers.py rename to erpnext/accounts/doctype/tax_withholding_group/tax_withholding_group.py index dbb69a2e769..2e688fa09d9 100644 --- a/erpnext/accounts/doctype/tax_withheld_vouchers/tax_withheld_vouchers.py +++ b/erpnext/accounts/doctype/tax_withholding_group/tax_withholding_group.py @@ -1,11 +1,11 @@ -# Copyright (c) 2022, Frappe Technologies Pvt. Ltd. and contributors +# Copyright (c) 2025, Frappe Technologies Pvt. Ltd. and contributors # For license information, please see license.txt # import frappe from frappe.model.document import Document -class TaxWithheldVouchers(Document): +class TaxWithholdingGroup(Document): # begin: auto-generated types # This code is auto-generated. Do not modify anything in this block. @@ -14,12 +14,7 @@ class TaxWithheldVouchers(Document): if TYPE_CHECKING: from frappe.types import DF - parent: DF.Data - parentfield: DF.Data - parenttype: DF.Data - taxable_amount: DF.Currency - voucher_name: DF.Data | None - voucher_type: DF.Data | None + group_name: DF.Data # end: auto-generated types pass diff --git a/erpnext/accounts/doctype/tax_withholding_group/test_tax_withholding_group.py b/erpnext/accounts/doctype/tax_withholding_group/test_tax_withholding_group.py new file mode 100644 index 00000000000..268febe3d7e --- /dev/null +++ b/erpnext/accounts/doctype/tax_withholding_group/test_tax_withholding_group.py @@ -0,0 +1,20 @@ +# Copyright (c) 2025, Frappe Technologies Pvt. Ltd. and Contributors +# See license.txt + +# import frappe +from frappe.tests import IntegrationTestCase + +# On IntegrationTestCase, the doctype test records and all +# link-field test record dependencies are recursively loaded +# Use these module variables to add/remove to/from that list +EXTRA_TEST_RECORD_DEPENDENCIES = [] # eg. ["User"] +IGNORE_TEST_RECORD_DEPENDENCIES = [] # eg. ["User"] + + +class IntegrationTestTaxWithholdingGroup(IntegrationTestCase): + """ + Integration tests for TaxWithholdingGroup. + Use this class for testing interactions between multiple components. + """ + + pass diff --git a/erpnext/accounts/doctype/tax_withholding_rate/tax_withholding_rate.json b/erpnext/accounts/doctype/tax_withholding_rate/tax_withholding_rate.json index c58d945c5aa..01ba2453f69 100644 --- a/erpnext/accounts/doctype/tax_withholding_rate/tax_withholding_rate.json +++ b/erpnext/accounts/doctype/tax_withholding_rate/tax_withholding_rate.json @@ -7,10 +7,11 @@ "field_order": [ "from_date", "to_date", - "tax_withholding_rate", + "tax_withholding_group", "column_break_3", - "single_threshold", - "cumulative_threshold" + "tax_withholding_rate", + "cumulative_threshold", + "single_threshold" ], "fields": [ { @@ -30,14 +31,14 @@ "fieldname": "single_threshold", "fieldtype": "Float", "in_list_view": 1, - "label": "Single Transaction Threshold" + "label": "Transaction Threshold" }, { "columns": 3, "fieldname": "cumulative_threshold", "fieldtype": "Float", "in_list_view": 1, - "label": "Cumulative Transaction Threshold" + "label": "Cumulative Threshold" }, { "columns": 2, @@ -54,20 +55,28 @@ "in_list_view": 1, "label": "To Date", "reqd": 1 + }, + { + "fieldname": "tax_withholding_group", + "fieldtype": "Link", + "in_list_view": 1, + "label": "Tax Withholding Group", + "options": "Tax Withholding Group" } ], "index_web_pages_for_search": 1, "istable": 1, "links": [], - "modified": "2024-03-27 13:10:52.708165", + "modified": "2025-06-29 05:31:05.120377", "modified_by": "Administrator", "module": "Accounts", "name": "Tax Withholding Rate", "owner": "Administrator", "permissions": [], "quick_entry": 1, + "row_format": "Dynamic", "sort_field": "creation", "sort_order": "DESC", "states": [], "track_changes": 1 -} \ No newline at end of file +} diff --git a/erpnext/accounts/doctype/tax_withholding_rate/tax_withholding_rate.py b/erpnext/accounts/doctype/tax_withholding_rate/tax_withholding_rate.py index 35d4e63ecca..984db8016ae 100644 --- a/erpnext/accounts/doctype/tax_withholding_rate/tax_withholding_rate.py +++ b/erpnext/accounts/doctype/tax_withholding_rate/tax_withholding_rate.py @@ -20,6 +20,7 @@ class TaxWithholdingRate(Document): parentfield: DF.Data parenttype: DF.Data single_threshold: DF.Float + tax_withholding_group: DF.Link | None tax_withholding_rate: DF.Float to_date: DF.Date # end: auto-generated types diff --git a/erpnext/accounts/general_ledger.py b/erpnext/accounts/general_ledger.py index a74b982754f..47323ad0f40 100644 --- a/erpnext/accounts/general_ledger.py +++ b/erpnext/accounts/general_ledger.py @@ -210,19 +210,20 @@ def distribute_gl_based_on_cost_center_allocation(gl_map, precision=None, from_r for d in gl_map: cost_center = d.get("cost_center") + cost_center_allocation = get_cost_center_allocation_data( + gl_map[0]["company"], gl_map[0]["posting_date"], cost_center + ) + + if not cost_center_allocation: + new_gl_map.append(d) + continue + # Validate budget against main cost center if not from_repost: validate_expense_against_budget( d, expense_amount=flt(d.debit, precision) - flt(d.credit, precision) ) - cost_center_allocation = get_cost_center_allocation_data( - gl_map[0]["company"], gl_map[0]["posting_date"], cost_center - ) - if not cost_center_allocation: - new_gl_map.append(d) - continue - if d.account == round_off_account: d.cost_center = cost_center_allocation[0][0] new_gl_map.append(d) @@ -406,7 +407,7 @@ def save_entries(gl_map, adv_adj, update_outstanding, from_repost=False): dimension_filter_map = get_dimension_filter_map() if gl_map: - check_freezing_date(gl_map[0]["posting_date"], adv_adj) + check_freezing_date(gl_map[0]["posting_date"], gl_map[0]["company"], adv_adj) is_opening = any(d.get("is_opening") == "Yes" for d in gl_map) if gl_map[0]["voucher_type"] != "Period Closing Voucher": validate_against_pcv(is_opening, gl_map[0]["posting_date"], gl_map[0]["company"]) @@ -426,7 +427,11 @@ def make_entry(args, adv_adj, update_outstanding, from_repost=False): gle.flags.notify_update = False gle.submit() - if not from_repost and gle.voucher_type != "Period Closing Voucher": + if ( + not from_repost + and gle.voucher_type != "Period Closing Voucher" + and (gle.is_cancelled == 0 or gle.voucher_type == "Journal Entry") + ): validate_expense_against_budget(args) @@ -767,7 +772,7 @@ def make_reverse_gl_entries( make_entry(new_gle, adv_adj, "Yes") -def check_freezing_date(posting_date, adv_adj=False): +def check_freezing_date(posting_date, company, adv_adj=False): """ Nobody can do GL Entries where posting date is before freezing date except authorized person @@ -776,17 +781,17 @@ def check_freezing_date(posting_date, adv_adj=False): Hence stop admin to bypass if accounts are freezed """ if not adv_adj: - acc_frozen_upto = frappe.get_single_value("Accounts Settings", "acc_frozen_upto") - if acc_frozen_upto: - frozen_accounts_modifier = frappe.get_single_value( - "Accounts Settings", "frozen_accounts_modifier" + acc_frozen_till_date = frappe.db.get_value("Company", company, "accounts_frozen_till_date") + if acc_frozen_till_date: + frozen_accounts_modifier = frappe.db.get_value( + "Company", company, "role_allowed_for_frozen_entries" ) - if getdate(posting_date) <= getdate(acc_frozen_upto) and ( + if getdate(posting_date) <= getdate(acc_frozen_till_date) and ( frozen_accounts_modifier not in frappe.get_roles() or frappe.session.user == "Administrator" ): frappe.throw( _("You are not authorized to add or update entries before {0}").format( - formatdate(acc_frozen_upto) + formatdate(acc_frozen_till_date) ) ) diff --git a/erpnext/accounts/letterhead/company_letterhead.html b/erpnext/accounts/letterhead/company_letterhead.html index f4b8db863f6..7cdf58cb6e0 100644 --- a/erpnext/accounts/letterhead/company_letterhead.html +++ b/erpnext/accounts/letterhead/company_letterhead.html @@ -1,108 +1,108 @@ - - - + + + - - {{ company_address.get("address_line1") or "" }}
    - {% if company_address.get("address_line2") %}{{ company_address.get("address_line2") }}
    {% endif %} - {{ company_address.get("city") or "" }}, {{ company_address.get("state") or "" }} {{ company_address.get("pincode") or "" }}, {{ company_address.get("country") or "" }}
    - {% endif %} - + - - +
    + {{ doc.doctype }} + {{ doc.name }} +
    + {% if website %} +
    + {{ _("Website:") }} + {{ website }} +
    + {% endif %} {% if email %} +
    + {{ _("Email:") }} + {{ email }} +
    + {% endif %} {% if phone_no %} +
    + {{ _("Contact:") }} + {{ phone_no }} +
    + {% endif %} + + +
    -
    - {% set company_logo = frappe.db.get_value("Company", doc.company, "company_logo") %} - {% if company_logo %} - Company Logo - {% endif %} -
    -
    +
    + {% set company_logo = frappe.db.get_value("Company", doc.company, "company_logo") %} {% if + company_logo %} + Company Logo + {% endif %} +
    +
    -
    - {{ doc.company }} -
    - {% if doc.company_address %} - {% set company_address = frappe.db.get_value("Address", doc.company_address, ["address_line1", "address_line2", "city", "state", "pincode", "country"], as_dict=True) %} +
    +
    {{ doc.company }}
    + {% if doc.company_address %} {% set company_address = frappe.db.get_value("Address", + doc.company_address, ["address_line1", "address_line2", "city", "state", "pincode", + "country"], as_dict=True) %} {% elif doc.billing_address %} {% set company_address = + frappe.db.get_value("Address", doc.billing_address, ["address_line1", "address_line2", "city", + "state", "pincode", "country"], as_dict=True) %} {% endif %} {% if company_address %} {{ + company_address.address_line1 or "" }}
    + {% if company_address.address_line2 %} {{ company_address.address_line2 }}
    + {% endif %} {{ company_address.city or "" }}, {{ company_address.state or "" }} {{ + company_address.pincode or "" }}, {{ company_address.country or ""}}
    + {% endif %} +
    + {% set website = frappe.db.get_value("Company", doc.company, "website") %} {% set email = + frappe.db.get_value("Company", doc.company, "email") %} {% set phone_no = + frappe.db.get_value("Company", doc.company, "phone_no") %} - - {% set company_details = frappe.db.get_value("Company", doc.company, ["website", "email", "phone_no"], as_dict=True) %} - -
    - {{ _("Invoice:") }} - {{ doc.name }} -
    - {% if company_details.website %} -
    - {{ _("Website:") }} - {{ company_details.website }} -
    - {% endif %} - {% if company_details.email %} -
    - {{ _("Email:") }} - {{ company_details.email }} -
    - {% endif %} - {% if company_details.phone_no %} -
    - {{ _("Contact:") }} - {{ company_details.phone_no }} -
    - {% endif %} -
    diff --git a/erpnext/accounts/letterhead/company_letterhead_grey.html b/erpnext/accounts/letterhead/company_letterhead_grey.html index 3736c19084f..a46d33ebd95 100644 --- a/erpnext/accounts/letterhead/company_letterhead_grey.html +++ b/erpnext/accounts/letterhead/company_letterhead_grey.html @@ -1,7 +1,7 @@ \n\t
    \n\t\t\n\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\n\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\n \n\t\t\t\t\n\t\t\t\t\n\t\t\t\n\t\t
    \n\t\t\t\t\t{{ _(\"Customer Name\") }}: {{doc.customer_name }}\n\t\t\t\t\n\t\t\t\t\t{{ _(\"Payment Due Date\") }}: {{\n\t\t\t\t\tfrappe.utils.format_date(doc.due_date) }}\n\t\t\t\t
    {{ _(\"Invoice Number\") }}: {{ doc.name }}\n\t\t\t\t\t{{ _(\"Invoice Date\") }}: {{\n\t\t\t\t\tfrappe.utils.format_date(doc.posting_date) }}\n\t\t\t\t
    {{ _(\"Bill From\") }}:
    \n\t\t\t\t\t{% if doc.company_address %}\n {% set company_address = frappe.db.get_value(\"Address\", doc.company_address, [\"address_line1\", \"address_line2\", \"city\", \"state\", \"pincode\", \"country\"], as_dict=True) %}\n {{ doc.company }}
    \n {{ company_address.get(\"address_line1\") or \"\" }}
    \n {% if company_address.get(\"address_line2\") %}{{ company_address.get(\"address_line2\") }}
    {% endif %}\n {{ company_address.get(\"city\") or \"\" }}, {{ company_address.get(\"state\") or \"\" }} {{ company_address.get(\"pincode\") or \"\" }}, {{ company_address.get(\"country\") or \"\" }}
    \n {% endif %}\n\t\t\t\t
    {{ _(\"Bill To\") }}:
    \n\t\t\t\t {% if doc.customer_address %}\n\t\t\t\t\t\t{% set customer_address = frappe.db.get_value(\"Address\", doc.customer_address, [\"address_line1\", \"address_line2\", \"city\", \"state\", \"pincode\", \"country\"], as_dict=True) %}\n {{ doc.customer_name }}
    \n\t\t\t\t\t\t{{ customer_address.address_line1 or \"\" }}
    \n\t\t\t\t\t\t{% if customer_address.address_line2 %}{{ customer_address.address_line2 }}
    {% endif %}\n\t\t\t\t\t\t{{ customer_address.city or \"\" }} {{ customer_address.state or \"\" }} {{ customer_address.pincode or \"\" }} {{ customer_address.country or \"\" }}
    \n\t\t\t\t\t{% endif %}\n\t\t\t\t
    \n\n\t\t\n\t\t{% set item_naming_by = frappe.db.get_single_value(\"Stock Settings\", \"item_naming_by\") %}\n\t\t\n\t\t\t\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t{% if item_naming_by != \"Item Code\" %}\n\t\t\t\t\t\t\n\t\t\t\t\t{% endif %}\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\n\t\t\t\n\t\t\t\n\t\t\t\t{% for item in doc.items %}\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t{% if item_naming_by != \"Item Code\" %}\n\t\t\t\t\t\t\n\t\t\t\t\t{% endif %}\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\n\t\t\t\t{% endfor %}\n\t\t\t\n\t\t
    {{ _(\"No\") }}{{ _(\"Item\") }}{{ _(\"Item Code\") }}{{ _(\"Quantity\") }}{{ _(\"Rate\") }}{{ _(\"Amount\") }}
    {{ loop.index }}{{ item.item_name }}{{ item.item_code }}{{ item.get_formatted(\"qty\", 0) }} {{ item.uom }}{{ item.get_formatted(\"net_rate\", doc) }}\n\t\t\t\t\t\t{{ item.get_formatted(\"net_amount\", doc) }}\n\t\t\t\t\t
    \n\n\t\t\n\t\t\n\t\t\t\n\t\t\t\n\t\t\t\n\t\t
    \n\t\t\t\t

    {{ _(\"Total in words\") }}

    \n\t\t\t\t
    {{ doc.in_words }}
    \n\t\t\t
    \n\t\t\t\t \n\t\t\t\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t{%- if doc.apply_discount_on == \"Net Total\" -%}\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t{%- endif -%}\n\t\t\t\t\t{%- for tax in doc.taxes -%}\n\t\t\t\t\t\t{%- if (tax.tax_amount or print_settings.print_taxes_with_zero_amount) and (not tax.included_in_print_rate or doc.flags.show_inclusive_tax_in_print) -%}\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t{%- endif -%}\n\t\t\t\t\t{%- endfor -%}\n\t\t\t\t\t{%- if doc.apply_discount_on == \"Grand Total\" -%}\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t{%- endif -%}\n\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t
    {{ _(\"Sub Total:\") }}
    {{ doc.get_formatted(\"total\", doc) }}
    \n\t\t\t\t\t\t\t\t
    {{ _(\"Discount\") }} ({{ doc.additional_discount_percentage }}%):\n\t\t\t\t\t\t\t
    {{ doc.get_formatted(\"discount_amount\", doc) }}
    {{ tax.get_formatted(\"description\") }} ({{ tax.get_formatted(\"rate\") }}%):
    {{ tax.get_formatted(\"tax_amount\") }}
    \n\t\t\t\t\t\t\t\t
    {{ _(\"Discount\") }} ({{ doc.additional_discount_percentage }}%):\n\t\t\t\t\t\t\t
    {{ doc.get_formatted(\"discount_amount\", doc) }}
    {{ _(\"Grand Total:\") }}{{ doc.get_formatted(\"grand_total\", doc) }}
    \n\t\t\t
    \n\n\t\t\n\t\t
    \n\t\t\t{% if doc.terms %}\n\t\t\t
    \n\t\t\t\t
    {{ _(\"Terms and Conditions\") }}
    \n\t\t\t\t{{ doc.terms}}\n\t\t\t
    \n\t\t\t{% endif %}\n\t
    \n
    \n{% endfor %}\n", + "idx": 0, + "line_breaks": 0, + "margin_bottom": 15.0, + "margin_left": 15.0, + "margin_right": 15.0, + "margin_top": 15.0, + "modified": "2025-11-30 16:58:32.571054", + "modified_by": "Administrator", + "module": "Accounts", + "name": "POS Invoice Standard", + "owner": "Administrator", + "page_number": "Hide", + "pdf_generator": "wkhtmltopdf", + "print_format_builder": 0, + "print_format_builder_beta": 0, + "print_format_for": "DocType", + "print_format_type": "Jinja", + "raw_printing": 0, + "show_section_headings": 0, + "standard": "Yes" +} diff --git a/erpnext/accounts/print_format/pos_invoice_with_item_image/__init__.py b/erpnext/accounts/print_format/pos_invoice_with_item_image/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/erpnext/accounts/print_format/pos_invoice_with_item_image/pos_invoice_with_item_image.json b/erpnext/accounts/print_format/pos_invoice_with_item_image/pos_invoice_with_item_image.json new file mode 100644 index 00000000000..ae878a47c77 --- /dev/null +++ b/erpnext/accounts/print_format/pos_invoice_with_item_image/pos_invoice_with_item_image.json @@ -0,0 +1,33 @@ +{ + "absolute_value": 0, + "align_labels_right": 0, + "creation": "2025-11-30 17:22:25.000765", + "custom_format": 1, + "default_print_language": "en", + "disabled": 0, + "doc_type": "POS Invoice", + "docstatus": 0, + "doctype": "Print Format", + "font_size": 14, + "html": "{%- macro add_header(page_num, max_pages, doc, letter_head, no_letterhead, footer, print_settings=None, print_heading_template=None) -%}\n\n{% if letter_head and not no_letterhead %}\n
    {{ letter_head }}
    \n{% endif %}\n{% if print_heading_template %}\n{{ frappe.render_template(print_heading_template, {\"doc\":doc}) }}\n{% endif %}\n{%- endmacro -%}\n\n{% for page in layout %}\n
    \n\t
    \n\t\t{{ add_header(loop.index, layout|len, doc, letter_head, no_letterhead, footer, print_settings) }}\n\t
    \n\t{%- if doc.meta.is_submittable and doc.docstatus==2-%}\n\t\t
    \n\t\t\t

    {{ _(\"CANCELLED\") }}

    \n\t\t
    \n\t{%- endif -%}\n\t{%- if doc.meta.is_submittable and doc.docstatus==0 and (print_settings==None or print_settings.add_draft_heading) -%}\n\t\t
    \n\t\t\t

    {{ _(\"DRAFT\") }}

    \n\t\t
    \n\t{%- endif -%}\n\n\t\n\n\t
    \n\t\t\n\t\t\t\n\t\t\t\t\n\n\t\t\t\t\n\t\t\t\n\t\t
    \n\t\t\t\t\t
    \n\t\t\t\t\t\t
    Customer Name:
    \n\t\t\t\t\t\t
    Bill to:
    \n\t\t\t\t\t
    \n\t\t\t\t\t
    \n\t\t\t\t\t\t
    {{ doc.customer_name }}
    \n\t\t\t\t\t\t
    \n \t\t\t\t\t{% if doc.customer_address %}\n \t\t\t\t\t\t{% set customer_address = frappe.db.get_value(\"Address\", doc.customer_address, [\"address_line1\", \"address_line2\", \"city\", \"state\", \"pincode\", \"country\"], as_dict=True) %}\n \t\t\t\t\t\t{{ customer_address.address_line1 or \"\" }}
    \n \t\t\t\t\t\t{% if customer_address.address_line2 %}{{ customer_address.address_line2 }}
    {% endif %}\n \t\t\t\t\t\t{{ customer_address.city or \"\" }} {{ customer_address.state or \"\" }} {{ customer_address.pincode or \"\" }} {{ customer_address.country or \"\" }}
    \n \t\t\t\t\t{% endif %}\n\t\t\t\t\t\t
    \n\n\t\t\t\t\t
    \n\t\t\t\t
    \n\t\t\t\t\t
    \n\t\t\t\t\t\t
    Invoice Number:
    \n\t\t\t\t\t
    \n\t\t\t\t\t
    \n\t\t\t\t\t\t
    {{ doc.name }}
    \n\t\t\t\t\t
    \n\t\t\t\t\t
    \n\t\t\t\t\t\t
    Invoice Date:
    \n\t\t\t\t\t
    \n\t\t\t\t\t
    \n\t\t\t\t\t\t
    {{ frappe.utils.format_date(doc.posting_date) }}
    \n\t\t\t\t\t
    \n\t\t\t\t\t
    \n\t\t\t\t\t\t
    Payment Due Date:
    \n\t\t\t\t\t
    \n\t\t\t\t\t
    \n\t\t\t\t\t\t
    {{ frappe.utils.format_date(doc.due_date) }}
    \n\t\t\t\t\t
    \n\t\t\t\t
    \n\n\t\t\n\t\t{% set item_naming_by = frappe.db.get_single_value(\"Stock Settings\", \"item_naming_by\") %}\n\t\t\n\t\t\t\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t{% if item_naming_by != \"Item Code\" %}\n\t\t\t\t\t\t\n\t\t\t\t\t{% endif %}\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\n\t\t\t\n\t\t\t\n\t\t\t\t{% for item in doc.items %}\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t{% if item_naming_by != \"Item Code\" %}\n\t\t\t\t\t\t\n\t\t\t\t\t{% endif %}\n\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\n\t\t\t\t{% endfor %}\n\t\t\t\n\t\t
    {{ _(\"No\") }}{{ _(\"Item\") }}{{ _(\"Item Code\") }}{{ _(\"Quantity\") }}{{ _(\"Rate\") }}{{ _(\"Amount\") }}
    {{ loop.index }}\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t{% if item.image %}\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t{% endif %}\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t{{ item.item_name }}\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t
    \n\t\t\t\t\t
    {{ item.item_code }}{{ item.get_formatted(\"qty\", 0) }} {{ item.uom }}{{ item.get_formatted(\"net_rate\", doc) }}{{ item.get_formatted(\"net_amount\", doc) }}
    \n\n\t\t
    \n\t\t\t\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\n\n\t\t\t\t{%- if doc.apply_discount_on == \"Net Total\" -%}\n\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t{%- endif -%}\n\t\t\t\t{%- for tax in doc.taxes -%}\n\t\t\t\t\t{%- if (tax.tax_amount or print_settings.print_taxes_with_zero_amount) and (not tax.included_in_print_rate or doc.flags.show_inclusive_tax_in_print) -%}\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t{%- endif -%}\n\t\t\t\t{%- endfor -%}\n\t\t\t\t{%- if doc.apply_discount_on == \"Grand Total\" -%}\n\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t{%- endif -%}\n\t\t\t
    {{ _(\"Sub Total:\") }}{{ doc.get_formatted(\"total\", doc) }}
    \n\t\t\t\t\t\t\t{{ _(\"Discount\") }} ({{ doc.additional_discount_percentage }}%):\n\t\t\t\t\t\t{{ doc.get_formatted(\"discount_amount\", doc) }}
    {{ tax.get_formatted(\"description\") }} ({{ tax.get_formatted(\"rate\") }}%):{{ tax.get_formatted(\"tax_amount\") }}
    \n\t\t\t\t\t\t\t{{ _(\"Discount\") }} ({{ doc.additional_discount_percentage }}%):\n\t\t\t\t\t\t{{ doc.get_formatted(\"discount_amount\", doc) }}
    \n\t\t
    \n\n\t\t
    \n\t\t\t\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\n\t\t\t
    \n\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t {{ _(\"In Words: \") }}{{ doc.in_words }}\n\t\t\t\t\t\t
    \n\t\t\t\t\t
    {{ _(\"Grand Total:\") }}\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t{{ doc.get_formatted(\"grand_total\", doc) }}\n\t\t\t\t\t\t\n\t\t\t\t\t
    \n\t\t
    \n\n\n\t\t\n\t\t{% if doc.terms %}\n\t\t
    \n\t\t\t
    {{ _(\"Terms and Conditions\") }}
    \n\t\t\t{{ doc.terms}}\n\t\t
    \n\t\t{% endif %}\n\t
    \n
    \n{% endfor %}\n", + "idx": 0, + "line_breaks": 0, + "margin_bottom": 15.0, + "margin_left": 15.0, + "margin_right": 15.0, + "margin_top": 15.0, + "modified": "2025-11-30 17:22:25.000765", + "modified_by": "Administrator", + "module": "Accounts", + "name": "POS Invoice with Item Image", + "owner": "Administrator", + "page_number": "Hide", + "pdf_generator": "wkhtmltopdf", + "print_format_builder": 0, + "print_format_builder_beta": 0, + "print_format_for": "DocType", + "print_format_type": "Jinja", + "raw_printing": 0, + "show_section_headings": 0, + "standard": "Yes" +} diff --git a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py index 2e507aef592..75e81d3b04c 100644 --- a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py +++ b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py @@ -1384,27 +1384,14 @@ class InitSQLProceduresForAR: amount_in_account_currency {_currency_type}) engine=memory; """ - # Function - genkey_function_name = "ar_genkey" - genkey_function_sql = f""" - create function `{genkey_function_name}`(rec row type of `{_row_def_table_name}`, allocate bool) returns char(40) - begin - if allocate then - return sha1(concat_ws(',', rec.account, rec.against_voucher_type, rec.against_voucher_no, rec.party)); - else - return sha1(concat_ws(',', rec.account, rec.voucher_type, rec.voucher_no, rec.party)); - end if; - end - """ - # Procedures init_procedure_name = "ar_init_tmp_table" init_procedure_sql = f""" create procedure ar_init_tmp_table(in ple row type of `{_row_def_table_name}`) begin - if not exists (select name from `{_voucher_balance_name}` where name = `{genkey_function_name}`(ple, false)) + if not exists (select name from `{_voucher_balance_name}` where name = sha1(concat_ws(',', ple.account, ple.against_voucher_type, ple.against_voucher_no, ple.party))) then - insert into `{_voucher_balance_name}` values (`{genkey_function_name}`(ple, false), ple.voucher_type, ple.voucher_no, ple.party, ple.account, ple.posting_date, ple.account_currency, ple.cost_center, 0, 0, 0, 0, 0, 0); + insert into `{_voucher_balance_name}` values (sha1(concat_ws(',', ple.account, ple.against_voucher_type, ple.against_voucher_no, ple.party)), ple.voucher_type, ple.voucher_no, ple.party, ple.account, ple.posting_date, ple.account_currency, ple.cost_center, 0, 0, 0, 0, 0, 0); end if; end; """ @@ -1446,16 +1433,13 @@ class InitSQLProceduresForAR: end if; - insert into `{_voucher_balance_name}` values (`{genkey_function_name}`(ple, true), ple.against_voucher_type, ple.against_voucher_no, ple.party, ple.account, ple.posting_date, ple.account_currency,'', invoiced, paid, 0, invoiced_in_account_currency, paid_in_account_currency, 0); + insert into `{_voucher_balance_name}` values (sha1(concat_ws(',', ple.account, ple.voucher_type, ple.voucher_no, ple.party)), ple.against_voucher_type, ple.against_voucher_no, ple.party, ple.account, ple.posting_date, ple.account_currency,'', invoiced, paid, 0, invoiced_in_account_currency, paid_in_account_currency, 0); end; """ def __init__(self): existing_procedures = frappe.db.get_routines() - if self.genkey_function_name not in existing_procedures: - frappe.db.sql(self.genkey_function_sql) - if self.init_procedure_name not in existing_procedures: frappe.db.sql(self.init_procedure_sql) diff --git a/erpnext/accounts/report/customer_ledger_summary/customer_ledger_summary.py b/erpnext/accounts/report/customer_ledger_summary/customer_ledger_summary.py index 6762d6d9cf3..1259430834e 100644 --- a/erpnext/accounts/report/customer_ledger_summary/customer_ledger_summary.py +++ b/erpnext/accounts/report/customer_ledger_summary/customer_ledger_summary.py @@ -69,12 +69,18 @@ class PartyLedgerSummaryReport: party_type = self.filters.party_type doctype = qb.DocType(party_type) + + party_details_fields = [ + doctype.name.as_("party"), + f"{scrub(party_type)}_name", + f"{scrub(party_type)}_group", + ] + + if party_type == "Customer": + party_details_fields.append(doctype.territory) + conditions = self.get_party_conditions(doctype) - query = ( - qb.from_(doctype) - .select(doctype.name.as_("party"), f"{scrub(party_type)}_name") - .where(Criterion.all(conditions)) - ) + query = qb.from_(doctype).select(*party_details_fields).where(Criterion.all(conditions)) from frappe.desk.reportview import build_match_conditions @@ -153,6 +159,31 @@ class PartyLedgerSummaryReport: credit_or_debit_note = "Credit Note" if self.filters.party_type == "Customer" else "Debit Note" + if self.filters.party_type == "Customer": + columns += [ + { + "label": _("Customer Group"), + "fieldname": "customer_group", + "fieldtype": "Link", + "options": "Customer Group", + }, + { + "label": _("Territory"), + "fieldname": "territory", + "fieldtype": "Link", + "options": "Territory", + }, + ] + else: + columns += [ + { + "label": _("Supplier Group"), + "fieldname": "supplier_group", + "fieldtype": "Link", + "options": "Supplier Group", + } + ] + columns += [ { "label": _("Opening Balance"), @@ -214,35 +245,6 @@ class PartyLedgerSummaryReport: }, ] - # Hidden columns for handling 'User Permissions' - if self.filters.party_type == "Customer": - columns += [ - { - "label": _("Territory"), - "fieldname": "territory", - "fieldtype": "Link", - "options": "Territory", - "hidden": 1, - }, - { - "label": _("Customer Group"), - "fieldname": "customer_group", - "fieldtype": "Link", - "options": "Customer Group", - "hidden": 1, - }, - ] - else: - columns += [ - { - "label": _("Supplier Group"), - "fieldname": "supplier_group", - "fieldtype": "Link", - "options": "Supplier Group", - "hidden": 1, - } - ] - columns.append({"label": _("Dr/Cr"), "fieldname": "dr_or_cr", "fieldtype": "Data", "width": 100}) return columns diff --git a/erpnext/accounts/report/customer_ledger_summary/test_customer_ledger_summary.py b/erpnext/accounts/report/customer_ledger_summary/test_customer_ledger_summary.py index 78174b097bd..14e88afca39 100644 --- a/erpnext/accounts/report/customer_ledger_summary/test_customer_ledger_summary.py +++ b/erpnext/accounts/report/customer_ledger_summary/test_customer_ledger_summary.py @@ -186,6 +186,8 @@ class TestCustomerLedgerSummary(AccountsTestMixin, IntegrationTestCase): expected = { "party": "_Test Customer", "customer_name": "_Test Customer", + "customer_group": "_Test Customer Group", + "territory": "_Test Territory", "party_name": "_Test Customer", "opening_balance": 0, "invoiced_amount": 100.0, @@ -213,6 +215,8 @@ class TestCustomerLedgerSummary(AccountsTestMixin, IntegrationTestCase): expected = { "party": "_Test Customer", "customer_name": "_Test Customer", + "customer_group": "_Test Customer Group", + "territory": "_Test Territory", "party_name": "_Test Customer", "opening_balance": 0, "invoiced_amount": 100.0, diff --git a/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py b/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py index 56b25cfe474..bcaf64b0574 100644 --- a/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py +++ b/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py @@ -5,7 +5,6 @@ import frappe from frappe import _ from frappe.utils import flt -from pypika import Order import erpnext from erpnext.accounts.report.item_wise_sales_register.item_wise_sales_register import ( @@ -41,16 +40,6 @@ def _execute(filters=None, additional_table_columns=None): tax_doctype="Purchase Taxes and Charges", ) - scrubbed_tax_fields = {} - - for tax in tax_columns: - scrubbed_tax_fields.update( - { - tax + " Rate": frappe.scrub(tax + " Rate"), - tax + " Amount": frappe.scrub(tax + " Amount"), - } - ) - po_pr_map = get_purchase_receipts_against_purchase_order(item_list) data = [] @@ -100,8 +89,8 @@ def _execute(filters=None, additional_table_columns=None): for tax, details in itemised_tax.get(d.name, {}).items(): row.update( { - scrubbed_tax_fields[tax + " Rate"]: details.get("tax_rate", 0), - scrubbed_tax_fields[tax + " Amount"]: details.get("tax_amount", 0), + f"{tax}_rate": details.get("tax_rate", 0), + f"{tax}_amount": details.get("tax_amount", 0), } ) if details.get("is_other_charges"): diff --git a/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py b/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py index cd0949721de..fa99ff8e42c 100644 --- a/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py +++ b/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py @@ -5,7 +5,7 @@ import frappe from frappe import _ from frappe.query_builder import functions as fn -from frappe.utils import cstr, flt +from frappe.utils import flt from frappe.utils.nestedset import get_descendants_of from frappe.utils.xlsxutils import handle_html @@ -32,15 +32,6 @@ def _execute(filters=None, additional_table_columns=None, additional_conditions= return columns, [], None, None, None, 0 itemised_tax, tax_columns = get_tax_accounts(item_list, columns, company_currency) - scrubbed_tax_fields = {} - - for tax in tax_columns: - scrubbed_tax_fields.update( - { - tax + " Rate": frappe.scrub(tax + " Rate"), - tax + " Amount": frappe.scrub(tax + " Amount"), - } - ) mode_of_payments = get_mode_of_payments(set(d.parent for d in item_list)) so_dn_map = get_delivery_notes_against_sales_order(item_list) @@ -101,8 +92,8 @@ def _execute(filters=None, additional_table_columns=None, additional_conditions= for tax, details in itemised_tax.get(d.name, {}).items(): row.update( { - scrubbed_tax_fields[tax + " Rate"]: details.get("tax_rate", 0), - scrubbed_tax_fields[tax + " Amount"]: details.get("tax_amount", 0), + f"{tax}_rate": details.get("tax_rate", 0), + f"{tax}_amount": details.get("tax_amount", 0), } ) if details.get("is_other_charges"): @@ -567,15 +558,24 @@ def get_tax_accounts( tax_details = query.run(as_dict=True) precision = frappe.get_precision(tax_doctype, "tax_amount", currency=company_currency) or 2 - tax_columns = set() + tax_columns = {} itemised_tax = {} + scrubbed_description_map = {} for row in tax_details: description = handle_html(row.description) or row.account_head + scrubbed_description = scrubbed_description_map.get(description) + if not scrubbed_description: + scrubbed_description = frappe.scrub(description) + scrubbed_description_map[description] = scrubbed_description + + if scrubbed_description not in tax_columns and row.amount: + # as description is text editor earlier and markup can break the column convention in reports + tax_columns[scrubbed_description] = description + rate = "NA" if row.rate == 0 else row.rate - tax_columns.add(description) itemised_tax.setdefault(row.item_row, {}).setdefault( - description, + scrubbed_description, frappe._dict( { "tax_rate": rate, @@ -585,14 +585,16 @@ def get_tax_accounts( ), ) - itemised_tax[row.item_row][description].tax_amount += flt(row.amount, precision) + itemised_tax[row.item_row][scrubbed_description].tax_amount += flt(row.amount, precision) - tax_columns = sorted(tax_columns) - for desc in tax_columns: + tax_columns_list = list(tax_columns.keys()) + tax_columns_list.sort() + for scrubbed_desc in tax_columns_list: + desc = tax_columns[scrubbed_desc] columns.append( { "label": _(desc + " Rate"), - "fieldname": frappe.scrub(desc + " Rate"), + "fieldname": f"{scrubbed_desc}_rate", "fieldtype": "Float", "width": 100, } @@ -601,7 +603,7 @@ def get_tax_accounts( columns.append( { "label": _(desc + " Amount"), - "fieldname": frappe.scrub(desc + " Amount"), + "fieldname": f"{scrubbed_desc}_amount", "fieldtype": "Currency", "options": "currency", "width": 100, @@ -639,7 +641,7 @@ def get_tax_accounts( }, ] - return itemised_tax, tax_columns + return itemised_tax, tax_columns_list def get_tax_details_query(doctype, tax_doctype): @@ -756,5 +758,5 @@ def add_sub_total_row(item, total_row_map, group_by_value, tax_columns): total_row["percent_gt"] += item["percent_gt"] for tax in tax_columns: - total_row.setdefault(frappe.scrub(tax + " Amount"), 0.0) - total_row[frappe.scrub(tax + " Amount")] += flt(item[frappe.scrub(tax + " Amount")]) + total_row.setdefault(f"{tax}_amount", 0.0) + total_row[f"{tax}_amount"] += flt(item[f"{tax}_amount"]) diff --git a/erpnext/accounts/report/tax_withholding_details/tax_withholding_details.js b/erpnext/accounts/report/tax_withholding_details/tax_withholding_details.js index bdc98ab0ae3..36b8adf764c 100644 --- a/erpnext/accounts/report/tax_withholding_details/tax_withholding_details.js +++ b/erpnext/accounts/report/tax_withholding_details/tax_withholding_details.js @@ -14,9 +14,8 @@ frappe.query_reports["Tax Withholding Details"] = { fieldname: "party_type", label: __("Party Type"), fieldtype: "Select", - options: ["Supplier", "Customer"], - reqd: 1, - default: "Supplier", + options: ["", "Supplier", "Customer"], + default: "", on_change: function () { frappe.query_report.set_filter_value("party", ""); }, diff --git a/erpnext/accounts/report/tax_withholding_details/tax_withholding_details.py b/erpnext/accounts/report/tax_withholding_details/tax_withholding_details.py index 922f2ee6d61..e485dac114b 100644 --- a/erpnext/accounts/report/tax_withholding_details/tax_withholding_details.py +++ b/erpnext/accounts/report/tax_withholding_details/tax_withholding_details.py @@ -1,194 +1,112 @@ # Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors # For license information, please see license.txt - import frappe from frappe import _ -from frappe.utils import flt, getdate - -from erpnext.accounts.utils import get_currency_precision +from frappe.query_builder.functions import IfNull def execute(filters=None): - if filters.get("party_type") == "Customer": - party_naming_by = frappe.get_single_value("Selling Settings", "cust_master_name") - else: - party_naming_by = frappe.db.get_single_value("Buying Settings", "supp_master_name") - - filters["naming_series"] = party_naming_by - + """Generate Tax Withholding Details report""" validate_filters(filters) - ( - tds_docs, - tds_accounts, - tax_category_map, - journal_entry_party_map, - net_total_map, - ) = get_tds_docs(filters) + # Process and format data + data = get_tax_withholding_data(filters) columns = get_columns(filters) - res = get_result( - filters, tds_docs, tds_accounts, tax_category_map, journal_entry_party_map, net_total_map - ) - return columns, res + return columns, data def validate_filters(filters): - """Validate if dates are properly set""" + """Validate report filters""" filters = frappe._dict(filters or {}) + + if not filters.from_date or not filters.to_date: + frappe.throw(_("From Date and To Date are required")) + if filters.from_date > filters.to_date: frappe.throw(_("From Date must be before To Date")) -def get_result(filters, tds_docs, tds_accounts, tax_category_map, journal_entry_party_map, net_total_map): - party_map = get_party_pan_map(filters.get("party_type")) - tax_rate_map = get_tax_rate_map(filters) - gle_map = get_gle_map(tds_docs) - precision = get_currency_precision() +def get_tax_withholding_data(filters): + """Process entries into final report format""" + data = [] + entries = get_tax_withholding_entries(filters) + if not entries: + return data - out = [] - entries = {} - for name, details in gle_map.items(): - for entry in details: - tax_amount, total_amount, grand_total, base_total = 0, 0, 0, 0 - tax_withholding_category, rate = None, None - bill_no, bill_date = "", "" - party = entry.party or entry.against - posting_date = entry.posting_date - voucher_type = entry.voucher_type + doc_info = get_additional_doc_info(entries) + party_details = get_party_details(entries) - if voucher_type == "Journal Entry": - party_list = journal_entry_party_map.get(name) - if party_list: - party = party_list[0] + for entry in entries: + doc_details = frappe._dict() + if entry.taxable_name: + doc_details = doc_info.get((entry.taxable_doctype, entry.taxable_name), {}) - if entry.account in tds_accounts.keys(): - tax_amount += entry.credit - entry.debit - # infer tax withholding category from the account if it's the single account for this category - tax_withholding_category = tds_accounts.get(entry.account) - # or else the consolidated value from the voucher document - if not tax_withholding_category: - tax_withholding_category = tax_category_map.get((voucher_type, name)) - # or else from the party default - if not tax_withholding_category: - tax_withholding_category = party_map.get(party, {}).get("tax_withholding_category") + party_info = party_details.get((entry.party_type, entry.party), {}) - rate = get_tax_withholding_rates(tax_rate_map.get(tax_withholding_category, []), posting_date) + row = { + "section_code": entry.tax_withholding_category, + "entity_type": party_info.get("entity_type"), + "rate": entry.tax_rate, + "total_amount": entry.taxable_amount, + "grand_total": doc_details.get("grand_total", 0), + "base_total": doc_details.get("base_total", 0), + "tax_amount": entry.withholding_amount, + "transaction_date": entry.withholding_date, + "transaction_type": entry.taxable_doctype, + "ref_no": entry.taxable_name, + "taxable_date": entry.taxable_date, + "supplier_invoice_no": doc_details.get("bill_no"), + "supplier_invoice_date": doc_details.get("bill_date"), + "withholding_doctype": entry.withholding_doctype, + "withholding_name": entry.withholding_name, + "party_name": party_info.get("party_name"), + "tax_id": entry.tax_id, + "party": entry.party, + "party_type": entry.party_type, + } + data.append(row) - values = net_total_map.get((voucher_type, name)) - - if values: - if voucher_type == "Journal Entry" and tax_amount and rate: - # back calculate total amount from rate and tax_amount - base_total = min(flt(tax_amount / (rate / 100), precision=precision), values[0]) - total_amount = grand_total = base_total - - else: - if tax_amount and rate: - # back calculate total amount from rate and tax_amount - total_amount = flt((tax_amount * 100) / rate, precision=precision) - else: - total_amount = values[0] - - grand_total = values[1] - base_total = values[2] - - if voucher_type == "Purchase Invoice": - bill_no = values[3] - bill_date = values[4] - else: - total_amount += entry.credit - - if tax_amount: - if party_map.get(party, {}).get("party_type") == "Supplier": - party_name = "supplier_name" - party_type = "supplier_type" - else: - party_name = "customer_name" - party_type = "customer_type" - - row = { - "pan" if frappe.db.has_column(filters.party_type, "pan") else "tax_id": party_map.get( - party, {} - ).get("pan"), - "party": party_map.get(party, {}).get("name"), - } - - if filters.naming_series == "Naming Series": - row["party_name"] = party_map.get(party, {}).get(party_name) - - row.update( - { - "section_code": tax_withholding_category or "", - "entity_type": party_map.get(party, {}).get(party_type), - "rate": rate, - "total_amount": total_amount, - "grand_total": grand_total, - "base_total": base_total, - "tax_amount": tax_amount, - "transaction_date": posting_date, - "transaction_type": voucher_type, - "ref_no": name, - "supplier_invoice_no": bill_no, - "supplier_invoice_date": bill_date, - } - ) - - key = entry.voucher_no - if key in entries: - entries[key]["tax_amount"] += tax_amount - else: - entries[key] = row - out = list(entries.values()) - out.sort(key=lambda x: (x["section_code"], x["transaction_date"])) - - return out + # Sort by section code and transaction date + data.sort(key=lambda x: (x["section_code"] or "", x["transaction_date"] or "")) + return data -def get_party_pan_map(party_type): +def get_party_details(entries): + """Fetch party details in batch for all entries""" party_map = frappe._dict() + parties_by_type = {"Customer": set(), "Supplier": set()} - fields = ["name", "tax_withholding_category"] - if party_type == "Supplier": - fields += ["supplier_type", "supplier_name"] - else: - fields += ["customer_type", "customer_name"] + # Group parties by type + for entry in entries: + if entry.party_type in parties_by_type and entry.party: + parties_by_type[entry.party_type].add(entry.party) - if frappe.db.has_column(party_type, "pan"): - fields.append("pan") + # Batch fetch for each party type + for party_type, party_set in parties_by_type.items(): + if not party_type or not party_set: + continue - party_details = frappe.db.get_all(party_type, fields=fields) + doctype = frappe.qb.DocType(party_type) + fields = [doctype.name] - for party in party_details: - party.party_type = party_type - party_map[party.name] = party + if party_type == "Supplier": + fields.extend([doctype.supplier_type.as_("entity_type"), doctype.supplier_name.as_("party_name")]) + elif party_type == "Customer": + fields.extend([doctype.customer_type.as_("entity_type"), doctype.customer_name.as_("party_name")]) + + query = frappe.qb.from_(doctype).select(*fields).where(doctype.name.isin(party_set)) + party_details = query.run(as_dict=True) + + for party in party_details: + party_map[(party_type, party.name)] = party return party_map -def get_gle_map(documents): - # create gle_map of the form - # {"purchase_invoice": list of dict of all gle created for this invoice} - gle_map = {} - - gle = frappe.db.get_all( - "GL Entry", - {"voucher_no": ["in", documents], "is_cancelled": 0}, - ["credit", "debit", "account", "voucher_no", "posting_date", "voucher_type", "against", "party"], - ) - - for d in gle: - if d.voucher_no not in gle_map: - gle_map[d.voucher_no] = [d] - else: - gle_map[d.voucher_no].append(d) - - return gle_map - - def get_columns(filters): - pan = "pan" if frappe.db.has_column(filters.party_type, "pan") else "tax_id" + """Generate report columns based on filters""" columns = [ { "label": _("Section Code"), @@ -197,286 +115,190 @@ def get_columns(filters): "fieldtype": "Link", "width": 90, }, - {"label": _(frappe.unscrub(pan)), "fieldname": pan, "fieldtype": "Data", "width": 60}, + {"label": _("Tax Id"), "fieldname": "tax_id", "fieldtype": "Data", "width": 60}, + { + "label": _(f"{filters.get('party_type', 'Party')} Name"), + "fieldname": "party_name", + "fieldtype": "Data", + "width": 180, + }, + { + "label": _(filters.get("party_type", "Party")), + "fieldname": "party", + "fieldtype": "Dynamic Link", + "options": "party_type", + "width": 180, + }, + { + "label": _("Entity Type"), + "fieldname": "entity_type", + "fieldtype": "Data", + "width": 100, + }, + { + "label": _("Supplier Invoice No"), + "fieldname": "supplier_invoice_no", + "fieldtype": "Data", + "width": 120, + }, + { + "label": _("Supplier Invoice Date"), + "fieldname": "supplier_invoice_date", + "fieldtype": "Date", + "width": 120, + }, + { + "label": _("Tax Rate %"), + "fieldname": "rate", + "fieldtype": "Percent", + "width": 60, + }, + { + "label": _("Total Amount"), + "fieldname": "total_amount", + "fieldtype": "Currency", + "width": 120, + }, + { + "label": _("Base Total"), + "fieldname": "base_total", + "fieldtype": "Currency", + "width": 120, + }, + { + "label": _("Tax Amount"), + "fieldname": "tax_amount", + "fieldtype": "Currency", + "width": 120, + }, + { + "label": _("Grand Total"), + "fieldname": "grand_total", + "fieldtype": "Currency", + "width": 120, + }, + { + "label": _("Reference Date"), + "fieldname": "taxable_date", + "fieldtype": "Date", + "width": 100, + }, + { + "label": _("Transaction Type"), + "fieldname": "transaction_type", + "fieldtype": "Data", + "width": 130, + }, + { + "label": _("Reference No."), + "fieldname": "ref_no", + "fieldtype": "Dynamic Link", + "options": "transaction_type", + "width": 180, + }, + { + "label": _("Date of Transaction"), + "fieldname": "transaction_date", + "fieldtype": "Date", + "width": 100, + }, + { + "label": _("Withholding Document"), + "fieldname": "withholding_name", + "fieldtype": "Dynamic Link", + "options": "withholding_doctype", + "width": 150, + }, ] - if filters.naming_series == "Naming Series": - columns.append( - { - "label": _(filters.party_type + " Name"), - "fieldname": "party_name", - "fieldtype": "Data", - "width": 180, - } - ) - else: - columns.append( - { - "label": _(filters.get("party_type")), - "fieldname": "party", - "fieldtype": "Dynamic Link", - "options": "party_type", - "width": 180, - } - ) - - columns.extend( - [ - {"label": _("Entity Type"), "fieldname": "entity_type", "fieldtype": "Data", "width": 100}, - ] - ) - if filters.party_type == "Supplier": - columns.extend( - [ - { - "label": _("Supplier Invoice No"), - "fieldname": "supplier_invoice_no", - "fieldtype": "Data", - "width": 120, - }, - { - "label": _("Supplier Invoice Date"), - "fieldname": "supplier_invoice_date", - "fieldtype": "Date", - "width": 120, - }, - ] - ) - - columns.extend( - [ - { - "label": _("TDS Rate %") if filters.get("party_type") == "Supplier" else _("TCS Rate %"), - "fieldname": "rate", - "fieldtype": "Percent", - "width": 60, - }, - { - "label": _("Total Amount"), - "fieldname": "total_amount", - "fieldtype": "Float", - "width": 120, - }, - { - "label": _("Base Total"), - "fieldname": "base_total", - "fieldtype": "Float", - "width": 120, - }, - { - "label": _("TDS Amount") if filters.get("party_type") == "Supplier" else _("TCS Amount"), - "fieldname": "tax_amount", - "fieldtype": "Float", - "width": 120, - }, - { - "label": _("Grand Total"), - "fieldname": "grand_total", - "fieldtype": "Float", - "width": 120, - }, - {"label": _("Transaction Type"), "fieldname": "transaction_type", "width": 130}, - { - "label": _("Reference No."), - "fieldname": "ref_no", - "fieldtype": "Dynamic Link", - "options": "transaction_type", - "width": 180, - }, - { - "label": _("Date of Transaction"), - "fieldname": "transaction_date", - "fieldtype": "Date", - "width": 100, - }, - ] - ) - return columns -def get_tds_docs(filters): - tds_documents = [] - purchase_invoices = [] - sales_invoices = [] - payment_entries = [] - journal_entries = [] - tax_category_map = frappe._dict() - net_total_map = frappe._dict() - journal_entry_party_map = frappe._dict() - bank_accounts = frappe.get_all("Account", {"is_group": 0, "account_type": "Bank"}, pluck="name") - - _tds_accounts = frappe.get_all( - "Tax Withholding Account", - {"company": filters.get("company")}, - ["account", "parent"], - ) - tds_accounts = {} - for tds_acc in _tds_accounts: - # if it turns out not to be the only tax withholding category, then don't include in the map - if tds_acc["account"] in tds_accounts: - tds_accounts[tds_acc["account"]] = None - else: - tds_accounts[tds_acc["account"]] = tds_acc["parent"] - - tds_docs = get_tds_docs_query(filters, bank_accounts, list(tds_accounts.keys())).run(as_dict=True) - - for d in tds_docs: - if d.voucher_type == "Purchase Invoice": - purchase_invoices.append(d.voucher_no) - if d.voucher_type == "Sales Invoice": - sales_invoices.append(d.voucher_no) - elif d.voucher_type == "Payment Entry": - payment_entries.append(d.voucher_no) - elif d.voucher_type == "Journal Entry": - journal_entries.append(d.voucher_no) - - tds_documents.append(d.voucher_no) - - if purchase_invoices: - get_doc_info(purchase_invoices, "Purchase Invoice", tax_category_map, net_total_map) - - if sales_invoices: - get_doc_info(sales_invoices, "Sales Invoice", tax_category_map, net_total_map) - - if payment_entries: - get_doc_info(payment_entries, "Payment Entry", tax_category_map, net_total_map) - - if journal_entries: - journal_entry_party_map = get_journal_entry_party_map(journal_entries) - get_doc_info(journal_entries, "Journal Entry", tax_category_map, net_total_map) - - return ( - tds_documents, - tds_accounts, - tax_category_map, - journal_entry_party_map, - net_total_map, - ) - - -def get_tds_docs_query(filters, bank_accounts, tds_accounts): - if not tds_accounts: - frappe.throw( - _("No {0} Accounts found for this company.").format(frappe.bold(_("Tax Withholding"))), - title=_("Accounts Missing Error"), - ) - gle = frappe.qb.DocType("GL Entry") +def get_tax_withholding_entries(filters): + twe = frappe.qb.DocType("Tax Withholding Entry") query = ( - frappe.qb.from_(gle) - .select("voucher_no", "voucher_type", "against", "party") - .where(gle.is_cancelled == 0) + frappe.qb.from_(twe) + .select( + twe.company, + twe.party_type, + twe.party, + IfNull(twe.tax_id, "").as_("tax_id"), + twe.tax_withholding_category, + IfNull(twe.tax_withholding_group, "").as_("tax_withholding_group"), + twe.taxable_amount, + twe.tax_rate, + twe.withholding_amount, + IfNull(twe.taxable_doctype, "").as_("taxable_doctype"), + IfNull(twe.taxable_name, "").as_("taxable_name"), + twe.taxable_date, + IfNull(twe.under_withheld_reason, "").as_("under_withheld_reason"), + IfNull(twe.lower_deduction_certificate, "").as_("lower_deduction_certificate"), + IfNull(twe.withholding_doctype, "").as_("withholding_doctype"), + IfNull(twe.withholding_name, "").as_("withholding_name"), + twe.withholding_date, + twe.status, + ) + .where(twe.docstatus == 1) + .where(twe.withholding_date >= filters.from_date) + .where(twe.withholding_date <= filters.to_date) + .where(IfNull(twe.withholding_name, "") != "") + .where(twe.status != "Duplicate") ) - if filters.get("from_date"): - query = query.where(gle.posting_date >= filters.get("from_date")) - if filters.get("to_date"): - query = query.where(gle.posting_date <= filters.get("to_date")) + if filters.get("company"): + query = query.where(twe.company == filters.get("company")) + + if filters.get("party_type"): + query = query.where(twe.party_type == filters.get("party_type")) if filters.get("party"): - party = [filters.get("party")] - jv_condition = gle.against.isin(party) | ( - (gle.voucher_type == "Journal Entry") & (gle.party == filters.get("party")) - ) - else: - party = frappe.get_all(filters.get("party_type"), pluck="name") - jv_condition = gle.against.isin(party) | ( - (gle.voucher_type == "Journal Entry") - & ((gle.party_type == filters.get("party_type")) | (gle.party_type == "")) - ) + query = query.where(twe.party == filters.get("party")) - query.where((gle.account.isin(tds_accounts) & jv_condition) | gle.party.isin(party)) - if bank_accounts: - query = query.where( - gle.against.notin(bank_accounts) & (gle.account.isin(tds_accounts) & jv_condition) - | gle.party.isin(party) - ) - - return query + return query.run(as_dict=True) -def get_journal_entry_party_map(journal_entries): - journal_entry_party_map = {} - for d in frappe.db.get_all( - "Journal Entry Account", - { - "parent": ("in", journal_entries), - "party_type": ("in", ("Supplier", "Customer")), - "party": ("is", "set"), - }, - ["parent", "party"], - ): - if d.parent not in journal_entry_party_map: - journal_entry_party_map[d.parent] = [] - journal_entry_party_map[d.parent].append(d.party) - - return journal_entry_party_map - - -def get_doc_info(vouchers, doctype, tax_category_map, net_total_map=None): - common_fields = ["name"] - fields_dict = { - "Purchase Invoice": [ - "tax_withholding_category", - "base_tax_withholding_net_total", - "grand_total", - "base_total", - "bill_no", - "bill_date", - ], - "Sales Invoice": ["base_net_total", "grand_total", "base_total"], - "Payment Entry": [ - "tax_withholding_category", - "paid_amount", - "paid_amount_after_tax", - "base_paid_amount", - ], - "Journal Entry": ["tax_withholding_category", "total_debit"], +def get_additional_doc_info(entries): + """Fetch additional document information in batch""" + doc_info = {} + docs_by_type = { + "Purchase Invoice": set(), + "Sales Invoice": set(), + "Payment Entry": set(), + "Journal Entry": set(), } - entries = frappe.get_all( - doctype, filters={"name": ("in", vouchers)}, fields=common_fields + fields_dict[doctype] - ) + # Group documents by type + for entry in entries: + if entry.taxable_name and entry.taxable_doctype in docs_by_type: + docs_by_type[entry.taxable_doctype].add(entry.taxable_name) + + for doctype_name, voucher_set in docs_by_type.items(): + if voucher_set: + _fetch_doc_info(doctype_name, voucher_set, doc_info) + + return doc_info + + +def _fetch_doc_info(doctype_name, voucher_set, doc_info): + doctype = frappe.qb.DocType(doctype_name) + fields = [doctype.name] + + # Add doctype-specific fields + if doctype_name == "Purchase Invoice": + fields.extend([doctype.grand_total, doctype.base_total, doctype.bill_no, doctype.bill_date]) + elif doctype_name == "Sales Invoice": + fields.extend([doctype.grand_total, doctype.base_total]) + elif doctype_name == "Payment Entry": + fields.extend( + [doctype.paid_amount_after_tax.as_("grand_total"), doctype.base_paid_amount.as_("base_total")] + ) + elif doctype_name == "Journal Entry": + fields.extend([doctype.total_debit.as_("grand_total"), doctype.total_debit.as_("base_total")]) + else: + return + + query = frappe.qb.from_(doctype).select(*fields).where(doctype.name.isin(voucher_set)) + entries = query.run(as_dict=True) for entry in entries: - tax_category_map[(doctype, entry.name)] = entry.tax_withholding_category - if doctype == "Purchase Invoice": - value = [ - entry.base_tax_withholding_net_total, - entry.grand_total, - entry.base_total, - entry.bill_no, - entry.bill_date, - ] - elif doctype == "Sales Invoice": - value = [entry.base_net_total, entry.grand_total, entry.base_total] - elif doctype == "Payment Entry": - value = [entry.paid_amount, entry.paid_amount_after_tax, entry.base_paid_amount] - else: - value = [entry.total_debit] * 3 - - net_total_map[(doctype, entry.name)] = value - - -def get_tax_rate_map(filters): - rate_map = frappe.get_all( - "Tax Withholding Rate", - filters={"from_date": ("<=", filters.to_date), "to_date": (">=", filters.from_date)}, - fields=["parent", "tax_withholding_rate", "from_date", "to_date"], - ) - - rate_list = frappe._dict() - - for rate in rate_map: - rate_list.setdefault(rate.parent, []).append(frappe._dict(rate)) - - return rate_list - - -def get_tax_withholding_rates(tax_withholding, posting_date): - # returns the row that matches with the fiscal year from posting date - for rate in tax_withholding: - if getdate(rate.from_date) <= getdate(posting_date) <= getdate(rate.to_date): - return rate.tax_withholding_rate - - return 0 + doc_info[(doctype_name, entry.name)] = entry diff --git a/erpnext/accounts/report/tds_computation_summary/tds_computation_summary.py b/erpnext/accounts/report/tds_computation_summary/tds_computation_summary.py index 2253b3631c1..49bf556da66 100644 --- a/erpnext/accounts/report/tds_computation_summary/tds_computation_summary.py +++ b/erpnext/accounts/report/tds_computation_summary/tds_computation_summary.py @@ -2,35 +2,18 @@ import frappe from frappe import _ from erpnext.accounts.report.tax_withholding_details.tax_withholding_details import ( - get_result, - get_tds_docs, + get_tax_withholding_data, ) from erpnext.accounts.utils import get_fiscal_year def execute(filters=None): - if filters.get("party_type") == "Customer": - party_naming_by = frappe.get_single_value("Selling Settings", "cust_master_name") - else: - party_naming_by = frappe.db.get_single_value("Buying Settings", "supp_master_name") - - filters.update({"naming_series": party_naming_by}) - validate_filters(filters) + data = get_tax_withholding_data(filters) columns = get_columns(filters) - ( - tds_docs, - tds_accounts, - tax_category_map, - journal_entry_party_map, - invoice_total_map, - ) = get_tds_docs(filters) - res = get_result( - filters, tds_docs, tds_accounts, tax_category_map, journal_entry_party_map, invoice_total_map - ) - final_result = group_by_party_and_category(res, filters) + final_result = group_by_party_and_category(data, filters) return columns, final_result @@ -55,7 +38,6 @@ def group_by_party_and_category(data, filters): party_category_wise_map.setdefault( (row.get("party"), row.get("section_code")), { - "pan": row.get("pan"), "tax_id": row.get("tax_id"), "party": row.get("party"), "party_name": row.get("party_name"), @@ -89,9 +71,8 @@ def get_final_result(party_category_wise_map): def get_columns(filters): - pan = "pan" if frappe.db.has_column(filters.party_type, "pan") else "tax_id" columns = [ - {"label": _(frappe.unscrub(pan)), "fieldname": pan, "fieldtype": "Data", "width": 90}, + {"label": _("Tax Id"), "fieldname": "tax_id", "fieldtype": "Data", "width": 90}, { "label": _(filters.get("party_type")), "fieldname": "party", @@ -99,47 +80,43 @@ def get_columns(filters): "options": "party_type", "width": 180, }, + { + "label": _(f"{filters.get('party_type', 'Party')} Name"), + "fieldname": "party_name", + "fieldtype": "Data", + "width": 180, + }, + { + "label": _("Section Code"), + "options": "Tax Withholding Category", + "fieldname": "section_code", + "fieldtype": "Link", + "width": 180, + }, + { + "label": _("Entity Type"), + "fieldname": "entity_type", + "fieldtype": "Data", + "width": 180, + }, + { + "label": _("Tax Rate %"), + "fieldname": "rate", + "fieldtype": "Percent", + "width": 120, + }, + { + "label": _("Total Amount"), + "fieldname": "total_amount", + "fieldtype": "Float", + "width": 120, + }, + { + "label": _("Tax Amount"), + "fieldname": "tax_amount", + "fieldtype": "Float", + "width": 120, + }, ] - if filters.naming_series == "Naming Series": - columns.append( - { - "label": _(filters.party_type + " Name"), - "fieldname": "party_name", - "fieldtype": "Data", - "width": 180, - } - ) - - columns.extend( - [ - { - "label": _("Section Code"), - "options": "Tax Withholding Category", - "fieldname": "section_code", - "fieldtype": "Link", - "width": 180, - }, - {"label": _("Entity Type"), "fieldname": "entity_type", "fieldtype": "Data", "width": 180}, - { - "label": _("TDS Rate %") if filters.get("party_type") == "Supplier" else _("TCS Rate %"), - "fieldname": "rate", - "fieldtype": "Percent", - "width": 120, - }, - { - "label": _("Total Amount"), - "fieldname": "total_amount", - "fieldtype": "Float", - "width": 120, - }, - { - "label": _("Tax Amount"), - "fieldname": "tax_amount", - "fieldtype": "Float", - "width": 120, - }, - ] - ) - return columns diff --git a/erpnext/accounts/report/trial_balance/trial_balance.py b/erpnext/accounts/report/trial_balance/trial_balance.py index 933e9cd30d9..66185c94297 100644 --- a/erpnext/accounts/report/trial_balance/trial_balance.py +++ b/erpnext/accounts/report/trial_balance/trial_balance.py @@ -447,7 +447,7 @@ def prepare_data(accounts, filters, parent_children_map, company_currency): } for key in value_fields: - row[key] = flt(d.get(key, 0.0), 3) + row[key] = flt(d.get(key, 0.0)) if abs(row[key]) >= get_zero_cutoff(company_currency): # ignore zero values diff --git a/erpnext/accounts/utils.py b/erpnext/accounts/utils.py index de58c0a930c..557eb21441b 100644 --- a/erpnext/accounts/utils.py +++ b/erpnext/accounts/utils.py @@ -199,6 +199,8 @@ def get_balance_on( ignore_account_permission=False, account_type=None, start_date=None, + finance_book=None, + include_default_fb_balances=False, ): if not account and frappe.form_dict.get("account"): account = frappe.form_dict.get("account") @@ -293,8 +295,31 @@ def get_balance_on( f"""gle.party_type = {frappe.db.escape(party_type)} and gle.party = {frappe.db.escape(party)} """ ) + default_finance_book = None if company: cond.append("""gle.company = %s """ % (frappe.db.escape(company))) + default_finance_book = frappe.get_cached_value("Company", company, "default_finance_book") + + if finance_book: + if default_finance_book and include_default_fb_balances: + cond.append( + f"""(gle.finance_book IN ( + {frappe.db.escape(finance_book)}, + {frappe.db.escape(default_finance_book)} + ) OR gle.finance_book IS NULL + )""" + ) + else: + cond.append(f"(gle.finance_book = {frappe.db.escape(finance_book)} OR gle.finance_book IS NULL)") + + elif default_finance_book and include_default_fb_balances: + # No finance book passed → fall back to default + cond.append( + f"""( + gle.finance_book = {frappe.db.escape(default_finance_book)} + OR gle.finance_book IS NULL + )""" + ) if account or (party_type and party) or account_type: precision = get_currency_precision() @@ -1333,7 +1358,7 @@ def get_children(doctype, parent, company, is_root=False, include_disabled=False @frappe.whitelist() -def get_account_balances(accounts, company): +def get_account_balances(accounts, company, finance_book=None, include_default_fb_balances=False): if isinstance(accounts, str): accounts = loads(accounts) @@ -1344,9 +1369,25 @@ def get_account_balances(accounts, company): for account in accounts: account["company_currency"] = company_currency - account["balance"] = flt(get_balance_on(account["value"], in_account_currency=False, company=company)) + account["balance"] = flt( + get_balance_on( + account=account["value"], + in_account_currency=False, + company=company, + finance_book=finance_book, + include_default_fb_balances=include_default_fb_balances, + ) + ) + if account["account_currency"] and account["account_currency"] != company_currency: - account["balance_in_account_currency"] = flt(get_balance_on(account["value"], company=company)) + account["balance_in_account_currency"] = flt( + get_balance_on( + account=account["value"], + company=company, + finance_book=finance_book, + include_default_fb_balances=include_default_fb_balances, + ) + ) return accounts diff --git a/erpnext/assets/doctype/asset/asset.js b/erpnext/assets/doctype/asset/asset.js index c50881fcd7a..e0b4593416a 100644 --- a/erpnext/assets/doctype/asset/asset.js +++ b/erpnext/assets/doctype/asset/asset.js @@ -80,6 +80,12 @@ frappe.ui.form.on("Asset", { } }, + before_submit: function (frm) { + if (frm.doc.is_composite_asset && !frm.has_active_capitalization) { + frappe.throw(__("Please capitalize this asset before submitting.")); + } + }, + refresh: function (frm) { frappe.ui.form.trigger("Asset", "is_existing_asset"); frm.toggle_display("next_depreciation_date", frm.doc.docstatus < 1); @@ -196,9 +202,10 @@ frappe.ui.form.on("Asset", { asset: frm.doc.name, }, callback: function (r) { + frm.has_active_capitalization = r.message; + if (!r.message) { - $(".primary-action").prop("hidden", true); - $(".form-message").text("Capitalize this asset to confirm"); + $(".form-message").text(__("Capitalize this asset before submitting.")); frm.add_custom_button(__("Capitalize Asset"), function () { frm.trigger("create_asset_capitalization"); @@ -270,8 +277,14 @@ frappe.ui.form.on("Asset", { const row = [ sch["idx"], frappe.format(sch["schedule_date"], { fieldtype: "Date" }), - frappe.format(sch["depreciation_amount"], { fieldtype: "Currency" }), - frappe.format(sch["accumulated_depreciation_amount"], { fieldtype: "Currency" }), + frappe.format(sch["depreciation_amount"], { + fieldtype: "Currency", + options: "Company:company:default_currency", + }), + frappe.format(sch["accumulated_depreciation_amount"], { + fieldtype: "Currency", + options: "Company:company:default_currency", + }), sch["journal_entry"] || "", ]; @@ -464,7 +477,6 @@ frappe.ui.form.on("Asset", { is_composite_asset: function (frm) { if (frm.doc.is_composite_asset) { frm.set_value("net_purchase_amount", 0); - frm.set_df_property("net_purchase_amount", "read_only", 1); } else { frm.set_df_property("net_purchase_amount", "read_only", 0); } @@ -532,7 +544,6 @@ frappe.ui.form.on("Asset", { callback: function (r) { var doclist = frappe.model.sync(r.message); frappe.set_route("Form", doclist[0].doctype, doclist[0].name); - $(".primary-action").prop("hidden", false); }, }); }, diff --git a/erpnext/assets/doctype/asset/asset.json b/erpnext/assets/doctype/asset/asset.json index af4d8f281e2..832f7c18e68 100644 --- a/erpnext/assets/doctype/asset/asset.json +++ b/erpnext/assets/doctype/asset/asset.json @@ -556,7 +556,8 @@ "fieldtype": "Currency", "label": "Net Purchase Amount", "mandatory_depends_on": "eval:(!doc.is_composite_asset || doc.docstatus==1)", - "options": "Company:company:default_currency" + "options": "Company:company:default_currency", + "read_only_depends_on": "eval: doc.is_composite_asset" } ], "idx": 72, @@ -600,7 +601,7 @@ "link_fieldname": "target_asset" } ], - "modified": "2025-11-04 22:39:00.817405", + "modified": "2025-12-18 16:36:40.904246", "modified_by": "Administrator", "module": "Assets", "name": "Asset", diff --git a/erpnext/assets/doctype/asset/asset.py b/erpnext/assets/doctype/asset/asset.py index 1d40abf2094..701be98a0d6 100644 --- a/erpnext/assets/doctype/asset/asset.py +++ b/erpnext/assets/doctype/asset/asset.py @@ -7,6 +7,7 @@ import math import frappe from frappe import _ +from frappe.query_builder.functions import IfNull, Sum from frappe.utils import ( cint, flt, @@ -121,7 +122,7 @@ class Asset(AccountsController): def validate(self): self.validate_category() self.validate_precision() - self.validate_linked_purchase_docs() + self.validate_linked_purchase_documents() self.set_purchase_doc_row_item() self.validate_asset_values() self.validate_asset_and_reference() @@ -141,21 +142,75 @@ class Asset(AccountsController): if self.split_from or not self.calculate_depreciation: return - schedules = [] - for row in self.get("finance_books"): - self.validate_asset_finance_books(row) - if not row.rate_of_depreciation: - row.rate_of_depreciation = self.get_depreciation_rate(row, on_validate=True) + created_schedules = [] + for fb_row in self.get("finance_books"): + if not fb_row.rate_of_depreciation: + fb_row.rate_of_depreciation = self.get_depreciation_rate(fb_row, on_validate=True) - schedule_doc = get_asset_depr_schedule_doc(self.name, "Draft", row.finance_book) - if not schedule_doc: - schedule_doc = frappe.new_doc("Asset Depreciation Schedule") - schedule_doc.asset = self.name - schedule_doc.create_depreciation_schedule(row) - schedule_doc.save() - schedules.append(schedule_doc.name) + existing_schedule = get_asset_depr_schedule_doc(self.name, "Draft", fb_row.finance_book) - self.show_schedule_creation_message(schedules) + if not existing_schedule: + new_schedule = frappe.new_doc("Asset Depreciation Schedule") + new_schedule.asset = self.name + new_schedule.create_depreciation_schedule(fb_row) + new_schedule.save() + created_schedules.append(new_schedule.name) + continue + + self.evaluate_and_recreate_depreciation_schedule(existing_schedule, fb_row) + created_schedules.append(existing_schedule.name) + + self.show_schedule_creation_message(created_schedules) + + def evaluate_and_recreate_depreciation_schedule(self, existing_doc, fb_row): + """Determine if depreciation schedule needs to be regenerated and recreate if necessary""" + + asset_details_changed = self.has_asset_details_changed(existing_doc) + depreciation_settings_changed = self.has_depreciation_settings_changed(existing_doc, fb_row) + if self.should_regenerate_depreciation_schedule( + existing_doc, asset_details_changed, depreciation_settings_changed + ): + existing_doc.create_depreciation_schedule(fb_row) + existing_doc.save() + + def has_asset_details_changed(self, existing_doc): + """Check if core asset details that affect depreciation have changed""" + return ( + self.net_purchase_amount != existing_doc.net_purchase_amount + or self.opening_accumulated_depreciation != existing_doc.opening_accumulated_depreciation + or self.opening_number_of_booked_depreciations + != existing_doc.opening_number_of_booked_depreciations + ) + + def has_depreciation_settings_changed(self, existing_doc, fb_row): + """Check if depreciation calculation settings have changed""" + + if not existing_doc.get("depreciation_schedule") or fb_row.depreciation_method != "Manual": + return True + + return ( + fb_row.depreciation_method != existing_doc.depreciation_method + or fb_row.total_number_of_depreciations != existing_doc.total_number_of_depreciations + or fb_row.frequency_of_depreciation != existing_doc.frequency_of_depreciation + or getdate(fb_row.depreciation_start_date) + != existing_doc.get("depreciation_schedule")[0].schedule_date + or fb_row.expected_value_after_useful_life != existing_doc.expected_value_after_useful_life + ) + + def should_regenerate_depreciation_schedule( + self, existing_doc, asset_details_changed, depreciation_settings_changed + ): + """Check all conditions to determine if schedule regeneration is required""" + + # Schedule doesn't exist yet + if not existing_doc.get("depreciation_schedule"): + return True + + # Either asset details or depreciation settings have changed + if asset_details_changed or depreciation_settings_changed: + return True + + return False def set_depr_rate_and_value_after_depreciation(self): if self.split_from: @@ -187,6 +242,10 @@ class Asset(AccountsController): self.validate_expected_value_after_useful_life() self.set_total_booked_depreciations() + def before_submit(self): + if self.is_composite_asset and not has_active_capitalization(self.name): + frappe.throw(_("Please capitalize this asset before submitting.")) + def on_submit(self): self.validate_in_use_date() self.make_asset_movement() @@ -422,20 +481,67 @@ class Asset(AccountsController): if self.available_for_use_date and getdate(self.available_for_use_date) < getdate(self.purchase_date): frappe.throw(_("Available-for-use Date should be after purchase date")) - def validate_linked_purchase_docs(self): - for doctype_field, doctype_name in [ + def validate_linked_purchase_documents(self): + for fieldname, doctype in [ ("purchase_receipt", "Purchase Receipt"), ("purchase_invoice", "Purchase Invoice"), ]: - linked_doc = getattr(self, doctype_field, None) - if linked_doc: - docstatus = frappe.db.get_value(doctype_name, linked_doc, "docstatus") - if docstatus == 0: - frappe.throw( - _("{0} is still in Draft. Please submit it before saving the Asset.").format( - get_link_to_form(doctype_name, linked_doc) - ) + purchase_doc = getattr(self, fieldname, None) + + if not purchase_doc: + continue + + if frappe.db.get_value(doctype, purchase_doc, "docstatus") == 0: + frappe.throw( + _("{0} is in Draft. Submit it before creating the Asset.").format( + get_link_to_form(doctype, purchase_doc) ) + ) + + self.validate_asset_qty_with_purchase_doc(doctype, purchase_doc) + + def validate_asset_qty_with_purchase_doc(self, doctype, purchase_doc): + Asset = frappe.qb.DocType("Asset") + + if doctype == "Purchase Invoice": + asset_filter = Asset.purchase_invoice == purchase_doc + else: + asset_filter = Asset.purchase_receipt == purchase_doc + + existing_asset_qty = ( + frappe.qb.from_(Asset) + .select(IfNull(Sum(Asset.asset_quantity), 0)) + .where((Asset.item_code == self.item_code) & (Asset.name != self.name) & (Asset.docstatus != 2)) + .where(asset_filter) + ).run()[0][0] + + PurchaseDoc = frappe.qb.DocType(doctype) + PurchaseDocItems = frappe.qb.DocType(f"{doctype} Item") + + purchased_qty = ( + frappe.qb.from_(PurchaseDoc) + .join(PurchaseDocItems) + .on(PurchaseDoc.name == PurchaseDocItems.parent) + .select(IfNull(Sum(PurchaseDocItems.qty), 0)) + .where(PurchaseDoc.name == purchase_doc) + .where(PurchaseDocItems.item_code == self.item_code) + ).run()[0][0] + + if (existing_asset_qty + self.asset_quantity) > purchased_qty: + frappe.throw( + _( + "Cannot create asset.

    " + "You're trying to create {0} asset(s) from {2} {3}.
    " + "However, only {1} item(s) were purchased and {4} asset(s) already exist against {5}." + ).format( + self.asset_quantity, + purchased_qty, + doctype, + get_link_to_form(doctype, purchase_doc), + existing_asset_qty, + purchase_doc, + ) + ) def validate_gross_and_purchase_amount(self): if self.is_existing_asset: @@ -482,6 +588,7 @@ class Asset(AccountsController): def set_depreciation_rate(self): for d in self.get("finance_books"): + self.validate_asset_finance_books(d) d.rate_of_depreciation = flt( self.get_depreciation_rate(d, on_validate=True), d.precision("rate_of_depreciation") ) @@ -490,6 +597,9 @@ class Asset(AccountsController): row.expected_value_after_useful_life = flt( row.expected_value_after_useful_life, self.precision("net_purchase_amount") ) + + if flt(row.expected_value_after_useful_life) < 0: + frappe.throw(_("Row {0}: Expected Value After Useful Life cannot be negative").format(row.idx)) if flt(row.expected_value_after_useful_life) >= flt(self.net_purchase_amount): frappe.throw( _("Row {0}: Expected Value After Useful Life must be less than Net Purchase Amount").format( @@ -500,6 +610,7 @@ class Asset(AccountsController): if not row.depreciation_start_date: row.depreciation_start_date = get_last_day(self.available_for_use_date) self.validate_depreciation_start_date(row) + self.validate_total_number_of_depreciations_and_frequency(row) if not self.is_existing_asset: self.opening_accumulated_depreciation = 0 @@ -536,6 +647,15 @@ class Asset(AccountsController): title=_("Invalid Schedule"), ) + def validate_total_number_of_depreciations_and_frequency(self, row): + if row.total_number_of_depreciations <= 0: + frappe.throw( + _("Row #{0}: Total Number of Depreciations must be greater than zero").format(row.idx) + ) + + if row.frequency_of_depreciation <= 0: + frappe.throw(_("Row #{0}: Frequency of Depreciation must be greater than zero").format(row.idx)) + def validate_depreciation_start_date(self, row): if row.depreciation_start_date: if getdate(row.depreciation_start_date) < getdate(self.purchase_date): @@ -1212,7 +1332,7 @@ def get_values_from_purchase_doc(purchase_doc_name, item_code, doctype): return { "company": purchase_doc.company, - "purchase_date": purchase_doc.get("bill_date") or purchase_doc.get("posting_date"), + "purchase_date": purchase_doc.get("posting_date"), "net_purchase_amount": flt(first_item.base_net_amount), "asset_quantity": first_item.qty, "cost_center": first_item.cost_center or purchase_doc.get("cost_center"), diff --git a/erpnext/assets/doctype/asset/depreciation.py b/erpnext/assets/doctype/asset/depreciation.py index 25148dc0a18..7a1b4b70af7 100644 --- a/erpnext/assets/doctype/asset/depreciation.py +++ b/erpnext/assets/doctype/asset/depreciation.py @@ -96,13 +96,28 @@ def get_depreciable_assets_data(date): .orderby(a.creation, order=Order.desc) ) - acc_frozen_upto = get_acc_frozen_upto() - if acc_frozen_upto: - res = res.where(ds.schedule_date > acc_frozen_upto) + companies_with_frozen_limits = get_companies_with_frozen_limits() - res = res.run() + for company, frozen_upto in companies_with_frozen_limits.items(): + res = res.where((a.company != company) | (ds.schedule_date > frozen_upto)) - return res + return res.run() + + +def get_companies_with_frozen_limits(): + companies_with_frozen_limits = {} + for d in frappe.get_all( + "Company", fields=["name", "accounts_frozen_till_date", "role_allowed_for_frozen_entries"] + ): + if not d.accounts_frozen_till_date: + continue + + if ( + d.role_allowed_for_frozen_entries not in frappe.get_roles() + and frappe.session.user != "Administrator" + ): + companies_with_frozen_limits[d.name] = getdate(d.accounts_frozen_till_date) + return companies_with_frozen_limits def make_depreciation_entry_on_disposal(asset_doc, disposal_date=None): @@ -111,20 +126,6 @@ def make_depreciation_entry_on_disposal(asset_doc, disposal_date=None): make_depreciation_entry(depr_schedule_name, disposal_date) -def get_acc_frozen_upto(): - acc_frozen_upto = frappe.get_single_value("Accounts Settings", "acc_frozen_upto") - - if not acc_frozen_upto: - return - - frozen_accounts_modifier = frappe.get_single_value("Accounts Settings", "frozen_accounts_modifier") - - if frozen_accounts_modifier not in frappe.get_roles() or frappe.session.user == "Administrator": - return getdate(acc_frozen_upto) - - return - - def get_credit_debit_accounts_for_asset(asset_category, company): # Returns credit and debit accounts for the given asset category and company. (_, accumulated_depr_account, depr_expense_account) = get_depreciation_accounts(asset_category, company) @@ -307,7 +308,8 @@ def set_depr_entry_posting_status_for_failed_assets(failed_asset_names): def notify_depr_entry_posting_error(failed_asset_names, error_log_names): - recipients = get_users_with_role("Accounts Manager") + user_role = frappe.db.get_single_value("Accounts Settings", "role_to_notify_on_depreciation_failure") + recipients = get_users_with_role(user_role or "Accounts Manager") if not recipients: recipients = get_users_with_role("System Manager") diff --git a/erpnext/assets/doctype/asset_capitalization/asset_capitalization.js b/erpnext/assets/doctype/asset_capitalization/asset_capitalization.js index fe2f76c2bb9..3857f6411f5 100644 --- a/erpnext/assets/doctype/asset_capitalization/asset_capitalization.js +++ b/erpnext/assets/doctype/asset_capitalization/asset_capitalization.js @@ -194,6 +194,13 @@ erpnext.assets.AssetCapitalization = class AssetCapitalization extends erpnext.s } } + serial_and_batch_bundle(doc, cdt, cdn) { + var row = frappe.get_doc(cdt, cdn); + if (cdt === "Asset Capitalization Stock Item") { + this.get_warehouse_details(row); + } + } + asset(doc, cdt, cdn) { var row = frappe.get_doc(cdt, cdn); if (cdt === "Asset Capitalization Asset Item") { @@ -407,6 +414,7 @@ erpnext.assets.AssetCapitalization = class AssetCapitalization extends erpnext.s voucher_type: me.frm.doc.doctype, voucher_no: me.frm.doc.name, allow_zero_valuation: 1, + serial_and_batch_bundle: item.serial_and_batch_bundle, }, }, callback: function (r) { diff --git a/erpnext/assets/doctype/asset_capitalization/asset_capitalization.py b/erpnext/assets/doctype/asset_capitalization/asset_capitalization.py index e1c8b16f735..ab12899f45b 100644 --- a/erpnext/assets/doctype/asset_capitalization/asset_capitalization.py +++ b/erpnext/assets/doctype/asset_capitalization/asset_capitalization.py @@ -352,6 +352,7 @@ class AssetCapitalization(StockController): "voucher_no": self.name, "company": self.company, "allow_zero_valuation": cint(item.get("allow_zero_valuation_rate")), + "serial_and_batch_bundle": item.serial_and_batch_bundle, } ) @@ -723,6 +724,7 @@ def get_consumed_stock_item_details(ctx: ItemDetailsCtx): "company": ctx.company, "serial_no": ctx.serial_no, "batch_no": ctx.batch_no, + "serial_and_batch_bundle": ctx.serial_and_batch_bundle, } ) out.update(get_warehouse_details(incoming_rate_args)) diff --git a/erpnext/buying/doctype/buying_settings/buying_settings.json b/erpnext/buying/doctype/buying_settings/buying_settings.json index 9a73760d269..1ce2dc24d1b 100644 --- a/erpnext/buying/doctype/buying_settings/buying_settings.json +++ b/erpnext/buying/doctype/buying_settings/buying_settings.json @@ -36,6 +36,7 @@ "backflush_raw_materials_of_subcontract_based_on", "column_break_11", "over_transfer_allowance", + "validate_consumed_qty", "section_break_xcug", "auto_create_subcontracting_order", "column_break_izrr", @@ -270,6 +271,14 @@ "label": "Fixed Outgoing Email Account", "link_filters": "[[\"Email Account\",\"enable_outgoing\",\"=\",1]]", "options": "Email Account" + }, + { + "default": "0", + "depends_on": "eval:doc.backflush_raw_materials_of_subcontract_based_on == \"Material Transferred for Subcontract\"", + "description": "Raw materials consumed qty will be validated based on FG BOM required qty", + "fieldname": "validate_consumed_qty", + "fieldtype": "Check", + "label": "Validate Consumed Qty (as per BOM)" } ], "grid_page_length": 50, @@ -278,7 +287,7 @@ "index_web_pages_for_search": 1, "issingle": 1, "links": [], - "modified": "2025-08-20 22:13:38.506889", + "modified": "2025-11-20 12:59:09.925862", "modified_by": "Administrator", "module": "Buying", "name": "Buying Settings", diff --git a/erpnext/buying/doctype/buying_settings/buying_settings.py b/erpnext/buying/doctype/buying_settings/buying_settings.py index 8b83418f6f8..3634f8a9069 100644 --- a/erpnext/buying/doctype/buying_settings/buying_settings.py +++ b/erpnext/buying/doctype/buying_settings/buying_settings.py @@ -44,6 +44,7 @@ class BuyingSettings(Document): supp_master_name: DF.Literal["Supplier Name", "Naming Series", "Auto Name"] supplier_group: DF.Link | None use_transaction_date_exchange_rate: DF.Check + validate_consumed_qty: DF.Check # end: auto-generated types def validate(self): diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.js b/erpnext/buying/doctype/purchase_order/purchase_order.js index a1b50202f5b..80f1a17f178 100644 --- a/erpnext/buying/doctype/purchase_order/purchase_order.js +++ b/erpnext/buying/doctype/purchase_order/purchase_order.js @@ -90,31 +90,6 @@ frappe.ui.form.on("Purchase Order", { prevent_past_schedule_dates(frm); }, - supplier: function (frm) { - // Do not update if inter company reference is there as the details will already be updated - if (frm.updating_party_details || frm.doc.inter_company_invoice_reference) return; - - if (frm.doc.__onload && frm.doc.__onload.load_after_mapping) return; - - erpnext.utils.get_party_details( - frm, - "erpnext.accounts.party.get_party_details", - { - posting_date: frm.doc.transaction_date, - bill_date: frm.doc.bill_date, - party: frm.doc.supplier, - party_type: "Supplier", - account: frm.doc.credit_to, - price_list: frm.doc.buying_price_list, - fetch_payment_terms_template: cint(!frm.doc.ignore_default_payment_terms_template), - }, - function () { - frm.set_df_property("apply_tds", "read_only", frm.supplier_tds ? 0 : 1); - frm.set_df_property("tax_withholding_category", "hidden", frm.supplier_tds ? 0 : 1); - } - ); - }, - get_materials_from_supplier: function (frm) { let po_details = []; @@ -162,15 +137,6 @@ frappe.ui.form.on("Purchase Order", { frm.set_value("transaction_date", frappe.datetime.get_today()); } - if (frm.doc.__onload && frm.doc.supplier) { - if (frm.is_new()) { - frm.doc.apply_tds = frm.doc.__onload.supplier_tds ? 1 : 0; - } - if (!frm.doc.__onload.supplier_tds) { - frm.set_df_property("apply_tds", "read_only", 1); - } - } - erpnext.queries.setup_queries(frm, "Warehouse", function () { return erpnext.queries.warehouse(frm.doc); }); @@ -181,14 +147,6 @@ frappe.ui.form.on("Purchase Order", { } }, - apply_tds: function (frm) { - if (!frm.doc.apply_tds) { - frm.set_value("tax_withholding_category", ""); - } else { - frm.set_value("tax_withholding_category", frm.supplier_tds); - } - }, - get_subcontracting_boms_for_finished_goods: function (fg_item) { return frappe.call({ method: "erpnext.subcontracting.doctype.subcontracting_bom.subcontracting_bom.get_subcontracting_boms_for_finished_goods", @@ -317,6 +275,7 @@ erpnext.buying.PurchaseOrderController = class PurchaseOrderController extends ( erpnext.buying.BuyingController ) { setup() { + this.setup_accounting_dimension_triggers(); this.frm.custom_make_buttons = { "Purchase Receipt": "Purchase Receipt", "Purchase Invoice": "Purchase Invoice", diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.json b/erpnext/buying/doctype/purchase_order/purchase_order.json index 8a8a222da73..f69be2c8e0b 100644 --- a/erpnext/buying/doctype/purchase_order/purchase_order.json +++ b/erpnext/buying/doctype/purchase_order/purchase_order.json @@ -22,8 +22,6 @@ "schedule_date", "column_break1", "company", - "apply_tds", - "tax_withholding_category", "is_subcontracted", "has_unit_price_items", "supplier_warehouse", @@ -57,8 +55,6 @@ "column_break_26", "total", "net_total", - "tax_withholding_net_total", - "base_tax_withholding_net_total", "section_break_48", "pricing_rules", "raw_material_details", @@ -107,6 +103,7 @@ "section_addresses", "supplier_address", "address_display", + "supplier_group", "col_break_address", "contact_person", "contact_display", @@ -1134,19 +1131,6 @@ "options": "Company", "read_only": 1 }, - { - "default": "0", - "fieldname": "apply_tds", - "fieldtype": "Check", - "label": "Apply Tax Withholding Amount" - }, - { - "depends_on": "eval: doc.apply_tds", - "fieldname": "tax_withholding_category", - "fieldtype": "Link", - "label": "Tax Withholding Category", - "options": "Tax Withholding Category" - }, { "collapsible": 1, "fieldname": "accounting_dimensions_section", @@ -1224,28 +1208,6 @@ "label": "Additional Info", "oldfieldtype": "Section Break" }, - { - "default": "0", - "depends_on": "apply_tds", - "fieldname": "tax_withholding_net_total", - "fieldtype": "Currency", - "hidden": 1, - "label": "Tax Withholding Net Total", - "no_copy": 1, - "options": "currency", - "read_only": 1 - }, - { - "depends_on": "apply_tds", - "fieldname": "base_tax_withholding_net_total", - "fieldtype": "Currency", - "hidden": 1, - "label": "Base Tax Withholding Net Total", - "no_copy": 1, - "options": "Company:company:default_currency", - "print_hide": 1, - "read_only": 1 - }, { "fieldname": "column_break_99", "fieldtype": "Column Break" @@ -1311,6 +1273,14 @@ "print_hide": 1, "read_only": 1 }, + { + "fieldname": "supplier_group", + "fieldtype": "Link", + "hidden": 1, + "label": "Supplier Group", + "options": "Supplier Group", + "print_hide": 1 + }, { "depends_on": "eval: doc.last_scanned_warehouse", "fieldname": "last_scanned_warehouse", @@ -1339,7 +1309,7 @@ "idx": 105, "is_submittable": 1, "links": [], - "modified": "2025-08-28 11:00:56.635116", + "modified": "2025-09-28 11:00:56.635116", "modified_by": "Administrator", "module": "Buying", "name": "Purchase Order", diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.py b/erpnext/buying/doctype/purchase_order/purchase_order.py index 5c3e0d92257..5eeb25e093b 100644 --- a/erpnext/buying/doctype/purchase_order/purchase_order.py +++ b/erpnext/buying/doctype/purchase_order/purchase_order.py @@ -15,9 +15,6 @@ from erpnext.accounts.doctype.sales_invoice.sales_invoice import ( update_linked_doc, validate_inter_company_party, ) -from erpnext.accounts.doctype.tax_withholding_category.tax_withholding_category import ( - get_party_tax_withholding_details, -) from erpnext.accounts.party import get_party_account, get_party_account_currency from erpnext.buying.utils import check_on_hold_or_closed_status, validate_for_items from erpnext.controllers.buying_controller import BuyingController @@ -61,7 +58,6 @@ class PurchaseOrder(BuyingController): advance_payment_status: DF.Literal["Not Initiated", "Initiated", "Partially Paid", "Fully Paid"] amended_from: DF.Link | None apply_discount_on: DF.Literal["", "Grand Total", "Net Total"] - apply_tds: DF.Check auto_repeat: DF.Link | None base_discount_amount: DF.Currency base_grand_total: DF.Currency @@ -69,7 +65,6 @@ class PurchaseOrder(BuyingController): base_net_total: DF.Currency base_rounded_total: DF.Currency base_rounding_adjustment: DF.Currency - base_tax_withholding_net_total: DF.Currency base_taxes_and_charges_added: DF.Currency base_taxes_and_charges_deducted: DF.Currency base_total: DF.Currency @@ -157,8 +152,6 @@ class PurchaseOrder(BuyingController): supplier_name: DF.Data | None supplier_warehouse: DF.Link | None tax_category: DF.Link | None - tax_withholding_category: DF.Link | None - tax_withholding_net_total: DF.Currency taxes: DF.Table[PurchaseTaxesandCharges] taxes_and_charges: DF.Link | None taxes_and_charges_added: DF.Currency @@ -191,8 +184,6 @@ class PurchaseOrder(BuyingController): ] def onload(self): - supplier_tds = frappe.db.get_value("Supplier", self.supplier, "tax_withholding_category") - self.set_onload("supplier_tds", supplier_tds) self.set_onload("can_update_items", self.can_update_items()) def before_validate(self): @@ -204,9 +195,6 @@ class PurchaseOrder(BuyingController): self.set_status() - # apply tax withholding only if checked and applicable - self.set_tax_withholding() - self.validate_supplier() self.validate_schedule_date() validate_for_items(self) @@ -284,36 +272,6 @@ class PurchaseOrder(BuyingController): [["Supplier Quotation", "supplier_quotation", "supplier_quotation_item"]] ) - def set_tax_withholding(self): - if not self.apply_tds: - return - - tax_withholding_details = get_party_tax_withholding_details(self, self.tax_withholding_category) - - if not tax_withholding_details: - return - - accounts = [] - for d in self.taxes: - if d.account_head == tax_withholding_details.get("account_head"): - d.update(tax_withholding_details) - accounts.append(d.account_head) - - if not accounts or tax_withholding_details.get("account_head") not in accounts: - self.append("taxes", tax_withholding_details) - - to_remove = [ - d - for d in self.taxes - if not d.tax_amount and d.account_head == tax_withholding_details.get("account_head") - ] - - for d in to_remove: - self.remove(d) - - # calculate totals again after applying TDS - self.calculate_taxes_and_totals() - def validate_supplier(self): prevent_po = frappe.db.get_value("Supplier", self.supplier, "prevent_pos") if prevent_po: @@ -695,13 +653,6 @@ class PurchaseOrder(BuyingController): if sco: update_sco_status(sco, "Closed" if self.status == "Closed" else None) - def set_missing_values(self, for_validate=False): - tds_category = frappe.db.get_value("Supplier", self.supplier, "tax_withholding_category") - if tds_category and not for_validate: - self.set_onload("supplier_tds", tds_category) - - super().set_missing_values(for_validate) - @frappe.request_cache def item_last_purchase_rate(name, conversion_rate, item_code, conversion_factor=1.0): @@ -839,10 +790,6 @@ def get_mapped_purchase_invoice(source_name, target_doc=None, ignore_permissions target.flags.ignore_permissions = ignore_permissions set_missing_values(source, target) - # set tax_withholding_category from Purchase Order - if source.apply_tds and source.tax_withholding_category and target.apply_tds: - target.tax_withholding_category = source.tax_withholding_category - # Get the advance paid Journal Entries in Purchase Invoice Advance if target.get("allocate_advances_automatically"): target.set_advances() @@ -929,6 +876,7 @@ def get_list_context(context=None): "show_search": True, "no_breadcrumbs": True, "title": _("Purchase Orders"), + "list_template": "templates/includes/list/list.html", } ) return list_context diff --git a/erpnext/buying/doctype/purchase_order/purchase_order_list.js b/erpnext/buying/doctype/purchase_order/purchase_order_list.js index 9b74348bca4..5c7aabee99d 100644 --- a/erpnext/buying/doctype/purchase_order/purchase_order_list.js +++ b/erpnext/buying/doctype/purchase_order/purchase_order_list.js @@ -51,11 +51,11 @@ frappe.listview_settings["Purchase Order"] = { onload: function (listview) { var method = "erpnext.buying.doctype.purchase_order.purchase_order.close_or_unclose_purchase_orders"; - listview.page.add_menu_item(__("Close"), function () { + listview.page.add_action_item(__("Close"), function () { listview.call_for_selected_items(method, { status: "Closed" }); }); - listview.page.add_menu_item(__("Reopen"), function () { + listview.page.add_action_item(__("Reopen"), function () { listview.call_for_selected_items(method, { status: "Submitted" }); }); diff --git a/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json b/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json index 3679e7337e8..5e5eb7fd55b 100644 --- a/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json +++ b/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json @@ -55,7 +55,6 @@ "pricing_rules", "stock_uom_rate", "is_free_item", - "apply_tds", "section_break_29", "net_rate", "net_amount", @@ -899,12 +898,6 @@ "fieldname": "column_break_54", "fieldtype": "Column Break" }, - { - "default": "1", - "fieldname": "apply_tds", - "fieldtype": "Check", - "label": "Apply TDS" - }, { "fieldname": "wip_composite_asset", "fieldtype": "Link", diff --git a/erpnext/buying/doctype/purchase_order_item/purchase_order_item.py b/erpnext/buying/doctype/purchase_order_item/purchase_order_item.py index c0747a614bc..25173bc27bf 100644 --- a/erpnext/buying/doctype/purchase_order_item/purchase_order_item.py +++ b/erpnext/buying/doctype/purchase_order_item/purchase_order_item.py @@ -18,7 +18,6 @@ class PurchaseOrderItem(Document): actual_qty: DF.Float against_blanket_order: DF.Check amount: DF.Currency - apply_tds: DF.Check base_amount: DF.Currency base_net_amount: DF.Currency base_net_rate: DF.Currency diff --git a/erpnext/buying/doctype/request_for_quotation/request_for_quotation.js b/erpnext/buying/doctype/request_for_quotation/request_for_quotation.js index 5e3adf7d50b..8ebef1571b5 100644 --- a/erpnext/buying/doctype/request_for_quotation/request_for_quotation.js +++ b/erpnext/buying/doctype/request_for_quotation/request_for_quotation.js @@ -551,7 +551,10 @@ erpnext.buying.RequestforQuotationController = class RequestforQuotationControll } else if (args.supplier_group) { frappe.db .get_list("Supplier", { - filters: { supplier_group: args.supplier_group }, + filters: { + supplier_group: args.supplier_group, + disabled: 0, + }, limit: 100, order_by: "name", }) diff --git a/erpnext/buying/doctype/request_for_quotation/request_for_quotation.py b/erpnext/buying/doctype/request_for_quotation/request_for_quotation.py index 992e4f758cb..2cf564e6152 100644 --- a/erpnext/buying/doctype/request_for_quotation/request_for_quotation.py +++ b/erpnext/buying/doctype/request_for_quotation/request_for_quotation.py @@ -386,6 +386,7 @@ def get_list_context(context=None): "show_search": True, "no_breadcrumbs": True, "title": _("Request for Quotation"), + "list_template": "templates/includes/list/list.html", } ) return list_context diff --git a/erpnext/buying/doctype/supplier/supplier.js b/erpnext/buying/doctype/supplier/supplier.js index 0621503c100..4b46ddc3d80 100644 --- a/erpnext/buying/doctype/supplier/supplier.js +++ b/erpnext/buying/doctype/supplier/supplier.js @@ -41,18 +41,20 @@ frappe.ui.form.on("Supplier", { frm.set_query("supplier_primary_contact", function (doc) { return { - query: "erpnext.buying.doctype.supplier.supplier.get_supplier_primary_contact", + query: "erpnext.buying.doctype.supplier.supplier.get_supplier_primary", filters: { supplier: doc.name, + type: "Contact", }, }; }); frm.set_query("supplier_primary_address", function (doc) { return { + query: "erpnext.buying.doctype.supplier.supplier.get_supplier_primary", filters: { - link_doctype: "Supplier", - link_name: doc.name, + supplier: doc.name, + type: "Address", }, }; }); @@ -133,6 +135,14 @@ frappe.ui.form.on("Supplier", { // indicators erpnext.utils.set_party_dashboard_indicators(frm); } + + frm.set_query("supplier_group", () => { + return { + filters: { + is_group: 0, + }, + }; + }); }, get_supplier_group_details: function (frm) { frappe.call({ diff --git a/erpnext/buying/doctype/supplier/supplier.json b/erpnext/buying/doctype/supplier/supplier.json index 6975bd56571..125a8b6adb1 100644 --- a/erpnext/buying/doctype/supplier/supplier.json +++ b/erpnext/buying/doctype/supplier/supplier.json @@ -37,9 +37,10 @@ "dashboard_tab", "tax_tab", "tax_id", - "column_break_27", "tax_category", + "column_break_27", "tax_withholding_category", + "tax_withholding_group", "contact_and_address_tab", "address_contacts", "address_html", @@ -480,6 +481,12 @@ "fieldtype": "Table", "label": "Customer Numbers", "options": "Customer Number At Supplier" + }, + { + "fieldname": "tax_withholding_group", + "fieldtype": "Link", + "label": "Tax Withholding Group", + "options": "Tax Withholding Group" } ], "grid_page_length": 50, @@ -493,7 +500,7 @@ "link_fieldname": "party" } ], - "modified": "2025-04-27 12:07:10.859758", + "modified": "2025-06-29 05:30:50.398653", "modified_by": "Administrator", "module": "Buying", "name": "Supplier", diff --git a/erpnext/buying/doctype/supplier/supplier.py b/erpnext/buying/doctype/supplier/supplier.py index e3aac1b407a..cfed11fabef 100644 --- a/erpnext/buying/doctype/supplier/supplier.py +++ b/erpnext/buying/doctype/supplier/supplier.py @@ -73,6 +73,7 @@ class Supplier(TransactionBase): tax_category: DF.Link | None tax_id: DF.Data | None tax_withholding_category: DF.Link | None + tax_withholding_group: DF.Link | None warn_pos: DF.Check warn_rfqs: DF.Check website: DF.Data | None @@ -219,19 +220,25 @@ class Supplier(TransactionBase): @frappe.whitelist() @frappe.validate_and_sanitize_search_inputs -def get_supplier_primary_contact(doctype, txt, searchfield, start, page_len, filters): +def get_supplier_primary(doctype, txt, searchfield, start, page_len, filters): supplier = filters.get("supplier") - contact = frappe.qb.DocType("Contact") + type = filters.get("type") + type_doctype = frappe.qb.DocType(type) dynamic_link = frappe.qb.DocType("Dynamic Link") - return ( - frappe.qb.from_(contact) + query = ( + frappe.qb.from_(type_doctype) .join(dynamic_link) - .on(contact.name == dynamic_link.parent) - .select(contact.name, contact.email_id) + .on(type_doctype.name == dynamic_link.parent) + .select(type_doctype.name) .where( (dynamic_link.link_name == supplier) & (dynamic_link.link_doctype == "Supplier") - & (contact.name.like(f"%{txt}%")) + & (type_doctype.name.like(f"%{txt}%")) ) - ).run(as_dict=False) + ) + + if type == "Contact": + query = query.select(type_doctype.email_id) + + return query.run() diff --git a/erpnext/buying/doctype/supplier_quotation/supplier_quotation.js b/erpnext/buying/doctype/supplier_quotation/supplier_quotation.js index 26f439ba03c..93f52d6ec42 100644 --- a/erpnext/buying/doctype/supplier_quotation/supplier_quotation.js +++ b/erpnext/buying/doctype/supplier_quotation/supplier_quotation.js @@ -32,6 +32,13 @@ erpnext.buying.SupplierQuotationController = class SupplierQuotationController e this.make_purchase_order.bind(this), __("Create") ); + this.frm.add_custom_button(__("Update Items"), () => { + erpnext.utils.update_child_items({ + frm: this.frm, + child_docname: "items", + cannot_add_row: false, + }); + }); this.frm.page.set_inner_btn_group_as_primary(__("Create")); this.frm.add_custom_button(__("Quotation"), this.make_quotation.bind(this), __("Create")); } else if (this.frm.doc.docstatus === 0) { diff --git a/erpnext/buying/doctype/supplier_quotation/supplier_quotation.py b/erpnext/buying/doctype/supplier_quotation/supplier_quotation.py index 10cba8a8be8..c3ba8c40cf3 100644 --- a/erpnext/buying/doctype/supplier_quotation/supplier_quotation.py +++ b/erpnext/buying/doctype/supplier_quotation/supplier_quotation.py @@ -232,6 +232,7 @@ def get_list_context(context=None): "show_search": True, "no_breadcrumbs": True, "title": _("Supplier Quotation"), + "list_template": "templates/includes/list/list.html", } ) @@ -347,3 +348,15 @@ def set_expired_status(): """, (nowdate()), ) + + +def get_purchased_items(supplier_quotation: str): + return frappe._dict( + frappe.get_all( + "Purchase Order Item", + filters={"supplier_quotation": supplier_quotation, "docstatus": 1}, + fields=["supplier_quotation_item", {"SUM": "qty"}], + group_by="supplier_quotation_item", + as_list=1, + ) + ) diff --git a/erpnext/buying/doctype/supplier_quotation/test_supplier_quotation.py b/erpnext/buying/doctype/supplier_quotation/test_supplier_quotation.py index b0e5c29fdb9..ffbec9bd73e 100644 --- a/erpnext/buying/doctype/supplier_quotation/test_supplier_quotation.py +++ b/erpnext/buying/doctype/supplier_quotation/test_supplier_quotation.py @@ -2,15 +2,112 @@ # License: GNU General Public License v3. See license.txt +import json + import frappe from frappe.tests import IntegrationTestCase, change_settings from frappe.utils import add_days, today from erpnext.buying.doctype.supplier_quotation.supplier_quotation import make_purchase_order -from erpnext.controllers.accounts_controller import InvalidQtyError +from erpnext.controllers.accounts_controller import InvalidQtyError, update_child_qty_rate class TestPurchaseOrder(IntegrationTestCase): + def test_update_child_supplier_quotation_add_item(self): + sq = frappe.copy_doc(self.globalTestRecords["Supplier Quotation"][0]) + sq.submit() + + trans_item = json.dumps( + [ + { + "item_code": sq.items[0].item_code, + "rate": sq.items[0].rate, + "qty": 5, + "docname": sq.items[0].name, + }, + {"item_code": "_Test Item 2", "rate": 300, "qty": 3, "description": "test"}, + ] + ) + update_child_qty_rate("Supplier Quotation", trans_item, sq.name) + sq.reload() + self.assertEqual(sq.get("items")[0].qty, 5) + self.assertEqual(sq.get("items")[1].rate, 300) + self.assertEqual(sq.get("items")[1].description, "test") + + def test_update_supplier_quotation_child_rate_disallow(self): + sq = frappe.copy_doc(self.globalTestRecords["Supplier Quotation"][0]) + sq.submit() + trans_item = json.dumps( + [ + { + "item_code": sq.items[0].item_code, + "rate": 300, + "qty": sq.items[0].qty, + "docname": sq.items[0].name, + }, + ] + ) + self.assertRaises( + frappe.ValidationError, update_child_qty_rate, "Supplier Quotation", trans_item, sq.name + ) + + def test_update_supplier_quotation_child_remove_item(self): + sq = frappe.copy_doc(self.globalTestRecords["Supplier Quotation"][0]) + sq.submit() + po = make_purchase_order(sq.name) + + trans_item = json.dumps( + [ + { + "item_code": sq.items[0].item_code, + "rate": sq.items[0].rate, + "qty": sq.items[0].qty, + "docname": sq.items[0].name, + }, + { + "item_code": "_Test Item 2", + "rate": 300, + "qty": 3, + }, + ] + ) + po.get("items")[0].schedule_date = add_days(today(), 1) + update_child_qty_rate("Supplier Quotation", trans_item, sq.name) + po.submit() + sq.reload() + + trans_item = json.dumps( + [ + { + "item_code": "_Test Item 2", + "rate": 300, + "qty": 3, + } + ] + ) + + frappe.db.savepoint("before_cancel") + # check if item having purchase order can be removed + self.assertRaises( + frappe.LinkExistsError, update_child_qty_rate, "Supplier Quotation", trans_item, sq.name + ) + frappe.db.rollback(save_point="before_cancel") + + trans_item = json.dumps( + [ + { + "item_code": sq.items[0].item_code, + "rate": sq.items[0].rate, + "qty": sq.items[0].qty, + "docname": sq.items[0].name, + } + ] + ) + + update_child_qty_rate("Supplier Quotation", trans_item, sq.name) + sq.reload() + self.assertEqual(len(sq.get("items")), 1) + def test_supplier_quotation_qty(self): sq = frappe.copy_doc(self.globalTestRecords["Supplier Quotation"][0]) sq.items[0].qty = 0 diff --git a/erpnext/buying/number_card/average_order_values/average_order_values.json b/erpnext/buying/number_card/average_order_values/average_order_values.json new file mode 100644 index 00000000000..15ac1f2ecec --- /dev/null +++ b/erpnext/buying/number_card/average_order_values/average_order_values.json @@ -0,0 +1,26 @@ +{ + "aggregate_function_based_on": "base_rounded_total", + "creation": "2025-12-19 16:10:00.369804", + "currency": "", + "docstatus": 0, + "doctype": "Number Card", + "document_type": "Purchase Order", + "dynamic_filters_json": "[[\"Purchase Order\",\"company\",\"=\",\"frappe.defaults.get_user_default(\\\"Company\\\")\"]]", + "filters_json": "[[\"Purchase Order\",\"transaction_date\",\"Timespan\",\"this quarter\"],[\"Purchase Order\",\"docstatus\",\"=\",\"1\"],[\"Purchase Order\",\"is_subcontracted\",\"=\",0]]", + "function": "Average", + "idx": 0, + "is_public": 1, + "is_standard": 1, + "label": "Average Order Values", + "modified": "2025-12-19 16:57:02.546572", + "modified_by": "Administrator", + "module": "Buying", + "name": "Average Order Values", + "owner": "Administrator", + "parent_document_type": "", + "report_function": "Sum", + "show_full_number": 0, + "show_percentage_stats": 1, + "stats_time_interval": "Weekly", + "type": "Document Type" +} diff --git a/erpnext/buying/number_card/purchase_orders_count/purchase_orders_count.json b/erpnext/buying/number_card/purchase_orders_count/purchase_orders_count.json new file mode 100644 index 00000000000..8e88f6877e4 --- /dev/null +++ b/erpnext/buying/number_card/purchase_orders_count/purchase_orders_count.json @@ -0,0 +1,26 @@ +{ + "aggregate_function_based_on": "", + "creation": "2025-12-19 16:08:48.262514", + "currency": "", + "docstatus": 0, + "doctype": "Number Card", + "document_type": "Purchase Order", + "dynamic_filters_json": "[[\"Purchase Order\",\"company\",\"=\",\"frappe.defaults.get_user_default(\\\"Company\\\")\"]]", + "filters_json": "[[\"Purchase Order\",\"transaction_date\",\"Timespan\",\"this quarter\"],[\"Purchase Order\",\"docstatus\",\"=\",\"1\"],[\"Purchase Order\",\"is_subcontracted\",\"=\",0]]", + "function": "Count", + "idx": 1, + "is_public": 1, + "is_standard": 1, + "label": "Purchase Orders Count", + "modified": "2025-12-19 16:57:12.960310", + "modified_by": "Administrator", + "module": "Buying", + "name": "Purchase Orders Count", + "owner": "Administrator", + "parent_document_type": "", + "report_function": "Sum", + "show_full_number": 0, + "show_percentage_stats": 1, + "stats_time_interval": "Weekly", + "type": "Document Type" +} diff --git a/erpnext/buying/number_card/total_purchase_amount/total_purchase_amount.json b/erpnext/buying/number_card/total_purchase_amount/total_purchase_amount.json new file mode 100644 index 00000000000..05bdc742dc0 --- /dev/null +++ b/erpnext/buying/number_card/total_purchase_amount/total_purchase_amount.json @@ -0,0 +1,26 @@ +{ + "aggregate_function_based_on": "base_rounded_total", + "creation": "2025-12-19 16:07:19.293268", + "currency": "", + "docstatus": 0, + "doctype": "Number Card", + "document_type": "Purchase Order", + "dynamic_filters_json": "[[\"Purchase Order\",\"company\",\"=\",\"frappe.defaults.get_user_default(\\\"Company\\\")\"]]", + "filters_json": "[[\"Purchase Order\",\"transaction_date\",\"Timespan\",\"this quarter\"],[\"Purchase Order\",\"docstatus\",\"=\",\"1\"],[\"Purchase Order\",\"is_subcontracted\",\"=\",0]]", + "function": "Sum", + "idx": 0, + "is_public": 1, + "is_standard": 1, + "label": "Total Purchase Amount", + "modified": "2025-12-19 16:57:24.263495", + "modified_by": "Administrator", + "module": "Buying", + "name": "Total Purchase Amount", + "owner": "Administrator", + "parent_document_type": "", + "report_function": "Sum", + "show_full_number": 0, + "show_percentage_stats": 0, + "stats_time_interval": "Weekly", + "type": "Document Type" +} diff --git a/erpnext/buying/print_format/purchase_order_standard/__init__.py b/erpnext/buying/print_format/purchase_order_standard/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/erpnext/buying/print_format/purchase_order_standard/purchase_order_standard.json b/erpnext/buying/print_format/purchase_order_standard/purchase_order_standard.json new file mode 100644 index 00000000000..c5ee7381d5f --- /dev/null +++ b/erpnext/buying/print_format/purchase_order_standard/purchase_order_standard.json @@ -0,0 +1,33 @@ +{ + "absolute_value": 0, + "align_labels_right": 0, + "creation": "2025-11-30 16:55:52.799647", + "custom_format": 1, + "default_print_language": "en", + "disabled": 0, + "doc_type": "Purchase Order", + "docstatus": 0, + "doctype": "Print Format", + "font_size": 14, + "html": "{%- macro add_header(page_num, max_pages, doc, letter_head, no_letterhead, footer, print_settings=None, print_heading_template=None) -%}\n\t{% if letter_head and not no_letterhead %}\n\t\t
    {{ letter_head }}
    \n\t{% endif %}\n\t{% if print_heading_template %}\n\t\t{{ frappe.render_template(print_heading_template, {\"doc\":doc}) }}\n\t{% endif %}\n{%- endmacro -%}\n\n{% for page in layout %}\n
    \n\t
    \n\t\t{{ add_header(loop.index, layout|len, doc, letter_head, no_letterhead, footer, print_settings) }}\n\t
    \n\t{%- if doc.meta.is_submittable and doc.docstatus==2-%}\n\t\t
    \n\t\t\t

    {{ _(\"CANCELLED\") }}

    \n\t\t
    \n\t{%- endif -%}\n\t{%- if doc.meta.is_submittable and doc.docstatus==0 and (print_settings==None or print_settings.add_draft_heading) -%}\n\t\t
    \n\t\t\t

    {{ _(\"DRAFT\") }}

    \n\t\t
    \n\t{%- endif -%}\n\n\t\n\t
    \n\t\t\n\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\n\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\n\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\n\t\t
    \n\t\t\t\t\t{{ _(\"Supplier Name\") }}: {{doc.supplier_name }}\n\t\t\t\t\n\t\t\t\t\t{{ _(\"Required By\") }}: {{\n\t\t\t\t\tfrappe.utils.format_date(doc.schedule_date) }}\n\t\t\t\t
    {{ _(\"Order Number\") }}: {{ doc.name }}\n\t\t\t\t\t{{ _(\"Order Date\") }}: {{\n\t\t\t\t\tfrappe.utils.format_date(doc.transaction_date) }}\n\t\t\t\t
    {{ _(\"Supplier Address\") }}:
    \n\t\t\t\t\t{% if doc.supplier_address %}\n\t\t\t\t\t\t{% set supplier_address = frappe.db.get_value(\"Address\", doc.supplier_address, [\"address_line1\", \"address_line2\", \"city\", \"state\", \"pincode\", \"country\"], as_dict=True) %}\n {{ doc.supplier_name }}
    \n\t\t\t\t\t\t{{ supplier_address.address_line1 or \"\" }}
    \n\t\t\t\t\t\t{% if supplier_address.address_line2 %}{{ supplier_address.address_line2 }}
    {% endif %}\n\t\t\t\t\t\t{{ supplier_address.city or \"\" }} {{ supplier_address.state or \"\" }} {{ supplier_address.pincode or \"\" }} {{ supplier_address.country or \"\" }}
    \n\t\t\t\t\t{% endif %}\n\t\t\t\t
    {{ _(\"Company Address\") }}:
    \n {% if doc.billing_address %}\n {% set billing_address = frappe.db.get_value(\"Address\", doc.billing_address, [\"address_line1\", \"address_line2\", \"city\", \"state\", \"pincode\", \"country\"], as_dict=True) %}\n {{ doc.company }}
    \n {{ billing_address.get(\"address_line1\") or \"\" }}
    \n {% if billing_address.get(\"address_line2\") %}{{ billing_address.get(\"address_line2\") }}
    {% endif %}\n {{ billing_address.get(\"city\") or \"\" }}, {{ billing_address.get(\"state\") or \"\" }} {{ billing_address.get(\"pincode\") or \"\" }}, {{ billing_address.get(\"country\") or \"\" }}
    \n {% endif %}\n\t\t\t\t
    \n\n\t\t\n\t\t{% set item_naming_by = frappe.db.get_single_value(\"Stock Settings\", \"item_naming_by\") %}\n\t\t\n\t\t\t\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t{% if item_naming_by != \"Item Code\" %}\n\t\t\t\t\t\t\n\t\t\t\t\t{% endif %}\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\n\t\t\t\n\t\t\t\n\t\t\t\t{% for item in doc.items %}\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t{% if item_naming_by != \"Item Code\" %}\n\t\t\t\t\t\t\n\t\t\t\t\t{% endif %}\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\n\t\t\t\t{% endfor %}\n\t\t\t\n\t\t
    {{ _(\"No\") }}{{ _(\"Item\") }}{{ _(\"Item Code\") }}{{ _(\"Quantity\") }}{{ _(\"Rate\") }}{{ _(\"Amount\") }}
    {{ loop.index }}{{ item.item_name }}{{ item.item_code }}{{ item.get_formatted(\"qty\", 0) }} {{ item.uom }}{{ item.get_formatted(\"net_rate\", doc) }}\n\t\t\t\t\t\t{{ item.get_formatted(\"net_amount\", doc) }}\n\t\t\t\t\t
    \n\n\t\t\n\t\t\n\t\t\t\n\t\t\t\n\t\t\t\n\t\t
    \n\t\t\t\t

    {{ _(\"Total in words\") }}

    \n\t\t\t\t
    {{ doc.in_words }}
    \n\t\t\t
    \n\t\t\t\t \n\t\t\t\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t{%- if doc.apply_discount_on == \"Net Total\" -%}\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t{%- endif -%}\n\t\t\t\t\t{%- for tax in doc.taxes -%}\n\t\t\t\t\t\t{%- if (tax.tax_amount or print_settings.print_taxes_with_zero_amount) and (not tax.included_in_print_rate or doc.flags.show_inclusive_tax_in_print) -%}\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t{%- endif -%}\n\t\t\t\t\t{%- endfor -%}\n\t\t\t\t\t{%- if doc.apply_discount_on == \"Grand Total\" -%}\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t{%- endif -%}\n\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t
    {{ _(\"Sub Total:\") }}
    {{ doc.get_formatted(\"total\", doc) }}
    \n\t\t\t\t\t\t\t\t
    {{ _(\"Discount\") }} ({{ doc.additional_discount_percentage }}%):\n\t\t\t\t\t\t\t
    {{ doc.get_formatted(\"discount_amount\", doc) }}
    {{ tax.get_formatted(\"description\") }} ({{ tax.get_formatted(\"rate\") }}%):
    {{ tax.get_formatted(\"tax_amount\") }}
    \n\t\t\t\t\t\t\t\t
    {{ _(\"Discount\") }} ({{ doc.additional_discount_percentage }}%):\n\t\t\t\t\t\t\t
    {{ doc.get_formatted(\"discount_amount\", doc) }}
    {{ _(\"Grand Total:\") }}{{ doc.get_formatted(\"grand_total\", doc) }}
    \n\t\t\t
    \n\n\t\t\n\t\t
    \n\t\t\t{% if doc.terms %}\n\t\t\t
    \n\t\t\t\t
    {{ _(\"Terms and Conditions\") }}
    \n\t\t\t\t{{ doc.terms}}\n\t\t\t
    \n\t\t\t{% endif %}\n\t
    \n
    \n{% endfor %}\n", + "idx": 0, + "line_breaks": 0, + "margin_bottom": 15.0, + "margin_left": 15.0, + "margin_right": 15.0, + "margin_top": 15.0, + "modified": "2025-11-30 16:55:52.799647", + "modified_by": "Administrator", + "module": "Buying", + "name": "Purchase Order Standard", + "owner": "Administrator", + "page_number": "Hide", + "pdf_generator": "wkhtmltopdf", + "print_format_builder": 0, + "print_format_builder_beta": 0, + "print_format_for": "DocType", + "print_format_type": "Jinja", + "raw_printing": 0, + "show_section_headings": 0, + "standard": "Yes" +} diff --git a/erpnext/buying/print_format/purchase_order_with_item_image/__init__.py b/erpnext/buying/print_format/purchase_order_with_item_image/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/erpnext/buying/print_format/purchase_order_with_item_image/purchase_order_with_item_image.json b/erpnext/buying/print_format/purchase_order_with_item_image/purchase_order_with_item_image.json new file mode 100644 index 00000000000..2f4c09b0cb6 --- /dev/null +++ b/erpnext/buying/print_format/purchase_order_with_item_image/purchase_order_with_item_image.json @@ -0,0 +1,33 @@ +{ + "absolute_value": 0, + "align_labels_right": 0, + "creation": "2025-11-30 17:07:51.896474", + "custom_format": 1, + "default_print_language": "en", + "disabled": 0, + "doc_type": "Purchase Order", + "docstatus": 0, + "doctype": "Print Format", + "font_size": 14, + "html": "{%- macro add_header(page_num, max_pages, doc, letter_head, no_letterhead, footer, print_settings=None, print_heading_template=None) -%}\n\n{% if letter_head and not no_letterhead %}\n
    {{ letter_head }}
    \n{% endif %}\n{% if print_heading_template %}\n{{ frappe.render_template(print_heading_template, {\"doc\":doc}) }}\n{% endif %}\n{%- endmacro -%}\n\n{% for page in layout %}\n
    \n\t
    \n\t\t{{ add_header(loop.index, layout|len, doc, letter_head, no_letterhead, footer, print_settings) }}\n\t
    \n\t{%- if doc.meta.is_submittable and doc.docstatus==2-%}\n\t\t
    \n\t\t\t

    {{ _(\"CANCELLED\") }}

    \n\t\t
    \n\t{%- endif -%}\n\t{%- if doc.meta.is_submittable and doc.docstatus==0 and (print_settings==None or print_settings.add_draft_heading) -%}\n\t\t
    \n\t\t\t

    {{ _(\"DRAFT\") }}

    \n\t\t
    \n\t{%- endif -%}\n\n\t\n\n\t
    \n\t\t\n\t\t\t\n\t\t\t\t\n\n\t\t\t\t\n\t\t\t\n\t\t
    \n\t\t\t\t\t
    \n\t\t\t\t\t\t
    Customer Name:
    \n\t\t\t\t\t\t
    Supplier Address:
    \n\t\t\t\t\t
    \n\t\t\t\t\t
    \n\t\t\t\t\t\t
    {{ doc.supplier_name }}
    \n\t\t\t\t\t\t
    \n \t\t\t\t\t{% if doc.supplier_address %}\n \t\t\t\t\t\t{% set supplier_address = frappe.db.get_value(\"Address\", doc.supplier_address, [\"address_line1\", \"address_line2\", \"city\", \"state\", \"pincode\", \"country\"], as_dict=True) %}\n {{ doc.supplier_name }}
    \n \t\t\t\t\t\t{{ supplier_address.address_line1 or \"\" }}
    \n \t\t\t\t\t\t{% if supplier_address.address_line2 %}{{ supplier_address.address_line2 }}
    {% endif %}\n \t\t\t\t\t\t{{ supplier_address.city or \"\" }} {{ supplier_address.state or \"\" }} {{ supplier_address.pincode or \"\" }} {{ supplier_address.country or \"\" }}
    \n \t\t\t\t\t{% endif %}\n\t\t\t\t\t\t
    \n\n\t\t\t\t\t
    \n\t\t\t\t
    \n\t\t\t\t\t
    \n\t\t\t\t\t\t
    {{ _(\"Purchase Order:\") }}
    \n\t\t\t\t\t
    \n\t\t\t\t\t
    \n\t\t\t\t\t\t
    {{ doc.name }}
    \n\t\t\t\t\t
    \n\t\t\t\t\t
    \n\t\t\t\t\t\t
    {{ _(\"Order Date:\") }}
    \n\t\t\t\t\t
    \n\t\t\t\t\t
    \n\t\t\t\t\t\t
    {{ frappe.utils.format_date(doc.transaction_date) }}
    \n\t\t\t\t\t
    \n\t\t\t\t\t
    \n\t\t\t\t\t\t
    {{ _(\"Required By:\") }}
    \n\t\t\t\t\t
    \n\t\t\t\t\t
    \n\t\t\t\t\t\t
    {{ frappe.utils.format_date(doc.schedule_date) }}
    \n\t\t\t\t\t
    \n\t\t\t\t
    \n\n\t\t\n\t\t{% set item_naming_by = frappe.db.get_single_value(\"Stock Settings\", \"item_naming_by\") %}\n\t\t\n\t\t\t\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t{% if item_naming_by != \"Item Code\" %}\n\t\t\t\t\t\t\n\t\t\t\t\t{% endif %}\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\n\t\t\t\n\t\t\t\n\t\t\t\t{% for item in doc.items %}\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t{% if item_naming_by != \"Item Code\" %}\n\t\t\t\t\t\t\n\t\t\t\t\t{% endif %}\n\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\n\t\t\t\t{% endfor %}\n\t\t\t\n\t\t
    {{ _(\"No\") }}{{ _(\"Item\") }}{{ _(\"Item Code\") }}{{ _(\"Quantity\") }}{{ _(\"Rate\") }}{{ _(\"Amount\") }}
    {{ loop.index }}\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t{% if item.image %}\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t{% endif %}\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t{{ item.item_name }}\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t
    \n\t\t\t\t\t
    {{ item.item_code }}{{ item.get_formatted(\"qty\", 0) }} {{ item.uom }}{{ item.get_formatted(\"net_rate\", doc) }}{{ item.get_formatted(\"net_amount\", doc) }}
    \n\n\t\t
    \n\t\t\t\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\n\n\t\t\t\t{%- if doc.apply_discount_on == \"Net Total\" -%}\n\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t{%- endif -%}\n\t\t\t\t{%- for tax in doc.taxes -%}\n\t\t\t\t\t{%- if (tax.tax_amount or print_settings.print_taxes_with_zero_amount) and (not tax.included_in_print_rate or doc.flags.show_inclusive_tax_in_print) -%}\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t{%- endif -%}\n\t\t\t\t{%- endfor -%}\n\t\t\t\t{%- if doc.apply_discount_on == \"Grand Total\" -%}\n\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t{%- endif -%}\n\t\t\t
    {{ _(\"Sub Total:\") }}{{ doc.get_formatted(\"total\", doc) }}
    \n\t\t\t\t\t\t\t{{ _(\"Discount\") }} ({{ doc.additional_discount_percentage }}%):\n\t\t\t\t\t\t{{ doc.get_formatted(\"discount_amount\", doc) }}
    {{ tax.get_formatted(\"description\") }} ({{ tax.get_formatted(\"rate\") }}%):{{ tax.get_formatted(\"tax_amount\") }}
    \n\t\t\t\t\t\t\t{{ _(\"Discount\") }} ({{ doc.additional_discount_percentage }}%):\n\t\t\t\t\t\t{{ doc.get_formatted(\"discount_amount\", doc) }}
    \n\t\t
    \n\n\t\t
    \n\t\t\t\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\n\t\t\t
    \n\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t {{ _(\"In Words: \") }}{{ doc.in_words }}\n\t\t\t\t\t\t
    \n\t\t\t\t\t
    {{ _(\"Grand Total:\") }}\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t{{ doc.get_formatted(\"grand_total\", doc) }}\n\t\t\t\t\t\t\n\t\t\t\t\t
    \n\t\t
    \n\n\n\t\t\n\t\t{% if doc.terms %}\n\t\t
    \n\t\t\t
    {{ _(\"Terms and Conditions\") }}
    \n\t\t\t{{ doc.terms}}\n\t\t
    \n\t\t{% endif %}\n\t
    \n
    \n{% endfor %}\n", + "idx": 0, + "line_breaks": 0, + "margin_bottom": 15.0, + "margin_left": 15.0, + "margin_right": 15.0, + "margin_top": 15.0, + "modified": "2025-11-30 20:07:51.896474", + "modified_by": "Administrator", + "module": "Buying", + "name": "Purchase Order with Item Image", + "owner": "Administrator", + "page_number": "Hide", + "pdf_generator": "wkhtmltopdf", + "print_format_builder": 0, + "print_format_builder_beta": 0, + "print_format_for": "DocType", + "print_format_type": "Jinja", + "raw_printing": 0, + "show_section_headings": 0, + "standard": "Yes" +} diff --git a/erpnext/buying/report/purchase_order_trends/purchase_order_trends.py b/erpnext/buying/report/purchase_order_trends/purchase_order_trends.py index a7b4a7207c6..dd518e838ad 100644 --- a/erpnext/buying/report/purchase_order_trends/purchase_order_trends.py +++ b/erpnext/buying/report/purchase_order_trends/purchase_order_trends.py @@ -36,7 +36,7 @@ def get_chart_data(data, conditions, filters): # fetch only periodic columns as labels columns = conditions.get("columns")[start:-2][2::2] - labels = [column.split(":")[0] for column in columns] + labels = [column.split(":")[0].replace(" (Amt)", "") for column in columns] datapoints = [0] * len(labels) for row in data: diff --git a/erpnext/buying/workspace/buying/buying.json b/erpnext/buying/workspace/buying/buying.json index db5c7d046db..18d86da9ea5 100644 --- a/erpnext/buying/workspace/buying/buying.json +++ b/erpnext/buying/workspace/buying/buying.json @@ -1,11 +1,12 @@ { + "app": "erpnext", "charts": [ { "chart_name": "Purchase Order Trends", "label": "Purchase Order Trends" } ], - "content": "[{\"id\":\"I3JijHOxil\",\"type\":\"onboarding\",\"data\":{\"onboarding_name\":\"Buying\",\"col\":12}},{\"id\":\"j3dJGo8Ok6\",\"type\":\"chart\",\"data\":{\"chart_name\":\"Purchase Order Trends\",\"col\":12}},{\"id\":\"oN7lXSwQji\",\"type\":\"spacer\",\"data\":{\"col\":12}},{\"id\":\"Ivw1PI_wEJ\",\"type\":\"header\",\"data\":{\"text\":\"Your Shortcuts\",\"col\":12}},{\"id\":\"RrWFEi4kCf\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Item\",\"col\":3}},{\"id\":\"RFIakryyJP\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Material Request\",\"col\":3}},{\"id\":\"bM10abFmf6\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Purchase Order\",\"col\":3}},{\"id\":\"lR0Hw_37Pu\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Purchase Analytics\",\"col\":3}},{\"id\":\"_HN0Ljw1lX\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Purchase Order Analysis\",\"col\":3}},{\"id\":\"kuLuiMRdnX\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Dashboard\",\"col\":3}},{\"id\":\"tQFeiKptW2\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Learn Procurement\",\"col\":3}},{\"id\":\"0NiuFE_EGS\",\"type\":\"spacer\",\"data\":{\"col\":12}},{\"id\":\"Xe2GVLOq8J\",\"type\":\"header\",\"data\":{\"text\":\"Reports & Masters\",\"col\":12}},{\"id\":\"QwqyG6XuUt\",\"type\":\"card\",\"data\":{\"card_name\":\"Buying\",\"col\":4}},{\"id\":\"bTPjOxC_N_\",\"type\":\"card\",\"data\":{\"card_name\":\"Items & Pricing\",\"col\":4}},{\"id\":\"87ht0HIneb\",\"type\":\"card\",\"data\":{\"card_name\":\"Settings\",\"col\":4}},{\"id\":\"EDOsBOmwgw\",\"type\":\"card\",\"data\":{\"card_name\":\"Supplier\",\"col\":4}},{\"id\":\"oWNNIiNb2i\",\"type\":\"card\",\"data\":{\"card_name\":\"Supplier Scorecard\",\"col\":4}},{\"id\":\"7F_13-ihHB\",\"type\":\"card\",\"data\":{\"card_name\":\"Key Reports\",\"col\":4}},{\"id\":\"pfwiLvionl\",\"type\":\"card\",\"data\":{\"card_name\":\"Other Reports\",\"col\":4}},{\"id\":\"8ySDy6s4qn\",\"type\":\"card\",\"data\":{\"card_name\":\"Regional\",\"col\":4}}]", + "content": "[{\"id\":\"j3dJGo8Ok6\",\"type\":\"chart\",\"data\":{\"chart_name\":\"Purchase Order Trends\",\"col\":12}},{\"id\":\"k75jSq2D6Z\",\"type\":\"number_card\",\"data\":{\"number_card_name\":\"Purchase Orders Count\",\"col\":4}},{\"id\":\"UPXys0lQLj\",\"type\":\"number_card\",\"data\":{\"number_card_name\":\"Total Purchase Amount\",\"col\":4}},{\"id\":\"yQGK3eb2hg\",\"type\":\"number_card\",\"data\":{\"number_card_name\":\"Average Order Values\",\"col\":4}},{\"id\":\"oN7lXSwQji\",\"type\":\"spacer\",\"data\":{\"col\":12}},{\"id\":\"Ivw1PI_wEJ\",\"type\":\"header\",\"data\":{\"text\":\"Your Shortcuts\",\"col\":12}},{\"id\":\"RrWFEi4kCf\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Item\",\"col\":3}},{\"id\":\"RFIakryyJP\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Material Request\",\"col\":3}},{\"id\":\"bM10abFmf6\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Purchase Order\",\"col\":3}},{\"id\":\"lR0Hw_37Pu\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Purchase Analytics\",\"col\":3}},{\"id\":\"_HN0Ljw1lX\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Purchase Order Analysis\",\"col\":3}},{\"id\":\"kuLuiMRdnX\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Dashboard\",\"col\":3}},{\"id\":\"tQFeiKptW2\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Learn Procurement\",\"col\":3}},{\"id\":\"0NiuFE_EGS\",\"type\":\"spacer\",\"data\":{\"col\":12}},{\"id\":\"Xe2GVLOq8J\",\"type\":\"header\",\"data\":{\"text\":\"Reports & Masters\",\"col\":12}},{\"id\":\"QwqyG6XuUt\",\"type\":\"card\",\"data\":{\"card_name\":\"Buying\",\"col\":4}},{\"id\":\"bTPjOxC_N_\",\"type\":\"card\",\"data\":{\"card_name\":\"Items & Pricing\",\"col\":4}},{\"id\":\"87ht0HIneb\",\"type\":\"card\",\"data\":{\"card_name\":\"Settings\",\"col\":4}},{\"id\":\"EDOsBOmwgw\",\"type\":\"card\",\"data\":{\"card_name\":\"Supplier\",\"col\":4}},{\"id\":\"oWNNIiNb2i\",\"type\":\"card\",\"data\":{\"card_name\":\"Supplier Scorecard\",\"col\":4}},{\"id\":\"7F_13-ihHB\",\"type\":\"card\",\"data\":{\"card_name\":\"Key Reports\",\"col\":4}},{\"id\":\"pfwiLvionl\",\"type\":\"card\",\"data\":{\"card_name\":\"Other Reports\",\"col\":4}},{\"id\":\"8ySDy6s4qn\",\"type\":\"card\",\"data\":{\"card_name\":\"Regional\",\"col\":4}}]", "creation": "2020-01-28 11:50:26.195467", "custom_blocks": [], "docstatus": 0, @@ -511,11 +512,24 @@ "type": "Link" } ], - "modified": "2023-07-04 14:43:30.387683", + "modified": "2025-12-19 16:12:02.461082", "modified_by": "Administrator", "module": "Buying", "name": "Buying", - "number_cards": [], + "number_cards": [ + { + "label": "Purchase Orders Count", + "number_card_name": "Purchase Orders Count" + }, + { + "label": "Total Purchase Amount", + "number_card_name": "Total Purchase Amount" + }, + { + "label": "Average Order Values", + "number_card_name": "Average Order Values" + } + ], "owner": "Administrator", "parent_page": "", "public": 1, @@ -558,11 +572,13 @@ { "label": "Purchase Analytics", "link_to": "Purchase Analytics", + "report_ref_doctype": "Purchase Order", "type": "Report" }, { "label": "Purchase Order Analysis", "link_to": "Purchase Order Analysis", + "report_ref_doctype": "Purchase Order", "type": "Report" }, { @@ -571,5 +587,6 @@ "type": "Dashboard" } ], - "title": "Buying" + "title": "Buying", + "type": "Workspace" } diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py index 3902b2f7202..59810544c0c 100644 --- a/erpnext/controllers/accounts_controller.py +++ b/erpnext/controllers/accounts_controller.py @@ -7,6 +7,7 @@ from collections import defaultdict import frappe from frappe import _, bold, qb, throw +from frappe.contacts.doctype.address.address import get_address_display from frappe.model.workflow import get_workflow_name, is_transition_condition_satisfied from frappe.query_builder import Criterion, DocType from frappe.query_builder.custom import ConstantColumn @@ -296,8 +297,6 @@ class AccountsController(TransactionBase): if self.doctype == "Purchase Invoice": self.calculate_paid_amount() - # apply tax withholding only if checked and applicable - self.set_tax_withholding() with temporary_flag("company", self.company): validate_regional(self) @@ -310,6 +309,52 @@ class AccountsController(TransactionBase): self.set_default_letter_head() self.validate_company_in_accounting_dimension() self.validate_party_address_and_contact() + self.validate_company_linked_addresses() + + def validate_company_linked_addresses(self): + address_fields = [] + sales_doctypes = ("Quotation", "Sales Order", "Delivery Note", "Sales Invoice") + purchase_doctypes = ("Purchase Order", "Purchase Receipt", "Purchase Invoice", "Supplier Quotation") + + if self.doctype in sales_doctypes: + address_fields = ["dispatch_address_name", "company_address"] + elif self.doctype in purchase_doctypes: + address_fields = ["billing_address", "shipping_address"] + + if not address_fields: + return + + # Determine if drop ship applies + is_drop_ship = self.doctype in { + "Purchase Order", + "Sales Order", + "Sales Invoice", + } and self.is_drop_ship(self.items) + + for field in address_fields: + address = self.get(field) + + if (field in ["dispatch_address_name", "shipping_address"]) and is_drop_ship: + continue + + if address and not frappe.db.exists( + "Dynamic Link", + { + "parent": address, + "parenttype": "Address", + "link_doctype": "Company", + "link_name": self.company, + }, + ): + frappe.throw( + _("{0} does not belong to the Company {1}.").format( + _(self.meta.get_label(field)), bold(self.company) + ) + ) + + @staticmethod + def is_drop_ship(items): + return any(item.delivered_by_supplier for item in items) def set_default_letter_head(self): if hasattr(self, "letter_head") and not self.letter_head: @@ -364,6 +409,24 @@ class AccountsController(TransactionBase): for _doctype in repost_doctypes: dt = frappe.qb.DocType(_doctype) + + cancelled_entries = ( + frappe.qb.from_(dt) + .select(dt.parent, dt.parenttype) + .where((dt.voucher_type == self.doctype) & (dt.voucher_no == self.name) & (dt.docstatus == 2)) + .run(as_dict=True) + ) + + if cancelled_entries: + entries = "
    ".join([get_link_to_form(d.parenttype, d.parent) for d in cancelled_entries]) + + frappe.throw( + _( + "The following cancelled repost entries exist for {0}:

    {1}

    " + "Kindly delete these entries before continuing." + ).format(self.name, entries) + ) + rows = ( frappe.qb.from_(dt) .select(dt.name, dt.parent, dt.parenttype) @@ -1034,6 +1097,12 @@ class AccountsController(TransactionBase): ): item.set("is_fixed_asset", ret.get("is_fixed_asset", 0)) + if self.doctype in ["Purchase Invoice", "Sales Invoice"] and item.meta.get_field( + "tax_withholding_category", + ): + if not item.get("tax_withholding_category") and ret.get("tax_withholding_category"): + item.set("tax_withholding_category", ret.get("tax_withholding_category")) + # Double check for cost center # Items add via promotional scheme may not have cost center set if hasattr(item, "cost_center") and not item.get("cost_center"): @@ -2313,7 +2382,7 @@ class AccountsController(TransactionBase): def validate_party(self): party_type, party = self.get_party() - validate_party_frozen_disabled(party_type, party) + validate_party_frozen_disabled(self.company, party_type, party) def get_party(self): party_type = None @@ -2642,7 +2711,9 @@ class AccountsController(TransactionBase): for d in self.get("payment_schedule"): d.validate_from_to_dates("discount_date", "due_date") - if self.doctype == "Sales Order" and getdate(d.due_date) < getdate(self.transaction_date): + if self.doctype in ["Sales Order", "Quotation"] and getdate(d.due_date) < getdate( + self.transaction_date + ): frappe.throw( _("Row {0}: Due Date in the Payment Terms table cannot be before Posting Date").format( d.idx @@ -3642,7 +3713,7 @@ def set_order_defaults(parent_doctype, parent_doctype_name, child_doctype, child conversion_factor = flt(get_conversion_factor(item.item_code, child_item.uom).get("conversion_factor")) child_item.conversion_factor = flt(trans_item.get("conversion_factor")) or conversion_factor - if child_doctype == "Purchase Order Item": + if child_doctype in ["Purchase Order Item", "Supplier Quotation Item"]: # Initialized value will update in parent validation child_item.base_rate = 1 child_item.base_amount = 1 @@ -3660,7 +3731,7 @@ def set_order_defaults(parent_doctype, parent_doctype_name, child_doctype, child return child_item -def validate_child_on_delete(row, parent): +def validate_child_on_delete(row, parent, ordered_item=None): """Check if partially transacted item (row) is being deleted.""" if parent.doctype == "Sales Order": if flt(row.delivered_qty): @@ -3688,13 +3759,17 @@ def validate_child_on_delete(row, parent): row.idx, row.item_code ) ) - - if flt(row.billed_amt): - frappe.throw( - _("Row #{0}: Cannot delete item {1} which has already been billed.").format( - row.idx, row.item_code + if parent.doctype in ["Purchase Order", "Sales Order"]: + if flt(row.billed_amt): + frappe.throw( + _("Row #{0}: Cannot delete item {1} which has already been billed.").format( + row.idx, row.item_code + ) ) - ) + + if parent.doctype == "Quotation": + if ordered_item.get(row.name): + frappe.throw(_("Cannot delete an item which has been ordered")) def update_bin_on_delete(row, doctype): @@ -3720,7 +3795,7 @@ def update_bin_on_delete(row, doctype): update_bin_qty(row.item_code, row.warehouse, qty_dict) -def validate_and_delete_children(parent, data) -> bool: +def validate_and_delete_children(parent, data, ordered_item=None) -> bool: deleted_children = [] updated_item_names = [d.get("docname") for d in data] for item in parent.items: @@ -3728,7 +3803,7 @@ def validate_and_delete_children(parent, data) -> bool: deleted_children.append(item) for d in deleted_children: - validate_child_on_delete(d, parent) + validate_child_on_delete(d, parent, ordered_item) d.cancel() d.delete() @@ -3737,16 +3812,19 @@ def validate_and_delete_children(parent, data) -> bool: # need to update ordered qty in Material Request first # bin uses Material Request Items to recalculate & update - parent.update_prevdoc_status() - - for d in deleted_children: - update_bin_on_delete(d, parent.doctype) + if parent.doctype not in ["Quotation", "Supplier Quotation"]: + parent.update_prevdoc_status() + for d in deleted_children: + update_bin_on_delete(d, parent.doctype) return bool(deleted_children) @frappe.whitelist() def update_child_qty_rate(parent_doctype, trans_items, parent_doctype_name, child_docname="items"): + from erpnext.buying.doctype.supplier_quotation.supplier_quotation import get_purchased_items + from erpnext.selling.doctype.quotation.quotation import get_ordered_items + def check_doc_permissions(doc, perm_type="create"): try: doc.check_permission(perm_type) @@ -3785,7 +3863,7 @@ def update_child_qty_rate(parent_doctype, trans_items, parent_doctype_name, chil ) def get_new_child_item(item_row): - child_doctype = "Sales Order Item" if parent_doctype == "Sales Order" else "Purchase Order Item" + child_doctype = parent_doctype + " Item" return set_order_defaults(parent_doctype, parent_doctype_name, child_doctype, child_docname, item_row) def is_allowed_zero_qty(): @@ -3810,6 +3888,21 @@ def update_child_qty_rate(parent_doctype, trans_items, parent_doctype_name, chil if parent_doctype == "Purchase Order" and flt(new_data.get("qty")) < flt(child_item.received_qty): frappe.throw(_("Cannot set quantity less than received quantity")) + if parent_doctype in ["Quotation", "Supplier Quotation"]: + if (parent_doctype == "Quotation" and not ordered_items) or ( + parent_doctype == "Supplier Quotation" and not purchased_items + ): + return + + qty_to_check = ( + ordered_items.get(child_item.name) + if parent_doctype == "Quotation" + else purchased_items.get(child_item.name) + ) + if qty_to_check: + if flt(new_data.get("qty")) < qty_to_check: + frappe.throw(_("Cannot reduce quantity than ordered or purchased quantity")) + def should_update_supplied_items(doc) -> bool: """Subcontracted PO can allow following changes *after submit*: @@ -3852,7 +3945,6 @@ def update_child_qty_rate(parent_doctype, trans_items, parent_doctype_name, chil frappe.throw(_("Finished Good Item {0} Qty can not be zero").format(new_data["fg_item"])) data = json.loads(trans_items) - any_qty_changed = False # updated to true if any item's qty changes items_added_or_removed = False # updated to true if any new item is added or removed any_conversion_factor_changed = False @@ -3860,7 +3952,16 @@ def update_child_qty_rate(parent_doctype, trans_items, parent_doctype_name, chil parent = frappe.get_doc(parent_doctype, parent_doctype_name) check_doc_permissions(parent, "write") - _removed_items = validate_and_delete_children(parent, data) + + if parent_doctype == "Quotation": + ordered_items = get_ordered_items(parent.name) + _removed_items = validate_and_delete_children(parent, data, ordered_items) + elif parent_doctype == "Supplier Quotation": + purchased_items = get_purchased_items(parent.name) + _removed_items = validate_and_delete_children(parent, data, purchased_items) + else: + _removed_items = validate_and_delete_children(parent, data) + items_added_or_removed |= _removed_items for d in data: @@ -3893,6 +3994,8 @@ def update_child_qty_rate(parent_doctype, trans_items, parent_doctype_name, chil elif parent_doctype == "Purchase Order": prev_date, new_date = child_item.get("schedule_date"), d.get("schedule_date") + prev_description, new_description = (child_item.get("description"), d.get("description")) + description_unchanged = prev_description == new_description rate_unchanged = prev_rate == new_rate qty_unchanged = prev_qty == new_qty fg_qty_unchanged = prev_fg_qty == new_fg_qty @@ -3900,7 +4003,9 @@ def update_child_qty_rate(parent_doctype, trans_items, parent_doctype_name, chil conversion_factor_unchanged = prev_con_fac == new_con_fac any_conversion_factor_changed |= not conversion_factor_unchanged date_unchanged = ( - prev_date == getdate(new_date) if prev_date and new_date else False + (prev_date == getdate(new_date) if prev_date and new_date else False) + if parent_doctype not in ["Quotation", "Supplier Quotation"] + else None ) # in case of delivery note etc if ( rate_unchanged @@ -3909,10 +4014,15 @@ def update_child_qty_rate(parent_doctype, trans_items, parent_doctype_name, chil and conversion_factor_unchanged and uom_unchanged and date_unchanged + and description_unchanged ): continue validate_quantity(child_item, d) + if parent_doctype in ["Quotation", "Supplier Quotation"]: + if not rate_unchanged: + frappe.throw(_("Rates cannot be modified for quoted items")) + if flt(child_item.get("qty")) != flt(d.get("qty")): any_qty_changed = True @@ -3928,6 +4038,7 @@ def update_child_qty_rate(parent_doctype, trans_items, parent_doctype_name, chil child_item.fg_item = d["fg_item"] child_item.qty = flt(d.get("qty")) + child_item.description = d.get("description") rate_precision = child_item.precision("rate") or 2 conv_fac_precision = child_item.precision("conversion_factor") or 2 qty_precision = child_item.precision("qty") or 2 @@ -3936,18 +4047,21 @@ def update_child_qty_rate(parent_doctype, trans_items, parent_doctype_name, chil rate_unchanged = prev_rate == new_rate if not rate_unchanged and not child_item.get("qty") and is_allowed_zero_qty(): frappe.throw(_("Rate of '{}' items cannot be changed").format(frappe.bold(_("Unit Price")))) - # Amount cannot be lesser than billed amount, except for negative amounts row_rate = flt(d.get("rate"), rate_precision) - amount_below_billed_amt = flt(child_item.billed_amt, rate_precision) > flt( - row_rate * flt(d.get("qty"), qty_precision), rate_precision - ) - if amount_below_billed_amt and row_rate > 0.0: - frappe.throw( - _( - "Row #{0}: Cannot set Rate if the billed amount is greater than the amount for Item {1}." - ).format(child_item.idx, child_item.item_code) + + if parent_doctype in ["Purchase Order", "Sales Order"]: + amount_below_billed_amt = flt(child_item.billed_amt, rate_precision) > flt( + row_rate * flt(d.get("qty"), qty_precision), rate_precision ) + if amount_below_billed_amt and row_rate > 0.0: + frappe.throw( + _( + "Row #{0}: Cannot set Rate if the billed amount is greater than the amount for Item {1}." + ).format(child_item.idx, child_item.item_code) + ) + else: + child_item.rate = row_rate else: child_item.rate = row_rate @@ -3975,26 +4089,27 @@ def update_child_qty_rate(parent_doctype, trans_items, parent_doctype_name, chil if d.get("bom_no") and parent_doctype == "Sales Order": child_item.bom_no = d.get("bom_no") - if flt(child_item.price_list_rate): - if flt(child_item.rate) > flt(child_item.price_list_rate): - # if rate is greater than price_list_rate, set margin - # or set discount - child_item.discount_percentage = 0 - child_item.margin_type = "Amount" - child_item.margin_rate_or_amount = flt( - child_item.rate - child_item.price_list_rate, - child_item.precision("margin_rate_or_amount"), - ) - child_item.rate_with_margin = child_item.rate - else: - child_item.discount_percentage = flt( - (1 - flt(child_item.rate) / flt(child_item.price_list_rate)) * 100.0, - child_item.precision("discount_percentage"), - ) - child_item.discount_amount = flt(child_item.price_list_rate) - flt(child_item.rate) - child_item.margin_type = "" - child_item.margin_rate_or_amount = 0 - child_item.rate_with_margin = 0 + if parent_doctype in ["Sales Order", "Purchase Order"]: + if flt(child_item.price_list_rate): + if flt(child_item.rate) > flt(child_item.price_list_rate): + # if rate is greater than price_list_rate, set margin + # or set discount + child_item.discount_percentage = 0 + child_item.margin_type = "Amount" + child_item.margin_rate_or_amount = flt( + child_item.rate - child_item.price_list_rate, + child_item.precision("margin_rate_or_amount"), + ) + child_item.rate_with_margin = child_item.rate + else: + child_item.discount_percentage = flt( + (1 - flt(child_item.rate) / flt(child_item.price_list_rate)) * 100.0, + child_item.precision("discount_percentage"), + ) + child_item.discount_amount = flt(child_item.price_list_rate) - flt(child_item.rate) + child_item.margin_type = "" + child_item.margin_rate_or_amount = 0 + child_item.rate_with_margin = 0 child_item.flags.ignore_validate_update_after_submit = True if new_child_flag: @@ -4016,13 +4131,14 @@ def update_child_qty_rate(parent_doctype, trans_items, parent_doctype_name, chil parent.doctype, parent.company, parent.base_grand_total ) - parent.set_payment_schedule() + if parent_doctype != "Supplier Quotation": + parent.set_payment_schedule() if parent_doctype == "Purchase Order": parent.validate_minimum_order_qty() parent.validate_budget() if parent.is_against_so(): parent.update_status_updater() - else: + elif parent_doctype == "Sales Order": parent.check_credit_limit() # reset index of child table @@ -4055,7 +4171,7 @@ def update_child_qty_rate(parent_doctype, trans_items, parent_doctype_name, chil "Items cannot be updated as Subcontracting Order is created against the Purchase Order {0}." ).format(frappe.bold(parent.name)) ) - else: # Sales Order + elif parent_doctype == "Sales Order": # Sales Order if parent.is_subcontracted and not parent.can_update_items(): frappe.throw( _( @@ -4073,9 +4189,10 @@ def update_child_qty_rate(parent_doctype, trans_items, parent_doctype_name, chil parent.reload() validate_workflow_conditions(parent) - parent.update_blanket_order() - parent.update_billing_percentage() - parent.set_status() + if parent_doctype in ["Purchase Order", "Sales Order"]: + parent.update_blanket_order() + parent.update_billing_percentage() + parent.set_status() parent.validate_uom_is_integer("uom", "qty") parent.validate_uom_is_integer("stock_uom", "stock_qty") @@ -4167,3 +4284,130 @@ def update_gl_dict_with_regional_fields(doc, gl_dict): def update_gl_dict_with_app_based_fields(doc, gl_dict): for method in frappe.get_hooks("update_gl_dict_with_app_based_fields", default=[]): frappe.get_attr(method)(doc, gl_dict) + + +@frappe.whitelist() +def get_missing_company_details(doctype, docname): + from frappe.contacts.doctype.address.address import get_address_display_list + + company = frappe.db.get_value(doctype, docname, "company") + if doctype == "Purchase Order": + company_address = frappe.db.get_value(doctype, docname, "billing_address") + else: + company_address = frappe.db.get_value(doctype, docname, "company_address") + + company_details = frappe.get_value( + "Company", company, ["company_logo", "website", "phone_no", "email"], as_dict=True + ) + + required_fields = [ + company_details.get("company_logo"), + company_details.get("phone_no"), + company_details.get("email"), + ] + + if not all(required_fields) and not frappe.has_permission("Company", "write", throw=False): + frappe.msgprint( + _( + "Some required Company details are missing. You don't have permission to update them. Please contact your System Manager." + ) + ) + return + + if not company_address and not frappe.has_permission(doctype, "write", throw=False): + frappe.msgprint( + _( + "Company Address is missing. You don't have permission to update it. Please contact your System Manager." + ) + ) + return + + address_display_list = get_address_display_list("Company", company) + address_line = address_display_list[0].get("address_line1") if address_display_list else "" + + required_fields.append(company_address) + required_fields.append(address_line) + + if all(required_fields): + return False + return { + "company_logo": company_details.get("company_logo"), + "website": company_details.get("website"), + "phone_no": company_details.get("phone_no"), + "email": company_details.get("email"), + "address_line": address_line, + "company": company, + "company_address": company_address, + "name": docname, + } + + +@frappe.whitelist() +def update_company_master_and_address(current_doctype, name, company, details): + from frappe.utils import validate_email_address + + if isinstance(details, str): + details = frappe.parse_json(details) + + if details.get("email"): + validate_email_address(details.get("email"), throw=True) + + company_fields = ["company_logo", "website", "phone_no", "email"] + company_fields_to_update = {field: details.get(field) for field in company_fields if details.get(field)} + + if company_fields_to_update: + frappe.db.set_value("Company", company, company_fields_to_update) + + company_address = details.get("company_address") + if details.get("address_line1"): + address_doc = frappe.get_doc( + { + "doctype": "Address", + "address_title": details.get("address_title"), + "address_type": details.get("address_type"), + "address_line1": details.get("address_line1"), + "address_line2": details.get("address_line2"), + "city": details.get("city"), + "state": details.get("state"), + "pincode": details.get("pincode"), + "country": details.get("country"), + "is_your_company_address": 1, + "links": [{"link_doctype": "Company", "link_name": company}], + } + ) + address_doc.insert() + company_address = address_doc.name + + update_doc_company_address(current_doctype, name, company_address, details) + + +def update_doc_company_address(current_doctype, docname, company_address, details): + if not company_address: + return + + address_field_map = { + "Purchase Order": ("billing_address", "billing_address_display"), + "Sales Invoice": ("company_address", "company_address_display"), + "Delivery Note": ("company_address", "company_address_display"), + "POS Invoice": ("company_address", "company_address_display"), + } + + address_field, display_field = address_field_map.get( + current_doctype, ("company_address", "company_address_display") + ) + + current_display = frappe.db.get_value(current_doctype, docname, display_field) + + if current_display and not details.get("address_line1"): + return + + from frappe.query_builder import DocType + + DocType = DocType(current_doctype) + + ( + frappe.qb.update(DocType) + .set(getattr(DocType, address_field), company_address) + .set(getattr(DocType, display_field), get_address_display(company_address)) + .where(DocType.name == docname) + ).run() diff --git a/erpnext/controllers/buying_controller.py b/erpnext/controllers/buying_controller.py index 373481fee72..a0d51a0c016 100644 --- a/erpnext/controllers/buying_controller.py +++ b/erpnext/controllers/buying_controller.py @@ -81,6 +81,19 @@ class BuyingController(SubcontractingController): ), ) + if ( + self.get("company") + and ( + default_buying_terms := frappe.get_value( + "Company", self.get("company"), "default_buying_terms" + ) + ) + and not self.get("tc_name") + and not self.get("terms") + ): + self.tc_name = default_buying_terms + self.terms = frappe.get_value("Terms and Conditions", self.get("tc_name"), "terms") + def validate_posting_date_with_po(self): po_list = {x.purchase_order for x in self.items if x.purchase_order} diff --git a/erpnext/controllers/sales_and_purchase_return.py b/erpnext/controllers/sales_and_purchase_return.py index a227c12ac05..09a42e79d4a 100644 --- a/erpnext/controllers/sales_and_purchase_return.py +++ b/erpnext/controllers/sales_and_purchase_return.py @@ -393,12 +393,14 @@ def make_return_doc(doctype: str, source_name: str, target_doc=None, return_agai elif doctype == "Purchase Invoice": # look for Print Heading "Debit Note" doc.select_print_heading = frappe.get_cached_value("Print Heading", _("Debit Note")) - if source.tax_withholding_category: - doc.set_onload("supplier_tds", source.tax_withholding_category) elif doctype == "Delivery Note": # manual additions to the return should hit the return warehous, too doc.set_warehouse = default_warehouse_for_sales_return + if doc.doctype in ["Sales Invoice", "Purchase Invoice"]: + doc.tax_withholding_group = source.tax_withholding_group + doc.ignore_tax_withholding_threshold = source.ignore_tax_withholding_threshold + for tax in doc.get("taxes") or []: if tax.charge_type == "Actual": tax.tax_amount = -1 * tax.tax_amount @@ -455,6 +457,7 @@ def make_return_doc(doctype: str, source_name: str, target_doc=None, return_agai def update_item(source_doc, target_doc, source_parent): target_doc.qty = -1 * source_doc.qty target_doc.pricing_rules = None + if doctype in ["Purchase Receipt", "Subcontracting Receipt"]: returned_qty_map = get_returned_qty_map_for_row( source_parent.name, source_parent.supplier, source_doc.name, doctype @@ -525,6 +528,8 @@ def make_return_doc(doctype: str, source_name: str, target_doc=None, return_agai target_doc.po_detail = source_doc.po_detail target_doc.pr_detail = source_doc.pr_detail target_doc.purchase_invoice_item = source_doc.name + target_doc.tax_withholding_category = source_doc.tax_withholding_category + target_doc.apply_tds = source_doc.apply_tds elif doctype == "Delivery Note": returned_qty_map = get_returned_qty_map_for_row( @@ -556,6 +561,8 @@ def make_return_doc(doctype: str, source_name: str, target_doc=None, return_agai if doctype == "Sales Invoice": target_doc.sales_invoice_item = source_doc.name + target_doc.tax_withholding_category = source_doc.tax_withholding_category + target_doc.apply_tds = source_doc.apply_tds else: target_doc.pos_invoice_item = source_doc.name diff --git a/erpnext/controllers/selling_controller.py b/erpnext/controllers/selling_controller.py index cafcf0195db..d7d12ff46bb 100644 --- a/erpnext/controllers/selling_controller.py +++ b/erpnext/controllers/selling_controller.py @@ -43,6 +43,19 @@ class SellingController(StockController): ), ) + if ( + self.get("company") + and ( + default_selling_terms := frappe.get_value( + "Company", self.get("company"), "default_selling_terms" + ) + ) + and not self.get("tc_name") + and not self.get("terms") + ): + self.tc_name = default_selling_terms + self.terms = frappe.get_value("Terms and Conditions", self.get("tc_name"), "terms") + def validate(self): super().validate() self.validate_items() diff --git a/erpnext/controllers/status_updater.py b/erpnext/controllers/status_updater.py index ea933b2967c..b12741487cd 100644 --- a/erpnext/controllers/status_updater.py +++ b/erpnext/controllers/status_updater.py @@ -94,6 +94,7 @@ status_map = { ["To Bill", "eval:self.per_billed < 100 and self.docstatus == 1"], ["Completed", "eval:self.per_billed == 100 and self.docstatus == 1"], ["Return Issued", "eval:self.per_returned == 100 and self.docstatus == 1"], + ["Return", "eval:self.is_return == 1 and self.per_billed == 0 and self.docstatus == 1"], ["Cancelled", "eval:self.docstatus==2"], ["Closed", "eval:self.status=='Closed' and self.docstatus != 2"], ], @@ -129,7 +130,7 @@ status_map = { ], [ "Received", - "eval:self.status != 'Stopped' and self.per_received == 100 and self.docstatus == 1 and self.material_request_type == 'Purchase'", + "eval:self.status != 'Stopped' and self.docstatus == 1 and ((self.per_received == 100 and self.material_request_type == 'Purchase') or (self.per_ordered == 100 and self.material_request_type == 'Customer Provided'))", ], [ "Partially Received", @@ -137,11 +138,11 @@ status_map = { ], [ "Partially Received", - "eval:self.status != 'Stopped' and self.per_ordered < 100 and self.per_ordered > 0 and self.docstatus == 1 and self.material_request_type == 'Material Transfer'", + "eval:self.status != 'Stopped' and self.per_ordered < 100 and self.per_ordered > 0 and self.docstatus == 1 and self.material_request_type in ['Material Transfer', 'Customer Provided']", ], [ "Partially Ordered", - "eval:self.status != 'Stopped' and self.per_ordered < 100 and self.per_ordered > 0 and self.docstatus == 1 and self.material_request_type != 'Material Transfer'", + "eval:self.status != 'Stopped' and self.per_ordered < 100 and self.per_ordered > 0 and self.docstatus == 1 and self.material_request_type not in ['Material Transfer', 'Customer Provided']", ], ], "POS Opening Entry": [ @@ -392,12 +393,16 @@ class StatusUpdater(Document): self.item_allowance, self.global_qty_allowance, self.global_amount_allowance, - ) = get_allowance_for( - item["item_code"], - self.item_allowance, - self.global_qty_allowance, - self.global_amount_allowance, - qty_or_amount, + ) = ( + get_allowance_for( + item["item_code"], + self.item_allowance, + self.global_qty_allowance, + self.global_amount_allowance, + qty_or_amount, + ) + if args["source_dt"] != "Pick List Item" + else (0, {}, None, None) ) role_allowed_to_over_deliver_receive = frappe.get_single_value( @@ -435,14 +440,17 @@ class StatusUpdater(Document): ): return - if qty_or_amount == "qty": - action_msg = _( - 'To allow over receipt / delivery, update "Over Receipt/Delivery Allowance" in Stock Settings or the Item.' - ) + if args["source_dt"] != "Pick List Item": + if qty_or_amount == "qty": + action_msg = _( + 'To allow over receipt / delivery, update "Over Receipt/Delivery Allowance" in Stock Settings or the Item.' + ) + else: + action_msg = _( + 'To allow over billing, update "Over Billing Allowance" in Accounts Settings or the Item.' + ) else: - action_msg = _( - 'To allow over billing, update "Over Billing Allowance" in Accounts Settings or the Item.' - ) + action_msg = None frappe.throw( _( @@ -454,8 +462,7 @@ class StatusUpdater(Document): frappe.bold(_(self.doctype)), frappe.bold(item.get("item_code")), ) - + "

    " - + action_msg, + + ("

    " + action_msg if action_msg else ""), OverAllowanceError, title=_("Limit Crossed"), ) diff --git a/erpnext/controllers/stock_controller.py b/erpnext/controllers/stock_controller.py index 8d4aeffd9d5..fce149e0e84 100644 --- a/erpnext/controllers/stock_controller.py +++ b/erpnext/controllers/stock_controller.py @@ -25,6 +25,7 @@ from erpnext.controllers.sales_and_purchase_return import ( from erpnext.setup.doctype.brand.brand import get_brand_defaults from erpnext.setup.doctype.item_group.item_group import get_item_group_defaults from erpnext.stock import get_warehouse_account_map +from erpnext.stock.doctype.batch.batch import get_batch_qty from erpnext.stock.doctype.inventory_dimension.inventory_dimension import ( get_evaluated_inventory_dimension, ) @@ -1216,6 +1217,12 @@ class StockController(AccountsController): ], }.get(self.doctype) + qty_field = { + "Sales Invoice": "qty", + "Delivery Note": "qty", + "Stock Entry": "fg_completed_qty", + }.get(self.doctype) + reserved_batches_data = self.get_reserved_batches(batches) items = self.items if self.doctype == "Stock Entry": @@ -1236,6 +1243,17 @@ class StockController(AccountsController): if row.voucher_no == value: continue + batch_qty = get_batch_qty( + row.batch_no, + row.warehouse, + posting_date=self.posting_date, + posting_time=self.posting_time, + consider_negative_batches=True, + ) + + if item.get(qty_field) < batch_qty: + continue + frappe.throw( _( "The batch {0} is already reserved in {1} {2}. So, cannot proceed with the {3} {4}, which is created against the {5} {6}." @@ -1264,6 +1282,7 @@ class StockController(AccountsController): doctype.voucher_type, doctype.voucher_no, doctype.item_code, + doctype.warehouse, ) .where((doctype.docstatus == 1) & (child_doc.batch_no.isin(batches))) ).run(as_dict=True) @@ -1626,7 +1645,7 @@ class StockController(AccountsController): rule = frappe.db.get_value( "Putaway Rule", {"item_code": item.get("item_code"), "warehouse": item.get(warehouse_field)}, - ["name", "disable"], + ["stock_capacity", "name", "disable"], as_dict=True, ) if rule: @@ -1645,7 +1664,11 @@ class StockController(AccountsController): rule_map[rule_name]["warehouse"] = item.get(warehouse_field) rule_map[rule_name]["item"] = item.get("item_code") rule_map[rule_name]["qty_put"] = 0 - rule_map[rule_name]["capacity"] = get_available_putaway_capacity(rule_name) + rule_map[rule_name]["capacity"] = ( + rule.stock_capacity + if self.doctype == "Stock Reconciliation" + else get_available_putaway_capacity(rule_name) + ) rule_map[rule_name]["qty_put"] += flt(stock_qty) for rule, values in rule_map.items(): diff --git a/erpnext/controllers/subcontracting_controller.py b/erpnext/controllers/subcontracting_controller.py index ff7342607c3..a6af04f989a 100644 --- a/erpnext/controllers/subcontracting_controller.py +++ b/erpnext/controllers/subcontracting_controller.py @@ -11,6 +11,7 @@ from frappe.model.mapper import get_mapped_doc from frappe.utils import cint, flt, get_link_to_form from erpnext.controllers.stock_controller import StockController +from erpnext.stock.doctype.batch.batch import get_batch_qty from erpnext.stock.doctype.serial_and_batch_bundle.serial_and_batch_bundle import ( combine_datetime, get_auto_batch_nos, @@ -220,7 +221,7 @@ class SubcontractingController(StockController): and self._doc_before_save ): for row in self._doc_before_save.get("items"): - item_dict[row.name] = (row.item_code, row.qty) + item_dict[row.name] = (row.item_code, row.qty + (row.get("rejected_qty") or 0)) return item_dict @@ -244,7 +245,10 @@ class SubcontractingController(StockController): for row in self.items: self.__reference_name.append(row.name) - if (row.name not in item_dict) or (row.item_code, row.qty) != item_dict[row.name]: + if (row.name not in item_dict) or ( + row.item_code, + row.qty + (row.get("rejected_qty") or 0), + ) != item_dict[row.name]: self.__changed_name.append(row.name) if item_dict.get(row.name): @@ -549,7 +553,7 @@ class SubcontractingController(StockController): if item.get("serial_and_batch_bundle"): frappe.delete_doc("Serial and Batch Bundle", item.serial_and_batch_bundle, force=True) - def __get_materials_from_bom(self, item_code, bom_no, exploded_item=0): + def _get_materials_from_bom(self, item_code, bom_no, exploded_item=0): data = [] doctype = "BOM Item" if not exploded_item else "BOM Explosion Item" @@ -590,7 +594,7 @@ class SubcontractingController(StockController): to_remove = [] for item in data: if item.is_phantom_item: - data += self.__get_materials_from_bom( + data += self._get_materials_from_bom( item.rm_item_code, item.bom_no, exploded_item=exploded_item ) to_remove.append(item) @@ -758,7 +762,11 @@ class SubcontractingController(StockController): serial_nos = get_filtered_serial_nos(serial_nos, self, "supplied_items") row.serial_no = "\n".join(serial_nos) - elif item_details.has_batch_no and not row.serial_and_batch_bundle and not row.batch_no: + elif ( + item_details.has_batch_no + and not row.serial_and_batch_bundle + and (not row.batch_no or self.batch_has_not_available(row.batch_no, row.consumed_qty)) + ): batches = get_auto_batch_nos(kwargs) if batches: consumed_qty = row.consumed_qty @@ -783,6 +791,11 @@ class SubcontractingController(StockController): ) consumed_qty -= d.get("qty") + def batch_has_not_available(self, batch_no, qty_required): + batch_qty = get_batch_qty(batch_no, self.supplier_warehouse, consider_negative_batches=True) + + return batch_qty < qty_required + def update_rate_for_supplied_items(self): if self.doctype != "Subcontracting Receipt": return @@ -921,10 +934,14 @@ class SubcontractingController(StockController): if self.doctype == self.subcontract_data.order_doctype or ( self.backflush_based_on == "BOM" or self.is_return ): - for bom_item in self.__get_materials_from_bom( + for bom_item in self._get_materials_from_bom( row.item_code, row.bom, row.get("include_exploded_items") ): - qty = flt(bom_item.qty_consumed_per_unit) * flt(row.qty) * row.conversion_factor + qty = ( + flt(bom_item.qty_consumed_per_unit) + * flt(row.qty + (row.get("rejected_qty") or 0)) + * row.conversion_factor + ) bom_item.main_item_code = row.item_code self.__update_reserve_warehouse(bom_item, row) self.__set_alternative_item(bom_item) diff --git a/erpnext/controllers/taxes_and_totals.py b/erpnext/controllers/taxes_and_totals.py index ab6cf1222b5..08b1fb32bf3 100644 --- a/erpnext/controllers/taxes_and_totals.py +++ b/erpnext/controllers/taxes_and_totals.py @@ -7,6 +7,7 @@ import json import frappe from frappe import _, scrub from frappe.model.document import Document, bulk_insert +from frappe.query_builder import functions from frappe.utils import cint, flt, round_based_on_smallest_currency_fraction import erpnext @@ -29,11 +30,6 @@ class calculate_taxes_and_totals: frappe.flags.round_off_applicable_accounts = [] frappe.flags.round_row_wise_tax = frappe.get_single_value("Accounts Settings", "round_row_wise_tax") - if doc.get("round_off_applicable_accounts_for_tax_withholding"): - frappe.flags.round_off_applicable_accounts.append( - doc.round_off_applicable_accounts_for_tax_withholding - ) - self._items = self.filter_rows() if self.doc.doctype == "Quotation" else self.doc.get("items") get_round_off_applicable_accounts(self.doc.company, frappe.flags.round_off_applicable_accounts) self.calculate() @@ -77,24 +73,11 @@ class calculate_taxes_and_totals: self.initialize_taxes() self.determine_exclusive_rate() self.calculate_net_total() - self.calculate_tax_withholding_net_total() self.calculate_taxes() self.adjust_grand_total_for_inclusive_tax() self.calculate_totals() self.calculate_total_net_weight() - def calculate_tax_withholding_net_total(self): - if hasattr(self.doc, "tax_withholding_net_total"): - sum_net_amount = 0 - sum_base_net_amount = 0 - for item in self._items: - if hasattr(item, "apply_tds") and item.apply_tds: - sum_net_amount += item.net_amount - sum_base_net_amount += item.base_net_amount - - self.doc.tax_withholding_net_total = sum_net_amount - self.doc.base_tax_withholding_net_total = sum_base_net_amount - def validate_item_tax_template(self): if self.doc.get("is_return") and self.doc.get("return_against"): return @@ -577,16 +560,7 @@ class calculate_taxes_and_totals: current_net_amount = item.net_amount # distribute the tax amount proportionally to each item row actual = flt(tax.tax_amount, tax.precision("tax_amount")) - - if tax.get("is_tax_withholding_account") and item.meta.get_field("apply_tds"): - if not item.get("apply_tds") or not self.doc.tax_withholding_net_total: - current_tax_amount = 0.0 - else: - current_tax_amount = item.net_amount * actual / self.doc.tax_withholding_net_total - else: - current_tax_amount = ( - item.net_amount * actual / self.doc.net_total if self.doc.net_total else 0.0 - ) + current_tax_amount = item.net_amount * actual / self.doc.net_total if self.doc.net_total else 0.0 elif tax.charge_type == "On Net Total": if tax.account_head in item_tax_map: @@ -779,6 +753,22 @@ class calculate_taxes_and_totals: discount_amount = self.doc.discount_amount or 0 grand_total = self.doc.grand_total + if self.doc.get("is_return") and self.doc.get("return_against"): + doctype = frappe.qb.DocType(self.doc.doctype) + + result = ( + frappe.qb.from_(doctype) + .select(functions.Sum(doctype.discount_amount).as_("total_return_discount")) + .where( + (doctype.return_against == self.doc.return_against) + & (doctype.is_return == 1) + & (doctype.docstatus == 1) + ) + ).run(as_dict=True) + + total_return_discount = abs(result[0].get("total_return_discount") or 0) + discount_amount += total_return_discount + # validate that discount amount cannot exceed the total before discount if ( (grand_total >= 0 and discount_amount > grand_total) diff --git a/erpnext/controllers/tests/test_accounts_controller.py b/erpnext/controllers/tests/test_accounts_controller.py index b001bdb351b..44e3d6a7bf4 100644 --- a/erpnext/controllers/tests/test_accounts_controller.py +++ b/erpnext/controllers/tests/test_accounts_controller.py @@ -16,7 +16,10 @@ from erpnext.accounts.doctype.payment_entry.test_payment_entry import create_pay from erpnext.accounts.doctype.purchase_invoice.test_purchase_invoice import make_purchase_invoice from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice from erpnext.accounts.party import get_party_account -from erpnext.buying.doctype.purchase_order.test_purchase_order import prepare_data_for_internal_transfer +from erpnext.buying.doctype.purchase_order.test_purchase_order import ( + create_purchase_order, + prepare_data_for_internal_transfer, +) from erpnext.projects.doctype.project.test_project import make_project from erpnext.stock.doctype.item.test_item import create_item @@ -2432,3 +2435,48 @@ class TestAccountsController(IntegrationTestCase): # Second return should only get remaining discount (100 - 60 = 40) self.assertEqual(return_si_2.discount_amount, -40) + + def test_company_linked_address(self): + from erpnext.crm.doctype.prospect.test_prospect import make_address + from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_order + + company_address = make_address( + address_title="Company", address_type="Shipping", address_line1="100", city="Mumbai" + ) + company_address.append("links", {"link_doctype": "Company", "link_name": "_Test Company"}) + company_address.save() + + customer_shipping = make_address( + address_title="Customer", address_type="Shipping", address_line1="10" + ) + customer_shipping.append("links", {"link_doctype": "Customer", "link_name": "_Test Customer"}) + customer_shipping.save() + + supplier_billing = make_address(address_title="Supplier", address_line1="2", city="Ahmedabad") + supplier_billing.append("links", {"link_doctype": "Supplier", "link_name": "_Test Supplier"}) + supplier_billing.save() + + po = create_purchase_order(do_not_save=True) + po.shipping_address = customer_shipping.name + self.assertRaises(frappe.ValidationError, po.save) + po.shipping_address = company_address.name + po.save() + + po.billing_address = supplier_billing.name + self.assertRaises(frappe.ValidationError, po.save) + po.billing_address = company_address.name + po.reload() + po.save() + + si = make_sales_order(do_not_save=1, do_not_submit=1) + si.dispatch_address_name = supplier_billing.name + self.assertRaises(frappe.ValidationError, si.save) + si.items[0].delivered_by_supplier = 1 + si.items[0].supplier = "_Test Supplier" + si.save() + + po = create_purchase_order(do_not_save=True) + po.shipping_address = customer_shipping.name + self.assertRaises(frappe.ValidationError, po.save) + po.items[0].delivered_by_supplier = 1 + po.save() diff --git a/erpnext/crm/doctype/email_campaign/email_campaign.py b/erpnext/crm/doctype/email_campaign/email_campaign.py index 6bfa4f8b3cb..a5a2132dc0c 100644 --- a/erpnext/crm/doctype/email_campaign/email_campaign.py +++ b/erpnext/crm/doctype/email_campaign/email_campaign.py @@ -123,7 +123,7 @@ def send_mail(entry, email_campaign): subject=frappe.render_template(email_template.get("subject"), context), content=frappe.render_template(email_template.response_, context), sender=sender, - recipients=recipient_list, + bcc=recipient_list, communication_medium="Email", sent_or_received="Sent", send_email=True, diff --git a/erpnext/crm/doctype/market_segment/market_segment.json b/erpnext/crm/doctype/market_segment/market_segment.json index 0ad3d0e4b59..85200018848 100644 --- a/erpnext/crm/doctype/market_segment/market_segment.json +++ b/erpnext/crm/doctype/market_segment/market_segment.json @@ -1,5 +1,6 @@ { "actions": [], + "allow_rename": 1, "autoname": "field:market_segment", "creation": "2018-10-01 09:59:14.479509", "doctype": "DocType", @@ -17,10 +18,11 @@ } ], "links": [], - "modified": "2024-08-16 19:24:55.811760", + "modified": "2025-12-17 12:09:34.687368", "modified_by": "Administrator", "module": "CRM", "name": "Market Segment", + "naming_rule": "By fieldname", "owner": "Administrator", "permissions": [ { @@ -37,9 +39,10 @@ } ], "quick_entry": 1, + "row_format": "Dynamic", "sort_field": "creation", "sort_order": "DESC", "states": [], "track_changes": 1, "translated_doctype": 1 -} \ No newline at end of file +} diff --git a/erpnext/hooks.py b/erpnext/hooks.py index 9a65062e7c4..9d7b7a5ed70 100644 --- a/erpnext/hooks.py +++ b/erpnext/hooks.py @@ -154,6 +154,14 @@ website_route_rules = [ "parents": [{"label": "Purchase Order", "route": "purchase-orders"}], }, }, + { + "from_route": "/purchase-orders/", + "to_route": "order", + "defaults": { + "doctype": "Purchase Order", + "parents": [{"label": "Purchase Order", "route": "purchase-orders"}], + }, + }, {"from_route": "/purchase-invoices", "to_route": "Purchase Invoice"}, { "from_route": "/purchase-invoices/", @@ -411,7 +419,9 @@ scheduler_events = { "0/15 * * * *": [ "erpnext.manufacturing.doctype.bom_update_log.bom_update_log.resume_bom_cost_update_jobs", ], - "0/30 * * * *": [], + "0/30 * * * *": [ + "erpnext.stock.doctype.repost_item_valuation.repost_item_valuation.run_parallel_reposting", + ], # Hourly but offset by 30 minutes "30 * * * *": [ "erpnext.accounts.doctype.gl_entry.gl_entry.rename_gle_sle_docs", @@ -647,6 +657,10 @@ global_search_doctypes = { ], } +ignore_links_on_delete = [ + "Tax Withholding Entry", +] + additional_timeline_content = {"*": ["erpnext.telephony.doctype.call_log.call_log.get_linked_call_logs"]} diff --git a/erpnext/locale/ar.po b/erpnext/locale/ar.po index d541c90d93d..550e6a63a15 100644 --- a/erpnext/locale/ar.po +++ b/erpnext/locale/ar.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: frappe\n" "Report-Msgid-Bugs-To: hello@frappe.io\n" -"POT-Creation-Date: 2025-11-16 09:35+0000\n" -"PO-Revision-Date: 2025-11-20 22:23\n" +"POT-Creation-Date: 2025-12-14 09:37+0000\n" +"PO-Revision-Date: 2025-12-15 01:40\n" "Last-Translator: hello@frappe.io\n" "Language-Team: Arabic\n" "MIME-Version: 1.0\n" @@ -27,7 +27,7 @@ msgstr "" msgid " Address" msgstr "" -#: erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py:677 +#: erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py:605 msgid " Amount" msgstr "" @@ -35,6 +35,11 @@ msgstr "" msgid " BOM" msgstr "" +#. Label of the default_wip_warehouse (Link) field in DocType 'Company' +#: erpnext/setup/doctype/company/company.json +msgid " Default Work In Progress Warehouse " +msgstr " افتراضي العمل في مستودع التقدم " + #. Label of the istable (Check) field in DocType 'Inventory Dimension' #: erpnext/stock/doctype/inventory_dimension/inventory_dimension.json msgid " Is Child Table" @@ -45,18 +50,23 @@ msgstr "" msgid " Is Subcontracted" msgstr "" -#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:174 +#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:196 msgid " Item" msgstr "" -#: erpnext/accounts/report/customer_ledger_summary/customer_ledger_summary.py:147 -#: erpnext/accounts/report/tax_withholding_details/tax_withholding_details.py:192 +#: erpnext/accounts/report/customer_ledger_summary/customer_ledger_summary.py:153 +#: erpnext/accounts/report/tax_withholding_details/tax_withholding_details.py:206 #: erpnext/accounts/report/tds_computation_summary/tds_computation_summary.py:107 #: erpnext/selling/report/sales_analytics/sales_analytics.py:128 msgid " Name" msgstr "" -#: erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py:668 +#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:144 +#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:185 +msgid " Phantom Item" +msgstr "" + +#: erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py:596 msgid " Rate" msgstr "" @@ -70,7 +80,7 @@ msgid " Skip Material Transfer" msgstr "" #: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:133 -#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:163 +#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:174 msgid " Sub Assembly" msgstr "" @@ -78,15 +88,15 @@ msgstr "" msgid " Summary" msgstr "" -#: erpnext/stock/doctype/item/item.py:236 +#: erpnext/stock/doctype/item/item.py:238 msgid "\"Customer Provided Item\" cannot be Purchase Item also" msgstr "\"الأصناف المقدمة من العملاء\" لا يمكن شرائها" -#: erpnext/stock/doctype/item/item.py:238 +#: erpnext/stock/doctype/item/item.py:240 msgid "\"Customer Provided Item\" cannot have Valuation Rate" msgstr "\"الأصناف المقدمة من العملاء\" لا يمكن ان تحتوي على تكلفة" -#: erpnext/stock/doctype/item/item.py:314 +#: erpnext/stock/doctype/item/item.py:315 msgid "\"Is Fixed Asset\" cannot be unchecked, as Asset record exists against the item" msgstr "\"اصل ثابت\" لا يمكن أن يكون غير محدد، حيث يوجد سجل أصول مقابل البند" @@ -141,7 +151,7 @@ msgstr "" msgid "% Delivered" msgstr "% تسليم" -#: erpnext/manufacturing/doctype/bom/bom.js:945 +#: erpnext/manufacturing/doctype/bom/bom.js:962 #, python-format msgid "% Finished Item Quantity" msgstr "" @@ -156,8 +166,8 @@ msgstr "" msgid "% Occupied" msgstr "" -#: erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py:285 -#: erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py:340 +#: erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py:277 +#: erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py:329 msgid "% Of Grand Total" msgstr "" @@ -246,11 +256,11 @@ msgstr "" msgid "% of materials delivered against this Sales Order" msgstr "" -#: erpnext/controllers/accounts_controller.py:2295 +#: erpnext/controllers/accounts_controller.py:2368 msgid "'Account' in the Accounting section of Customer {0}" msgstr "" -#: erpnext/selling/doctype/sales_order/sales_order.py:346 +#: erpnext/selling/doctype/sales_order/sales_order.py:348 msgid "'Allow Multiple Sales Orders Against a Customer's Purchase Order'" msgstr "" @@ -262,11 +272,11 @@ msgstr "'على أساس' و 'المجموعة حسب' لا يمكن أن يكو msgid "'Days Since Last Order' must be greater than or equal to zero" msgstr "يجب أن تكون \"الأيام منذ آخر طلب\" أكبر من أو تساوي الصفر" -#: erpnext/controllers/accounts_controller.py:2300 +#: erpnext/controllers/accounts_controller.py:2373 msgid "'Default {0} Account' in Company {1}" msgstr "" -#: erpnext/accounts/doctype/journal_entry/journal_entry.py:1283 +#: erpnext/accounts/doctype/journal_entry/journal_entry.py:1198 msgid "'Entries' cannot be empty" msgstr "المدخلات لا يمكن أن تكون فارغة" @@ -280,7 +290,7 @@ msgstr "من تاريخ (مطلوب)" msgid "'From Date' must be after 'To Date'" msgstr "\"من تاريخ \" يجب أن يكون بعد \" إلى تاريخ \"" -#: erpnext/stock/doctype/item/item.py:397 +#: erpnext/stock/doctype/item/item.py:398 msgid "'Has Serial No' can not be 'Yes' for non-stock item" msgstr "\"لهُ رقم تسلسل\" لا يمكن ان يكون \"نعم\" لبند غير قابل للتخزين" @@ -292,8 +302,8 @@ msgstr "" msgid "'Inspection Required before Purchase' has disabled for the item {0}, no need to create the QI" msgstr "" -#: erpnext/stock/report/stock_ledger/stock_ledger.py:598 -#: erpnext/stock/report/stock_ledger/stock_ledger.py:631 +#: erpnext/stock/report/stock_ledger/stock_ledger.py:601 +#: erpnext/stock/report/stock_ledger/stock_ledger.py:634 msgid "'Opening'" msgstr "'افتتاحي'" @@ -307,11 +317,11 @@ msgstr "' إلى تاريخ ' مطلوب" msgid "'To Package No.' cannot be less than 'From Package No.'" msgstr "" -#: erpnext/controllers/sales_and_purchase_return.py:81 +#: erpnext/controllers/sales_and_purchase_return.py:80 msgid "'Update Stock' can not be checked because items are not delivered via {0}" msgstr ""الأوراق المالية التحديث" لا يمكن التحقق من أنه لم يتم تسليم المواد عن طريق {0}" -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:439 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:388 msgid "'Update Stock' cannot be checked for fixed asset sale" msgstr "لا يمكن التحقق من ' تحديث المخزون ' لبيع الأصول الثابتة\\n
    \\n'Update Stock' cannot be checked for fixed asset sale" @@ -323,8 +333,8 @@ msgstr "" msgid "'{0}' has been already added." msgstr "" -#: erpnext/setup/doctype/company/company.py:259 -#: erpnext/setup/doctype/company/company.py:270 +#: erpnext/setup/doctype/company/company.py:295 +#: erpnext/setup/doctype/company/company.py:306 msgid "'{0}' should be in company currency {1}." msgstr "" @@ -580,10 +590,18 @@ msgstr "" msgid "90 Above" msgstr "" +#: erpnext/assets/doctype/asset/asset.py:474 +msgid "Cannot create asset.

    You're trying to create {0} asset(s) from {2} {3}.
    However, only {1} item(s) were purchased and {4} asset(s) already exist against {5}." +msgstr "" + #: erpnext/crm/doctype/appointment_booking_settings/appointment_booking_settings.py:61 msgid "From Time cannot be later than To Time for {0}" msgstr "من الوقت لا يمكن أن يكون بعد من إلى الوقت لـ {0}" +#: erpnext/accounts/doctype/pos_invoice/pos_invoice.py:432 +msgid "Row #{0}: Bundle {1} in warehouse {2} has insufficient packed items:
      {3}
    " +msgstr "" + #. Content of the 'Help Text' (HTML) field in DocType 'Process Statement Of #. Accounts' #: erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.json @@ -708,19 +726,24 @@ msgstr "" msgid "
  • Clearance date must be after cheque date for row(s): {0}
  • " msgstr "" -#: erpnext/controllers/accounts_controller.py:2188 +#: erpnext/controllers/accounts_controller.py:2261 msgid "
  • Item {0} in row(s) {1} billed more than {2}
  • " msgstr "" +#: erpnext/accounts/doctype/pos_invoice/pos_invoice.py:423 +msgid "
  • Packed Item {0}: Required {1}, Available {2}
  • " +msgstr "" + #: erpnext/accounts/doctype/bank_clearance/bank_clearance.py:118 msgid "
  • Payment document required for row(s): {0}
  • " msgstr "" #: erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.py:163 +#: erpnext/utilities/bulk_transaction.py:35 msgid "
  • {}
  • " msgstr "" -#: erpnext/controllers/accounts_controller.py:2185 +#: erpnext/controllers/accounts_controller.py:2258 msgid "

    Cannot overbill for the following Items:

    " msgstr "" @@ -756,7 +779,7 @@ msgstr "" msgid "

    Please correct the following row(s):

      " msgstr "" -#: erpnext/controllers/buying_controller.py:108 +#: erpnext/controllers/buying_controller.py:121 msgid "

      Posting Date {0} cannot be before Purchase Order date for the following:

        " msgstr "" @@ -764,7 +787,7 @@ msgstr "" msgid "

        Price List Rate has not been set as editable in Selling Settings. In this scenario, setting Update Price List Based On to Price List Rate will prevent auto-updation of Item Price.

        Are you sure you want to continue?" msgstr "" -#: erpnext/controllers/accounts_controller.py:2197 +#: erpnext/controllers/accounts_controller.py:2270 msgid "

        To allow over-billing, please set allowance in Accounts Settings.

        " msgstr "" @@ -816,6 +839,7 @@ msgstr "" #. Header text in the Projects Workspace #. Header text in the Selling Workspace #. Header text in the Home Workspace +#. Header text in the Subcontracting Workspace #. Header text in the Support Workspace #: erpnext/accounts/workspace/accounting/accounting.json #: erpnext/accounts/workspace/payables/payables.json @@ -826,19 +850,13 @@ msgstr "" #: erpnext/projects/workspace/projects/projects.json #: erpnext/selling/workspace/selling/selling.json #: erpnext/setup/workspace/home/home.json +#: erpnext/subcontracting/workspace/subcontracting/subcontracting.json #: erpnext/support/workspace/support/support.json msgid "Reports & Masters" msgstr "" -#. Header text in the Settings Workspace -#: erpnext/setup/workspace/settings/settings.json -msgid "Settings" -msgstr "" - -#. Header text in the Accounting Workspace #. Header text in the Payables Workspace #. Header text in the Receivables Workspace -#: erpnext/accounts/workspace/accounting/accounting.json #: erpnext/accounts/workspace/payables/payables.json #: erpnext/accounts/workspace/receivables/receivables.json msgid "Shortcuts" @@ -862,6 +880,7 @@ msgstr "" #. Header text in the Projects Workspace #. Header text in the Quality Workspace #. Header text in the Home Workspace +#. Header text in the Subcontracting Workspace #. Header text in the Support Workspace #: erpnext/assets/workspace/assets/assets.json #: erpnext/buying/workspace/buying/buying.json @@ -870,15 +889,16 @@ msgstr "" #: erpnext/projects/workspace/projects/projects.json #: erpnext/quality_management/workspace/quality/quality.json #: erpnext/setup/workspace/home/home.json +#: erpnext/subcontracting/workspace/subcontracting/subcontracting.json #: erpnext/support/workspace/support/support.json msgid "Your Shortcuts" msgstr "" -#: erpnext/accounts/doctype/payment_request/payment_request.py:991 +#: erpnext/accounts/doctype/payment_request/payment_request.py:995 msgid "Grand Total: {0}" msgstr "" -#: erpnext/accounts/doctype/payment_request/payment_request.py:992 +#: erpnext/accounts/doctype/payment_request/payment_request.py:996 msgid "Outstanding Amount: {0}" msgstr "" @@ -923,7 +943,7 @@ msgstr "" msgid "A - C" msgstr "" -#: erpnext/selling/doctype/customer/customer.py:314 +#: erpnext/selling/doctype/customer/customer.py:323 msgid "A Customer Group exists with same name please change the Customer name or rename the Customer Group" msgstr "مجموعة الزبائن موجودة بنفس الاسم أرجو تغير اسم العميل أو اعادة تسمية مجموعة الزبائن\\n
        \\nA Customer Group exists with same name please change the Customer name or rename the Customer Group" @@ -953,11 +973,11 @@ msgstr "" msgid "A Reconciliation Job {0} is running for the same filters. Cannot reconcile now" msgstr "" -#: erpnext/accounts/doctype/journal_entry/journal_entry.py:1812 +#: erpnext/accounts/doctype/journal_entry/journal_entry.py:1952 msgid "A Reverse Journal Entry {0} already exists for this Journal Entry." msgstr "" -#: erpnext/setup/doctype/company/company.py:1037 +#: erpnext/setup/doctype/company/company.py:1078 msgid "A Transaction Deletion Document: {0} is triggered for {0}" msgstr "" @@ -981,6 +1001,10 @@ msgstr "" msgid "A logical Warehouse against which stock entries are made." msgstr "" +#: erpnext/stock/serial_batch_bundle.py:1440 +msgid "A naming series conflict occurred while creating serial numbers. Please change the naming series for the item {0}." +msgstr "" + #: erpnext/templates/emails/confirm_appointment.html:2 msgid "A new appointment has been created for you with {0}" msgstr "تم إنشاء موعد جديد لك من خلال {0}" @@ -1057,11 +1081,11 @@ msgstr "" msgid "Abbreviation" msgstr "اسم مختصر" -#: erpnext/setup/doctype/company/company.py:194 +#: erpnext/setup/doctype/company/company.py:230 msgid "Abbreviation already used for another company" msgstr "الاختصار يستخدم بالفعل لشركة أخرى\\n
        \\nAbbreviation already used for another company" -#: erpnext/setup/doctype/company/company.py:191 +#: erpnext/setup/doctype/company/company.py:227 msgid "Abbreviation is mandatory" msgstr "الاسم المختصر إلزامي" @@ -1114,7 +1138,7 @@ msgstr "" #. Label of the qty (Float) field in DocType 'Purchase Receipt Item' #. Label of the qty (Float) field in DocType 'Subcontracting Receipt Item' -#: erpnext/public/js/controllers/transaction.js:2791 +#: erpnext/public/js/controllers/transaction.js:2799 #: erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json #: erpnext/subcontracting/doctype/subcontracting_receipt_item/subcontracting_receipt_item.json msgid "Accepted Quantity" @@ -1147,7 +1171,7 @@ msgstr "" msgid "According to CEFACT/ICG/2010/IC013 or CEFACT/ICG/2010/IC010" msgstr "" -#: erpnext/stock/doctype/stock_entry/stock_entry.py:870 +#: erpnext/stock/doctype/stock_entry/stock_entry.py:938 msgid "According to the BOM {0}, the Item '{1}' is missing in the stock entry." msgstr "" @@ -1159,6 +1183,7 @@ msgstr "رصيد حسابك" #. Label of the account_category (Link) field in DocType 'Account' #. Name of a DocType #: erpnext/accounts/doctype/account/account.json +#: erpnext/accounts/doctype/account/account_tree.js:166 #: erpnext/accounts/doctype/account_category/account_category.json msgid "Account Category" msgstr "" @@ -1264,8 +1289,8 @@ msgstr "" msgid "Account Manager" msgstr "إدارة حساب المستخدم" -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1034 -#: erpnext/controllers/accounts_controller.py:2304 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:983 +#: erpnext/controllers/accounts_controller.py:2377 msgid "Account Missing" msgstr "الحساب مفقود" @@ -1283,7 +1308,7 @@ msgstr "الحساب مفقود" msgid "Account Name" msgstr "اسم الحساب" -#: erpnext/accounts/doctype/account/account.py:371 +#: erpnext/accounts/doctype/account/account.py:373 msgid "Account Not Found" msgstr "الحساب غير موجود" @@ -1296,7 +1321,7 @@ msgstr "الحساب غير موجود" msgid "Account Number" msgstr "رقم الحساب" -#: erpnext/accounts/doctype/account/account.py:357 +#: erpnext/accounts/doctype/account/account.py:359 msgid "Account Number {0} already used in account {1}" msgstr "رقم الحساب {0} بالفعل مستخدم في الحساب {1}" @@ -1335,7 +1360,7 @@ msgstr "نوع الحساب الفرعي" #. Label of the account_type (Select) field in DocType 'Payment Ledger Entry' #. Label of the account_type (Select) field in DocType 'Party Type' #: erpnext/accounts/doctype/account/account.json -#: erpnext/accounts/doctype/account/account.py:204 +#: erpnext/accounts/doctype/account/account.py:206 #: erpnext/accounts/doctype/account/account_tree.js:158 #: erpnext/accounts/doctype/bank_account/bank_account.json #: erpnext/accounts/doctype/bank_account_type/bank_account_type.json @@ -1347,15 +1372,15 @@ msgstr "نوع الحساب الفرعي" msgid "Account Type" msgstr "نوع الحساب" -#: erpnext/stock/report/stock_and_account_value_comparison/stock_and_account_value_comparison.py:125 +#: erpnext/stock/report/stock_and_account_value_comparison/stock_and_account_value_comparison.py:128 msgid "Account Value" msgstr "قيمة الحساب" -#: erpnext/accounts/doctype/account/account.py:326 +#: erpnext/accounts/doctype/account/account.py:328 msgid "Account balance already in Credit, you are not allowed to set 'Balance Must Be' as 'Debit'" msgstr "رصيد الحساب بالفعل دائن ، لا يسمح لك لتعيين ' الرصيد يجب ان يكون ' ك ' مدين '\\n
        \\nAccount balance already in Credit, you are not allowed to set 'Balance Must Be' as 'Debit'" -#: erpnext/accounts/doctype/account/account.py:320 +#: erpnext/accounts/doctype/account/account.py:322 msgid "Account balance already in Debit, you are not allowed to set 'Balance Must Be' as 'Credit'" msgstr "رصيد الحساب رصيد مدين، لا يسمح لك بتغييره 'الرصيد يجب أن يكون دائن'" @@ -1369,6 +1394,10 @@ msgstr "رصيد الحساب رصيد مدين، لا يسمح لك بتغيي msgid "Account for Change Amount" msgstr "حساب لتغيير المبلغ" +#: erpnext/accounts/doctype/budget/budget.py:150 +msgid "Account is mandatory" +msgstr "" + #: erpnext/accounts/doctype/bank_clearance/bank_clearance.py:46 msgid "Account is mandatory to get payment entries" msgstr "الحساب إلزامي للحصول على إدخالات الدفع" @@ -1377,28 +1406,28 @@ msgstr "الحساب إلزامي للحصول على إدخالات الدفع" msgid "Account is not set for the dashboard chart {0}" msgstr "لم يتم تعيين الحساب لمخطط لوحة المعلومات {0}" -#: erpnext/assets/doctype/asset/asset.py:776 +#: erpnext/assets/doctype/asset/asset.py:824 msgid "Account not Found" msgstr "" -#: erpnext/accounts/doctype/account/account.py:425 +#: erpnext/accounts/doctype/account/account.py:427 msgid "Account with child nodes cannot be converted to ledger" msgstr "لا يمكن تحويل الحساب إلى دفتر الأستاذ لأن لديه حسابات فرعية\\n
        \\nAccount with child nodes cannot be converted to ledger" -#: erpnext/accounts/doctype/account/account.py:277 +#: erpnext/accounts/doctype/account/account.py:279 msgid "Account with child nodes cannot be set as ledger" msgstr "الحساب لديه حسابات فرعية لا يمكن إضافته لدفتر الأستاذ.\\n
        \\nAccount with child nodes cannot be set as ledger" -#: erpnext/accounts/doctype/account/account.py:436 +#: erpnext/accounts/doctype/account/account.py:438 msgid "Account with existing transaction can not be converted to group." msgstr "لا يمكن تحويل حساب جرت عليه أي عملية إلى تصنيف مجموعة" -#: erpnext/accounts/doctype/account/account.py:465 +#: erpnext/accounts/doctype/account/account.py:467 msgid "Account with existing transaction can not be deleted" msgstr "الحساب لديه معاملات موجودة لا يمكن حذفه\\n
        \\nAccount with existing transaction can not be deleted" -#: erpnext/accounts/doctype/account/account.py:271 -#: erpnext/accounts/doctype/account/account.py:427 +#: erpnext/accounts/doctype/account/account.py:273 +#: erpnext/accounts/doctype/account/account.py:429 msgid "Account with existing transaction cannot be converted to ledger" msgstr "لا يمكن تحويل الحساب مع الحركة الموجودة إلى دفتر الأستاذ\\n
        \\nAccount with existing transaction cannot be converted to ledger" @@ -1406,23 +1435,23 @@ msgstr "لا يمكن تحويل الحساب مع الحركة الموجودة msgid "Account {0} added multiple times" msgstr "" -#: erpnext/accounts/doctype/account/account.py:289 +#: erpnext/accounts/doctype/account/account.py:291 msgid "Account {0} cannot be converted to Group as it is already set as {1} for {2}." msgstr "" -#: erpnext/accounts/doctype/account/account.py:286 +#: erpnext/accounts/doctype/account/account.py:288 msgid "Account {0} cannot be disabled as it is already set as {1} for {2}." msgstr "" -#: erpnext/setup/doctype/company/company.py:241 +#: erpnext/accounts/doctype/budget/budget.py:159 +msgid "Account {0} does not belong to company {1}" +msgstr "" + +#: erpnext/setup/doctype/company/company.py:277 msgid "Account {0} does not belong to company: {1}" msgstr "الحساب {0} لا يتنمى للشركة {1}\\n
        \\nAccount {0} does not belong to company: {1}" -#: erpnext/accounts/doctype/budget/budget.py:104 -msgid "Account {0} does not belongs to company {1}" -msgstr "الحساب {0} لا ينتمي للشركة {1}\\n
        \\nAccount {0} does not belongs to company {1}" - -#: erpnext/accounts/doctype/account/account.py:585 +#: erpnext/accounts/doctype/account/account.py:587 msgid "Account {0} does not exist" msgstr "حساب {0} غير موجود" @@ -1442,19 +1471,15 @@ msgstr "الحساب {0} لا يتطابق مع الشركة {1} في طريقة msgid "Account {0} doesn't belong to Company {1}" msgstr "" -#: erpnext/accounts/doctype/account/account.py:542 +#: erpnext/accounts/doctype/account/account.py:544 msgid "Account {0} exists in parent company {1}." msgstr "الحساب {0} موجود في الشركة الأم {1}." -#: erpnext/accounts/doctype/budget/budget.py:114 -msgid "Account {0} has been entered multiple times" -msgstr "الحساب {0} تم إدخاله عدة مرات\\n
        \\nAccount {0} has been entered multiple times" - -#: erpnext/accounts/doctype/account/account.py:409 +#: erpnext/accounts/doctype/account/account.py:411 msgid "Account {0} is added in the child company {1}" msgstr "تتم إضافة الحساب {0} في الشركة التابعة {1}" -#: erpnext/setup/doctype/company/company.py:230 +#: erpnext/setup/doctype/company/company.py:266 msgid "Account {0} is disabled." msgstr "" @@ -1462,43 +1487,43 @@ msgstr "" msgid "Account {0} is frozen" msgstr "الحساب {0} مجمد\\n
        \\nAccount {0} is frozen" -#: erpnext/controllers/accounts_controller.py:1391 +#: erpnext/controllers/accounts_controller.py:1464 msgid "Account {0} is invalid. Account Currency must be {1}" msgstr "الحساب {0} غير صحيح. يجب أن تكون عملة الحساب {1}" -#: erpnext/accounts/doctype/journal_entry/journal_entry.py:336 +#: erpnext/accounts/doctype/journal_entry/journal_entry.py:337 msgid "Account {0} should be of type Expense" msgstr "" -#: erpnext/accounts/doctype/account/account.py:150 +#: erpnext/accounts/doctype/account/account.py:152 msgid "Account {0}: Parent account {1} can not be a ledger" msgstr "الحساب {0}: الحساب الرئيسي {1} لا يمكن أن يكون حساب دفتر أستاذ" -#: erpnext/accounts/doctype/account/account.py:156 +#: erpnext/accounts/doctype/account/account.py:158 msgid "Account {0}: Parent account {1} does not belong to company: {2}" msgstr "الحساب {0}: الحساب الرئيسي {1} لا ينتمي إلى الشركة: {2}" -#: erpnext/accounts/doctype/account/account.py:144 +#: erpnext/accounts/doctype/account/account.py:146 msgid "Account {0}: Parent account {1} does not exist" msgstr "الحساب {0}: الحسابه الأب {1} غير موجود" -#: erpnext/accounts/doctype/account/account.py:147 +#: erpnext/accounts/doctype/account/account.py:149 msgid "Account {0}: You can not assign itself as parent account" msgstr "الحساب {0}: لا يمكنك جعله حساب رئيسي" -#: erpnext/accounts/general_ledger.py:452 +#: erpnext/accounts/general_ledger.py:459 msgid "Account: {0} is capital Work in progress and can not be updated by Journal Entry" msgstr "الحساب: {0} عبارة "Capital work" قيد التقدم ولا يمكن تحديثها بواسطة "إدخال دفتر اليومية"" -#: erpnext/accounts/doctype/journal_entry/journal_entry.py:351 +#: erpnext/accounts/doctype/journal_entry/journal_entry.py:352 msgid "Account: {0} can only be updated via Stock Transactions" msgstr "الحساب: {0} لا يمكن تحديثه إلا من خلال معاملات المخزون" -#: erpnext/accounts/doctype/payment_entry/payment_entry.py:2786 +#: erpnext/accounts/doctype/payment_entry/payment_entry.py:2787 msgid "Account: {0} is not permitted under Payment Entry" msgstr "الحساب: {0} غير مسموح به بموجب إدخال الدفع" -#: erpnext/controllers/accounts_controller.py:3188 +#: erpnext/controllers/accounts_controller.py:3261 msgid "Account: {0} with currency: {1} can not be selected" msgstr "الحساب: {0} مع العملة: {1} لا يمكن اختياره" @@ -1771,56 +1796,57 @@ msgstr "" msgid "Accounting Entries" msgstr "القيود المحاسبة" -#: erpnext/assets/doctype/asset/asset.py:810 -#: erpnext/assets/doctype/asset/asset.py:825 +#: erpnext/assets/doctype/asset/asset.py:858 +#: erpnext/assets/doctype/asset/asset.py:873 #: erpnext/assets/doctype/asset_capitalization/asset_capitalization.py:561 msgid "Accounting Entry for Asset" msgstr "المدخلات الحسابية للأصول" -#: erpnext/stock/doctype/stock_entry/stock_entry.py:1812 -#: erpnext/stock/doctype/stock_entry/stock_entry.py:1832 +#: erpnext/stock/doctype/stock_entry/stock_entry.py:1882 +#: erpnext/stock/doctype/stock_entry/stock_entry.py:1902 msgid "Accounting Entry for LCV in Stock Entry {0}" msgstr "" -#: erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py:812 +#: erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py:867 msgid "Accounting Entry for Landed Cost Voucher for SCR {0}" msgstr "" -#: erpnext/stock/doctype/purchase_receipt/purchase_receipt.py:824 +#: erpnext/stock/doctype/purchase_receipt/purchase_receipt.py:839 msgid "Accounting Entry for Service" msgstr "القيد المحاسبي للخدمة" -#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:1011 -#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:1032 -#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:1050 -#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:1071 -#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:1092 -#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:1120 -#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:1227 -#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:1463 -#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:1485 -#: erpnext/controllers/stock_controller.py:681 -#: erpnext/controllers/stock_controller.py:698 -#: erpnext/stock/doctype/purchase_receipt/purchase_receipt.py:917 -#: erpnext/stock/doctype/stock_entry/stock_entry.py:1757 -#: erpnext/stock/doctype/stock_entry/stock_entry.py:1771 -#: erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py:647 +#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:1013 +#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:1034 +#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:1052 +#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:1073 +#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:1094 +#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:1122 +#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:1229 +#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:1465 +#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:1487 +#: erpnext/controllers/stock_controller.py:683 +#: erpnext/controllers/stock_controller.py:700 +#: erpnext/stock/doctype/purchase_receipt/purchase_receipt.py:932 +#: erpnext/stock/doctype/stock_entry/stock_entry.py:1827 +#: erpnext/stock/doctype/stock_entry/stock_entry.py:1841 +#: erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py:702 msgid "Accounting Entry for Stock" msgstr "القيود المحاسبية للمخزون" -#: erpnext/stock/doctype/purchase_receipt/purchase_receipt.py:721 +#: erpnext/stock/doctype/purchase_receipt/purchase_receipt.py:736 msgid "Accounting Entry for {0}" msgstr "" -#: erpnext/controllers/accounts_controller.py:2345 +#: erpnext/controllers/accounts_controller.py:2418 msgid "Accounting Entry for {0}: {1} can only be made in currency: {2}" msgstr "المدخل المحاسبي ل {0}: {1} يمكن أن يكون فقط بالعملة {1}.\\n
        \\nAccounting Entry for {0}: {1} can only be made in currency: {2}" #: erpnext/accounts/doctype/invoice_discounting/invoice_discounting.js:193 -#: erpnext/buying/doctype/supplier/supplier.js:90 +#: erpnext/assets/doctype/asset_repair/asset_repair.js:171 +#: erpnext/buying/doctype/supplier/supplier.js:92 #: erpnext/public/js/controllers/stock_controller.js:88 #: erpnext/public/js/utils/ledger_preview.js:8 -#: erpnext/selling/doctype/customer/customer.js:170 +#: erpnext/selling/doctype/customer/customer.js:173 #: erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.js:50 msgid "Accounting Ledger" msgstr "موازنة دفتر الأستاذ" @@ -1842,10 +1868,10 @@ msgid "Accounting Period overlaps with {0}" msgstr "فترة المحاسبة تتداخل مع {0}" #. Description of the 'Accounts Frozen Till Date' (Date) field in DocType -#. 'Accounts Settings' -#: erpnext/accounts/doctype/accounts_settings/accounts_settings.json -msgid "Accounting entries are frozen up to this date. Nobody can create or modify entries except users with the role specified below" -msgstr "تم تجميد قيود المحاسبة حتى هذا التاريخ. لا يمكن لأي شخص إنشاء أو تعديل الإدخالات باستثناء المستخدمين الذين لديهم الدور المحدد أدناه" +#. 'Company' +#: erpnext/setup/doctype/company/company.json +msgid "Accounting entries are frozen up to this date. Only users with the specified role can create or modify entries before this date." +msgstr "" #. Label of the applicable_on_account (Link) field in DocType 'Applicable On #. Account' @@ -1871,7 +1897,7 @@ msgstr "تم تجميد قيود المحاسبة حتى هذا التاريخ. #: erpnext/buying/doctype/supplier/supplier.json #: erpnext/selling/doctype/customer/customer.json #: erpnext/setup/doctype/company/company.json -#: erpnext/setup/doctype/company/company.py:400 +#: erpnext/setup/doctype/company/company.py:436 #: erpnext/setup/doctype/customer_group/customer_group.json #: erpnext/setup/doctype/email_digest/email_digest.json #: erpnext/setup/doctype/incoterm/incoterm.json @@ -1882,12 +1908,14 @@ msgstr "الحسابات" #. Label of the closing_settings_tab (Tab Break) field in DocType 'Accounts #. Settings' +#. Label of the accounts_closing_tab (Tab Break) field in DocType 'Company' #: erpnext/accounts/doctype/accounts_settings/accounts_settings.json +#: erpnext/setup/doctype/company/company.json msgid "Accounts Closing" msgstr "" -#. Label of the acc_frozen_upto (Date) field in DocType 'Accounts Settings' -#: erpnext/accounts/doctype/accounts_settings/accounts_settings.json +#. Label of the accounts_frozen_till_date (Date) field in DocType 'Company' +#: erpnext/setup/doctype/company/company.json msgid "Accounts Frozen Till Date" msgstr "الحسابات المجمدة حتى تاريخ" @@ -1895,7 +1923,7 @@ msgstr "الحسابات المجمدة حتى تاريخ" msgid "Accounts Included in Report" msgstr "" -#: erpnext/accounts/report/tax_withholding_details/tax_withholding_details.py:348 +#: erpnext/accounts/report/tax_withholding_details/tax_withholding_details.py:362 msgid "Accounts Missing Error" msgstr "" @@ -1910,12 +1938,12 @@ msgstr "" #. Label of a Link in the Payables Workspace #. Label of a shortcut in the Payables Workspace #: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:154 -#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:255 +#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:256 #: erpnext/accounts/doctype/journal_entry/journal_entry.json #: erpnext/accounts/report/accounts_payable/accounts_payable.json -#: erpnext/accounts/report/accounts_payable_summary/accounts_payable_summary.js:108 +#: erpnext/accounts/report/accounts_payable_summary/accounts_payable_summary.js:113 #: erpnext/accounts/workspace/payables/payables.json -#: erpnext/buying/doctype/supplier/supplier.js:102 +#: erpnext/buying/doctype/supplier/supplier.js:104 msgid "Accounts Payable" msgstr "الحسابات الدائنة" @@ -1932,7 +1960,6 @@ msgstr "ملخص الحسابات المستحقة للدفع" #. Option for the 'Report' (Select) field in DocType 'Process Statement Of #. Accounts' #. Name of a report -#. Label of a shortcut in the Accounting Workspace #. Label of a Link in the Receivables Workspace #. Label of a shortcut in the Receivables Workspace #: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:12 @@ -1941,9 +1968,8 @@ msgstr "ملخص الحسابات المستحقة للدفع" #: erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.json #: erpnext/accounts/report/accounts_receivable/accounts_receivable.json #: erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.js:136 -#: erpnext/accounts/workspace/accounting/accounting.json #: erpnext/accounts/workspace/receivables/receivables.json -#: erpnext/selling/doctype/customer/customer.js:159 +#: erpnext/selling/doctype/customer/customer.js:162 msgid "Accounts Receivable" msgstr "الحسابات المدينة" @@ -1987,7 +2013,6 @@ msgstr "" #. Name of a DocType #. Label of a Link in the Accounting Workspace -#. Label of a Link in the Settings Workspace #. Label of a shortcut in the Settings Workspace #: erpnext/accounts/doctype/accounts_settings/accounts_settings.json #: erpnext/accounts/workspace/accounting/accounting.json @@ -1995,7 +2020,7 @@ msgstr "" msgid "Accounts Settings" msgstr "إعدادات الحسابات" -#: erpnext/accounts/doctype/journal_entry/journal_entry.py:1382 +#: erpnext/accounts/doctype/journal_entry/journal_entry.py:1297 msgid "Accounts table cannot be blank." msgstr "جدول الحسابات لا يمكن أن يكون فارغا." @@ -2005,7 +2030,7 @@ msgid "Accounts to Merge" msgstr "" #: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:158 -#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:264 +#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:265 msgid "Accrued Expenses" msgstr "" @@ -2039,15 +2064,15 @@ msgstr "قيمة الاستهلاك المتراكمة" msgid "Accumulated Depreciation as on" msgstr "الاستهلاك المتراكم كما في" -#: erpnext/accounts/doctype/budget/budget.py:253 +#: erpnext/accounts/doctype/budget/budget.py:521 msgid "Accumulated Monthly" msgstr "متراكمة شهريا" -#: erpnext/controllers/budget_controller.py:422 +#: erpnext/controllers/budget_controller.py:425 msgid "Accumulated Monthly Budget for Account {0} against {1} {2} is {3}. It will be collectively ({4}) exceeded by {5}" msgstr "" -#: erpnext/controllers/budget_controller.py:324 +#: erpnext/controllers/budget_controller.py:327 msgid "Accumulated Monthly Budget for Account {0} against {1}: {2} is {3}. It will be exceeded by {4}" msgstr "" @@ -2283,7 +2308,7 @@ msgstr "تاريخ الإنتهاء الفعلي" msgid "Actual End Date (via Timesheet)" msgstr "تاريخ الإنتهاء الفعلي (عبر ورقة الوقت)" -#: erpnext/manufacturing/doctype/work_order/work_order.py:221 +#: erpnext/manufacturing/doctype/work_order/work_order.py:222 msgid "Actual End Date cannot be before Actual Start Date" msgstr "" @@ -2297,7 +2322,7 @@ msgstr "الفعلي وقت الانتهاء" msgid "Actual Expense" msgstr "" -#: erpnext/accounts/doctype/budget/budget.py:319 +#: erpnext/accounts/doctype/budget/budget.py:601 msgid "Actual Expenses" msgstr "" @@ -2345,7 +2370,7 @@ msgstr "الكمية الفعلية (في المصدر / الهدف)" msgid "Actual Qty in Warehouse" msgstr "الكمية الفعلية في المستودع" -#: erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py:198 +#: erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py:202 msgid "Actual Qty is mandatory" msgstr "الكمية الفعلية هي إلزامية" @@ -2405,7 +2430,7 @@ msgstr "الوقت الفعلي (بالساعات)" msgid "Actual qty in stock" msgstr "الكمية الفعلية في المخزون" -#: erpnext/accounts/doctype/payment_entry/payment_entry.js:1527 +#: erpnext/accounts/doctype/payment_entry/payment_entry.js:1526 #: erpnext/public/js/controllers/accounts.js:197 msgid "Actual type tax cannot be included in Item rate in row {0}" msgstr "نوع الضريبة الفعلي لا يمكن تضمينه في معدل الصنف في الصف {0}" @@ -2414,7 +2439,7 @@ msgstr "نوع الضريبة الفعلي لا يمكن تضمينه في مع msgid "Ad-hoc Qty" msgstr "" -#: erpnext/stock/doctype/item/item.js:557 +#: erpnext/stock/doctype/item/item.js:576 #: erpnext/stock/doctype/price_list/price_list.js:8 msgid "Add / Edit Prices" msgstr "إضافة و تعديل الأسعار" @@ -2447,7 +2472,7 @@ msgstr "" msgid "Add Employees" msgstr "إضافة موظفين" -#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:234 +#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:256 #: erpnext/selling/doctype/sales_order/sales_order.js:277 #: erpnext/stock/dashboard/item_dashboard.js:216 msgid "Add Item" @@ -2495,13 +2520,18 @@ msgstr "" msgid "Add Order Discount" msgstr "أضف خصم الطلب" +#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:281 +#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:416 +msgid "Add Phantom Item" +msgstr "" + #. Label of the add_quote (Check) field in DocType 'Email Digest' #: erpnext/setup/doctype/email_digest/email_digest.json msgid "Add Quote" msgstr "إضافة عرض سعر" #. Label of the add_raw_materials (Button) field in DocType 'BOM Operation' -#: erpnext/manufacturing/doctype/bom/bom.js:973 +#: erpnext/manufacturing/doctype/bom/bom.js:990 #: erpnext/manufacturing/doctype/bom_operation/bom_operation.json msgid "Add Raw Materials" msgstr "" @@ -2557,8 +2587,8 @@ msgstr "" msgid "Add Stock" msgstr "" -#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:259 -#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:390 +#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:281 +#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:416 msgid "Add Sub Assembly" msgstr "" @@ -2586,7 +2616,7 @@ msgid "Add details" msgstr "" #: erpnext/stock/doctype/pick_list/pick_list.js:86 -#: erpnext/stock/doctype/pick_list/pick_list.py:859 +#: erpnext/stock/doctype/pick_list/pick_list.py:866 msgid "Add items in the Item Locations table" msgstr "أضف عناصر في جدول "مواقع العناصر"" @@ -2773,7 +2803,7 @@ msgstr "مبلغ الخصم الإضافي" msgid "Additional Discount Amount (Company Currency)" msgstr "مقدار الخصم الاضافي (بعملة الشركة)" -#: erpnext/controllers/taxes_and_totals.py:731 +#: erpnext/controllers/taxes_and_totals.py:805 msgid "Additional Discount Amount ({discount_amount}) cannot exceed the total before such discount ({total_before_discount})" msgstr "" @@ -2849,7 +2879,7 @@ msgstr "معلومة اضافية" msgid "Additional Information updated successfully." msgstr "" -#: erpnext/manufacturing/doctype/work_order/work_order.js:777 +#: erpnext/manufacturing/doctype/work_order/work_order.js:787 msgid "Additional Material Transfer" msgstr "" @@ -2872,7 +2902,7 @@ msgstr "تكاليف تشغيل اضافية" msgid "Additional Transferred Qty" msgstr "" -#: erpnext/manufacturing/doctype/work_order/work_order.py:664 +#: erpnext/manufacturing/doctype/work_order/work_order.py:665 msgid "Additional Transferred Qty {0}\n" "\t\t\t\t\tcannot be greater than {1}.\n" "\t\t\t\t\tTo fix this, increase the percentage value\n" @@ -2885,6 +2915,10 @@ msgstr "" msgid "Additional information regarding the customer." msgstr "معلومات إضافية عن الزبون." +#: erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py:584 +msgid "Additional {0} {1} of item {2} required as per BOM to complete this transaction" +msgstr "" + #. Label of the address_and_contact_tab (Tab Break) field in DocType 'Dunning' #. Label of the contact_and_address_tab (Tab Break) field in DocType 'POS #. Invoice' @@ -3030,11 +3064,11 @@ msgstr "" msgid "Adjust Qty" msgstr "" -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.js:1111 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.js:1112 msgid "Adjustment Against" msgstr "" -#: erpnext/stock/doctype/purchase_receipt/purchase_receipt.py:649 +#: erpnext/stock/doctype/purchase_receipt/purchase_receipt.py:664 msgid "Adjustment based on Purchase Invoice rate" msgstr "" @@ -3108,7 +3142,7 @@ msgstr "" #: erpnext/accounts/doctype/pos_invoice/pos_invoice.json #: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json #: erpnext/accounts/doctype/sales_invoice/sales_invoice.json -#: erpnext/controllers/accounts_controller.py:279 +#: erpnext/controllers/accounts_controller.py:285 #: erpnext/setup/doctype/company/company.json msgid "Advance Payments" msgstr "دفعات مقدمة" @@ -3151,11 +3185,11 @@ msgstr "" msgid "Advance amount" msgstr "المبلغ مقدما" -#: erpnext/controllers/taxes_and_totals.py:868 +#: erpnext/controllers/taxes_and_totals.py:942 msgid "Advance amount cannot be greater than {0} {1}" msgstr "قيمة الدفعة المقدمة لا يمكن أن تكون أكبر من {0} {1}" -#: erpnext/accounts/doctype/journal_entry/journal_entry.py:930 +#: erpnext/accounts/doctype/journal_entry/journal_entry.py:845 msgid "Advance paid against {0} {1} cannot be greater than Grand Total {2}" msgstr "" @@ -3213,7 +3247,7 @@ msgstr "مقابل" #: erpnext/accounts/doctype/journal_entry_account/journal_entry_account.json #: erpnext/accounts/report/bank_clearance_summary/bank_clearance_summary.py:39 #: erpnext/accounts/report/bank_reconciliation_statement/bank_reconciliation_statement.py:91 -#: erpnext/accounts/report/general_ledger/general_ledger.py:741 +#: erpnext/accounts/report/general_ledger/general_ledger.py:748 msgid "Against Account" msgstr "مقابل الحساب" @@ -3228,14 +3262,10 @@ msgstr "مقابل الحساب" msgid "Against Blanket Order" msgstr "ضد بطانية النظام" -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1127 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1076 msgid "Against Customer Order {0}" msgstr "" -#: erpnext/selling/doctype/sales_order/sales_order.js:1589 -msgid "Against Default Supplier" -msgstr "ضد المورد الافتراضي" - #. Label of the dn_detail (Data) field in DocType 'Delivery Note Item' #: erpnext/stock/doctype/delivery_note_item/delivery_note_item.json msgid "Against Delivery Note Item" @@ -3287,7 +3317,7 @@ msgstr "" msgid "Against Income Account" msgstr "مقابل حساب الدخل" -#: erpnext/accounts/doctype/journal_entry/journal_entry.py:792 +#: erpnext/accounts/doctype/journal_entry/journal_entry.py:707 #: erpnext/accounts/doctype/payment_entry/payment_entry.py:771 msgid "Against Journal Entry {0} does not have any unmatched {1} entry" msgstr "قيد اليومية المقابل {0} لا يحتوى مدخل {1} غير مطابق\\n
        \\nAgainst Journal Entry {0} does not have any unmatched {1} entry" @@ -3329,13 +3359,13 @@ msgstr "مقابل بند طلب مبيعات" msgid "Against Stock Entry" msgstr "ضد دخول الأسهم" -#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:330 +#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:332 msgid "Against Supplier Invoice {0}" msgstr "" #. Label of the against_voucher (Dynamic Link) field in DocType 'GL Entry' #: erpnext/accounts/doctype/gl_entry/gl_entry.json -#: erpnext/accounts/report/general_ledger/general_ledger.py:774 +#: erpnext/accounts/report/general_ledger/general_ledger.py:781 msgid "Against Voucher" msgstr "مقابل إيصال" @@ -3359,7 +3389,7 @@ msgstr "" #: erpnext/accounts/doctype/advance_payment_ledger_entry/advance_payment_ledger_entry.json #: erpnext/accounts/doctype/gl_entry/gl_entry.json #: erpnext/accounts/doctype/payment_ledger_entry/payment_ledger_entry.json -#: erpnext/accounts/report/general_ledger/general_ledger.py:772 +#: erpnext/accounts/report/general_ledger/general_ledger.py:779 #: erpnext/accounts/report/payment_ledger/payment_ledger.py:183 msgid "Against Voucher Type" msgstr "مقابل إيصال نوع" @@ -3377,7 +3407,7 @@ msgstr "عمر" msgid "Age (Days)" msgstr "(العمر (أيام" -#: erpnext/stock/report/stock_ageing/stock_ageing.py:218 +#: erpnext/stock/report/stock_ageing/stock_ageing.py:220 msgid "Age ({0})" msgstr "" @@ -3473,7 +3503,7 @@ msgstr "" #: erpnext/accounts/doctype/chart_of_accounts_importer/chart_of_accounts_importer.js:165 #: erpnext/accounts/doctype/chart_of_accounts_importer/chart_of_accounts_importer.js:185 #: erpnext/accounts/doctype/chart_of_accounts_importer/chart_of_accounts_importer.py:166 -#: erpnext/accounts/utils.py:1483 erpnext/public/js/setup_wizard.js:184 +#: erpnext/accounts/utils.py:1490 erpnext/public/js/setup_wizard.js:184 msgid "All Accounts" msgstr "جميع الحسابات" @@ -3497,7 +3527,7 @@ msgstr "" msgid "All Activities HTML" msgstr "" -#: erpnext/manufacturing/doctype/bom/bom.py:303 +#: erpnext/manufacturing/doctype/bom/bom.py:306 msgid "All BOMs" msgstr "كل الأصناف المركبة" @@ -3525,14 +3555,8 @@ msgstr "جميع مجموعات العملاء" #: erpnext/patches/v11_0/update_department_lft_rgt.py:9 #: erpnext/patches/v11_0/update_department_lft_rgt.py:11 #: erpnext/patches/v11_0/update_department_lft_rgt.py:16 -#: erpnext/setup/doctype/company/company.py:393 -#: erpnext/setup/doctype/company/company.py:396 -#: erpnext/setup/doctype/company/company.py:401 -#: erpnext/setup/doctype/company/company.py:407 -#: erpnext/setup/doctype/company/company.py:413 -#: erpnext/setup/doctype/company/company.py:419 -#: erpnext/setup/doctype/company/company.py:425 -#: erpnext/setup/doctype/company/company.py:431 +#: erpnext/setup/doctype/company/company.py:429 +#: erpnext/setup/doctype/company/company.py:432 #: erpnext/setup/doctype/company/company.py:437 #: erpnext/setup/doctype/company/company.py:443 #: erpnext/setup/doctype/company/company.py:449 @@ -3540,6 +3564,12 @@ msgstr "جميع مجموعات العملاء" #: erpnext/setup/doctype/company/company.py:461 #: erpnext/setup/doctype/company/company.py:467 #: erpnext/setup/doctype/company/company.py:473 +#: erpnext/setup/doctype/company/company.py:479 +#: erpnext/setup/doctype/company/company.py:485 +#: erpnext/setup/doctype/company/company.py:491 +#: erpnext/setup/doctype/company/company.py:497 +#: erpnext/setup/doctype/company/company.py:503 +#: erpnext/setup/doctype/company/company.py:509 msgid "All Departments" msgstr "جميع الاقسام" @@ -3615,7 +3645,7 @@ msgstr "جميع مجموعات الموردين" msgid "All Territories" msgstr "جميع الأقاليم" -#: erpnext/setup/doctype/company/company.py:338 +#: erpnext/setup/doctype/company/company.py:374 msgid "All Warehouses" msgstr "جميع المخازن" @@ -3633,27 +3663,27 @@ msgstr "يجب نقل جميع الاتصالات بما في ذلك وما فو msgid "All items are already requested" msgstr "" -#: erpnext/stock/doctype/purchase_receipt/purchase_receipt.py:1354 +#: erpnext/stock/doctype/purchase_receipt/purchase_receipt.py:1369 msgid "All items have already been Invoiced/Returned" msgstr "تم بالفعل تحرير / إرجاع جميع العناصر" -#: erpnext/stock/doctype/delivery_note/delivery_note.py:1202 +#: erpnext/stock/doctype/delivery_note/delivery_note.py:1207 msgid "All items have already been received" msgstr "" -#: erpnext/stock/doctype/stock_entry/stock_entry.py:2910 +#: erpnext/stock/doctype/stock_entry/stock_entry.py:2992 msgid "All items have already been transferred for this Work Order." msgstr "جميع الإصناف تم نقلها لأمر العمل" -#: erpnext/public/js/controllers/transaction.js:2899 +#: erpnext/public/js/controllers/transaction.js:2907 msgid "All items in this document already have a linked Quality Inspection." msgstr "" -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1266 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1215 msgid "All items must be linked to a Sales Order or Subcontracting Inward Order for this Sales Invoice." msgstr "" -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1277 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1226 msgid "All linked Sales Orders must be subcontracted." msgstr "" @@ -3667,11 +3697,11 @@ msgstr "" msgid "All the items have been already returned." msgstr "" -#: erpnext/manufacturing/doctype/work_order/work_order.js:1176 +#: erpnext/manufacturing/doctype/work_order/work_order.js:1171 msgid "All the required items (raw materials) will be fetched from BOM and populated in this table. Here you can also change the Source Warehouse for any item. And during the production, you can track transferred raw materials from this table." msgstr "" -#: erpnext/stock/doctype/delivery_note/delivery_note.py:853 +#: erpnext/stock/doctype/delivery_note/delivery_note.py:857 msgid "All these items have already been Invoiced/Returned" msgstr "تم بالفعل إصدار فاتورة / إرجاع جميع هذه العناصر" @@ -3700,7 +3730,7 @@ msgstr "تخصيص مبلغ الدفع" msgid "Allocate Payment Based On Payment Terms" msgstr "تخصيص الدفع على أساس شروط الدفع" -#: erpnext/accounts/doctype/payment_entry/payment_entry.js:1717 +#: erpnext/accounts/doctype/payment_entry/payment_entry.js:1716 msgid "Allocate Payment Request" msgstr "" @@ -3731,7 +3761,7 @@ msgstr "تخصيص" #: erpnext/accounts/doctype/advance_taxes_and_charges/advance_taxes_and_charges.json #: erpnext/accounts/doctype/bank_transaction/bank_transaction.json #: erpnext/accounts/doctype/bank_transaction_payments/bank_transaction_payments.json -#: erpnext/accounts/doctype/payment_entry/payment_entry.js:1708 +#: erpnext/accounts/doctype/payment_entry/payment_entry.js:1707 #: erpnext/accounts/doctype/payment_reconciliation_allocation/payment_reconciliation_allocation.json #: erpnext/accounts/doctype/process_payment_reconciliation_log_allocations/process_payment_reconciliation_log_allocations.json #: erpnext/accounts/doctype/purchase_invoice_advance/purchase_invoice_advance.json @@ -3757,11 +3787,11 @@ msgstr "" msgid "Allocated amount" msgstr "المبلغ المخصص" -#: erpnext/accounts/utils.py:617 +#: erpnext/accounts/utils.py:621 msgid "Allocated amount cannot be greater than unadjusted amount" msgstr "لا يمكن أن يكون المبلغ المخصص أكبر من المبلغ غير المعدل" -#: erpnext/accounts/utils.py:615 +#: erpnext/accounts/utils.py:619 msgid "Allocated amount cannot be negative" msgstr "لا يمكن أن يكون المبلغ المخصص سالبًا" @@ -3782,13 +3812,13 @@ msgstr "توزيع" msgid "Allocations" msgstr "" -#: erpnext/manufacturing/report/production_planning_report/production_planning_report.py:422 +#: erpnext/manufacturing/report/production_planning_report/production_planning_report.py:427 msgid "Allotted Qty" msgstr "الكمية المخصصة" #. Label of the allow_account_creation_against_child_company (Check) field in #. DocType 'Company' -#: erpnext/accounts/doctype/account/account.py:540 +#: erpnext/accounts/doctype/account/account.py:542 #: erpnext/accounts/doctype/chart_of_accounts_importer/chart_of_accounts_importer.py:68 #: erpnext/setup/doctype/company/company.json msgid "Allow Account Creation Against Child Company" @@ -3863,7 +3893,7 @@ msgstr "" msgid "Allow Item To Be Added Multiple Times in a Transaction" msgstr "السماح بإضافة العنصر عدة مرات في المعاملة" -#: erpnext/controllers/selling_controller.py:813 +#: erpnext/controllers/selling_controller.py:838 msgid "Allow Item to Be Added Multiple Times in a Transaction" msgstr "" @@ -4203,7 +4233,7 @@ msgstr "" msgid "Allows users to submit Supplier Quotations with zero quantity. Useful when rates are fixed but the quantities are not. Eg. Rate Contracts." msgstr "" -#: erpnext/stock/doctype/pick_list/pick_list.py:1001 +#: erpnext/stock/doctype/pick_list/pick_list.py:1008 msgid "Already Picked" msgstr "" @@ -4219,11 +4249,11 @@ msgstr "تم تعيين الإعداد الافتراضي في الملف الش msgid "Also you can't switch back to FIFO after setting the valuation method to Moving Average for this item." msgstr "" -#: erpnext/manufacturing/doctype/bom/bom.js:221 +#: erpnext/manufacturing/doctype/bom/bom.js:222 #: erpnext/manufacturing/doctype/work_order/work_order.js:165 #: erpnext/manufacturing/doctype/work_order/work_order.js:180 #: erpnext/public/js/utils.js:496 -#: erpnext/stock/doctype/stock_entry/stock_entry.js:264 +#: erpnext/stock/doctype/stock_entry/stock_entry.js:269 msgid "Alternate Item" msgstr "صنف بديل" @@ -4239,7 +4269,7 @@ msgstr "رمز الصنف البديل" msgid "Alternative Item Name" msgstr "اسم الصنف البديل" -#: erpnext/selling/doctype/quotation/quotation.js:361 +#: erpnext/selling/doctype/quotation/quotation.js:362 msgid "Alternative Items" msgstr "" @@ -4263,6 +4293,7 @@ msgstr "" #. Charges' #. Label of the amount (Data) field in DocType 'Bank Clearance Detail' #. Label of the amount (Currency) field in DocType 'Bank Guarantee' +#. Label of the amount (Currency) field in DocType 'Budget Distribution' #. Label of the amount (Float) field in DocType 'Cashier Closing Payments' #. Label of the sec_break1 (Section Break) field in DocType 'Journal Entry #. Account' @@ -4300,7 +4331,7 @@ msgstr "" #. Reference' #. Label of the tax_amount (Currency) field in DocType 'Sales Taxes and #. Charges' -#. Label of the amount (Int) field in DocType 'Share Balance' +#. Label of the amount (Currency) field in DocType 'Share Balance' #. Label of the amount (Currency) field in DocType 'Share Transfer' #. Label of the amount (Currency) field in DocType 'Asset Capitalization #. Service Item' @@ -4360,8 +4391,9 @@ msgstr "" #: erpnext/accounts/doctype/advance_taxes_and_charges/advance_taxes_and_charges.json #: erpnext/accounts/doctype/bank_clearance_detail/bank_clearance_detail.json #: erpnext/accounts/doctype/bank_guarantee/bank_guarantee.json +#: erpnext/accounts/doctype/budget_distribution/budget_distribution.json #: erpnext/accounts/doctype/cashier_closing_payments/cashier_closing_payments.json -#: erpnext/accounts/doctype/journal_entry/journal_entry.js:588 +#: erpnext/accounts/doctype/journal_entry/journal_entry.js:592 #: erpnext/accounts/doctype/journal_entry_account/journal_entry_account.json #: erpnext/accounts/doctype/payment_entry/payment_entry.json #: erpnext/accounts/doctype/payment_ledger_entry/payment_ledger_entry.json @@ -4394,8 +4426,8 @@ msgstr "" #: erpnext/accounts/report/bank_clearance_summary/bank_clearance_summary.py:45 #: erpnext/accounts/report/billed_items_to_be_received/billed_items_to_be_received.py:79 #: erpnext/accounts/report/delivered_items_to_be_billed/delivered_items_to_be_billed.py:44 -#: erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py:275 -#: erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py:330 +#: erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py:267 +#: erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py:319 #: erpnext/accounts/report/payment_ledger/payment_ledger.py:201 #: erpnext/accounts/report/payment_period_based_on_invoice_date/payment_period_based_on_invoice_date.py:111 #: erpnext/accounts/report/received_items_to_be_billed/received_items_to_be_billed.py:44 @@ -4416,7 +4448,7 @@ msgstr "" #: erpnext/manufacturing/doctype/bom_item/bom_item.json #: erpnext/manufacturing/doctype/bom_scrap_item/bom_scrap_item.json #: erpnext/manufacturing/doctype/work_order_item/work_order_item.json -#: erpnext/selling/doctype/quotation/quotation.js:299 +#: erpnext/selling/doctype/quotation/quotation.js:300 #: erpnext/selling/doctype/quotation_item/quotation_item.json #: erpnext/selling/doctype/sales_order_item/sales_order_item.json #: erpnext/selling/page/point_of_sale/pos_item_cart.js:46 @@ -4455,6 +4487,8 @@ msgstr "كمية" msgid "Amount (AED)" msgstr "" +#. Label of the base_amount (Currency) field in DocType 'Advance Payment Ledger +#. Entry' #. Label of the base_tax_amount (Currency) field in DocType 'Advance Taxes and #. Charges' #. Label of the amount (Currency) field in DocType 'Payment Entry Deduction' @@ -4477,6 +4511,7 @@ msgstr "" #. Charges' #. Label of the amount (Currency) field in DocType 'Landed Cost Vendor Invoice' #. Label of the base_amount (Currency) field in DocType 'Purchase Receipt Item' +#: erpnext/accounts/doctype/advance_payment_ledger_entry/advance_payment_ledger_entry.json #: erpnext/accounts/doctype/advance_taxes_and_charges/advance_taxes_and_charges.json #: erpnext/accounts/doctype/payment_entry_deduction/payment_entry_deduction.json #: erpnext/accounts/doctype/pos_invoice_item/pos_invoice_item.json @@ -4616,16 +4651,16 @@ msgstr "الإجمالي" msgid "An Item Group is a way to classify items based on types." msgstr "" -#: erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py:446 +#: erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py:520 msgid "An error has been appeared while reposting item valuation via {0}" msgstr "" #: erpnext/public/js/controllers/buying.js:380 -#: erpnext/public/js/utils/sales_common.js:464 +#: erpnext/public/js/utils/sales_common.js:489 msgid "An error occurred during the update process" msgstr "حدث خطأ أثناء عملية التحديث" -#: erpnext/stock/reorder_item.py:378 +#: erpnext/stock/reorder_item.py:386 msgid "An error occurred for certain Items while creating Material Requests based on Re-order level. Please rectify these issues :" msgstr "" @@ -4641,11 +4676,11 @@ msgstr "" msgid "Annual Billing: {0}" msgstr "الفواتير السنوية: {0}" -#: erpnext/controllers/budget_controller.py:446 +#: erpnext/controllers/budget_controller.py:449 msgid "Annual Budget for Account {0} against {1} {2} is {3}. It will be collectively ({4}) exceeded by {5}" msgstr "" -#: erpnext/controllers/budget_controller.py:311 +#: erpnext/controllers/budget_controller.py:314 msgid "Annual Budget for Account {0} against {1}: {2} is {3}. It will be exceeded by {4}" msgstr "" @@ -4668,9 +4703,9 @@ msgstr "الدخل السنوي" msgid "Annual Revenue" msgstr "" -#: erpnext/accounts/doctype/budget/budget.py:86 -msgid "Another Budget record '{0}' already exists against {1} '{2}' and account '{3}' for fiscal year {4}" -msgstr "سجل الموازنة الآخر '{0}' موجود بالفعل مقابل {1} '{2}' وحساب '{3}' للسنة المالية {4}" +#: erpnext/accounts/doctype/budget/budget.py:142 +msgid "Another Budget record '{0}' already exists against {1} '{2}' and account '{3}' with overlapping fiscal years." +msgstr "" #: erpnext/accounts/doctype/cost_center_allocation/cost_center_allocation.py:107 msgid "Another Cost Center Allocation record {0} applicable from {1}, hence this allocation will be applicable upto {2}" @@ -4813,7 +4848,7 @@ msgstr "رمز القسيمة المطبق" msgid "Applied on each reading." msgstr "" -#: erpnext/stock/doctype/putaway_rule/putaway_rule.py:188 +#: erpnext/stock/doctype/putaway_rule/putaway_rule.py:197 msgid "Applied putaway rules." msgstr "" @@ -5060,7 +5095,7 @@ msgstr "" msgid "Are you sure you want to clear all demo data?" msgstr "" -#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:451 +#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:480 msgid "Are you sure you want to delete this Item?" msgstr "" @@ -5072,6 +5107,10 @@ msgstr "" msgid "Are you sure you want to restart this subscription?" msgstr "" +#: erpnext/accounts/doctype/budget/budget.js:82 +msgid "Are you sure you want to revise this budget? The current budget will be cancelled and a new draft will be created." +msgstr "" + #. Label of the area (Float) field in DocType 'Location' #. Name of a UOM #: erpnext/assets/doctype/location/location.json @@ -5084,7 +5123,7 @@ msgstr "منطقة" msgid "Area UOM" msgstr "وحدة قياس المساحة" -#: erpnext/manufacturing/report/production_planning_report/production_planning_report.py:430 +#: erpnext/manufacturing/report/production_planning_report/production_planning_report.py:435 msgid "Arrival Quantity" msgstr "كمية الوصول" @@ -5119,7 +5158,7 @@ msgstr "نظرًا لتمكين الحقل {0} ، يكون الحقل {1} إلز msgid "As the field {0} is enabled, the value of the field {1} should be more than 1." msgstr "أثناء تمكين الحقل {0} ، يجب أن تكون قيمة الحقل {1} أكثر من 1." -#: erpnext/stock/doctype/item/item.py:984 +#: erpnext/stock/doctype/item/item.py:987 msgid "As there are existing submitted transactions against item {0}, you can not change the value of {1}." msgstr "" @@ -5131,7 +5170,7 @@ msgstr "" msgid "As there are sufficient Sub Assembly Items, Work Order is not required for Warehouse {0}." msgstr "" -#: erpnext/manufacturing/doctype/production_plan/production_plan.py:1788 +#: erpnext/manufacturing/doctype/production_plan/production_plan.py:1794 msgid "As there are sufficient raw materials, Material Request is not required for Warehouse {0}." msgstr "نظرًا لوجود مواد خام كافية ، فإن طلب المواد ليس مطلوبًا للمستودع {0}." @@ -5181,7 +5220,7 @@ msgstr "" #: erpnext/assets/doctype/asset_shift_allocation/asset_shift_allocation.json #: erpnext/assets/doctype/asset_value_adjustment/asset_value_adjustment.json #: erpnext/assets/workspace/assets/assets.json -#: erpnext/stock/doctype/purchase_receipt/purchase_receipt.js:215 +#: erpnext/stock/doctype/purchase_receipt/purchase_receipt.js:189 #: erpnext/stock/doctype/serial_no/serial_no.json msgid "Asset" msgstr "الأصول" @@ -5261,7 +5300,7 @@ msgstr "حساب فئة الأصول" msgid "Asset Category Name" msgstr "اسم فئة الأصول" -#: erpnext/stock/doctype/item/item.py:305 +#: erpnext/stock/doctype/item/item.py:307 msgid "Asset Category is mandatory for Fixed Asset item" msgstr "فئة الموجودات إلزامية لبنود الموجودات الثابتة\\n
        \\nAsset Category is mandatory for Fixed Asset item" @@ -5299,7 +5338,7 @@ msgstr "" msgid "Asset Depreciation Schedule {0} for Asset {1} and Finance Book {2} already exists." msgstr "" -#: erpnext/assets/doctype/asset/asset.py:180 +#: erpnext/assets/doctype/asset/asset.py:181 msgid "Asset Depreciation Schedules created/updated:
        {0}

        Please check, edit if needed, and submit the Asset." msgstr "" @@ -5372,7 +5411,7 @@ msgstr "فريق صيانة الأصول" #. Label of a Link in the Assets Workspace #: erpnext/assets/doctype/asset_movement/asset_movement.json #: erpnext/assets/workspace/assets/assets.json -#: erpnext/stock/doctype/purchase_receipt/purchase_receipt.js:226 +#: erpnext/stock/doctype/purchase_receipt/purchase_receipt.js:200 msgid "Asset Movement" msgstr "حركة الأصول" @@ -5381,7 +5420,7 @@ msgstr "حركة الأصول" msgid "Asset Movement Item" msgstr "بند حركة الأصول" -#: erpnext/assets/doctype/asset/asset.py:1056 +#: erpnext/assets/doctype/asset/asset.py:1104 msgid "Asset Movement record {0} created" msgstr "تم إنشاء سجل حركة الأصول {0}\\n
        \\nAsset Movement record {0} created" @@ -5431,7 +5470,7 @@ msgstr "" #. Label of the asset_received_but_not_billed (Link) field in DocType 'Company' #: erpnext/accounts/doctype/account/account.json #: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:165 -#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:278 +#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:279 #: erpnext/accounts/report/account_balance/account_balance.js:38 #: erpnext/setup/doctype/company/company.json msgid "Asset Received But Not Billed" @@ -5512,15 +5551,15 @@ msgstr "لا يمكن نشر تسوية قيمة الأصل قبل تاريخ ش msgid "Asset Value Analytics" msgstr "تحليلات قيمة الأصول" -#: erpnext/assets/doctype/asset/asset.py:212 +#: erpnext/assets/doctype/asset/asset.py:213 msgid "Asset cancelled" msgstr "" -#: erpnext/assets/doctype/asset/asset.py:605 +#: erpnext/assets/doctype/asset/asset.py:653 msgid "Asset cannot be cancelled, as it is already {0}" msgstr "لا يمكن إلغاء الأصل، لانه بالفعل {0}" -#: erpnext/assets/doctype/asset/depreciation.py:389 +#: erpnext/assets/doctype/asset/depreciation.py:391 msgid "Asset cannot be scrapped before the last depreciation entry." msgstr "" @@ -5528,15 +5567,15 @@ msgstr "" msgid "Asset capitalized after Asset Capitalization {0} was submitted" msgstr "" -#: erpnext/assets/doctype/asset/asset.py:221 +#: erpnext/assets/doctype/asset/asset.py:222 msgid "Asset created" msgstr "" -#: erpnext/assets/doctype/asset/asset.py:1296 +#: erpnext/assets/doctype/asset/asset.py:1344 msgid "Asset created after being split from Asset {0}" msgstr "" -#: erpnext/assets/doctype/asset/asset.py:224 +#: erpnext/assets/doctype/asset/asset.py:225 msgid "Asset deleted" msgstr "" @@ -5544,7 +5583,7 @@ msgstr "" msgid "Asset issued to Employee {0}" msgstr "" -#: erpnext/assets/doctype/asset_repair/asset_repair.py:145 +#: erpnext/assets/doctype/asset_repair/asset_repair.py:179 msgid "Asset out of order due to Asset Repair {0}" msgstr "" @@ -5552,7 +5591,7 @@ msgstr "" msgid "Asset received at Location {0} and issued to Employee {1}" msgstr "" -#: erpnext/assets/doctype/asset/depreciation.py:450 +#: erpnext/assets/doctype/asset/depreciation.py:452 msgid "Asset restored" msgstr "" @@ -5560,24 +5599,24 @@ msgstr "" msgid "Asset restored after Asset Capitalization {0} was cancelled" msgstr "" -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1496 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1445 msgid "Asset returned" msgstr "" -#: erpnext/assets/doctype/asset/depreciation.py:437 +#: erpnext/assets/doctype/asset/depreciation.py:439 msgid "Asset scrapped" msgstr "" -#: erpnext/assets/doctype/asset/depreciation.py:439 +#: erpnext/assets/doctype/asset/depreciation.py:441 msgid "Asset scrapped via Journal Entry {0}" msgstr "ألغت الأصول عن طريق قيد اليومية {0}\\n
        \\n Asset scrapped via Journal Entry {0}" -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1496 -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1499 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1445 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1448 msgid "Asset sold" msgstr "" -#: erpnext/assets/doctype/asset/asset.py:199 +#: erpnext/assets/doctype/asset/asset.py:200 msgid "Asset submitted" msgstr "" @@ -5585,15 +5624,15 @@ msgstr "" msgid "Asset transferred to Location {0}" msgstr "" -#: erpnext/assets/doctype/asset/asset.py:1305 +#: erpnext/assets/doctype/asset/asset.py:1353 msgid "Asset updated after being split into Asset {0}" msgstr "" -#: erpnext/assets/doctype/asset_repair/asset_repair.py:399 +#: erpnext/assets/doctype/asset_repair/asset_repair.py:442 msgid "Asset updated due to Asset Repair {0} {1}." msgstr "" -#: erpnext/assets/doctype/asset/depreciation.py:371 +#: erpnext/assets/doctype/asset/depreciation.py:373 msgid "Asset {0} cannot be scrapped, as it is already {1}" msgstr "لا يمكن إلغاء الأصل {0} ، كما هو بالفعل {1}\\n
        \\nAsset {0} cannot be scrapped, as it is already {1}" @@ -5622,7 +5661,7 @@ msgstr "" msgid "Asset {0} has been updated. Please set the depreciation details if any and submit it." msgstr "" -#: erpnext/assets/doctype/asset_repair/asset_repair.py:72 +#: erpnext/assets/doctype/asset_repair/asset_repair.py:75 msgid "Asset {0} is in {1} status and cannot be repaired." msgstr "" @@ -5634,11 +5673,11 @@ msgstr "" msgid "Asset {0} is not submitted. Please submit the asset before proceeding." msgstr "" -#: erpnext/assets/doctype/asset/depreciation.py:369 +#: erpnext/assets/doctype/asset/depreciation.py:371 msgid "Asset {0} must be submitted" msgstr "الاصل {0} يجب تقديمه" -#: erpnext/controllers/buying_controller.py:1007 +#: erpnext/controllers/buying_controller.py:1020 msgid "Asset {assets_link} created for {item_code}" msgstr "" @@ -5668,15 +5707,15 @@ msgstr "" msgid "Assets" msgstr "الأصول" -#: erpnext/controllers/buying_controller.py:1025 +#: erpnext/controllers/buying_controller.py:1038 msgid "Assets not created for {item_code}. You will have to create asset manually." msgstr "لم يتم إنشاء الأصول لـ {item_code}. سيكون عليك إنشاء الأصل يدويًا." -#: erpnext/controllers/buying_controller.py:1012 +#: erpnext/controllers/buying_controller.py:1025 msgid "Assets {assets_link} created for {item_code}" msgstr "" -#: erpnext/manufacturing/doctype/job_card/job_card.js:219 +#: erpnext/manufacturing/doctype/job_card/job_card.js:231 msgid "Assign Job to Employee" msgstr "" @@ -5708,20 +5747,20 @@ msgstr "" msgid "At least one account with exchange gain or loss is required" msgstr "" -#: erpnext/assets/doctype/asset/asset.py:1162 +#: erpnext/assets/doctype/asset/asset.py:1210 msgid "At least one asset has to be selected." msgstr "" -#: erpnext/accounts/doctype/pos_invoice/pos_invoice.py:972 +#: erpnext/accounts/doctype/pos_invoice/pos_invoice.py:1037 msgid "At least one invoice has to be selected." msgstr "" -#: erpnext/controllers/sales_and_purchase_return.py:169 +#: erpnext/controllers/sales_and_purchase_return.py:168 msgid "At least one item should be entered with negative quantity in return document" msgstr "" -#: erpnext/accounts/doctype/pos_invoice/pos_invoice.py:485 -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:599 +#: erpnext/accounts/doctype/pos_invoice/pos_invoice.py:530 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:548 msgid "At least one mode of payment is required for POS invoice." msgstr "يلزم وضع واحد نمط واحد للدفع لفاتورة نقطة البيع.\\n
        \\nAt least one mode of payment is required for POS invoice." @@ -5737,11 +5776,11 @@ msgstr "" msgid "At least one row is required for a financial report template" msgstr "" -#: erpnext/stock/doctype/stock_entry/stock_entry.py:704 +#: erpnext/stock/doctype/stock_entry/stock_entry.py:772 msgid "At least one warehouse is mandatory" msgstr "" -#: erpnext/stock/doctype/stock_entry/stock_entry.py:617 +#: erpnext/stock/doctype/stock_entry/stock_entry.py:685 msgid "At row #{0}: the Difference Account must not be a Stock type account, please change the Account Type for the account {1} or select a different account" msgstr "" @@ -5749,7 +5788,7 @@ msgstr "" msgid "At row #{0}: the sequence id {1} cannot be less than previous row sequence id {2}" msgstr "في الصف # {0}: لا يمكن أن يكون معرف التسلسل {1} أقل من معرف تسلسل الصف السابق {2}" -#: erpnext/stock/doctype/stock_entry/stock_entry.py:628 +#: erpnext/stock/doctype/stock_entry/stock_entry.py:696 msgid "At row #{0}: you have selected the Difference Account {1}, which is a Cost of Goods Sold type account. Please select a different account" msgstr "" @@ -5757,7 +5796,7 @@ msgstr "" msgid "At row {0}: Batch No is mandatory for Item {1}" msgstr "" -#: erpnext/manufacturing/doctype/bom_creator/bom_creator.py:93 +#: erpnext/manufacturing/doctype/bom_creator/bom_creator.py:95 msgid "At row {0}: Parent Row No cannot be set for item {1}" msgstr "" @@ -5769,15 +5808,15 @@ msgstr "" msgid "At row {0}: Serial No is mandatory for Item {1}" msgstr "" -#: erpnext/controllers/stock_controller.py:629 +#: erpnext/controllers/stock_controller.py:631 msgid "At row {0}: Serial and Batch Bundle {1} has already created. Please remove the values from the serial no or batch no fields." msgstr "" -#: erpnext/manufacturing/doctype/bom_creator/bom_creator.py:87 +#: erpnext/manufacturing/doctype/bom_creator/bom_creator.py:89 msgid "At row {0}: set Parent Row No for item {1}" msgstr "" -#: erpnext/subcontracting/doctype/subcontracting_inward_order/subcontracting_inward_order.py:221 +#: erpnext/subcontracting/doctype/subcontracting_inward_order/subcontracting_inward_order.py:225 msgid "Atleast one raw material for Finished Good Item {0} should be customer provided." msgstr "" @@ -5833,7 +5872,7 @@ msgstr "السمة اسم" msgid "Attribute Value" msgstr "السمة القيمة" -#: erpnext/stock/doctype/item/item.py:920 +#: erpnext/stock/doctype/item/item.py:923 msgid "Attribute table is mandatory" msgstr "جدول الخصائص إلزامي" @@ -5841,11 +5880,11 @@ msgstr "جدول الخصائص إلزامي" msgid "Attribute value: {0} must appear only once" msgstr "" -#: erpnext/stock/doctype/item/item.py:924 +#: erpnext/stock/doctype/item/item.py:927 msgid "Attribute {0} selected multiple times in Attributes Table" msgstr "تم تحديد السمة {0} عدة مرات في جدول السمات\\n
        \\nAttribute {0} selected multiple times in Attributes Table" -#: erpnext/stock/doctype/item/item.py:852 +#: erpnext/stock/doctype/item/item.py:855 msgid "Attributes" msgstr "سمات" @@ -5932,6 +5971,12 @@ msgstr "" msgid "Auto Created" msgstr "إنشاء تلقائي" +#. Label of the auto_created_via_reorder (Check) field in DocType 'Material +#. Request' +#: erpnext/stock/doctype/material_request/material_request.json +msgid "Auto Created (Reorder)" +msgstr "" + #. Label of the auto_created_serial_and_batch_bundle (Check) field in DocType #. 'Stock Ledger Entry' #: erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.json @@ -5964,7 +6009,7 @@ msgstr "" msgid "Auto Material Request" msgstr "طلب مواد تلقائي" -#: erpnext/stock/reorder_item.py:329 +#: erpnext/stock/reorder_item.py:337 msgid "Auto Material Requests Generated" msgstr "إنشاء طلب مواد تلقائي" @@ -6025,7 +6070,7 @@ msgstr "" msgid "Auto Reserve Stock for Sales Order on Purchase" msgstr "" -#: erpnext/accounts/doctype/accounts_settings/accounts_settings.py:157 +#: erpnext/accounts/doctype/accounts_settings/accounts_settings.py:148 msgid "Auto Tax Settings Error" msgstr "" @@ -6047,7 +6092,7 @@ msgid "Auto re-order" msgstr "إعادة ترتيب تلقائي" #: erpnext/public/js/controllers/buying.js:375 -#: erpnext/public/js/utils/sales_common.js:459 +#: erpnext/public/js/utils/sales_common.js:484 msgid "Auto repeat document updated" msgstr "تكرار تلقائي للمستندات المحدثة" @@ -6110,7 +6155,7 @@ msgid "Availability Of Slots" msgstr "توافر فتحات" #: erpnext/manufacturing/doctype/workstation/workstation.js:513 -#: erpnext/manufacturing/report/production_planning_report/production_planning_report.py:379 +#: erpnext/manufacturing/report/production_planning_report/production_planning_report.py:384 msgid "Available" msgstr "متاح" @@ -6140,11 +6185,11 @@ msgstr "متاح للاستخدام تاريخ" #. Label of the available_quantity_section (Section Break) field in DocType #. 'Pick List Item' #: erpnext/manufacturing/doctype/workstation/workstation.js:505 -#: erpnext/manufacturing/report/bom_stock_calculated/bom_stock_calculated.py:80 +#: erpnext/manufacturing/report/bom_stock_calculated/bom_stock_calculated.py:88 #: erpnext/public/js/utils.js:556 #: erpnext/stock/doctype/delivery_note_item/delivery_note_item.json #: erpnext/stock/doctype/pick_list_item/pick_list_item.json -#: erpnext/stock/report/stock_ageing/stock_ageing.py:167 +#: erpnext/stock/report/stock_ageing/stock_ageing.py:169 msgid "Available Qty" msgstr "الكمية المتاحة" @@ -6222,11 +6267,11 @@ msgstr "المخزون المتوفر" msgid "Available Stock for Packing Items" msgstr "المخزون المتاج للأصناف المعبأة" -#: erpnext/assets/doctype/asset/asset.py:317 +#: erpnext/assets/doctype/asset/asset.py:318 msgid "Available for use date is required" msgstr "مطلوب تاريخ متاح للاستخدام" -#: erpnext/stock/doctype/stock_entry/stock_entry.py:837 +#: erpnext/stock/doctype/stock_entry/stock_entry.py:905 msgid "Available quantity is {0}, you need {1}" msgstr "الكمية المتاحة هي {0} ، تحتاج إلى {1}" @@ -6239,12 +6284,12 @@ msgstr "متاح {0}" msgid "Available-for-use Date" msgstr "التاريخ المتاح للاستخدام" -#: erpnext/assets/doctype/asset/asset.py:423 +#: erpnext/assets/doctype/asset/asset.py:424 msgid "Available-for-use Date should be after purchase date" msgstr "يجب أن يكون التاريخ متاحًا بعد تاريخ الشراء" -#: erpnext/stock/report/stock_ageing/stock_ageing.py:168 -#: erpnext/stock/report/stock_ageing/stock_ageing.py:202 +#: erpnext/stock/report/stock_ageing/stock_ageing.py:170 +#: erpnext/stock/report/stock_ageing/stock_ageing.py:204 #: erpnext/stock/report/stock_balance/stock_balance.py:515 msgid "Average Age" msgstr "متوسط العمر" @@ -6345,15 +6390,15 @@ msgstr "" #: erpnext/manufacturing/doctype/work_order/work_order.js:216 #: erpnext/manufacturing/doctype/work_order_operation/work_order_operation.json #: erpnext/manufacturing/report/bom_explorer/bom_explorer.js:8 -#: erpnext/manufacturing/report/bom_explorer/bom_explorer.py:56 +#: erpnext/manufacturing/report/bom_explorer/bom_explorer.py:67 #: erpnext/manufacturing/report/bom_stock_calculated/bom_stock_calculated.js:8 #: erpnext/manufacturing/report/bom_stock_report/bom_stock_report.js:5 #: erpnext/manufacturing/report/work_order_stock_report/work_order_stock_report.py:109 #: erpnext/manufacturing/workspace/manufacturing/manufacturing.json -#: erpnext/selling/doctype/sales_order/sales_order.js:1403 -#: erpnext/stock/doctype/material_request/material_request.js:336 +#: erpnext/selling/doctype/sales_order/sales_order.js:1407 +#: erpnext/stock/doctype/material_request/material_request.js:337 #: erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json -#: erpnext/stock/doctype/stock_entry/stock_entry.js:658 +#: erpnext/stock/doctype/stock_entry/stock_entry.js:671 #: erpnext/stock/report/bom_search/bom_search.py:38 #: erpnext/subcontracting/doctype/subcontracting_inward_order_item/subcontracting_inward_order_item.json #: erpnext/subcontracting/doctype/subcontracting_order_item/subcontracting_order_item.json @@ -6365,7 +6410,7 @@ msgstr "قائمة مكونات المواد" msgid "BOM 1" msgstr "" -#: erpnext/manufacturing/doctype/bom/bom.py:1628 +#: erpnext/manufacturing/doctype/bom/bom.py:1670 msgid "BOM 1 {0} and BOM 2 {1} should not be same" msgstr "يجب ألا يكون BOM 1 {0} و BOM 2 {1} متطابقين" @@ -6443,7 +6488,7 @@ msgstr "" msgid "BOM Item" msgstr "صنف قائمة المواد" -#: erpnext/manufacturing/report/bom_explorer/bom_explorer.py:59 +#: erpnext/manufacturing/report/bom_explorer/bom_explorer.py:71 #: erpnext/manufacturing/report/production_plan_summary/production_plan_summary.py:174 msgid "BOM Level" msgstr "" @@ -6502,7 +6547,7 @@ msgstr "عملية قائمة المواد" msgid "BOM Operations Time" msgstr "وقت عمليات BOM" -#: erpnext/manufacturing/report/bom_stock_report/bom_stock_report.py:25 +#: erpnext/manufacturing/report/bom_stock_report/bom_stock_report.py:26 msgid "BOM Qty" msgstr "BOM الكمية" @@ -6541,8 +6586,8 @@ msgstr "تقرير مخزون فاتورة المواد" msgid "BOM Tree" msgstr "" -#: erpnext/manufacturing/report/bom_stock_report/bom_stock_report.py:26 -msgid "BOM UoM" +#: erpnext/manufacturing/report/bom_stock_report/bom_stock_report.py:27 +msgid "BOM UOM" msgstr "" #. Name of a DocType @@ -6594,7 +6639,7 @@ msgstr "صنف الموقع الالكتروني بقائمة المواد" msgid "BOM Website Operation" msgstr "عملية الموقع الالكتروني بقائمة المواد" -#: erpnext/stock/doctype/stock_entry/stock_entry.js:1299 +#: erpnext/stock/doctype/stock_entry/stock_entry.js:1306 msgid "BOM and Manufacturing Quantity are required" msgstr "مطلوب، قائمة مكونات المواد و كمية التصنيع" @@ -6604,8 +6649,8 @@ msgstr "مطلوب، قائمة مكونات المواد و كمية التصن msgid "BOM and Production" msgstr "" -#: erpnext/stock/doctype/material_request/material_request.js:368 -#: erpnext/stock/doctype/stock_entry/stock_entry.js:710 +#: erpnext/stock/doctype/material_request/material_request.js:372 +#: erpnext/stock/doctype/stock_entry/stock_entry.js:723 msgid "BOM does not contain any stock item" msgstr "فاتورة الموارد لا تحتوي على أي صنف مخزون" @@ -6613,23 +6658,23 @@ msgstr "فاتورة الموارد لا تحتوي على أي صنف مخزو msgid "BOM recursion: {0} cannot be child of {1}" msgstr "تكرار BOM: {0} لا يمكن أن يكون تابعًا لـ {1}" -#: erpnext/manufacturing/doctype/bom/bom.py:677 +#: erpnext/manufacturing/doctype/bom/bom.py:688 msgid "BOM recursion: {1} cannot be parent or child of {0}" msgstr "" -#: erpnext/manufacturing/doctype/bom/bom.py:1378 +#: erpnext/manufacturing/doctype/bom/bom.py:1412 msgid "BOM {0} does not belong to Item {1}" msgstr "قائمة المواد {0} لا تنتمي إلى الصنف {1}" -#: erpnext/manufacturing/doctype/bom/bom.py:1360 +#: erpnext/manufacturing/doctype/bom/bom.py:1394 msgid "BOM {0} must be active" msgstr "قائمة مكونات المواد {0} يجب أن تكون نشطة\\n
        \\nBOM {0} must be active" -#: erpnext/manufacturing/doctype/bom/bom.py:1363 +#: erpnext/manufacturing/doctype/bom/bom.py:1397 msgid "BOM {0} must be submitted" msgstr "قائمة مكونات المواد {0} يجب أن تكون مسجلة\\n
        \\nBOM {0} must be submitted" -#: erpnext/manufacturing/doctype/bom/bom.py:765 +#: erpnext/manufacturing/doctype/bom/bom.py:776 msgid "BOM {0} not found for the item {1}" msgstr "" @@ -6650,7 +6695,7 @@ msgstr "" msgid "BOMs creation has been enqueued, kindly check the status after some time" msgstr "" -#: erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py:340 +#: erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py:344 msgid "Backdated Stock Entry" msgstr "إدخال مخزون مؤرخ" @@ -6662,7 +6707,7 @@ msgstr "إدخال مخزون مؤرخ" #. Order Operation' #: erpnext/manufacturing/doctype/bom_operation/bom_operation.json #: erpnext/manufacturing/doctype/job_card/job_card.json -#: erpnext/manufacturing/doctype/work_order/work_order.js:361 +#: erpnext/manufacturing/doctype/work_order/work_order.js:368 #: erpnext/manufacturing/doctype/work_order_operation/work_order_operation.json msgid "Backflush Materials From WIP Warehouse" msgstr "" @@ -6700,7 +6745,7 @@ msgstr "الموازنة" msgid "Balance (Dr - Cr)" msgstr "الرصيد (مدين - دائن)" -#: erpnext/accounts/report/general_ledger/general_ledger.py:693 +#: erpnext/accounts/report/general_ledger/general_ledger.py:700 msgid "Balance ({0})" msgstr "الرصيد ({0})" @@ -6745,7 +6790,7 @@ msgstr "الرقم التسلسلي للميزان" #: erpnext/accounts/doctype/process_period_closing_voucher_detail/process_period_closing_voucher_detail.json #: erpnext/accounts/report/balance_sheet/balance_sheet.json #: erpnext/accounts/workspace/financial_reports/financial_reports.json -#: erpnext/public/js/financial_statements.js:256 +#: erpnext/public/js/financial_statements.js:267 #: erpnext/setup/doctype/email_digest/email_digest.json msgid "Balance Sheet" msgstr "المركز المالي" @@ -6993,7 +7038,7 @@ msgid "Bank Name" msgstr "" #: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:179 -#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:308 +#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:309 msgid "Bank Overdraft Account" msgstr "حساب السحب من البنك بدون رصيد" @@ -7098,11 +7143,11 @@ msgstr "الخدمات المصرفية" msgid "Barcode Type" msgstr "نوع الباركود" -#: erpnext/stock/doctype/item/item.py:456 +#: erpnext/stock/doctype/item/item.py:475 msgid "Barcode {0} already used in Item {1}" msgstr "الباركود {0} مستخدم بالفعل في الصنف {1}" -#: erpnext/stock/doctype/item/item.py:471 +#: erpnext/stock/doctype/item/item.py:490 msgid "Barcode {0} is not a valid {1} code" msgstr "الباركود {0} ليس رمز {1} صالحًا" @@ -7171,7 +7216,7 @@ msgstr "" msgid "Base Tax Withholding Net Total" msgstr "" -#: erpnext/accounts/report/tax_withholding_details/tax_withholding_details.py:247 +#: erpnext/accounts/report/tax_withholding_details/tax_withholding_details.py:261 msgid "Base Total" msgstr "" @@ -7331,7 +7376,7 @@ msgstr "حالة انتهاء صلاحية الدفعة الصنف" #: erpnext/manufacturing/doctype/job_card/job_card.json #: erpnext/manufacturing/report/cost_of_poor_quality_report/cost_of_poor_quality_report.js:89 #: erpnext/manufacturing/report/cost_of_poor_quality_report/cost_of_poor_quality_report.py:115 -#: erpnext/public/js/controllers/transaction.js:2817 +#: erpnext/public/js/controllers/transaction.js:2825 #: erpnext/public/js/utils/barcode_scanner.js:281 #: erpnext/public/js/utils/serial_no_batch_selector.js:438 #: erpnext/stock/doctype/delivery_note_item/delivery_note_item.json @@ -7364,11 +7409,11 @@ msgstr "رقم دفعة" msgid "Batch No is mandatory" msgstr "" -#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:2994 +#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:3027 msgid "Batch No {0} does not exists" msgstr "" -#: erpnext/stock/utils.py:640 +#: erpnext/stock/utils.py:646 msgid "Batch No {0} is linked with Item {1} which has serial no. Please scan serial no instead." msgstr "" @@ -7387,11 +7432,11 @@ msgstr "" msgid "Batch Nos" msgstr "" -#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:1658 +#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:1687 msgid "Batch Nos are created successfully" msgstr "" -#: erpnext/controllers/sales_and_purchase_return.py:1071 +#: erpnext/controllers/sales_and_purchase_return.py:1072 msgid "Batch Not Available for Return" msgstr "" @@ -7419,7 +7464,7 @@ msgstr "كمية الدفعة" #. Label of the batch_size (Float) field in DocType 'Work Order Operation' #: erpnext/manufacturing/doctype/bom_operation/bom_operation.json #: erpnext/manufacturing/doctype/operation/operation.json -#: erpnext/manufacturing/doctype/work_order/work_order.js:343 +#: erpnext/manufacturing/doctype/work_order/work_order.js:350 #: erpnext/manufacturing/doctype/work_order/work_order.json #: erpnext/manufacturing/doctype/work_order_operation/work_order_operation.json msgid "Batch Size" @@ -7436,7 +7481,7 @@ msgstr "دفعة UOM" msgid "Batch and Serial No" msgstr "" -#: erpnext/manufacturing/doctype/work_order/work_order.py:881 +#: erpnext/manufacturing/doctype/work_order/work_order.py:885 msgid "Batch not created for item {} since it does not have a batch series." msgstr "" @@ -7444,16 +7489,16 @@ msgstr "" msgid "Batch {0} and Warehouse" msgstr "" -#: erpnext/controllers/sales_and_purchase_return.py:1070 +#: erpnext/controllers/sales_and_purchase_return.py:1071 msgid "Batch {0} is not available in warehouse {1}" msgstr "" -#: erpnext/stock/doctype/stock_entry/stock_entry.py:3086 -#: erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py:286 +#: erpnext/stock/doctype/stock_entry/stock_entry.py:3168 +#: erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py:290 msgid "Batch {0} of Item {1} has expired." msgstr "الدفعة {0} للعنصر {1} انتهت صلاحيتها\\n
        \\nBatch {0} of Item {1} has expired." -#: erpnext/stock/doctype/stock_entry/stock_entry.py:3092 +#: erpnext/stock/doctype/stock_entry/stock_entry.py:3174 msgid "Batch {0} of Item {1} is disabled." msgstr "تم تعطيل الدفعة {0} من الصنف {1}." @@ -7517,10 +7562,10 @@ msgstr "" #. Label of a Card Break in the Manufacturing Workspace #. Label of a Link in the Manufacturing Workspace -#: erpnext/manufacturing/doctype/bom/bom.py:1234 +#: erpnext/manufacturing/doctype/bom/bom.py:1251 #: erpnext/manufacturing/workspace/manufacturing/manufacturing.json -#: erpnext/stock/doctype/material_request/material_request.js:126 -#: erpnext/stock/doctype/stock_entry/stock_entry.js:644 +#: erpnext/stock/doctype/material_request/material_request.js:127 +#: erpnext/stock/doctype/stock_entry/stock_entry.js:657 msgid "Bill of Materials" msgstr "فاتورة المواد" @@ -7620,7 +7665,7 @@ msgstr "" msgid "Billing Address Name" msgstr "اسم عنوان تقديم الفواتير" -#: erpnext/controllers/accounts_controller.py:503 +#: erpnext/controllers/accounts_controller.py:573 msgid "Billing Address does not belong to the {0}" msgstr "" @@ -7845,8 +7890,8 @@ msgstr "صنف أمر بطانية" msgid "Blanket Order Rate" msgstr "بطالة سعر النظام" -#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js:108 -#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js:260 +#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js:109 +#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js:261 msgid "Block Invoice" msgstr "حظر الفاتورة" @@ -7953,11 +7998,11 @@ msgstr "حجز" msgid "Booked Fixed Asset" msgstr "حجز الأصول الثابتة" -#: erpnext/stock/doctype/warehouse/warehouse.py:144 +#: erpnext/stock/doctype/warehouse/warehouse.py:146 msgid "Booking stock value across multiple accounts will make it harder to track stock and account value." msgstr "" -#: erpnext/accounts/general_ledger.py:804 +#: erpnext/accounts/general_ledger.py:811 msgid "Books have been closed till the period ending on {0}" msgstr "" @@ -8041,7 +8086,7 @@ msgstr "" msgid "Brokerage" msgstr "" -#: erpnext/manufacturing/doctype/bom/bom.js:164 +#: erpnext/manufacturing/doctype/bom/bom.js:165 msgid "Browse BOM" msgstr "تصفح قائمة المواد" @@ -8101,38 +8146,65 @@ msgstr "ميزانية" msgid "Budget Account" msgstr "حساب الميزانية" -#. Label of the accounts (Table) field in DocType 'Budget' -#: erpnext/accounts/doctype/budget/budget.json -msgid "Budget Accounts" -msgstr "حسابات الميزانية" - #. Label of the budget_against (Select) field in DocType 'Budget' #: erpnext/accounts/doctype/budget/budget.json #: erpnext/accounts/report/budget_variance_report/budget_variance_report.js:80 msgid "Budget Against" msgstr "الميزانية مقابل" +#. Label of the budget_amount (Currency) field in DocType 'Budget' #. Label of the budget_amount (Currency) field in DocType 'Budget Account' +#: erpnext/accounts/doctype/budget/budget.json #: erpnext/accounts/doctype/budget_account/budget_account.json msgid "Budget Amount" msgstr "قيمة الميزانية" +#: erpnext/accounts/doctype/budget/budget.py:84 +msgid "Budget Amount can not be {0}." +msgstr "" + #. Label of the budget_detail (Section Break) field in DocType 'Company' #: erpnext/setup/doctype/company/company.json msgid "Budget Detail" msgstr "تفاصيل الميزانية" -#: erpnext/accounts/doctype/budget/budget.py:299 -#: erpnext/accounts/doctype/budget/budget.py:301 -#: erpnext/controllers/budget_controller.py:286 +#. Label of the budget_distribution (Table) field in DocType 'Budget' +#. Name of a DocType +#: erpnext/accounts/doctype/budget/budget.json +#: erpnext/accounts/doctype/budget_distribution/budget_distribution.json +msgid "Budget Distribution" +msgstr "" + +#. Label of the budget_distribution_total (Currency) field in DocType 'Budget' +#: erpnext/accounts/doctype/budget/budget.json +msgid "Budget Distribution Total" +msgstr "" + +#. Label of the budget_end_date (Date) field in DocType 'Budget' +#: erpnext/accounts/doctype/budget/budget.json +msgid "Budget End Date" +msgstr "" + +#: erpnext/accounts/doctype/budget/budget.py:570 +#: erpnext/accounts/doctype/budget/budget.py:572 #: erpnext/controllers/budget_controller.py:289 +#: erpnext/controllers/budget_controller.py:292 msgid "Budget Exceeded" msgstr "" +#: erpnext/accounts/doctype/budget/budget.py:229 +msgid "Budget Limit Exceeded" +msgstr "" + #: erpnext/accounts/doctype/cost_center/cost_center_tree.js:61 msgid "Budget List" msgstr "قائمة الميزانية" +#. Label of the budget_start_date (Date) field in DocType 'Budget' +#: erpnext/accounts/doctype/budget/budget.json +msgid "Budget Start Date" +msgstr "" + #. Name of a report #. Label of a Link in the Accounting Workspace #: erpnext/accounts/doctype/cost_center/cost_center_tree.js:77 @@ -8141,11 +8213,11 @@ msgstr "قائمة الميزانية" msgid "Budget Variance Report" msgstr "تقرير إنحرافات الموازنة" -#: erpnext/accounts/doctype/budget/budget.py:101 +#: erpnext/accounts/doctype/budget/budget.py:157 msgid "Budget cannot be assigned against Group Account {0}" msgstr "لايمكن أسناد الميزانية للمجموعة Account {0}" -#: erpnext/accounts/doctype/budget/budget.py:108 +#: erpnext/accounts/doctype/budget/budget.py:162 msgid "Budget cannot be assigned against {0}, as it's not an Income or Expense account" msgstr "لا يمكن تعيين الميزانية مقابل {0}، حيث إنها ليست حسابا للدخل أو للمصروفات" @@ -8281,7 +8353,6 @@ msgstr "معدل الشراء" #. Name of a DocType #. Label of a Link in the Buying Workspace -#. Label of a Link in the Settings Workspace #. Label of a shortcut in the Settings Workspace #: erpnext/buying/doctype/buying_settings/buying_settings.json #: erpnext/buying/workspace/buying/buying.json @@ -8345,10 +8416,8 @@ msgstr "" #. Name of a DocType #. Label of a Link in the CRM Workspace -#. Label of a Link in the Settings Workspace #: erpnext/crm/doctype/crm_settings/crm_settings.json #: erpnext/crm/workspace/crm/crm.json -#: erpnext/setup/workspace/settings/settings.json msgid "CRM Settings" msgstr "" @@ -8599,7 +8668,7 @@ msgstr "جداول الحملة" msgid "Can be approved by {0}" msgstr "يمكن الموافقة عليها بواسطة {0}" -#: erpnext/manufacturing/doctype/work_order/work_order.py:2418 +#: erpnext/manufacturing/doctype/work_order/work_order.py:2459 msgid "Can not close Work Order. Since {0} Job Cards are in Work In Progress state." msgstr "" @@ -8627,17 +8696,18 @@ msgstr "لا يمكن التصفية بناءً على طريقة الدفع ، msgid "Can not filter based on Voucher No, if grouped by Voucher" msgstr "لا يمكن الفلتره علي اساس (رقم الأيصال)، إذا تم وضعه في مجموعة على اساس (ايصال)" -#: erpnext/accounts/doctype/journal_entry/journal_entry.py:1441 -#: erpnext/accounts/doctype/payment_entry/payment_entry.py:2940 +#: erpnext/accounts/doctype/journal_entry/journal_entry.py:1580 +#: erpnext/accounts/doctype/payment_entry/payment_entry.py:2941 msgid "Can only make payment against unbilled {0}" msgstr "يمكن إجراء دفعة فقط مقابل فاتورة غير مدفوعة {0}" -#: erpnext/accounts/doctype/payment_entry/payment_entry.js:1495 -#: erpnext/controllers/accounts_controller.py:3097 +#: erpnext/accounts/doctype/payment_entry/payment_entry.js:1494 +#: erpnext/controllers/accounts_controller.py:3170 #: erpnext/public/js/controllers/accounts.js:103 msgid "Can refer row only if the charge type is 'On Previous Row Amount' or 'Previous Row Total'" msgstr "" +#: erpnext/setup/doctype/company/company.py:198 #: erpnext/stock/doctype/stock_settings/stock_settings.py:144 msgid "Can't change the valuation method, as there are transactions against some items which do not have its own valuation method" msgstr "" @@ -8688,17 +8758,17 @@ msgstr "" msgid "Cannot Calculate Arrival Time as Driver Address is Missing." msgstr "لا يمكن حساب وقت الوصول حيث أن عنوان برنامج التشغيل مفقود." -#: erpnext/setup/doctype/company/company.py:181 +#: erpnext/setup/doctype/company/company.py:217 msgid "Cannot Change Inventory Account Setting" msgstr "" -#: erpnext/controllers/sales_and_purchase_return.py:375 +#: erpnext/controllers/sales_and_purchase_return.py:376 msgid "Cannot Create Return" msgstr "" -#: erpnext/stock/doctype/item/item.py:627 -#: erpnext/stock/doctype/item/item.py:640 -#: erpnext/stock/doctype/item/item.py:654 +#: erpnext/stock/doctype/item/item.py:630 +#: erpnext/stock/doctype/item/item.py:643 +#: erpnext/stock/doctype/item/item.py:657 msgid "Cannot Merge" msgstr "" @@ -8718,11 +8788,11 @@ msgstr "" msgid "Cannot amend {0} {1}, please create a new one instead." msgstr "" -#: erpnext/accounts/doctype/journal_entry/journal_entry.py:365 +#: erpnext/accounts/doctype/journal_entry/journal_entry.py:1327 msgid "Cannot apply TDS against multiple parties in one entry" msgstr "" -#: erpnext/stock/doctype/item/item.py:308 +#: erpnext/stock/doctype/item/item.py:310 msgid "Cannot be a fixed asset item as Stock Ledger is created." msgstr "لا يمكن أن يكون عنصر الأصول الثابتة كما يتم إنشاء دفتر الأستاذ." @@ -8738,11 +8808,11 @@ msgstr "" msgid "Cannot cancel Stock Reservation Entry {0}, as it has used in the work order {1}. Please cancel the work order first or unreserved the stock" msgstr "" -#: erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py:234 +#: erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py:246 msgid "Cannot cancel as processing of cancelled documents is pending." msgstr "" -#: erpnext/manufacturing/doctype/work_order/work_order.py:1066 +#: erpnext/manufacturing/doctype/work_order/work_order.py:1070 msgid "Cannot cancel because submitted Stock Entry {0} exists" msgstr "لا يمكن الإلغاء لان هناك تدوينات مخزون مقدمة {0} موجوده" @@ -8754,15 +8824,15 @@ msgstr "" msgid "Cannot cancel this Manufacturing Stock Entry as quantity of Finished Good produced cannot be less than quantity delivered in the linked Subcontracting Inward Order." msgstr "" -#: erpnext/controllers/buying_controller.py:1116 +#: erpnext/controllers/buying_controller.py:1129 msgid "Cannot cancel this document as it is linked with the submitted asset {asset_link}. Please cancel the asset to continue." msgstr "" -#: erpnext/stock/doctype/stock_entry/stock_entry.py:394 +#: erpnext/stock/doctype/stock_entry/stock_entry.py:457 msgid "Cannot cancel transaction for Completed Work Order." msgstr "لا يمكن إلغاء المعاملة لأمر العمل المكتمل." -#: erpnext/stock/doctype/item/item.py:872 +#: erpnext/stock/doctype/item/item.py:875 msgid "Cannot change Attributes after stock transaction. Make a new Item and transfer stock to the new Item" msgstr "لا يمكن تغيير سمات بعد معاملة الأسهم. جعل عنصر جديد ونقل الأسهم إلى البند الجديد" @@ -8774,19 +8844,19 @@ msgstr "لا يمكن تغيير تاريخ بدء السنه المالية و msgid "Cannot change Reference Document Type." msgstr "" -#: erpnext/accounts/deferred_revenue.py:52 +#: erpnext/accounts/deferred_revenue.py:53 msgid "Cannot change Service Stop Date for item in row {0}" msgstr "لا يمكن تغيير تاريخ إيقاف الخدمة للعنصر الموجود في الصف {0}" -#: erpnext/stock/doctype/item/item.py:863 +#: erpnext/stock/doctype/item/item.py:866 msgid "Cannot change Variant properties after stock transaction. You will have to make a new Item to do this." msgstr "لا يمكن تغيير خصائص المتغير بعد معاملة المخزون. سيكون عليك عمل عنصر جديد للقيام بذلك." -#: erpnext/setup/doctype/company/company.py:286 +#: erpnext/setup/doctype/company/company.py:322 msgid "Cannot change company's default currency, because there are existing transactions. Transactions must be cancelled to change the default currency." msgstr "لا يمكن تغيير العملة الافتراضية للشركة، لأن هناك معاملات موجودة. يجب إلغاء المعاملات لتغيير العملة الافتراضية." -#: erpnext/projects/doctype/task/task.py:144 +#: erpnext/projects/doctype/task/task.py:145 msgid "Cannot complete task {0} as its dependant task {1} are not completed / cancelled." msgstr "" @@ -8798,19 +8868,19 @@ msgstr "لا يمكن تحويل مركز التكلفة إلى حساب دفت msgid "Cannot convert Task to non-group because the following child Tasks exist: {0}." msgstr "" -#: erpnext/accounts/doctype/account/account.py:438 +#: erpnext/accounts/doctype/account/account.py:440 msgid "Cannot convert to Group because Account Type is selected." msgstr "" -#: erpnext/accounts/doctype/account/account.py:274 +#: erpnext/accounts/doctype/account/account.py:276 msgid "Cannot covert to Group because Account Type is selected." msgstr "لا يمكن تحويل الحساب إلى تصنيف مجموعة لأن نوع الحساب تم اختياره." -#: erpnext/stock/doctype/purchase_receipt/purchase_receipt.py:998 +#: erpnext/stock/doctype/purchase_receipt/purchase_receipt.py:1013 msgid "Cannot create Stock Reservation Entries for future dated Purchase Receipts." msgstr "" -#: erpnext/selling/doctype/sales_order/sales_order.py:1976 +#: erpnext/selling/doctype/sales_order/sales_order.py:1848 #: erpnext/stock/doctype/pick_list/pick_list.py:205 msgid "Cannot create a pick list for Sales Order {0} because it has reserved stock. Please unreserve the stock in order to create a pick list." msgstr "" @@ -8819,11 +8889,11 @@ msgstr "" msgid "Cannot create accounting entries against disabled accounts: {0}" msgstr "" -#: erpnext/controllers/sales_and_purchase_return.py:374 +#: erpnext/controllers/sales_and_purchase_return.py:375 msgid "Cannot create return for consolidated invoice {0}." msgstr "" -#: erpnext/manufacturing/doctype/bom/bom.py:1090 +#: erpnext/manufacturing/doctype/bom/bom.py:1108 msgid "Cannot deactivate or cancel BOM as it is linked with other BOMs" msgstr "لا يمكن تعطيل أو إلغاء قائمة المواد لانها مترابطة مع قوائم مواد اخرى" @@ -8836,7 +8906,7 @@ msgstr "لا يمكن ان تعلن بانها فقدت ، لأنه تم تقد msgid "Cannot deduct when category is for 'Valuation' or 'Valuation and Total'" msgstr "لا يمكن الخصم عندما تكون الفئة \"التقييم\" أو \"التقييم والإجمالي\"" -#: erpnext/accounts/doctype/payment_entry/payment_entry.js:1814 +#: erpnext/accounts/doctype/payment_entry/payment_entry.js:1813 msgid "Cannot delete Exchange Gain/Loss row" msgstr "" @@ -8844,15 +8914,15 @@ msgstr "" msgid "Cannot delete Serial No {0}, as it is used in stock transactions" msgstr "لا يمكن حذف الرقم التسلسلي {0}، لانه يتم استخدامها في قيود المخزون" -#: erpnext/setup/doctype/company/company.py:516 +#: erpnext/setup/doctype/company/company.py:552 msgid "Cannot disable perpetual inventory, as there are existing Stock Ledger Entries for the company {0}. Please cancel the stock transactions first and try again." msgstr "" -#: erpnext/manufacturing/doctype/work_order/work_order.py:681 +#: erpnext/manufacturing/doctype/work_order/work_order.py:682 msgid "Cannot disassemble more than produced quantity." msgstr "" -#: erpnext/setup/doctype/company/company.py:178 +#: erpnext/setup/doctype/company/company.py:214 msgid "Cannot enable Item-wise Inventory Account, as there are existing Stock Ledger Entries for the company {0} with Warehouse-wise Inventory Account. Please cancel the stock transactions first and try again." msgstr "" @@ -8860,8 +8930,8 @@ msgstr "" msgid "Cannot enqueue multi docs for one company. {0} is already queued/running for company: {1}" msgstr "" -#: erpnext/selling/doctype/sales_order/sales_order.py:772 -#: erpnext/selling/doctype/sales_order/sales_order.py:795 +#: erpnext/selling/doctype/sales_order/sales_order.py:771 +#: erpnext/selling/doctype/sales_order/sales_order.py:794 msgid "Cannot ensure delivery by Serial No as Item {0} is added with and without Ensure Delivery by Serial No." msgstr "لا يمكن ضمان التسليم بواسطة Serial No حيث أن العنصر {0} مضاف مع وبدون ضمان التسليم بواسطة Serial No." @@ -8873,23 +8943,23 @@ msgstr "" msgid "Cannot find Item with this Barcode" msgstr "لا يمكن العثور على عنصر بهذا الرمز الشريطي" -#: erpnext/controllers/accounts_controller.py:3645 +#: erpnext/controllers/accounts_controller.py:3718 msgid "Cannot find a default warehouse for item {0}. Please set one in the Item Master or in Stock Settings." msgstr "" -#: erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py:515 +#: erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py:516 msgid "Cannot make any transactions until the deletion job is completed" msgstr "" -#: erpnext/manufacturing/doctype/work_order/work_order.py:529 +#: erpnext/manufacturing/doctype/work_order/work_order.py:530 msgid "Cannot produce more Item {0} than Sales Order quantity {1}" msgstr "لا يمكن أن تنتج المزيد من البند {0} اكثر من كمية طلب المبيعات {1}" -#: erpnext/manufacturing/doctype/work_order/work_order.py:1421 +#: erpnext/manufacturing/doctype/work_order/work_order.py:1425 msgid "Cannot produce more item for {0}" msgstr "" -#: erpnext/manufacturing/doctype/work_order/work_order.py:1425 +#: erpnext/manufacturing/doctype/work_order/work_order.py:1429 msgid "Cannot produce more than {0} items for {1}" msgstr "" @@ -8897,8 +8967,8 @@ msgstr "" msgid "Cannot receive from customer against negative outstanding" msgstr "" -#: erpnext/accounts/doctype/payment_entry/payment_entry.js:1512 -#: erpnext/controllers/accounts_controller.py:3112 +#: erpnext/accounts/doctype/payment_entry/payment_entry.js:1511 +#: erpnext/controllers/accounts_controller.py:3185 #: erpnext/public/js/controllers/accounts.js:120 msgid "Cannot refer row number greater than or equal to current row number for this Charge type" msgstr "لا يمكن أن يشير رقم الصف أكبر من أو يساوي رقم الصف الحالي لهذا النوع المسؤول" @@ -8911,16 +8981,16 @@ msgstr "" msgid "Cannot retrieve link token. Check Error Log for more information" msgstr "" -#: erpnext/accounts/doctype/payment_entry/payment_entry.js:1504 -#: erpnext/accounts/doctype/payment_entry/payment_entry.js:1683 -#: erpnext/accounts/doctype/payment_entry/payment_entry.py:1888 -#: erpnext/controllers/accounts_controller.py:3102 +#: erpnext/accounts/doctype/payment_entry/payment_entry.js:1503 +#: erpnext/accounts/doctype/payment_entry/payment_entry.js:1682 +#: erpnext/accounts/doctype/payment_entry/payment_entry.py:1889 +#: erpnext/controllers/accounts_controller.py:3175 #: erpnext/public/js/controllers/accounts.js:112 -#: erpnext/public/js/controllers/taxes_and_totals.js:521 +#: erpnext/public/js/controllers/taxes_and_totals.js:524 msgid "Cannot select charge type as 'On Previous Row Amount' or 'On Previous Row Total' for first row" msgstr "لا يمكن تحديد نوع التهمة باسم ' في الصف السابق المبلغ ' أو ' في السابق صف إجمالي \" ل لصف الأول" -#: erpnext/selling/doctype/quotation/quotation.py:285 +#: erpnext/selling/doctype/quotation/quotation.py:287 msgid "Cannot set as Lost as Sales Order is made." msgstr "لا يمكن أن تعين كخسارة لأنه تم تقديم أمر البيع.
        Cannot set as Lost as Sales Order is made." @@ -8928,15 +8998,15 @@ msgstr "لا يمكن أن تعين كخسارة لأنه تم تقديم أمر msgid "Cannot set authorization on basis of Discount for {0}" msgstr "لا يمكن تحديد التخويل على أساس الخصم ل {0}" -#: erpnext/stock/doctype/item/item.py:718 +#: erpnext/stock/doctype/item/item.py:721 msgid "Cannot set multiple Item Defaults for a company." msgstr "لا يمكن تعيين عدة عناصر افتراضية لأي شركة." -#: erpnext/controllers/accounts_controller.py:3800 +#: erpnext/controllers/accounts_controller.py:3873 msgid "Cannot set quantity less than delivered quantity" msgstr "لا يمكن ضبط كمية أقل من الكمية المسلمة" -#: erpnext/controllers/accounts_controller.py:3803 +#: erpnext/controllers/accounts_controller.py:3876 msgid "Cannot set quantity less than received quantity" msgstr "لا يمكن تعيين كمية أقل من الكمية المستلمة" @@ -8944,7 +9014,7 @@ msgstr "لا يمكن تعيين كمية أقل من الكمية المستل msgid "Cannot set the field {0} for copying in variants" msgstr "لا يمكن تعيين الحقل {0} للنسخ في المتغيرات" -#: erpnext/accounts/doctype/payment_entry/payment_entry.py:1998 +#: erpnext/accounts/doctype/payment_entry/payment_entry.py:1999 msgid "Cannot {0} from {1} without any negative outstanding invoice" msgstr "" @@ -8979,7 +9049,7 @@ msgstr "" msgid "Capacity Planning" msgstr "القدرة على التخطيط" -#: erpnext/manufacturing/doctype/work_order/work_order.py:1052 +#: erpnext/manufacturing/doctype/work_order/work_order.py:1056 msgid "Capacity Planning Error, planned start time can not be same as end time" msgstr "خطأ في تخطيط السعة ، لا يمكن أن يكون وقت البدء المخطط له هو نفسه وقت الانتهاء" @@ -8994,7 +9064,7 @@ msgstr "القدرة على التخطيط لل(أيام)" msgid "Capacity in Stock UOM" msgstr "" -#: erpnext/stock/doctype/putaway_rule/putaway_rule.py:85 +#: erpnext/stock/doctype/putaway_rule/putaway_rule.py:86 msgid "Capacity must be greater than 0" msgstr "" @@ -9004,7 +9074,7 @@ msgid "Capital Equipment" msgstr "" #: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:190 -#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:332 +#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:333 msgid "Capital Stock" msgstr "رأس المال" @@ -9032,6 +9102,10 @@ msgstr "" msgid "Capitalize Repair Cost" msgstr "" +#: erpnext/assets/doctype/asset/asset.js:201 +msgid "Capitalize this asset to confirm" +msgstr "" + #. Option for the 'Status' (Select) field in DocType 'Asset' #: erpnext/assets/doctype/asset/asset.json #: erpnext/assets/doctype/asset/asset_list.js:14 @@ -9100,7 +9174,7 @@ msgstr "الدخول النقدية" msgid "Cash Flow" msgstr "التدفق النقدي" -#: erpnext/public/js/financial_statements.js:266 +#: erpnext/public/js/financial_statements.js:277 msgid "Cash Flow Statement" msgstr "بيان التدفق النقدي" @@ -9121,7 +9195,7 @@ msgstr "التدفق النقدي من العمليات" msgid "Cash In Hand" msgstr "النقدية الحاضرة" -#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:320 +#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:322 msgid "Cash or Bank Account is mandatory for making payment entry" msgstr "الحساب النقدي أو البنكي مطلوب لعمل مدخل بيع
        Cash or Bank Account is mandatory for making payment entry" @@ -9215,12 +9289,12 @@ msgstr "تفاصيل التصنيف" msgid "Category-wise Asset Value" msgstr "قيمة الأصول حسب الفئة" -#: erpnext/buying/doctype/purchase_order/purchase_order.py:333 +#: erpnext/buying/doctype/purchase_order/purchase_order.py:335 #: erpnext/buying/doctype/request_for_quotation/request_for_quotation.py:115 msgid "Caution" msgstr "الحذر" -#: erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py:169 +#: erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py:181 msgid "Caution: This might alter frozen accounts." msgstr "" @@ -9303,7 +9377,7 @@ msgstr "" msgid "Change Amount" msgstr "تغيير المبلغ" -#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js:93 +#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js:94 msgid "Change Release Date" msgstr "تغيير تاريخ الإصدار" @@ -9320,7 +9394,7 @@ msgstr "تغيير تاريخ الإصدار" msgid "Change in Stock Value" msgstr "" -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1053 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1002 msgid "Change the account type to Receivable or select a different account." msgstr "قم بتغيير نوع الحساب إلى "ذمم مدينة" أو حدد حسابًا مختلفًا." @@ -9330,7 +9404,7 @@ msgstr "قم بتغيير نوع الحساب إلى "ذمم مدينة&quo msgid "Change this date manually to setup the next synchronization start date" msgstr "قم بتغيير هذا التاريخ يدويًا لإعداد تاريخ بدء المزامنة التالي" -#: erpnext/selling/doctype/customer/customer.py:126 +#: erpnext/selling/doctype/customer/customer.py:127 msgid "Changed customer name to '{}' as '{}' already exists." msgstr "" @@ -9338,7 +9412,7 @@ msgstr "" msgid "Changes in {0}" msgstr "" -#: erpnext/stock/doctype/item/item.js:315 +#: erpnext/stock/doctype/item/item.js:330 msgid "Changing Customer Group for the selected Customer is not allowed." msgstr "لا يسمح بتغيير مجموعة العملاء للعميل المحدد." @@ -9352,8 +9426,8 @@ msgstr "" msgid "Channel Partner" msgstr "شريك القناة" -#: erpnext/accounts/doctype/payment_entry/payment_entry.py:2317 -#: erpnext/controllers/accounts_controller.py:3165 +#: erpnext/accounts/doctype/payment_entry/payment_entry.py:2318 +#: erpnext/controllers/accounts_controller.py:3238 msgid "Charge of type 'Actual' in row {0} cannot be included in Item Rate or Paid Amount" msgstr "" @@ -9398,7 +9472,6 @@ msgid "Chart Tree" msgstr "شجرة الرسم البياني" #. Label of a Link in the Accounting Workspace -#. Label of a shortcut in the Accounting Workspace #. Label of the section_break_28 (Section Break) field in DocType 'Company' #. Label of a Link in the Home Workspace #: erpnext/accounts/doctype/account/account.js:69 @@ -9406,7 +9479,7 @@ msgstr "شجرة الرسم البياني" #: erpnext/accounts/doctype/cost_center/cost_center_tree.js:52 #: erpnext/accounts/workspace/accounting/accounting.json #: erpnext/public/js/setup_wizard.js:43 -#: erpnext/setup/doctype/company/company.js:116 +#: erpnext/setup/doctype/company/company.js:123 #: erpnext/setup/doctype/company/company.json #: erpnext/setup/workspace/home/home.json msgid "Chart of Accounts" @@ -9422,7 +9495,7 @@ msgid "Chart of Accounts Importer" msgstr "مخطط حسابات المستورد" #. Label of a Link in the Accounting Workspace -#: erpnext/accounts/doctype/account/account_tree.js:187 +#: erpnext/accounts/doctype/account/account_tree.js:195 #: erpnext/accounts/doctype/cost_center/cost_center.js:41 #: erpnext/accounts/workspace/accounting/accounting.json msgid "Chart of Cost Centers" @@ -9437,6 +9510,11 @@ msgstr "الرسوم البيانية على أساس" msgid "Chassis No" msgstr "رقم الشاسيه" +#. Label of the warehouse_group (Link) field in DocType 'Item Reorder' +#: erpnext/stock/doctype/item_reorder/item_reorder.json +msgid "Check Availability in Warehouse" +msgstr "" + #. Label of the check_supplier_invoice_uniqueness (Check) field in DocType #. 'Accounts Settings' #: erpnext/accounts/doctype/accounts_settings/accounts_settings.json @@ -9454,11 +9532,6 @@ msgstr "تحقق ما إذا كان هو وحدة الزراعة المائية" msgid "Check if material transfer entry is not required" msgstr "تحقق مما إذا كان إدخال نقل المواد غير مطلوب" -#. Label of the warehouse_group (Link) field in DocType 'Item Reorder' -#: erpnext/stock/doctype/item_reorder/item_reorder.json -msgid "Check in (group)" -msgstr "تحقق في (مجموعة)" - #. Description of the 'Must be Whole Number' (Check) field in DocType 'UOM' #: erpnext/setup/doctype/uom/uom.json msgid "Check this to disallow fractions. (for Nos)" @@ -9526,7 +9599,7 @@ msgstr "عرض الشيك" #. Label of the reference_date (Date) field in DocType 'Payment Entry' #: erpnext/accounts/doctype/payment_entry/payment_entry.json -#: erpnext/public/js/controllers/transaction.js:2727 +#: erpnext/public/js/controllers/transaction.js:2735 msgid "Cheque/Reference Date" msgstr "تاريخ الصك / السند المرجع" @@ -9574,12 +9647,12 @@ msgstr "اسم الطفل" #. Label of the child_row_reference (Data) field in DocType 'Quality #. Inspection' -#: erpnext/public/js/controllers/transaction.js:2823 +#: erpnext/public/js/controllers/transaction.js:2831 #: erpnext/stock/doctype/quality_inspection/quality_inspection.json msgid "Child Row Reference" msgstr "" -#: erpnext/projects/doctype/task/task.py:304 +#: erpnext/projects/doctype/task/task.py:312 msgid "Child Task exists for this Task. You can not delete this Task." msgstr "مهمة تابعة موجودة لهذه المهمة. لا يمكنك حذف هذه المهمة." @@ -9587,11 +9660,11 @@ msgstr "مهمة تابعة موجودة لهذه المهمة. لا يمكنك msgid "Child nodes can be only created under 'Group' type nodes" msgstr "العقد التابعة يمكن أن تنشأ إلا في إطار 'مجموعة' نوع العُقد" -#: erpnext/stock/doctype/warehouse/warehouse.py:101 +#: erpnext/stock/doctype/warehouse/warehouse.py:103 msgid "Child warehouse exists for this warehouse. You can not delete this warehouse." msgstr "مستودع فرعي موجود لهذا المستودع. لا يمكنك حذف هذا المستودع.\\n
        \\nChild warehouse exists for this warehouse. You can not delete this warehouse." -#: erpnext/projects/doctype/task/task.py:252 +#: erpnext/projects/doctype/task/task.py:260 msgid "Circular Reference Error" msgstr "" @@ -9727,11 +9800,11 @@ msgstr "وثيقة مغلقة" msgid "Closed Documents" msgstr "وثائق مغلقة" -#: erpnext/manufacturing/doctype/work_order/work_order.py:2341 +#: erpnext/manufacturing/doctype/work_order/work_order.py:2382 msgid "Closed Work Order can not be stopped or Re-opened" msgstr "" -#: erpnext/selling/doctype/sales_order/sales_order.py:523 +#: erpnext/selling/doctype/sales_order/sales_order.py:525 msgid "Closed order cannot be cancelled. Unclose to cancel." msgstr "الطلب المغلق لايمكن إلغاؤه. ازالة الاغلاق لكي تتمكن من الالغاء" @@ -9781,7 +9854,7 @@ msgstr "مبلغ الإغلاق" #: erpnext/accounts/doctype/bank_reconciliation_tool/bank_reconciliation_tool.json #: erpnext/accounts/doctype/financial_report_row/financial_report_row.json #: erpnext/accounts/doctype/process_period_closing_voucher_detail/process_period_closing_voucher_detail.json -#: erpnext/accounts/report/customer_ledger_summary/customer_ledger_summary.py:201 +#: erpnext/accounts/report/customer_ledger_summary/customer_ledger_summary.py:232 msgid "Closing Balance" msgstr "الرصيد الختامي" @@ -10146,7 +10219,7 @@ msgstr "شركات" #: erpnext/accounts/doctype/gl_entry/gl_entry.json #: erpnext/accounts/doctype/invoice_discounting/invoice_discounting.json #: erpnext/accounts/doctype/item_tax_template/item_tax_template.json -#: erpnext/accounts/doctype/journal_entry/journal_entry.js:137 +#: erpnext/accounts/doctype/journal_entry/journal_entry.js:141 #: erpnext/accounts/doctype/journal_entry/journal_entry.json #: erpnext/accounts/doctype/journal_entry_template/journal_entry_template.json #: erpnext/accounts/doctype/ledger_health_monitor_company/ledger_health_monitor_company.json @@ -10212,9 +10285,9 @@ msgstr "شركات" #: erpnext/accounts/report/gross_profit/gross_profit.js:8 #: erpnext/accounts/report/invalid_ledger_entries/invalid_ledger_entries.js:8 #: erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.js:40 -#: erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py:232 +#: erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py:224 #: erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.js:28 -#: erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py:280 +#: erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py:269 #: erpnext/accounts/report/payment_ledger/payment_ledger.js:8 #: erpnext/accounts/report/payment_period_based_on_invoice_date/payment_period_based_on_invoice_date.js:8 #: erpnext/accounts/report/pos_register/pos_register.js:8 @@ -10274,7 +10347,7 @@ msgstr "شركات" #: erpnext/maintenance/doctype/maintenance_visit/maintenance_visit.json #: erpnext/manufacturing/doctype/blanket_order/blanket_order.json #: erpnext/manufacturing/doctype/bom/bom.json -#: erpnext/manufacturing/doctype/bom_creator/bom_creator.js:51 +#: erpnext/manufacturing/doctype/bom_creator/bom_creator.js:52 #: erpnext/manufacturing/doctype/bom_creator/bom_creator.json #: erpnext/manufacturing/doctype/job_card/job_card.json #: erpnext/manufacturing/doctype/master_production_schedule/master_production_schedule.json @@ -10298,7 +10371,7 @@ msgstr "شركات" #: erpnext/projects/doctype/timesheet/timesheet.json #: erpnext/projects/report/project_summary/project_summary.js:8 #: erpnext/projects/report/project_wise_stock_tracking/project_wise_stock_tracking.py:44 -#: erpnext/public/js/financial_statements.js:278 +#: erpnext/public/js/financial_statements.js:289 #: erpnext/public/js/purchase_trends_filters.js:8 #: erpnext/public/js/sales_trends_filters.js:51 #: erpnext/regional/doctype/import_supplier_invoice/import_supplier_invoice.json @@ -10474,7 +10547,7 @@ msgstr "" msgid "Company Address Name" msgstr "اسم عنوان الشركة" -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:308 +#: erpnext/controllers/accounts_controller.py:4267 msgid "Company Address is missing. You don't have permission to update it. Please contact your System Manager." msgstr "" @@ -10538,7 +10611,7 @@ msgid "Company Email" msgstr "البريد الإلكتروني الخاص بالشركة" #. Label of the company_logo (Attach Image) field in DocType 'Company' -#: erpnext/setup/doctype/company/company.json +#: erpnext/public/js/print.js:64 erpnext/setup/doctype/company/company.json msgid "Company Logo" msgstr "شعار الشركة" @@ -10564,12 +10637,12 @@ msgstr "" msgid "Company and Posting Date is mandatory" msgstr "" -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:2547 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:2500 msgid "Company currencies of both the companies should match for Inter Company Transactions." msgstr "يجب أن تتطابق عملات الشركة لكلتا الشركتين مع معاملات Inter Inter Company." -#: erpnext/stock/doctype/material_request/material_request.js:362 -#: erpnext/stock/doctype/stock_entry/stock_entry.js:704 +#: erpnext/stock/doctype/material_request/material_request.js:366 +#: erpnext/stock/doctype/stock_entry/stock_entry.js:717 msgid "Company field is required" msgstr "حقل الشركة مطلوب" @@ -10585,11 +10658,11 @@ msgstr "" msgid "Company is mandatory for generating an invoice. Please set a default company in Global Defaults." msgstr "" -#: erpnext/setup/doctype/company/company.js:215 +#: erpnext/setup/doctype/company/company.js:222 msgid "Company name not same" msgstr "اسم الشركة ليس مماثل\\n
        \\nCompany name not same" -#: erpnext/assets/doctype/asset/asset.py:265 +#: erpnext/assets/doctype/asset/asset.py:266 msgid "Company of asset {0} and purchase document {1} doesn't matches." msgstr "شركة الأصل {0} ومستند الشراء {1} غير متطابقين." @@ -10620,7 +10693,7 @@ msgstr "" msgid "Company {0} added multiple times" msgstr "" -#: erpnext/accounts/doctype/account/account.py:507 +#: erpnext/accounts/doctype/account/account.py:509 #: erpnext/manufacturing/report/material_requirements_planning_report/material_requirements_planning_report.py:1289 msgid "Company {0} does not exist" msgstr "الشركة {0} غير موجودة" @@ -10633,7 +10706,7 @@ msgstr "" msgid "Company {} does not exist yet. Taxes setup aborted." msgstr "" -#: erpnext/accounts/doctype/pos_invoice/pos_invoice.py:529 +#: erpnext/accounts/doctype/pos_invoice/pos_invoice.py:574 msgid "Company {} does not match with POS Profile Company {}" msgstr "" @@ -10658,12 +10731,12 @@ msgstr "" #. Label of the competitors (Table MultiSelect) field in DocType 'Opportunity' #. Label of the competitors (Table MultiSelect) field in DocType 'Quotation' #: erpnext/crm/doctype/opportunity/opportunity.json -#: erpnext/public/js/utils/sales_common.js:558 +#: erpnext/public/js/utils/sales_common.js:583 #: erpnext/selling/doctype/quotation/quotation.json msgid "Competitors" msgstr "" -#: erpnext/manufacturing/doctype/job_card/job_card.js:256 +#: erpnext/manufacturing/doctype/job_card/job_card.js:268 #: erpnext/manufacturing/doctype/workstation/workstation.js:151 msgid "Complete Job" msgstr "" @@ -10682,7 +10755,7 @@ msgstr "اكتمل بواسطة" msgid "Completed On" msgstr "" -#: erpnext/projects/doctype/task/task.py:184 +#: erpnext/projects/doctype/task/task.py:185 msgid "Completed On cannot be greater than Today" msgstr "" @@ -10701,12 +10774,12 @@ msgstr "العملية المكتملة" msgid "Completed Qty" msgstr "الكمية المكتملة" -#: erpnext/manufacturing/doctype/work_order/work_order.py:1335 +#: erpnext/manufacturing/doctype/work_order/work_order.py:1339 msgid "Completed Qty cannot be greater than 'Qty to Manufacture'" msgstr "لا يمكن أن تكون الكمية المكتملة أكبر من "الكمية إلى التصنيع"" -#: erpnext/manufacturing/doctype/job_card/job_card.js:304 -#: erpnext/manufacturing/doctype/job_card/job_card.js:425 +#: erpnext/manufacturing/doctype/job_card/job_card.js:316 +#: erpnext/manufacturing/doctype/job_card/job_card.js:437 #: erpnext/manufacturing/doctype/workstation/workstation.js:296 msgid "Completed Quantity" msgstr "الكمية المكتملة" @@ -10744,7 +10817,7 @@ msgstr "اكتمال بواسطة" msgid "Completion Date" msgstr "تاريخ الانتهاء" -#: erpnext/assets/doctype/asset_repair/asset_repair.py:80 +#: erpnext/assets/doctype/asset_repair/asset_repair.py:83 msgid "Completion Date can not be before Failure Date. Please adjust the dates accordingly." msgstr "" @@ -10838,7 +10911,7 @@ msgstr "" msgid "Consider Minimum Order Qty" msgstr "" -#: erpnext/manufacturing/doctype/work_order/work_order.js:980 +#: erpnext/manufacturing/doctype/work_order/work_order.js:993 msgid "Consider Process Loss" msgstr "" @@ -10910,7 +10983,7 @@ msgstr "القوائم المالية الموحدة" #. Log' #: erpnext/accounts/doctype/pos_invoice/pos_invoice.json #: erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.json -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:612 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:561 msgid "Consolidated Sales Invoice" msgstr "فاتورة المبيعات الموحدة" @@ -10983,6 +11056,7 @@ msgstr "" #. Label of the consumed_qty (Float) field in DocType 'Purchase Order Item #. Supplied' +#. Label of the consumed_qty (Float) field in DocType 'Job Card Item' #. Label of the consumed_qty (Float) field in DocType 'Work Order Item' #. Label of the consumed_qty (Float) field in DocType 'Stock Reservation Entry' #. Label of the consumed_qty (Float) field in DocType 'Subcontracting Inward @@ -10993,6 +11067,7 @@ msgstr "" #. Supplied Item' #: erpnext/buying/doctype/purchase_order_item_supplied/purchase_order_item_supplied.json #: erpnext/buying/report/subcontract_order_summary/subcontract_order_summary.py:153 +#: erpnext/manufacturing/doctype/job_card_item/job_card_item.json #: erpnext/manufacturing/doctype/work_order_item/work_order_item.json #: erpnext/manufacturing/report/bom_variance_report/bom_variance_report.py:59 #: erpnext/manufacturing/report/work_order_consumed_materials/work_order_consumed_materials.py:146 @@ -11004,7 +11079,7 @@ msgstr "" msgid "Consumed Qty" msgstr "تستهلك الكمية" -#: erpnext/manufacturing/doctype/work_order/work_order.py:1710 +#: erpnext/manufacturing/doctype/work_order/work_order.py:1717 msgid "Consumed Qty cannot be greater than Reserved Qty for item {0}" msgstr "" @@ -11033,6 +11108,10 @@ msgstr "" msgid "Consumed Stock Total Value" msgstr "" +#: erpnext/stock/doctype/stock_entry_type/stock_entry_type.py:118 +msgid "Consumed quantity of item {0} exceeds transferred quantity." +msgstr "" + #: erpnext/setup/setup_wizard/data/industry_type.txt:15 msgid "Consumer Products" msgstr "" @@ -11157,12 +11236,12 @@ msgstr "" msgid "Contact Person" msgstr "الشخص الذي يمكن الاتصال به" -#: erpnext/controllers/accounts_controller.py:515 +#: erpnext/controllers/accounts_controller.py:585 msgid "Contact Person does not belong to the {0}" msgstr "" #: erpnext/accounts/letterhead/company_letterhead.html:101 -#: erpnext/accounts/letterhead/company_letterhead_grey.html:117 +#: erpnext/accounts/letterhead/company_letterhead_grey.html:119 msgid "Contact:" msgstr "اتصال:" @@ -11331,28 +11410,28 @@ msgstr "معامل التحويل" #. Label of the conversion_rate (Float) field in DocType 'BOM Creator' #: erpnext/accounts/doctype/dunning/dunning.json #: erpnext/manufacturing/doctype/bom/bom.json -#: erpnext/manufacturing/doctype/bom_creator/bom_creator.js:85 +#: erpnext/manufacturing/doctype/bom_creator/bom_creator.js:86 #: erpnext/manufacturing/doctype/bom_creator/bom_creator.json msgid "Conversion Rate" msgstr "معدل التحويل" -#: erpnext/stock/doctype/item/item.py:392 +#: erpnext/stock/doctype/item/item.py:393 msgid "Conversion factor for default Unit of Measure must be 1 in row {0}" msgstr "معامل التحويل الافتراضي لوحدة القياس يجب أن يكون 1 في الصف {0}" -#: erpnext/controllers/stock_controller.py:84 +#: erpnext/controllers/stock_controller.py:86 msgid "Conversion factor for item {0} has been reset to 1.0 as the uom {1} is same as stock uom {2}." msgstr "" -#: erpnext/controllers/accounts_controller.py:2880 +#: erpnext/controllers/accounts_controller.py:2953 msgid "Conversion rate cannot be 0" msgstr "" -#: erpnext/controllers/accounts_controller.py:2887 +#: erpnext/controllers/accounts_controller.py:2960 msgid "Conversion rate is 1.00, but document currency is different from company currency" msgstr "" -#: erpnext/controllers/accounts_controller.py:2883 +#: erpnext/controllers/accounts_controller.py:2956 msgid "Conversion rate must be 1.00 if document currency is same as company currency" msgstr "" @@ -11406,11 +11485,6 @@ msgstr "تم نسخها من" msgid "Copy Fields to Variant" msgstr "نسخ الحقول إلى متغير" -#. Label of a Card Break in the Settings Workspace -#: erpnext/setup/workspace/settings/settings.json -msgid "Core" -msgstr "" - #. Option for the 'Corrective/Preventive' (Select) field in DocType 'Quality #. Action' #: erpnext/quality_management/doctype/quality_action/quality_action.json @@ -11423,13 +11497,13 @@ msgstr "تصحيحي" msgid "Corrective Action" msgstr "اجراء تصحيحي" -#: erpnext/manufacturing/doctype/job_card/job_card.js:482 +#: erpnext/manufacturing/doctype/job_card/job_card.js:494 msgid "Corrective Job Card" msgstr "" #. Label of the corrective_operation_section (Tab Break) field in DocType 'Job #. Card' -#: erpnext/manufacturing/doctype/job_card/job_card.js:489 +#: erpnext/manufacturing/doctype/job_card/job_card.js:501 #: erpnext/manufacturing/doctype/job_card/job_card.json msgid "Corrective Operation" msgstr "" @@ -11573,10 +11647,10 @@ msgstr "" #: erpnext/accounts/report/asset_depreciation_ledger/asset_depreciation_ledger.py:204 #: erpnext/accounts/report/customer_ledger_summary/customer_ledger_summary.js:98 #: erpnext/accounts/report/general_ledger/general_ledger.js:153 -#: erpnext/accounts/report/general_ledger/general_ledger.py:767 +#: erpnext/accounts/report/general_ledger/general_ledger.py:774 #: erpnext/accounts/report/gross_profit/gross_profit.js:68 #: erpnext/accounts/report/gross_profit/gross_profit.py:384 -#: erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py:308 +#: erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py:297 #: erpnext/accounts/report/purchase_register/purchase_register.js:46 #: erpnext/accounts/report/sales_payment_summary/sales_payment_summary.py:29 #: erpnext/accounts/report/sales_register/sales_register.js:52 @@ -11599,7 +11673,7 @@ msgstr "" #: erpnext/buying/doctype/supplier_quotation_item/supplier_quotation_item.json #: erpnext/buying/report/procurement_tracker/procurement_tracker.js:15 #: erpnext/buying/report/procurement_tracker/procurement_tracker.py:32 -#: erpnext/public/js/financial_statements.js:371 +#: erpnext/public/js/financial_statements.js:382 #: erpnext/selling/doctype/sales_order/sales_order.json #: erpnext/selling/doctype/sales_order_item/sales_order_item.json #: erpnext/stock/doctype/delivery_note/delivery_note.json @@ -11652,7 +11726,7 @@ msgstr "رقم مركز التكلفة" msgid "Cost Center and Budgeting" msgstr "مركز التكلفة والميزانية" -#: erpnext/public/js/utils/sales_common.js:492 +#: erpnext/public/js/utils/sales_common.js:517 msgid "Cost Center for Item rows has been updated to {0}" msgstr "" @@ -11660,8 +11734,8 @@ msgstr "" msgid "Cost Center is a part of Cost Center Allocation, hence cannot be converted to a group" msgstr "" -#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:1428 -#: erpnext/stock/doctype/purchase_receipt/purchase_receipt.py:883 +#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:1430 +#: erpnext/stock/doctype/purchase_receipt/purchase_receipt.py:898 msgid "Cost Center is required in row {0} in Taxes table for type {1}" msgstr "مركز التكلفة مطلوب في الصف {0} في جدول الضرائب للنوع {1}\\n
        \\nCost Center is required in row {0} in Taxes table for type {1}" @@ -11681,11 +11755,11 @@ msgstr "مركز التكلفة مع المعاملات الحالية لا يم msgid "Cost Center {0} cannot be used for allocation as it is used as main cost center in other allocation record." msgstr "" -#: erpnext/assets/doctype/asset/asset.py:293 +#: erpnext/assets/doctype/asset/asset.py:294 msgid "Cost Center {} doesn't belong to Company {}" msgstr "" -#: erpnext/assets/doctype/asset/asset.py:300 +#: erpnext/assets/doctype/asset/asset.py:301 msgid "Cost Center {} is a group cost center and group cost centers cannot be used in transactions" msgstr "" @@ -11693,7 +11767,7 @@ msgstr "" msgid "Cost Center: {0} does not exist" msgstr "مركز التكلفة: {0} غير موجود" -#: erpnext/setup/doctype/company/company.js:106 +#: erpnext/setup/doctype/company/company.js:113 msgid "Cost Centers" msgstr "مراكز التكلفة" @@ -11727,7 +11801,7 @@ msgstr "تكلفة السلع والمواد المسلمة" msgid "Cost of Goods Sold" msgstr "تكلفة البضاعة المباعة" -#: erpnext/stock/doctype/stock_entry/stock_entry.py:631 +#: erpnext/stock/doctype/stock_entry/stock_entry.py:699 msgid "Cost of Goods Sold Account in Items Table" msgstr "" @@ -11804,11 +11878,11 @@ msgstr "" msgid "Could Not Delete Demo Data" msgstr "" -#: erpnext/selling/doctype/quotation/quotation.py:606 +#: erpnext/selling/doctype/quotation/quotation.py:608 msgid "Could not auto create Customer due to the following missing mandatory field(s):" msgstr "تعذر إنشاء العميل تلقائيًا بسبب الحقول الإلزامية التالية المفقودة:" -#: erpnext/stock/doctype/delivery_note/delivery_note.py:676 +#: erpnext/stock/doctype/delivery_note/delivery_note.py:680 msgid "Could not create Credit Note automatically, please uncheck 'Issue Credit Note' and submit again" msgstr "تعذر إنشاء إشعار دائن تلقائيًا ، يُرجى إلغاء تحديد "إشعار ائتمان الإصدار" وإرساله مرة أخرى" @@ -11969,8 +12043,8 @@ msgstr "إنشاء زبائن محتملين" msgid "Create Ledger Entries for Change Amount" msgstr "" -#: erpnext/buying/doctype/supplier/supplier.js:216 -#: erpnext/selling/doctype/customer/customer.js:266 +#: erpnext/buying/doctype/supplier/supplier.js:226 +#: erpnext/selling/doctype/customer/customer.js:285 msgid "Create Link" msgstr "" @@ -11984,7 +12058,7 @@ msgstr "" msgid "Create Missing Party" msgstr "إنشاء طرف مفقود" -#: erpnext/manufacturing/doctype/bom_creator/bom_creator.js:163 +#: erpnext/manufacturing/doctype/bom_creator/bom_creator.js:164 msgid "Create Multi-level BOM" msgstr "" @@ -12012,11 +12086,11 @@ msgstr "إنشاء مدخل فتح نقطة البيع" msgid "Create Payment Entry" msgstr "إنشاء إدخال الدفع" -#: erpnext/accounts/doctype/pos_invoice/pos_invoice.py:814 +#: erpnext/accounts/doctype/pos_invoice/pos_invoice.py:859 msgid "Create Payment Entry for Consolidated POS Invoices." msgstr "" -#: erpnext/manufacturing/doctype/work_order/work_order.js:759 +#: erpnext/manufacturing/doctype/work_order/work_order.js:769 msgid "Create Pick List" msgstr "إنشاء قائمة انتقاء" @@ -12028,7 +12102,7 @@ msgstr "إنشاء تنسيق طباعة" msgid "Create Prospect" msgstr "" -#: erpnext/selling/doctype/sales_order/sales_order.js:1637 +#: erpnext/selling/doctype/sales_order/sales_order.js:1660 #: erpnext/utilities/activation.py:106 msgid "Create Purchase Order" msgstr "إنشاء أمر الشراء" @@ -12069,12 +12143,12 @@ msgstr "إنشاء أمر مبيعات" msgid "Create Sales Orders to help you plan your work and deliver on-time" msgstr "قم بإنشاء أوامر المبيعات لمساعدتك في تخطيط عملك وتقديمه في الوقت المحدد" -#: erpnext/stock/doctype/stock_entry/stock_entry.js:423 +#: erpnext/stock/doctype/stock_entry/stock_entry.js:428 msgid "Create Sample Retention Stock Entry" msgstr "إنشاء نموذج إدخال مخزون الاحتفاظ" #: erpnext/stock/dashboard/item_dashboard.js:283 -#: erpnext/stock/doctype/material_request/material_request.js:482 +#: erpnext/stock/doctype/material_request/material_request.js:486 #: erpnext/stock/doctype/pick_list/pick_list.js:138 msgid "Create Stock Entry" msgstr "" @@ -12083,7 +12157,7 @@ msgstr "" msgid "Create Supplier Quotation" msgstr "إنشاء اقتباس مورد" -#: erpnext/setup/doctype/company/company.js:150 +#: erpnext/setup/doctype/company/company.js:157 msgid "Create Tax Template" msgstr "إنشاء قالب الضريبة" @@ -12106,12 +12180,12 @@ msgstr "إنشاء صلاحية المستخدم" msgid "Create Users" msgstr "إنشاء المستخدمين" -#: erpnext/stock/doctype/item/item.js:853 +#: erpnext/stock/doctype/item/item.js:872 msgid "Create Variant" msgstr "إنشاء متغير" -#: erpnext/stock/doctype/item/item.js:667 -#: erpnext/stock/doctype/item/item.js:711 +#: erpnext/stock/doctype/item/item.js:686 +#: erpnext/stock/doctype/item/item.js:730 msgid "Create Variants" msgstr "إنشاء المتغيرات" @@ -12119,12 +12193,12 @@ msgstr "إنشاء المتغيرات" msgid "Create Workstation" msgstr "" -#: erpnext/stock/doctype/item/item.js:694 -#: erpnext/stock/doctype/item/item.js:846 +#: erpnext/stock/doctype/item/item.js:713 +#: erpnext/stock/doctype/item/item.js:865 msgid "Create a variant with the template image." msgstr "" -#: erpnext/stock/stock_ledger.py:2008 +#: erpnext/stock/stock_ledger.py:2045 msgid "Create an incoming stock transaction for the Item." msgstr "قم بإنشاء حركة مخزون واردة للصنف." @@ -12156,7 +12230,7 @@ msgstr "" msgid "Creating Accounts..." msgstr "إنشاء حسابات ..." -#: erpnext/selling/doctype/sales_order/sales_order.js:1531 +#: erpnext/selling/doctype/sales_order/sales_order.js:1535 msgid "Creating Delivery Note ..." msgstr "" @@ -12180,12 +12254,12 @@ msgstr "" msgid "Creating Purchase Invoices ..." msgstr "" -#: erpnext/selling/doctype/sales_order/sales_order.js:1657 +#: erpnext/selling/doctype/sales_order/sales_order.js:1684 msgid "Creating Purchase Order ..." msgstr "إنشاء أمر شراء ..." -#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js:738 -#: erpnext/buying/doctype/purchase_order/purchase_order.js:559 +#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js:739 +#: erpnext/buying/doctype/purchase_order/purchase_order.js:560 #: erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.js:73 msgid "Creating Purchase Receipt ..." msgstr "" @@ -12199,11 +12273,11 @@ msgstr "" msgid "Creating Stock Entry" msgstr "" -#: erpnext/selling/doctype/sales_order/sales_order.js:1791 +#: erpnext/selling/doctype/sales_order/sales_order.js:1805 msgid "Creating Subcontracting Inward Order ..." msgstr "" -#: erpnext/buying/doctype/purchase_order/purchase_order.js:574 +#: erpnext/buying/doctype/purchase_order/purchase_order.js:575 msgid "Creating Subcontracting Order ..." msgstr "" @@ -12215,7 +12289,7 @@ msgstr "" msgid "Creating User..." msgstr "" -#: erpnext/accounts/doctype/opening_invoice_creation_tool/opening_invoice_creation_tool.py:284 +#: erpnext/accounts/doctype/opening_invoice_creation_tool/opening_invoice_creation_tool.py:287 msgid "Creating {} out of {} {}" msgstr "إنشاء {} من {} {}" @@ -12225,16 +12299,16 @@ msgstr "إنشاء {} من {} {}" msgid "Creation" msgstr "" -#: erpnext/utilities/bulk_transaction.py:189 +#: erpnext/utilities/bulk_transaction.py:210 msgid "Creation of {1}(s) successful" msgstr "" -#: erpnext/utilities/bulk_transaction.py:206 +#: erpnext/utilities/bulk_transaction.py:227 msgid "Creation of {0} failed.\n" "\t\t\t\tCheck Bulk Transaction Log" msgstr "" -#: erpnext/utilities/bulk_transaction.py:197 +#: erpnext/utilities/bulk_transaction.py:218 msgid "Creation of {0} partially successful.\n" "\t\t\t\tCheck Bulk Transaction Log" msgstr "" @@ -12258,15 +12332,15 @@ msgstr "" msgid "Credit" msgstr "دائن" -#: erpnext/accounts/report/general_ledger/general_ledger.py:711 +#: erpnext/accounts/report/general_ledger/general_ledger.py:718 msgid "Credit (Transaction)" msgstr "" -#: erpnext/accounts/report/general_ledger/general_ledger.py:686 +#: erpnext/accounts/report/general_ledger/general_ledger.py:693 msgid "Credit ({0})" msgstr "الائتمان ({0})" -#: erpnext/accounts/doctype/journal_entry/journal_entry.js:602 +#: erpnext/accounts/doctype/journal_entry/journal_entry.js:606 msgid "Credit Account" msgstr "حساب دائن" @@ -12344,7 +12418,7 @@ msgstr "الائتمان أيام" msgid "Credit Limit" msgstr "الحد الائتماني" -#: erpnext/selling/doctype/customer/customer.py:584 +#: erpnext/selling/doctype/customer/customer.py:593 msgid "Credit Limit Crossed" msgstr "" @@ -12392,7 +12466,7 @@ msgstr "أشهر الائتمان" #: erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts_accounts_receivable.html:176 #: erpnext/accounts/report/accounts_receivable/accounts_receivable.html:147 #: erpnext/accounts/report/accounts_receivable/accounts_receivable.py:1216 -#: erpnext/controllers/sales_and_purchase_return.py:390 +#: erpnext/controllers/sales_and_purchase_return.py:391 #: erpnext/setup/setup_wizard/operations/install_fixtures.py:303 #: erpnext/stock/doctype/delivery_note/delivery_note.js:89 #: erpnext/stock/doctype/stock_entry/stock_entry.json @@ -12408,7 +12482,7 @@ msgstr "ملاحظة الائتمان المبلغ" #. Option for the 'Status' (Select) field in DocType 'Sales Invoice' #: erpnext/accounts/doctype/pos_invoice/pos_invoice.json #: erpnext/accounts/doctype/sales_invoice/sales_invoice.json -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:268 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:270 msgid "Credit Note Issued" msgstr "الائتمان مذكرة صادرة" @@ -12418,15 +12492,15 @@ msgstr "الائتمان مذكرة صادرة" msgid "Credit Note will update it's own outstanding amount, even if 'Return Against' is specified." msgstr "" -#: erpnext/stock/doctype/delivery_note/delivery_note.py:673 +#: erpnext/stock/doctype/delivery_note/delivery_note.py:677 msgid "Credit Note {0} has been created automatically" msgstr "تم إنشاء ملاحظة الائتمان {0} تلقائيًا" #. Label of the credit_to (Link) field in DocType 'Purchase Invoice' #: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json -#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:375 -#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:383 -#: erpnext/controllers/accounts_controller.py:2284 +#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:377 +#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:385 +#: erpnext/controllers/accounts_controller.py:2357 msgid "Credit To" msgstr "دائن الى" @@ -12435,16 +12509,16 @@ msgstr "دائن الى" msgid "Credit in Company Currency" msgstr "المدين في عملة الشركة" -#: erpnext/selling/doctype/customer/customer.py:550 -#: erpnext/selling/doctype/customer/customer.py:605 +#: erpnext/selling/doctype/customer/customer.py:559 +#: erpnext/selling/doctype/customer/customer.py:614 msgid "Credit limit has been crossed for customer {0} ({1}/{2})" msgstr "تم تجاوز حد الائتمان للعميل {0} ({1} / {2})" -#: erpnext/selling/doctype/customer/customer.py:343 +#: erpnext/selling/doctype/customer/customer.py:352 msgid "Credit limit is already defined for the Company {0}" msgstr "تم تحديد حد الائتمان بالفعل للشركة {0}" -#: erpnext/selling/doctype/customer/customer.py:604 +#: erpnext/selling/doctype/customer/customer.py:613 msgid "Credit limit reached for customer {0}" msgstr "تم بلوغ حد الائتمان للعميل {0}" @@ -12453,7 +12527,7 @@ msgid "Creditor Turnover Ratio" msgstr "" #: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:155 -#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:256 +#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:257 msgid "Creditors" msgstr "الدائنين" @@ -12499,7 +12573,7 @@ msgstr "معايير الوزن" msgid "Criteria weights must add up to 100%" msgstr "" -#: erpnext/accounts/doctype/accounts_settings/accounts_settings.py:144 +#: erpnext/accounts/doctype/accounts_settings/accounts_settings.py:135 msgid "Cron Interval should be between 1 and 59 Min" msgstr "" @@ -12613,7 +12687,7 @@ msgstr "يجب أن يكون صرف العملات ساريًا للشراء أ msgid "Currency and Price List" msgstr "العملة وقائمة الأسعار" -#: erpnext/accounts/doctype/account/account.py:344 +#: erpnext/accounts/doctype/account/account.py:346 msgid "Currency can not be changed after making entries using some other currency" msgstr "لا يمكن تغيير العملة بعد إجراء إدخالات باستخدام بعض العملات الأخرى" @@ -12621,9 +12695,9 @@ msgstr "لا يمكن تغيير العملة بعد إجراء إدخالات msgid "Currency filters are currently unsupported in Custom Financial Report." msgstr "" -#: erpnext/accounts/doctype/payment_entry/payment_entry.py:1665 -#: erpnext/accounts/doctype/payment_entry/payment_entry.py:1733 -#: erpnext/accounts/utils.py:2364 +#: erpnext/accounts/doctype/payment_entry/payment_entry.py:1666 +#: erpnext/accounts/doctype/payment_entry/payment_entry.py:1734 +#: erpnext/accounts/utils.py:2390 msgid "Currency for {0} must be {1}" msgstr "العملة ل {0} يجب أن تكون {1} \\n
        \\nCurrency for {0} must be {1}" @@ -12631,7 +12705,7 @@ msgstr "العملة ل {0} يجب أن تكون {1} \\n
        \\nCurrency for {0} msgid "Currency of the Closing Account must be {0}" msgstr "عملة الحساب الختامي يجب أن تكون {0}" -#: erpnext/manufacturing/doctype/bom/bom.py:611 +#: erpnext/manufacturing/doctype/bom/bom.py:622 msgid "Currency of the price list {0} must be {1} or {2}" msgstr "العملة من قائمة الأسعار {0} يجب أن تكون {1} أو {2}" @@ -12712,7 +12786,7 @@ msgid "Current Level" msgstr "" #: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:153 -#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:254 +#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:255 msgid "Current Liabilities" msgstr "الخصوم المتداولة" @@ -12898,7 +12972,7 @@ msgstr "" #: erpnext/accounts/doctype/pricing_rule/pricing_rule.json #: erpnext/accounts/doctype/process_statement_of_accounts_customer/process_statement_of_accounts_customer.json #: erpnext/accounts/doctype/promotional_scheme/promotional_scheme.json -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.js:303 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.js:304 #: erpnext/accounts/doctype/sales_invoice/sales_invoice.json #: erpnext/accounts/doctype/sales_invoice_reference/sales_invoice_reference.json #: erpnext/accounts/doctype/tax_rule/tax_rule.json @@ -12907,7 +12981,7 @@ msgstr "" #: erpnext/accounts/report/gross_profit/gross_profit.py:405 #: erpnext/accounts/report/inactive_sales_items/inactive_sales_items.py:37 #: erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.js:22 -#: erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py:224 +#: erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py:213 #: erpnext/accounts/report/pos_register/pos_register.js:44 #: erpnext/accounts/report/pos_register/pos_register.py:120 #: erpnext/accounts/report/pos_register/pos_register.py:181 @@ -12916,7 +12990,7 @@ msgstr "" #: erpnext/accounts/workspace/receivables/receivables.json #: erpnext/assets/doctype/asset/asset.json #: erpnext/buying/doctype/purchase_order/purchase_order.json -#: erpnext/buying/doctype/supplier/supplier.js:184 +#: erpnext/buying/doctype/supplier/supplier.js:194 #: erpnext/crm/doctype/contract/contract.json #: erpnext/crm/doctype/lead/lead.js:32 #: erpnext/crm/doctype/opportunity/opportunity.js:99 @@ -12926,7 +13000,7 @@ msgstr "" #: erpnext/maintenance/doctype/maintenance_schedule/maintenance_schedule.json #: erpnext/maintenance/doctype/maintenance_visit/maintenance_visit.json #: erpnext/manufacturing/doctype/blanket_order/blanket_order.json -#: erpnext/manufacturing/doctype/master_production_schedule/master_production_schedule.js:88 +#: erpnext/manufacturing/doctype/master_production_schedule/master_production_schedule.js:98 #: erpnext/manufacturing/doctype/production_plan/production_plan.json #: erpnext/manufacturing/doctype/production_plan_sales_order/production_plan_sales_order.json #: erpnext/projects/doctype/project/project.json @@ -12940,7 +13014,7 @@ msgstr "" #: erpnext/selling/doctype/customer/customer.json #: erpnext/selling/doctype/installation_note/installation_note.json #: erpnext/selling/doctype/party_specific_item/party_specific_item.json -#: erpnext/selling/doctype/sales_order/sales_order.js:1179 +#: erpnext/selling/doctype/sales_order/sales_order.js:1183 #: erpnext/selling/doctype/sales_order/sales_order.json #: erpnext/selling/doctype/sales_order/sales_order_calendar.js:19 #: erpnext/selling/doctype/sms_center/sms_center.json @@ -12968,8 +13042,8 @@ msgstr "" #: erpnext/setup/doctype/customer_group/customer_group.json #: erpnext/setup/doctype/territory/territory.json #: erpnext/setup/workspace/home/home.json -#: erpnext/stock/doctype/delivery_note/delivery_note.js:218 -#: erpnext/stock/doctype/delivery_note/delivery_note.js:489 +#: erpnext/stock/doctype/delivery_note/delivery_note.js:219 +#: erpnext/stock/doctype/delivery_note/delivery_note.js:490 #: erpnext/stock/doctype/delivery_note/delivery_note.json #: erpnext/stock/doctype/delivery_stop/delivery_stop.json #: erpnext/stock/doctype/item/item.json @@ -12978,7 +13052,7 @@ msgstr "" #: erpnext/stock/doctype/pick_list/pick_list.json #: erpnext/stock/doctype/serial_no/serial_no.json #: erpnext/stock/doctype/shipment/shipment.json -#: erpnext/stock/doctype/stock_entry/stock_entry.js:361 +#: erpnext/stock/doctype/stock_entry/stock_entry.js:366 #: erpnext/stock/doctype/warehouse/warehouse.json #: erpnext/stock/report/delayed_item_report/delayed_item_report.js:36 #: erpnext/stock/report/delayed_item_report/delayed_item_report.py:121 @@ -13054,7 +13128,7 @@ msgid "Customer Addresses And Contacts" msgstr "عناوين العملاء وجهات الإتصال" #: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:159 -#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:268 +#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:269 msgid "Customer Advances" msgstr "" @@ -13173,9 +13247,9 @@ msgstr "ملاحظات العميل" #: erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.js:85 #: erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.py:185 #: erpnext/accounts/report/customer_ledger_summary/customer_ledger_summary.js:56 -#: erpnext/accounts/report/customer_ledger_summary/customer_ledger_summary.py:228 +#: erpnext/accounts/report/customer_ledger_summary/customer_ledger_summary.py:165 #: erpnext/accounts/report/gross_profit/gross_profit.py:412 -#: erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py:211 +#: erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py:200 #: erpnext/accounts/report/sales_register/sales_register.js:27 #: erpnext/accounts/report/sales_register/sales_register.py:202 #: erpnext/crm/doctype/opportunity/opportunity.json @@ -13285,7 +13359,7 @@ msgstr "رقم محمول العميل" #: erpnext/accounts/report/customer_ledger_summary/customer_ledger_summary.js:92 #: erpnext/accounts/report/delivered_items_to_be_billed/delivered_items_to_be_billed.py:35 #: erpnext/accounts/report/gross_profit/gross_profit.py:419 -#: erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py:231 +#: erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py:220 #: erpnext/accounts/report/sales_register/sales_register.py:193 #: erpnext/buying/doctype/purchase_order/purchase_order.json #: erpnext/crm/doctype/opportunity/opportunity.json @@ -13390,7 +13464,7 @@ msgstr "العملاء المقدمة" msgid "Customer Provided Item Cost" msgstr "" -#: erpnext/setup/doctype/company/company.py:442 +#: erpnext/setup/doctype/company/company.py:478 msgid "Customer Service" msgstr "خدمة العملاء" @@ -13421,7 +13495,7 @@ msgstr "" msgid "Customer Warehouse (Optional)" msgstr "مستودع العميل (اختياري)" -#: erpnext/subcontracting/doctype/subcontracting_inward_order/subcontracting_inward_order.py:141 +#: erpnext/subcontracting/doctype/subcontracting_inward_order/subcontracting_inward_order.py:145 msgid "Customer Warehouse {0} does not belong to Customer {1}." msgstr "" @@ -13447,9 +13521,9 @@ msgstr "عميل أو بند" msgid "Customer required for 'Customerwise Discount'" msgstr "الزبون مطلوب للخصم المعني بالزبائن" -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1170 -#: erpnext/selling/doctype/sales_order/sales_order.py:420 -#: erpnext/stock/doctype/delivery_note/delivery_note.py:420 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1119 +#: erpnext/selling/doctype/sales_order/sales_order.py:422 +#: erpnext/stock/doctype/delivery_note/delivery_note.py:424 msgid "Customer {0} does not belong to project {1}" msgstr "العميل {0} لا ينتمي الى المشروع {1}\\n
        \\nCustomer {0} does not belong to project {1}" @@ -13559,7 +13633,7 @@ msgstr "" msgid "DFS" msgstr "" -#: erpnext/projects/doctype/project/project.py:673 +#: erpnext/projects/doctype/project/project.py:674 msgid "Daily Project Summary for {0}" msgstr "ملخص المشروع اليومي لـ {0}" @@ -13648,7 +13722,7 @@ msgstr "تاريخ الميلاد لا يمكن أن يكون بعد تاريخ msgid "Date of Commencement" msgstr "تاريخ البدء" -#: erpnext/setup/doctype/company/company.js:87 +#: erpnext/setup/doctype/company/company.js:94 msgid "Date of Commencement should be greater than Date of Incorporation" msgstr "يجب أن يكون تاريخ البدء أكبر من تاريخ التأسيس" @@ -13672,7 +13746,7 @@ msgstr "تاريخ الإصدار" msgid "Date of Joining" msgstr "" -#: erpnext/accounts/report/tax_withholding_details/tax_withholding_details.py:273 +#: erpnext/accounts/report/tax_withholding_details/tax_withholding_details.py:287 msgid "Date of Transaction" msgstr "تاريخ المعاملة" @@ -13804,11 +13878,11 @@ msgstr "" msgid "Debit" msgstr "مدين" -#: erpnext/accounts/report/general_ledger/general_ledger.py:704 +#: erpnext/accounts/report/general_ledger/general_ledger.py:711 msgid "Debit (Transaction)" msgstr "" -#: erpnext/accounts/report/general_ledger/general_ledger.py:679 +#: erpnext/accounts/report/general_ledger/general_ledger.py:686 msgid "Debit ({0})" msgstr "مدين ({0})" @@ -13818,7 +13892,7 @@ msgstr "مدين ({0})" msgid "Debit / Credit Note Posting Date" msgstr "" -#: erpnext/accounts/doctype/journal_entry/journal_entry.js:592 +#: erpnext/accounts/doctype/journal_entry/journal_entry.js:596 msgid "Debit Account" msgstr "حساب مدين" @@ -13861,9 +13935,9 @@ msgstr "" #: erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts_accounts_receivable.html:178 #: erpnext/accounts/report/accounts_receivable/accounts_receivable.html:147 #: erpnext/accounts/report/accounts_receivable/accounts_receivable.py:1219 -#: erpnext/controllers/sales_and_purchase_return.py:394 +#: erpnext/controllers/sales_and_purchase_return.py:395 #: erpnext/setup/setup_wizard/operations/install_fixtures.py:304 -#: erpnext/stock/doctype/purchase_receipt/purchase_receipt.js:61 +#: erpnext/stock/doctype/purchase_receipt/purchase_receipt.js:52 msgid "Debit Note" msgstr "إشعار مدين" @@ -13887,17 +13961,17 @@ msgstr "" #. Label of the debit_to (Link) field in DocType 'Sales Invoice' #: erpnext/accounts/doctype/pos_invoice/pos_invoice.json #: erpnext/accounts/doctype/sales_invoice/sales_invoice.json -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1038 -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1049 -#: erpnext/controllers/accounts_controller.py:2284 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:987 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:998 +#: erpnext/controllers/accounts_controller.py:2357 msgid "Debit To" msgstr "الخصم ل" -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1034 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:983 msgid "Debit To is required" msgstr "مدين الى مطلوب" -#: erpnext/accounts/general_ledger.py:523 +#: erpnext/accounts/general_ledger.py:530 msgid "Debit and Credit not equal for {0} #{1}. Difference is {2}." msgstr "المدين و الدائن غير متساوي ل {0} # {1}. الفرق هو {2}." @@ -13958,7 +14032,7 @@ msgstr "" msgid "Decimeter" msgstr "" -#: erpnext/public/js/utils/sales_common.js:585 +#: erpnext/public/js/utils/sales_common.js:610 msgid "Declare Lost" msgstr "أعلن فقدت" @@ -14020,14 +14094,14 @@ msgstr "" #. Label of the default_advance_paid_account (Link) field in DocType 'Company' #: erpnext/setup/doctype/company/company.json -#: erpnext/setup/doctype/company/company.py:271 +#: erpnext/setup/doctype/company/company.py:307 msgid "Default Advance Paid Account" msgstr "" #. Label of the default_advance_received_account (Link) field in DocType #. 'Company' #: erpnext/setup/doctype/company/company.json -#: erpnext/setup/doctype/company/company.py:260 +#: erpnext/setup/doctype/company/company.py:296 msgid "Default Advance Received Account" msgstr "" @@ -14036,19 +14110,19 @@ msgstr "" msgid "Default BOM" msgstr "الافتراضي BOM" -#: erpnext/stock/doctype/item/item.py:417 +#: erpnext/stock/doctype/item/item.py:436 msgid "Default BOM ({0}) must be active for this item or its template" msgstr "يجب أن تكون قائمة المواد الافتراضية ({0}) نشطة لهذا الصنف أو قوالبه" -#: erpnext/manufacturing/doctype/work_order/work_order.py:2151 +#: erpnext/manufacturing/doctype/work_order/work_order.py:2184 msgid "Default BOM for {0} not found" msgstr "فاتورة المواد ل {0} غير موجودة\\n
        \\nDefault BOM for {0} not found" -#: erpnext/controllers/accounts_controller.py:3841 +#: erpnext/controllers/accounts_controller.py:3914 msgid "Default BOM not found for FG Item {0}" msgstr "" -#: erpnext/manufacturing/doctype/work_order/work_order.py:2148 +#: erpnext/manufacturing/doctype/work_order/work_order.py:2181 msgid "Default BOM not found for Item {0} and Project {1}" msgstr "لم يتم العثور على قائمة المواد الافتراضية للمادة {0} والمشروع {1}" @@ -14176,9 +14250,8 @@ msgstr "حساب النفقات الإفتراضي" msgid "Default Finance Book" msgstr "دفتر المالية الافتراضي" -#. Label of the default_fg_warehouse (Link) field in DocType 'Manufacturing -#. Settings' -#: erpnext/manufacturing/doctype/manufacturing_settings/manufacturing_settings.json +#. Label of the default_fg_warehouse (Link) field in DocType 'Company' +#: erpnext/setup/doctype/company/company.json msgid "Default Finished Goods Warehouse" msgstr "المخزن الافتراضي للبضائع التامة الصنع" @@ -14313,14 +14386,18 @@ msgstr "عدد أيام صلاحية عرض الأسعار الافتراضي" msgid "Default Receivable Account" msgstr "حساب المدينون الافتراضي" +#. Label of the default_sales_contact (Link) field in DocType 'Company' +#: erpnext/setup/doctype/company/company.json +msgid "Default Sales Contact" +msgstr "" + #. Label of the sales_uom (Link) field in DocType 'Item' #: erpnext/stock/doctype/item/item.json msgid "Default Sales Unit of Measure" msgstr "وحدة قياس المبيعات الافتراضية" -#. Label of the default_scrap_warehouse (Link) field in DocType 'Manufacturing -#. Settings' -#: erpnext/manufacturing/doctype/manufacturing_settings/manufacturing_settings.json +#. Label of the default_scrap_warehouse (Link) field in DocType 'Company' +#: erpnext/setup/doctype/company/company.json msgid "Default Scrap Warehouse" msgstr "مستودع الخردة الافتراضي" @@ -14358,6 +14435,11 @@ msgstr "المستودع المصدر الافتراضي" msgid "Default Stock UOM" msgstr "افتراضي وحدة قياس السهم" +#. Label of the valuation_method (Select) field in DocType 'Company' +#: erpnext/setup/doctype/company/company.json +msgid "Default Stock Valuation Method" +msgstr "" + #. Label of the default_supplier (Link) field in DocType 'Item Default' #: erpnext/stock/doctype/item_default/item_default.json msgid "Default Supplier" @@ -14385,15 +14467,15 @@ msgstr "الإقليم الافتراضي" msgid "Default Unit of Measure" msgstr "وحدة القياس الافتراضية" -#: erpnext/stock/doctype/item/item.py:1267 +#: erpnext/stock/doctype/item/item.py:1270 msgid "Default Unit of Measure for Item {0} cannot be changed directly because you have already made some transaction(s) with another UOM. You need to either cancel the linked documents or create a new Item." msgstr "" -#: erpnext/stock/doctype/item/item.py:1250 +#: erpnext/stock/doctype/item/item.py:1253 msgid "Default Unit of Measure for Item {0} cannot be changed directly because you have already made some transaction(s) with another UOM. You will need to create a new Item to use a different Default UOM." msgstr "لا يمكن تغيير وحدة القياس الافتراضية للبند {0} مباشرة لأنك قمت بالفعل ببعض المعاملات (المعاملة) مع UOM أخرى. ستحتاج إلى إنشاء عنصر جديد لاستخدام واجهة مستخدم افتراضية مختلفة.\\n
        \\nDefault Unit of Measure for Item {0} cannot be changed directly because you have already made some transaction(s) with another UOM. You will need to create a new Item to use a different Default UOM." -#: erpnext/stock/doctype/item/item.py:898 +#: erpnext/stock/doctype/item/item.py:901 msgid "Default Unit of Measure for Variant '{0}' must be same as in Template '{1}'" msgstr "وحدة القياس الافتراضية للمتغير '{0}' يجب أن تكون كما في النمودج '{1}'" @@ -14420,18 +14502,6 @@ msgstr "النماذج الافتراضية" msgid "Default Warehouse for Sales Return" msgstr "المستودع الافتراضي لعائد المبيعات" -#. Label of the section_break_6 (Section Break) field in DocType 'Manufacturing -#. Settings' -#: erpnext/manufacturing/doctype/manufacturing_settings/manufacturing_settings.json -msgid "Default Warehouses for Production" -msgstr "المستودعات الافتراضية للإنتاج" - -#. Label of the default_wip_warehouse (Link) field in DocType 'Manufacturing -#. Settings' -#: erpnext/manufacturing/doctype/manufacturing_settings/manufacturing_settings.json -msgid "Default Work In Progress Warehouse" -msgstr "افتراضي العمل في مستودع التقدم" - #. Label of the workstation (Link) field in DocType 'Operation' #: erpnext/manufacturing/doctype/operation/operation.json msgid "Default Workstation" @@ -14448,7 +14518,7 @@ msgstr "سيتم تحديث الحساب الافتراضي تلقائيا في msgid "Default settings for your stock-related transactions" msgstr "" -#: erpnext/setup/doctype/company/company.js:184 +#: erpnext/setup/doctype/company/company.js:191 msgid "Default tax templates for sales, purchase and items are created." msgstr "" @@ -14526,7 +14596,7 @@ msgstr "حساب الإيرادات المؤجلة" msgid "Deferred Revenue and Expense" msgstr "" -#: erpnext/accounts/deferred_revenue.py:542 +#: erpnext/accounts/deferred_revenue.py:543 msgid "Deferred accounting failed for some invoices:" msgstr "" @@ -14608,20 +14678,25 @@ msgstr "" #. Label of the delete_transactions (Check) field in DocType 'Transaction #. Deletion Record' -#: erpnext/setup/doctype/company/company.js:161 +#: erpnext/setup/doctype/company/company.js:168 #: erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.json msgid "Delete Transactions" msgstr "" -#: erpnext/setup/doctype/company/company.js:230 +#: erpnext/setup/doctype/company/company.js:237 msgid "Delete all the Transactions for this Company" msgstr "حذف كل المعاملات المتعلقة بالشركة\\n
        \\nDelete all the Transactions for this Company" +#. Label of a Link in the Settings Workspace +#: erpnext/setup/workspace/settings/settings.json +msgid "Deleted Documents" +msgstr "" + #: erpnext/edi/doctype/code_list/code_list.js:28 msgid "Deleting {0} and all associated Common Code documents..." msgstr "" -#: erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py:502 +#: erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py:503 msgid "Deletion in Progress!" msgstr "" @@ -14646,7 +14721,7 @@ msgstr "" #. Option for the 'Status' (Select) field in DocType 'Stock Reservation Entry' #. Option for the 'Status' (Select) field in DocType 'Subcontracting Inward #. Order' -#: erpnext/buying/doctype/purchase_order/purchase_order.js:400 +#: erpnext/buying/doctype/purchase_order/purchase_order.js:401 #: erpnext/buying/doctype/purchase_order/purchase_order.json #: erpnext/buying/doctype/purchase_order/purchase_order_list.js:20 #: erpnext/controllers/website_list_for_contact.py:209 @@ -14735,7 +14810,7 @@ msgid "Delivered: {0}" msgstr "تسليم: {0}" #. Option for the 'Purpose' (Select) field in DocType 'Pick List' -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.js:124 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.js:125 #: erpnext/stock/doctype/pick_list/pick_list.json msgid "Delivery" msgstr "تسليم" @@ -14752,7 +14827,7 @@ msgstr "تسليم" #: erpnext/public/js/utils.js:791 #: erpnext/selling/doctype/delivery_schedule_item/delivery_schedule_item.json #: erpnext/selling/doctype/sales_order/sales_order.js:624 -#: erpnext/selling/doctype/sales_order/sales_order.js:1474 +#: erpnext/selling/doctype/sales_order/sales_order.js:1478 #: erpnext/selling/doctype/sales_order/sales_order.json #: erpnext/selling/doctype/sales_order_item/sales_order_item.json #: erpnext/selling/report/sales_order_analysis/sales_order_analysis.py:321 @@ -14765,7 +14840,7 @@ msgstr "تاريخ التسليم" msgid "Delivery Details" msgstr "تفاصيل التسليم" -#: erpnext/manufacturing/doctype/master_production_schedule/master_production_schedule.js:109 +#: erpnext/manufacturing/doctype/master_production_schedule/master_production_schedule.js:119 msgid "Delivery From Date" msgstr "" @@ -14791,21 +14866,21 @@ msgstr "" #. Label of a Link in the Stock Workspace #. Label of a shortcut in the Stock Workspace #: erpnext/accounts/doctype/pos_invoice_item/pos_invoice_item.json -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.js:326 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.js:327 #: erpnext/accounts/doctype/sales_invoice/sales_invoice_list.js:36 #: erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json #: erpnext/accounts/report/delivered_items_to_be_billed/delivered_items_to_be_billed.js:22 #: erpnext/accounts/report/delivered_items_to_be_billed/delivered_items_to_be_billed.py:21 -#: erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py:294 +#: erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py:283 #: erpnext/accounts/report/sales_register/sales_register.py:245 -#: erpnext/selling/doctype/sales_order/sales_order.js:1038 +#: erpnext/selling/doctype/sales_order/sales_order.js:1042 #: erpnext/selling/doctype/sales_order/sales_order_list.js:81 #: erpnext/setup/doctype/authorization_rule/authorization_rule.json #: erpnext/stock/doctype/delivery_note/delivery_note.json #: erpnext/stock/doctype/delivery_stop/delivery_stop.json #: erpnext/stock/doctype/delivery_trip/delivery_trip.js:52 #: erpnext/stock/doctype/packing_slip/packing_slip.json -#: erpnext/stock/doctype/purchase_receipt/purchase_receipt.js:75 +#: erpnext/stock/doctype/purchase_receipt/purchase_receipt.js:66 #: erpnext/stock/doctype/quality_inspection/quality_inspection.json #: erpnext/stock/doctype/shipment_delivery_note/shipment_delivery_note.json #: erpnext/stock/workspace/stock/stock.json @@ -14847,7 +14922,7 @@ msgstr "" msgid "Delivery Note Trends" msgstr "توجهات إشعارات التسليم" -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1426 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1375 msgid "Delivery Note {0} is not submitted" msgstr "لم يتم اعتماد ملاحظه التسليم {0}\\n
        \\nDelivery Note {0} is not submitted" @@ -14897,14 +14972,14 @@ msgstr "توقف التسليم" msgid "Delivery To" msgstr "التسليم إلى" -#: erpnext/manufacturing/doctype/master_production_schedule/master_production_schedule.js:115 +#: erpnext/manufacturing/doctype/master_production_schedule/master_production_schedule.js:125 msgid "Delivery To Date" msgstr "" #. Label of the delivery_trip (Link) field in DocType 'Delivery Note' #. Name of a DocType #. Label of a Link in the Stock Workspace -#: erpnext/stock/doctype/delivery_note/delivery_note.js:283 +#: erpnext/stock/doctype/delivery_note/delivery_note.js:284 #: erpnext/stock/doctype/delivery_note/delivery_note.json #: erpnext/stock/doctype/delivery_trip/delivery_trip.json #: erpnext/stock/workspace/stock/stock.json @@ -14934,7 +15009,7 @@ msgstr "مستودع تسليم" msgid "Delivery to" msgstr "" -#: erpnext/selling/doctype/sales_order/sales_order.py:439 +#: erpnext/selling/doctype/sales_order/sales_order.py:441 msgid "Delivery warehouse required for stock item {0}" msgstr "مستودع التسليم مطلوب للبند المستودعي {0}\\n
        \\nDelivery warehouse required for stock item {0}" @@ -14991,7 +15066,7 @@ msgstr "" msgid "Dependent Task" msgstr "مهمة تابعة" -#: erpnext/projects/doctype/task/task.py:177 +#: erpnext/projects/doctype/task/task.py:178 msgid "Dependent Task {0} is not a Template Task" msgstr "" @@ -15086,11 +15161,11 @@ msgstr "حركة الإهلاك" msgid "Depreciation Entry Posting Status" msgstr "" -#: erpnext/assets/doctype/asset/asset.py:1130 +#: erpnext/assets/doctype/asset/asset.py:1178 msgid "Depreciation Entry against asset {0}" msgstr "" -#: erpnext/assets/doctype/asset/depreciation.py:252 +#: erpnext/assets/doctype/asset/depreciation.py:253 msgid "Depreciation Entry against {0} worth {1}" msgstr "" @@ -15102,7 +15177,7 @@ msgstr "" msgid "Depreciation Expense Account" msgstr "حساب نفقات الاهلاك" -#: erpnext/assets/doctype/asset/depreciation.py:299 +#: erpnext/assets/doctype/asset/depreciation.py:300 msgid "Depreciation Expense Account should be an Income or Expense Account." msgstr "" @@ -15133,11 +15208,11 @@ msgstr "تاريخ ترحيل الإهلاك" msgid "Depreciation Posting Date cannot be before Available-for-use Date" msgstr "" -#: erpnext/assets/doctype/asset/asset.py:322 +#: erpnext/assets/doctype/asset/asset.py:323 msgid "Depreciation Row {0}: Depreciation Posting Date cannot be before Available-for-use Date" msgstr "" -#: erpnext/assets/doctype/asset/asset.py:590 +#: erpnext/assets/doctype/asset/asset.py:638 msgid "Depreciation Row {0}: Expected value after useful life must be greater than or equal to {1}" msgstr "صف الإهلاك {0}: يجب أن تكون القيمة المتوقعة بعد العمر الافتراضي أكبر من أو تساوي {1}" @@ -15164,7 +15239,7 @@ msgstr "جدول الاهلاك الزمني" msgid "Depreciation Schedule View" msgstr "" -#: erpnext/assets/doctype/asset/asset.py:417 +#: erpnext/assets/doctype/asset/asset.py:418 msgid "Depreciation cannot be calculated for fully depreciated assets" msgstr "" @@ -15190,7 +15265,7 @@ msgstr "" #. Label of the order_lost_reason (Small Text) field in DocType 'Opportunity' #. Label of the order_lost_reason (Small Text) field in DocType 'Quotation' #: erpnext/crm/doctype/opportunity/opportunity.json -#: erpnext/public/js/utils/sales_common.js:564 +#: erpnext/public/js/utils/sales_common.js:589 #: erpnext/selling/doctype/quotation/quotation.json msgid "Detailed Reason" msgstr "سبب مفصل" @@ -15243,11 +15318,11 @@ msgstr "الفرق ( المدين - الدائن )" msgid "Difference Account" msgstr "حساب الفرق" -#: erpnext/stock/doctype/stock_entry/stock_entry.py:620 +#: erpnext/stock/doctype/stock_entry/stock_entry.py:688 msgid "Difference Account in Items Table" msgstr "" -#: erpnext/stock/doctype/stock_entry/stock_entry.py:609 +#: erpnext/stock/doctype/stock_entry/stock_entry.py:677 msgid "Difference Account must be a Asset/Liability type account (Temporary Opening), since this Stock Entry is an Opening Entry" msgstr "" @@ -15302,16 +15377,16 @@ msgstr "" msgid "Difference Posting Date" msgstr "" -#: erpnext/manufacturing/report/bom_stock_calculated/bom_stock_calculated.py:92 +#: erpnext/manufacturing/report/bom_stock_calculated/bom_stock_calculated.py:100 msgid "Difference Qty" msgstr "" #: erpnext/stock/report/incorrect_stock_value_report/incorrect_stock_value_report.py:136 -#: erpnext/stock/report/stock_and_account_value_comparison/stock_and_account_value_comparison.py:131 +#: erpnext/stock/report/stock_and_account_value_comparison/stock_and_account_value_comparison.py:134 msgid "Difference Value" msgstr "قيمة الفرق" -#: erpnext/stock/doctype/delivery_note/delivery_note.js:498 +#: erpnext/stock/doctype/delivery_note/delivery_note.js:499 msgid "Different 'Source Warehouse' and 'Target Warehouse' can be set for each row." msgstr "" @@ -15371,7 +15446,7 @@ msgstr "النفقات المباشرة" #. Option for the 'Account Type' (Select) field in DocType 'Account' #: erpnext/accounts/doctype/account/account.json #: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:141 -#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:236 +#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:237 msgid "Direct Income" msgstr "إيراد مباشر" @@ -15454,15 +15529,15 @@ msgstr "" msgid "Disabled Account Selected" msgstr "" -#: erpnext/stock/utils.py:446 +#: erpnext/stock/utils.py:450 msgid "Disabled Warehouse {0} cannot be used for this transaction." msgstr "" -#: erpnext/controllers/accounts_controller.py:833 +#: erpnext/controllers/accounts_controller.py:903 msgid "Disabled pricing rules since this {} is an internal transfer" msgstr "" -#: erpnext/controllers/accounts_controller.py:847 +#: erpnext/controllers/accounts_controller.py:917 msgid "Disabled tax included prices since this {} is an internal transfer" msgstr "" @@ -15483,10 +15558,14 @@ msgstr "" msgid "Disassemble" msgstr "" -#: erpnext/manufacturing/doctype/work_order/work_order.js:231 +#: erpnext/manufacturing/doctype/work_order/work_order.js:232 msgid "Disassemble Order" msgstr "" +#: erpnext/manufacturing/doctype/work_order/work_order.js:443 +msgid "Disassemble Qty cannot be less than or equal to 0." +msgstr "" + #. Label of the disassembled_qty (Float) field in DocType 'Work Order' #: erpnext/manufacturing/doctype/work_order/work_order.json msgid "Disassembled Qty" @@ -15698,7 +15777,7 @@ msgstr "" msgid "Discount must be less than 100" msgstr "يجب أن يكون الخصم أقل من 100" -#: erpnext/accounts/doctype/payment_entry/payment_entry.py:3418 +#: erpnext/accounts/doctype/payment_entry/payment_entry.py:3419 msgid "Discount of {} applied as per Payment Term" msgstr "" @@ -15770,7 +15849,7 @@ msgstr "" msgid "Dislikes" msgstr "يكره" -#: erpnext/setup/doctype/company/company.py:436 +#: erpnext/setup/doctype/company/company.py:472 msgid "Dispatch" msgstr "ارسال" @@ -15851,7 +15930,7 @@ msgstr "" msgid "Disposal Date" msgstr "تاريخ التخلص" -#: erpnext/assets/doctype/asset/depreciation.py:824 +#: erpnext/assets/doctype/asset/depreciation.py:826 msgid "Disposal date {0} cannot be before {1} date {2} of the asset." msgstr "" @@ -15915,6 +15994,11 @@ msgstr "" msgid "Distribute Charges Based On" msgstr "توزيع الرسوم بناء على" +#. Label of the distribute_equally (Check) field in DocType 'Budget' +#: erpnext/accounts/doctype/budget/budget.json +msgid "Distribute Equally" +msgstr "" + #. Option for the 'Distribute Charges Based On' (Select) field in DocType #. 'Landed Cost Voucher' #: erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.json @@ -15951,6 +16035,11 @@ msgstr "" msgid "Distributed Discount Amount" msgstr "" +#. Label of the distribution_frequency (Select) field in DocType 'Budget' +#: erpnext/accounts/doctype/budget/budget.json +msgid "Distribution Frequency" +msgstr "" + #. Label of the distribution_id (Data) field in DocType 'Monthly Distribution' #: erpnext/accounts/doctype/monthly_distribution/monthly_distribution.json msgid "Distribution Name" @@ -15962,7 +16051,7 @@ msgid "Distributor" msgstr "موزع" #: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:191 -#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:337 +#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:338 msgid "Dividends Paid" msgstr "توزيع الأرباح" @@ -16032,7 +16121,7 @@ msgstr "هل تريد أن تخطر جميع العملاء عن طريق الب msgid "Do you want to submit the material request" msgstr "هل ترغب في تقديم طلب المواد" -#: erpnext/manufacturing/doctype/job_card/job_card.js:94 +#: erpnext/manufacturing/doctype/job_card/job_card.js:103 msgid "Do you want to submit the stock entry?" msgstr "" @@ -16063,7 +16152,7 @@ msgstr "" msgid "Documents Processed on each trigger. Queue Size should be between 5 and 100" msgstr "" -#: erpnext/accounts/doctype/repost_accounting_ledger/repost_accounting_ledger.py:254 +#: erpnext/accounts/doctype/repost_accounting_ledger/repost_accounting_ledger.py:257 msgid "Documents: {0} have deferred revenue/expense enabled for them. Cannot repost." msgstr "" @@ -16152,7 +16241,7 @@ msgstr "دخول وقت التوقف" msgid "Downtime Reason" msgstr "سبب التوقف" -#: erpnext/accounts/report/customer_ledger_summary/customer_ledger_summary.py:246 +#: erpnext/accounts/report/customer_ledger_summary/customer_ledger_summary.py:248 msgid "Dr/Cr" msgstr "" @@ -16237,7 +16326,7 @@ msgstr "" msgid "Due Date cannot be before {0}" msgstr "" -#: erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py:129 +#: erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py:138 msgid "Due to stock closing entry {0}, you cannot repost item valuation before {1}" msgstr "" @@ -16245,7 +16334,7 @@ msgstr "" #. Label of a Card Break in the Receivables Workspace #. Label of a Link in the Receivables Workspace #: erpnext/accounts/doctype/dunning/dunning.json -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.js:150 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.js:151 #: erpnext/accounts/workspace/receivables/receivables.json msgid "Dunning" msgstr "إنذار بالدفع" @@ -16301,7 +16390,7 @@ msgstr "" msgid "Duplicate Entry. Please check Authorization Rule {0}" msgstr "إدخال مكرر. يرجى التحقق من قاعدة التخويل {0}" -#: erpnext/assets/doctype/asset/asset.py:349 +#: erpnext/assets/doctype/asset/asset.py:350 msgid "Duplicate Finance Book" msgstr "" @@ -16319,7 +16408,7 @@ msgid "Duplicate POS Fields" msgstr "" #: erpnext/accounts/doctype/pos_closing_entry/pos_closing_entry.py:104 -#: erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.py:65 +#: erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.py:64 msgid "Duplicate POS Invoices found" msgstr "" @@ -16331,6 +16420,10 @@ msgstr "مشروع مكرر مع المهام" msgid "Duplicate Sales Invoices found" msgstr "" +#: erpnext/stock/serial_batch_bundle.py:1443 +msgid "Duplicate Serial Number Error" +msgstr "" + #: erpnext/stock/doctype/stock_closing_entry/stock_closing_entry.py:78 msgid "Duplicate Stock Closing Entry" msgstr "" @@ -16369,7 +16462,7 @@ msgid "Duration in Days" msgstr "المدة في أيام" #: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:170 -#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:285 +#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:286 #: erpnext/setup/setup_wizard/operations/taxes_setup.py:256 msgid "Duties and Taxes" msgstr "الرسوم والضرائب" @@ -16385,12 +16478,12 @@ msgstr "" msgid "Dyne" msgstr "" -#: erpnext/regional/italy/utils.py:248 erpnext/regional/italy/utils.py:268 -#: erpnext/regional/italy/utils.py:278 erpnext/regional/italy/utils.py:286 -#: erpnext/regional/italy/utils.py:293 erpnext/regional/italy/utils.py:297 -#: erpnext/regional/italy/utils.py:304 erpnext/regional/italy/utils.py:313 -#: erpnext/regional/italy/utils.py:338 erpnext/regional/italy/utils.py:345 -#: erpnext/regional/italy/utils.py:450 +#: erpnext/regional/italy/utils.py:221 erpnext/regional/italy/utils.py:241 +#: erpnext/regional/italy/utils.py:251 erpnext/regional/italy/utils.py:259 +#: erpnext/regional/italy/utils.py:266 erpnext/regional/italy/utils.py:270 +#: erpnext/regional/italy/utils.py:277 erpnext/regional/italy/utils.py:286 +#: erpnext/regional/italy/utils.py:311 erpnext/regional/italy/utils.py:318 +#: erpnext/regional/italy/utils.py:423 msgid "E-Invoicing Information Missing" msgstr "الفواتير الإلكترونية معلومات مفقودة" @@ -16433,7 +16526,7 @@ msgstr "معرف المستخدم ERPNext" msgid "Each Transaction" msgstr "كل عملية" -#: erpnext/stock/report/stock_ageing/stock_ageing.py:174 +#: erpnext/stock/report/stock_ageing/stock_ageing.py:176 msgid "Earliest" msgstr "أولا" @@ -16446,7 +16539,7 @@ msgstr "أقدم عمر" msgid "Earnest Money" msgstr "العربون" -#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:499 +#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:528 msgid "Edit BOM" msgstr "" @@ -16482,7 +16575,7 @@ msgstr "" #: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json #: erpnext/accounts/doctype/sales_invoice/sales_invoice.json #: erpnext/assets/doctype/asset_capitalization/asset_capitalization.json -#: erpnext/stock/doctype/delivery_note/delivery_note.js:502 +#: erpnext/stock/doctype/delivery_note/delivery_note.js:503 #: erpnext/stock/doctype/delivery_note/delivery_note.json #: erpnext/stock/doctype/purchase_receipt/purchase_receipt.json #: erpnext/stock/doctype/stock_entry/stock_entry.json @@ -16515,8 +16608,8 @@ msgstr "المؤهلات العلمية" msgid "Either 'Selling' or 'Buying' must be selected" msgstr "" -#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:268 -#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:413 +#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:290 +#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:441 msgid "Either Workstation or Workstation Type is mandatory" msgstr "" @@ -16566,11 +16659,6 @@ msgstr "" msgid "Ells (UK)" msgstr "" -#. Label of a Card Break in the Settings Workspace -#: erpnext/setup/workspace/settings/settings.json -msgid "Email / Notifications" -msgstr "" - #: erpnext/www/book_appointment/index.html:52 msgid "Email Address (required)" msgstr "" @@ -16651,8 +16739,8 @@ msgstr "أرسل بريد إلكتروني إلى {0}" msgid "Email verification failed." msgstr "" -#: erpnext/accounts/letterhead/company_letterhead.html:95 -#: erpnext/accounts/letterhead/company_letterhead_grey.html:111 +#: erpnext/accounts/letterhead/company_letterhead.html:96 +#: erpnext/accounts/letterhead/company_letterhead_grey.html:114 msgid "Email:" msgstr "البريد الإلكتروني:" @@ -16746,7 +16834,7 @@ msgid "Employee Advances" msgstr "سلف الموظفين" #: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:184 -#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:321 +#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:322 msgid "Employee Benefits Obligation" msgstr "" @@ -16826,7 +16914,7 @@ msgstr "الموظف مطلوب أثناء إصدار الأصول {0}" msgid "Employee {0} does not belong to the company {1}" msgstr "" -#: erpnext/manufacturing/doctype/job_card/job_card.py:315 +#: erpnext/manufacturing/doctype/job_card/job_card.py:310 msgid "Employee {0} is currently working on another workstation. Please assign another employee." msgstr "" @@ -16843,7 +16931,7 @@ msgstr "فارغة" msgid "Ems(Pica)" msgstr "" -#: erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py:1717 +#: erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py:1720 msgid "Enable Allow Partial Reservation in the Stock Settings to reserve partial stock." msgstr "" @@ -16859,7 +16947,7 @@ msgstr "تمكين جدولة موعد" msgid "Enable Auto Email" msgstr "تفعيل البريد الإلكتروني التلقائي" -#: erpnext/stock/doctype/item/item.py:1059 +#: erpnext/stock/doctype/item/item.py:1062 msgid "Enable Auto Re-Order" msgstr "تمكين إعادة الطلب التلقائي" @@ -17033,8 +17121,8 @@ msgstr "لا يمكن أن يكون تاريخ الانتهاء قبل تاري #. Label of the end_time (Time) field in DocType 'Stock Reposting Settings' #. Label of the end_time (Time) field in DocType 'Service Day' #. Label of the end_time (Datetime) field in DocType 'Call Log' -#: erpnext/manufacturing/doctype/job_card/job_card.js:362 -#: erpnext/manufacturing/doctype/job_card/job_card.js:432 +#: erpnext/manufacturing/doctype/job_card/job_card.js:374 +#: erpnext/manufacturing/doctype/job_card/job_card.js:444 #: erpnext/manufacturing/doctype/workstation_working_hour/workstation_working_hour.json #: erpnext/stock/doctype/stock_reposting_settings/stock_reposting_settings.json #: erpnext/support/doctype/service_day/service_day.json @@ -17042,7 +17130,7 @@ msgstr "لا يمكن أن يكون تاريخ الانتهاء قبل تاري msgid "End Time" msgstr "" -#: erpnext/stock/doctype/stock_entry/stock_entry.js:287 +#: erpnext/stock/doctype/stock_entry/stock_entry.js:292 msgid "End Transit" msgstr "" @@ -17050,7 +17138,7 @@ msgstr "" #: erpnext/accounts/report/deferred_revenue_and_expense/deferred_revenue_and_expense.js:64 #: erpnext/accounts/report/financial_ratios/financial_ratios.js:25 #: erpnext/assets/report/fixed_asset_register/fixed_asset_register.js:89 -#: erpnext/public/js/financial_statements.js:340 +#: erpnext/public/js/financial_statements.js:351 msgid "End Year" msgstr "نهاية السنة" @@ -17095,7 +17183,7 @@ msgstr "" #: erpnext/manufacturing/report/bom_stock_report/bom_stock_report.html:13 #: erpnext/manufacturing/report/bom_stock_report/bom_stock_report.html:23 -#: erpnext/manufacturing/report/bom_stock_report/bom_stock_report.py:29 +#: erpnext/manufacturing/report/bom_stock_report/bom_stock_report.py:30 msgid "Enough Parts to Build" msgstr "يكفي لبناء أجزاء" @@ -17109,6 +17197,10 @@ msgstr "ضمان التسليم على أساس المسلسل المنتجة" msgid "Enter API key in Google Settings." msgstr "أدخل مفتاح API في إعدادات Google." +#: erpnext/public/js/print.js:51 +msgid "Enter Company Details" +msgstr "" + #: erpnext/setup/doctype/employee/employee.js:102 msgid "Enter First and Last name of Employee, based on Which Full Name will be updated. IN transactions, it will be Full Name which will be fetched." msgstr "" @@ -17121,12 +17213,12 @@ msgstr "" msgid "Enter Serial Nos" msgstr "" -#: erpnext/stock/doctype/material_request/material_request.js:419 +#: erpnext/stock/doctype/material_request/material_request.js:423 msgid "Enter Supplier" msgstr "أدخل المورد" -#: erpnext/manufacturing/doctype/job_card/job_card.js:389 -#: erpnext/manufacturing/doctype/job_card/job_card.js:458 +#: erpnext/manufacturing/doctype/job_card/job_card.js:401 +#: erpnext/manufacturing/doctype/job_card/job_card.js:470 #: erpnext/manufacturing/doctype/workstation/workstation.js:312 msgid "Enter Value" msgstr "أدخل القيمة" @@ -17135,7 +17227,7 @@ msgstr "أدخل القيمة" msgid "Enter Visit Details" msgstr "" -#: erpnext/manufacturing/doctype/routing/routing.js:78 +#: erpnext/manufacturing/doctype/routing/routing.js:88 msgid "Enter a name for Routing." msgstr "" @@ -17151,7 +17243,7 @@ msgstr "" msgid "Enter amount to be redeemed." msgstr "أدخل المبلغ المراد استرداده." -#: erpnext/stock/doctype/item/item.js:1015 +#: erpnext/stock/doctype/item/item.js:1034 msgid "Enter an Item Code, the name will be auto-filled the same as Item Code on clicking inside the Item Name field." msgstr "" @@ -17167,7 +17259,7 @@ msgstr "أدخل رقم هاتف العميل" msgid "Enter date to scrap asset" msgstr "" -#: erpnext/assets/doctype/asset/asset.py:415 +#: erpnext/assets/doctype/asset/asset.py:416 msgid "Enter depreciation details" msgstr "أدخل تفاصيل الاستهلاك" @@ -17183,7 +17275,7 @@ msgstr "" msgid "Enter the Bank Guarantee Number before submitting." msgstr "" -#: erpnext/manufacturing/doctype/routing/routing.js:83 +#: erpnext/manufacturing/doctype/routing/routing.js:93 msgid "Enter the Operation, the table will fetch the Operation details like Hourly Rate, Workstation automatically.\n\n" " After that, set the Operation Time in minutes and the table will calculate the Operation Costs based on the Hourly Rate and Operation Time." msgstr "" @@ -17196,15 +17288,15 @@ msgstr "" msgid "Enter the name of the bank or lending institution before submitting." msgstr "" -#: erpnext/stock/doctype/item/item.js:1041 +#: erpnext/stock/doctype/item/item.js:1060 msgid "Enter the opening stock units." msgstr "" -#: erpnext/manufacturing/doctype/bom/bom.js:918 +#: erpnext/manufacturing/doctype/bom/bom.js:935 msgid "Enter the quantity of the Item that will be manufactured from this Bill of Materials." msgstr "" -#: erpnext/manufacturing/doctype/work_order/work_order.js:1138 +#: erpnext/manufacturing/doctype/work_order/work_order.js:1133 msgid "Enter the quantity to manufacture. Raw material Items will be fetched only when this is set." msgstr "" @@ -17237,7 +17329,7 @@ msgstr "نوع الدخول" #. Option for the 'Root Type' (Select) field in DocType 'Ledger Merge' #: erpnext/accounts/doctype/account/account.json #: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:189 -#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:331 +#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:332 #: erpnext/accounts/doctype/ledger_merge/ledger_merge.json #: erpnext/accounts/report/account_balance/account_balance.js:29 #: erpnext/accounts/report/account_balance/account_balance.js:45 @@ -17265,7 +17357,7 @@ msgstr "" msgid "Error Description" msgstr "وصف خاطئ" -#: erpnext/accounts/doctype/opening_invoice_creation_tool/opening_invoice_creation_tool.py:274 +#: erpnext/accounts/doctype/opening_invoice_creation_tool/opening_invoice_creation_tool.py:277 msgid "Error Occurred" msgstr "" @@ -17281,15 +17373,15 @@ msgstr "حدث خطأ أثناء تقييم صيغة المعايير" msgid "Error in party matching for Bank Transaction {0}" msgstr "" -#: erpnext/assets/doctype/asset/depreciation.py:315 +#: erpnext/assets/doctype/asset/depreciation.py:317 msgid "Error while posting depreciation entries" msgstr "" -#: erpnext/accounts/deferred_revenue.py:540 +#: erpnext/accounts/deferred_revenue.py:541 msgid "Error while processing deferred accounting for {0}" msgstr "" -#: erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py:442 +#: erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py:516 msgid "Error while reposting item valuation" msgstr "" @@ -17345,7 +17437,7 @@ msgstr "" msgid "Example URL" msgstr "" -#: erpnext/stock/doctype/item/item.py:990 +#: erpnext/stock/doctype/item/item.py:993 msgid "Example of a linked document: {0}" msgstr "" @@ -17360,7 +17452,7 @@ msgstr "" msgid "Example: ABCD.#####. If series is set and Batch No is not mentioned in transactions, then automatic batch number will be created based on this series. If you always want to explicitly mention Batch No for this item, leave this blank. Note: this setting will take priority over the Naming Series Prefix in Stock Settings." msgstr "مثال: ABCD. #####. إذا تم ضبط المسلسل ولم يتم ذكر رقم الدفعة في المعاملات ، فسيتم إنشاء رقم الدفعة تلقائيًا استنادًا إلى هذه السلسلة. إذا كنت تريد دائمًا الإشارة صراحة إلى Batch No لهذا العنصر ، فاترك هذا فارغًا. ملاحظة: سيأخذ هذا الإعداد الأولوية على بادئة Naming Series في إعدادات المخزون." -#: erpnext/stock/stock_ledger.py:2274 +#: erpnext/stock/stock_ledger.py:2311 msgid "Example: Serial No {0} reserved in {1}." msgstr "" @@ -17374,7 +17466,7 @@ msgstr "دور الموافقة على الموازنة الاستثنائية" msgid "Excess Materials Consumed" msgstr "" -#: erpnext/manufacturing/doctype/job_card/job_card.py:987 +#: erpnext/manufacturing/doctype/job_card/job_card.py:1012 msgid "Excess Transfer" msgstr "" @@ -17410,15 +17502,17 @@ msgstr "" #: erpnext/accounts/doctype/payment_entry_reference/payment_entry_reference.json #: erpnext/accounts/doctype/purchase_invoice_advance/purchase_invoice_advance.json #: erpnext/accounts/doctype/sales_invoice_advance/sales_invoice_advance.json -#: erpnext/setup/doctype/company/company.py:624 +#: erpnext/setup/doctype/company/company.py:665 msgid "Exchange Gain/Loss" msgstr "أرباح / خسائر الناتجة عن صرف العملة" -#: erpnext/controllers/accounts_controller.py:1696 -#: erpnext/controllers/accounts_controller.py:1780 +#: erpnext/controllers/accounts_controller.py:1769 +#: erpnext/controllers/accounts_controller.py:1853 msgid "Exchange Gain/Loss amount has been booked through {0}" msgstr "" +#. Label of the exchange_rate (Float) field in DocType 'Advance Payment Ledger +#. Entry' #. Label of the exchange_rate (Float) field in DocType 'Journal Entry Account' #. Label of the exchange_rate (Float) field in DocType 'Payment Entry #. Reference' @@ -17446,6 +17540,7 @@ msgstr "" #. Label of the exchange_rate (Float) field in DocType 'Landed Cost Taxes and #. Charges' #. Label of the conversion_rate (Float) field in DocType 'Purchase Receipt' +#: erpnext/accounts/doctype/advance_payment_ledger_entry/advance_payment_ledger_entry.json #: erpnext/accounts/doctype/journal_entry_account/journal_entry_account.json #: erpnext/accounts/doctype/payment_entry_reference/payment_entry_reference.json #: erpnext/accounts/doctype/payment_reconciliation_allocation/payment_reconciliation_allocation.json @@ -17497,7 +17592,7 @@ msgstr "حساب إعادة تقييم سعر الصرف" msgid "Exchange Rate Revaluation Settings" msgstr "" -#: erpnext/controllers/sales_and_purchase_return.py:73 +#: erpnext/controllers/sales_and_purchase_return.py:72 msgid "Exchange Rate must be same as {0} {1} ({2})" msgstr "يجب أن يكون سعر الصرف نفس {0} {1} ({2})" @@ -17509,7 +17604,7 @@ msgstr "يجب أن يكون سعر الصرف نفس {0} {1} ({2})" msgid "Excise Entry" msgstr "الدخول المكوس" -#: erpnext/stock/doctype/stock_entry/stock_entry.js:1367 +#: erpnext/stock/doctype/stock_entry/stock_entry.js:1374 msgid "Excise Invoice" msgstr "المكوس الفاتورة" @@ -17574,7 +17669,7 @@ msgstr "" msgid "Expected Amount" msgstr "المبلغ المتوقع" -#: erpnext/manufacturing/report/production_planning_report/production_planning_report.py:424 +#: erpnext/manufacturing/report/production_planning_report/production_planning_report.py:429 msgid "Expected Arrival Date" msgstr "وصول التاريخ المتوقع" @@ -17604,7 +17699,7 @@ msgstr "تاريخ الإغلاق المتوقع" msgid "Expected Delivery Date" msgstr "تاريخ التسليم المتوقع" -#: erpnext/selling/doctype/sales_order/sales_order.py:401 +#: erpnext/selling/doctype/sales_order/sales_order.py:403 msgid "Expected Delivery Date should be after Sales Order Date" msgstr "يجب أن يكون تاريخ التسليم المتوقع بعد تاريخ أمر المبيعات" @@ -17622,7 +17717,7 @@ msgstr "يجب أن يكون تاريخ التسليم المتوقع بعد ت msgid "Expected End Date" msgstr "تاريخ الإنتهاء المتوقع" -#: erpnext/projects/doctype/task/task.py:113 +#: erpnext/projects/doctype/task/task.py:114 msgid "Expected End Date should be less than or equal to parent task's Expected End Date {0}." msgstr "" @@ -17678,7 +17773,7 @@ msgstr "القيمة المتوقعة بعد حياة مفيدة" #: erpnext/accounts/doctype/cashier_closing/cashier_closing.json #: erpnext/accounts/doctype/ledger_merge/ledger_merge.json #: erpnext/accounts/doctype/process_deferred_accounting/process_deferred_accounting.json -#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:601 +#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:603 #: erpnext/accounts/report/account_balance/account_balance.js:28 #: erpnext/accounts/report/deferred_revenue_and_expense/deferred_revenue_and_expense.js:89 #: erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.py:184 @@ -17686,7 +17781,7 @@ msgstr "القيمة المتوقعة بعد حياة مفيدة" msgid "Expense" msgstr "نفقة" -#: erpnext/controllers/stock_controller.py:895 +#: erpnext/controllers/stock_controller.py:897 msgid "Expense / Difference account ({0}) must be a 'Profit or Loss' account" msgstr "حساب نفقات / قروق ({0}) يجب ان يكون حساب ارباح و خسائر" @@ -17719,7 +17814,7 @@ msgstr "حساب نفقات / قروق ({0}) يجب ان يكون حساب ار #: erpnext/accounts/doctype/pos_profile/pos_profile.json #: erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json #: erpnext/accounts/report/account_balance/account_balance.js:46 -#: erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py:253 +#: erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py:245 #: erpnext/assets/doctype/asset_capitalization_service_item/asset_capitalization_service_item.json #: erpnext/assets/doctype/asset_repair_purchase_invoice/asset_repair_purchase_invoice.json #: erpnext/buying/doctype/purchase_order_item/purchase_order_item.json @@ -17734,7 +17829,7 @@ msgstr "حساب نفقات / قروق ({0}) يجب ان يكون حساب ار msgid "Expense Account" msgstr "حساب النفقات" -#: erpnext/controllers/stock_controller.py:875 +#: erpnext/controllers/stock_controller.py:877 msgid "Expense Account Missing" msgstr "حساب المصاريف مفقود" @@ -17749,20 +17844,16 @@ msgstr "" msgid "Expense Head" msgstr "عنوان المصروف" -#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:495 -#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:519 -#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:539 +#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:497 +#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:521 +#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:541 msgid "Expense Head Changed" msgstr "تغيير رأس المصاريف" -#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:597 +#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:599 msgid "Expense account is mandatory for item {0}" msgstr "اجباري حساب النفقات للصنف {0}" -#: erpnext/assets/doctype/asset_repair/asset_repair.py:127 -msgid "Expense account {0} not present in Purchase Invoice {1}" -msgstr "" - #: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:81 #: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:140 msgid "Expenses" @@ -17785,7 +17876,7 @@ msgid "Expenses Included In Valuation" msgstr "المصروفات متضمنة في تقييم السعر" #: erpnext/stock/doctype/pick_list/pick_list.py:256 -#: erpnext/stock/doctype/stock_entry/stock_entry.js:385 +#: erpnext/stock/doctype/stock_entry/stock_entry.js:390 msgid "Expired Batches" msgstr "دفعات منتهية الصلاحية" @@ -17843,10 +17934,6 @@ msgstr "تنبؤ تجانس أسي" msgid "Export E-Invoices" msgstr "تصدير الفواتير الإلكترونية" -#: erpnext/setup/setup_wizard/operations/install_fixtures.py:301 -msgid "External" -msgstr "" - #. Label of the external_work_history (Table) field in DocType 'Employee' #: erpnext/setup/doctype/employee/employee.json msgid "External Work History" @@ -17856,7 +17943,7 @@ msgstr "سجل العمل الخارجي" msgid "Extra Consumed Qty" msgstr "" -#: erpnext/manufacturing/doctype/job_card/job_card.py:233 +#: erpnext/manufacturing/doctype/job_card/job_card.py:227 msgid "Extra Job Card Quantity" msgstr "" @@ -17879,11 +17966,14 @@ msgstr "صغير جدا" msgid "FG / Semi FG Item" msgstr "" +#. Option for the 'Default Stock Valuation Method' (Select) field in DocType +#. 'Company' #. Option for the 'Valuation Method' (Select) field in DocType 'Item' #. Option for the 'Default Valuation Method' (Select) field in DocType 'Stock #. Settings' #. Option for the 'Pick Serial / Batch Based On' (Select) field in DocType #. 'Stock Settings' +#: erpnext/setup/doctype/company/company.json #: erpnext/stock/doctype/item/item.json #: erpnext/stock/doctype/stock_settings/stock_settings.json msgid "FIFO" @@ -17942,7 +18032,7 @@ msgstr "فشل في تثبيت الإعدادات المسبقة" msgid "Failed to login" msgstr "فشل في تسجيل الدخول" -#: erpnext/accounts/doctype/bank_statement_import/bank_statement_import.py:163 +#: erpnext/accounts/doctype/bank_statement_import/bank_statement_import.py:164 msgid "Failed to parse MT940 format. Error: {0}" msgstr "" @@ -17959,7 +18049,7 @@ msgstr "أخفق إعداد الشركة" msgid "Failed to setup defaults" msgstr "فشل في إعداد الإعدادات الافتراضية" -#: erpnext/setup/doctype/company/company.py:821 +#: erpnext/setup/doctype/company/company.py:862 msgid "Failed to setup defaults for country {0}. Please contact support." msgstr "" @@ -18031,7 +18121,7 @@ msgstr "" msgid "Fetch Subscription Updates" msgstr "جلب تحديثات الاشتراك" -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.js:1050 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.js:1051 msgid "Fetch Timesheet" msgstr "" @@ -18053,8 +18143,8 @@ msgstr "" msgid "Fetch Value From" msgstr "" -#: erpnext/stock/doctype/material_request/material_request.js:354 -#: erpnext/stock/doctype/stock_entry/stock_entry.js:681 +#: erpnext/stock/doctype/material_request/material_request.js:358 +#: erpnext/stock/doctype/stock_entry/stock_entry.js:694 msgid "Fetch exploded BOM (including sub-assemblies)" msgstr "جلب BOM انفجرت (بما في ذلك المجالس الفرعية)" @@ -18072,16 +18162,16 @@ msgstr "" msgid "Fetching Error" msgstr "" -#: erpnext/manufacturing/doctype/master_production_schedule/master_production_schedule.js:188 +#: erpnext/manufacturing/doctype/master_production_schedule/master_production_schedule.js:198 msgid "Fetching Material Requests..." msgstr "" -#: erpnext/manufacturing/doctype/master_production_schedule/master_production_schedule.js:135 +#: erpnext/manufacturing/doctype/master_production_schedule/master_production_schedule.js:145 msgid "Fetching Sales Orders..." msgstr "" #: erpnext/accounts/doctype/dunning/dunning.js:135 -#: erpnext/public/js/controllers/transaction.js:1472 +#: erpnext/public/js/controllers/transaction.js:1480 msgid "Fetching exchange rates ..." msgstr "" @@ -18114,7 +18204,7 @@ msgstr "إعادة تسمية الملف" #: erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.js:16 #: erpnext/accounts/report/deferred_revenue_and_expense/deferred_revenue_and_expense.js:16 -#: erpnext/public/js/financial_statements.js:292 +#: erpnext/public/js/financial_statements.js:303 msgid "Filter Based On" msgstr "عامل التصفية على أساس" @@ -18148,11 +18238,11 @@ msgstr "" msgid "Filter on Payment" msgstr "" -#: erpnext/manufacturing/doctype/master_production_schedule/master_production_schedule.js:148 +#: erpnext/manufacturing/doctype/master_production_schedule/master_production_schedule.js:158 msgid "Filters for Material Requests" msgstr "" -#: erpnext/manufacturing/doctype/master_production_schedule/master_production_schedule.js:82 +#: erpnext/manufacturing/doctype/master_production_schedule/master_production_schedule.js:92 msgid "Filters for Sales Orders" msgstr "" @@ -18219,7 +18309,7 @@ msgstr "" #: erpnext/assets/doctype/asset_shift_allocation/asset_shift_allocation.json #: erpnext/assets/doctype/asset_value_adjustment/asset_value_adjustment.json #: erpnext/assets/report/fixed_asset_register/fixed_asset_register.js:48 -#: erpnext/public/js/financial_statements.js:286 +#: erpnext/public/js/financial_statements.js:297 msgid "Finance Book" msgstr "كتاب المالية" @@ -18280,7 +18370,7 @@ msgstr "" #. Label of a Card Break in the Financial Reports Workspace #: erpnext/accounts/workspace/financial_reports/financial_reports.json -#: erpnext/public/js/financial_statements.js:254 +#: erpnext/public/js/financial_statements.js:265 msgid "Financial Statements" msgstr "البيانات المالية" @@ -18294,9 +18384,9 @@ msgstr "" msgid "Financial reports will be generated using GL Entry doctypes (should be enabled if Period Closing Voucher is not posted for all years sequentially or missing) " msgstr "" -#: erpnext/manufacturing/doctype/work_order/work_order.js:843 -#: erpnext/manufacturing/doctype/work_order/work_order.js:858 -#: erpnext/manufacturing/doctype/work_order/work_order.js:867 +#: erpnext/manufacturing/doctype/work_order/work_order.js:853 +#: erpnext/manufacturing/doctype/work_order/work_order.js:868 +#: erpnext/manufacturing/doctype/work_order/work_order.js:877 msgid "Finish" msgstr "إنهاء" @@ -18353,15 +18443,15 @@ msgstr "" msgid "Finished Good Item Quantity" msgstr "" -#: erpnext/controllers/accounts_controller.py:3827 +#: erpnext/controllers/accounts_controller.py:3900 msgid "Finished Good Item is not specified for service item {0}" msgstr "" -#: erpnext/controllers/accounts_controller.py:3844 +#: erpnext/controllers/accounts_controller.py:3917 msgid "Finished Good Item {0} Qty can not be zero" msgstr "" -#: erpnext/controllers/accounts_controller.py:3838 +#: erpnext/controllers/accounts_controller.py:3911 msgid "Finished Good Item {0} must be a sub-contracted item" msgstr "" @@ -18406,7 +18496,7 @@ msgstr "" msgid "Finished Good {0} must be a sub-contracted item." msgstr "" -#: erpnext/setup/doctype/company/company.py:341 +#: erpnext/setup/doctype/company/company.py:377 msgid "Finished Goods" msgstr "السلع تامة الصنع" @@ -18437,7 +18527,6 @@ msgstr "" #. Label of the warehouse (Link) field in DocType 'Production Plan Item' #. Label of the fg_warehouse (Link) field in DocType 'Work Order Operation' #: erpnext/manufacturing/doctype/bom_operation/bom_operation.json -#: erpnext/manufacturing/doctype/manufacturing_settings/manufacturing_settings.js:30 #: erpnext/manufacturing/doctype/production_plan_item/production_plan_item.json #: erpnext/manufacturing/doctype/work_order_operation/work_order_operation.json msgid "Finished Goods Warehouse" @@ -18448,7 +18537,7 @@ msgstr "مستودع البضائع الجاهزة" msgid "Finished Goods based Operating Cost" msgstr "" -#: erpnext/stock/doctype/stock_entry/stock_entry.py:1523 +#: erpnext/stock/doctype/stock_entry/stock_entry.py:1593 msgid "Finished Item {0} does not match with Work Order {1}" msgstr "" @@ -18502,11 +18591,10 @@ msgstr "وقت الاستجابة الأول للمشكلات" msgid "First Response Time for Opportunity" msgstr "وقت الاستجابة الأول للفرصة" -#: erpnext/regional/italy/utils.py:256 +#: erpnext/regional/italy/utils.py:229 msgid "Fiscal Regime is mandatory, kindly set the fiscal regime in the company {0}" msgstr "النظام المالي إلزامي ، يرجى تعيين النظام المالي في الشركة {0}" -#. Label of the fiscal_year (Link) field in DocType 'Budget' #. Name of a DocType #. Label of the fiscal_year (Link) field in DocType 'GL Entry' #. Label of the fiscal_year (Link) field in DocType 'Monthly Distribution' @@ -18516,7 +18604,6 @@ msgstr "النظام المالي إلزامي ، يرجى تعيين النظا #. Certificate' #. Label of the fiscal_year (Link) field in DocType 'Target Detail' #. Label of the fiscal_year (Data) field in DocType 'Stock Ledger Entry' -#: erpnext/accounts/doctype/budget/budget.json #: erpnext/accounts/doctype/fiscal_year/fiscal_year.json #: erpnext/accounts/doctype/gl_entry/gl_entry.json #: erpnext/accounts/doctype/monthly_distribution/monthly_distribution.json @@ -18562,6 +18649,10 @@ msgstr "السنة المالية {0} غير موجودة" msgid "Fiscal Year {0} does not exist" msgstr "السنة المالية {0} غير موجودة" +#: erpnext/accounts/doctype/budget/budget.py:97 +msgid "Fiscal Year {0} is not available for Company {1}." +msgstr "" + #: erpnext/accounts/report/trial_balance/trial_balance.py:43 msgid "Fiscal Year {0} is required" msgstr "السنة المالية {0} مطلوبة" @@ -18586,7 +18677,7 @@ msgstr "الأصول الثابتة" #. Capitalization Asset Item' #. Label of the fixed_asset_account (Link) field in DocType 'Asset Category #. Account' -#: erpnext/assets/doctype/asset/asset.py:772 +#: erpnext/assets/doctype/asset/asset.py:820 #: erpnext/assets/doctype/asset_capitalization_asset_item/asset_capitalization_asset_item.json #: erpnext/assets/doctype/asset_category_account/asset_category_account.json msgid "Fixed Asset Account" @@ -18597,7 +18688,7 @@ msgstr "حساب الأصول الثابتة" msgid "Fixed Asset Defaults" msgstr "" -#: erpnext/stock/doctype/item/item.py:302 +#: erpnext/stock/doctype/item/item.py:304 msgid "Fixed Asset Item must be a non-stock item." msgstr "يجب أن يكون بند الأصول الثابتة عنصرا غير مخزون.
        \\nFixed Asset Item must be a non-stock item." @@ -18612,7 +18703,7 @@ msgstr "سجل الأصول الثابتة" msgid "Fixed Asset Turnover Ratio" msgstr "" -#: erpnext/manufacturing/doctype/bom/bom.py:668 +#: erpnext/manufacturing/doctype/bom/bom.py:679 msgid "Fixed Asset item {0} cannot be used in BOMs." msgstr "" @@ -18690,7 +18781,7 @@ msgstr "اتبع التقويم الأشهر" msgid "Following Material Requests have been raised automatically based on Item's re-order level" msgstr "تم رفع طلبات المواد التالية تلقائيا بناء على مستوى اعادة الطلب للبنود" -#: erpnext/selling/doctype/customer/customer.py:775 +#: erpnext/selling/doctype/customer/customer.py:784 msgid "Following fields are mandatory to create address:" msgstr "الحقول التالية إلزامية لإنشاء العنوان:" @@ -18722,7 +18813,7 @@ msgstr "" msgid "For" msgstr "لأجل" -#: erpnext/public/js/utils/sales_common.js:367 +#: erpnext/public/js/utils/sales_common.js:389 msgid "For 'Product Bundle' items, Warehouse, Serial No and Batch No will be considered from the 'Packing List' table. If Warehouse and Batch No are same for all packing items for any 'Product Bundle' item, those values can be entered in the main Item table, values will be copied to 'Packing List' table." msgstr "لبنود حزمة المنتج والمستودع والرقم المتسلسل ورقم الدفعة ستأخذ بعين الاعتبار من جدول قائمة التغليف. اذا كان للمستودع ورقم الدفعة نفس البند من بنود التغليف لأي بند من حزمة المنتج. هذه القيم يمكن ادخالها في جدول البند الرئيسي. والقيم سيتم نسخها الى جدول قائمة التغليف." @@ -18742,7 +18833,7 @@ msgstr "للشراء" msgid "For Company" msgstr "للشركة" -#: erpnext/stock/doctype/material_request/material_request.js:397 +#: erpnext/stock/doctype/material_request/material_request.js:401 msgid "For Default Supplier (Optional)" msgstr "للمورد الافتراضي (اختياري)" @@ -18751,7 +18842,7 @@ msgstr "للمورد الافتراضي (اختياري)" msgid "For Item" msgstr "" -#: erpnext/controllers/stock_controller.py:1441 +#: erpnext/controllers/stock_controller.py:1546 msgid "For Item {0} cannot be received more than {1} qty against the {2} {3}" msgstr "" @@ -18761,7 +18852,7 @@ msgid "For Job Card" msgstr "" #. Label of the for_operation (Link) field in DocType 'Job Card' -#: erpnext/manufacturing/doctype/job_card/job_card.js:502 +#: erpnext/manufacturing/doctype/job_card/job_card.js:514 #: erpnext/manufacturing/doctype/job_card/job_card.json msgid "For Operation" msgstr "" @@ -18782,7 +18873,7 @@ msgstr "لائحة الأسعار" msgid "For Production" msgstr "للإنتاج" -#: erpnext/stock/doctype/stock_entry/stock_entry.py:721 +#: erpnext/stock/doctype/stock_entry/stock_entry.py:789 msgid "For Quantity (Manufactured Qty) is mandatory" msgstr "للكمية (الكمية المصنعة) إلزامية\\n
        \\nFor Quantity (Manufactured Qty) is mandatory" @@ -18792,7 +18883,7 @@ msgstr "للكمية (الكمية المصنعة) إلزامية\\n
        \\nFor Q msgid "For Raw Materials" msgstr "" -#: erpnext/controllers/accounts_controller.py:1362 +#: erpnext/controllers/accounts_controller.py:1435 msgid "For Return Invoices with Stock effect, '0' qty Items are not allowed. Following rows are affected: {0}" msgstr "" @@ -18810,8 +18901,8 @@ msgstr "للمورد" #: erpnext/manufacturing/doctype/material_request_plan_item/material_request_plan_item.json #: erpnext/manufacturing/doctype/production_plan/production_plan.js:471 #: erpnext/manufacturing/doctype/production_plan/production_plan.json -#: erpnext/selling/doctype/sales_order/sales_order.js:1395 -#: erpnext/stock/doctype/material_request/material_request.js:346 +#: erpnext/selling/doctype/sales_order/sales_order.js:1399 +#: erpnext/stock/doctype/material_request/material_request.js:347 #: erpnext/templates/form_grid/material_request_grid.html:36 msgid "For Warehouse" msgstr "لمستودع" @@ -18820,11 +18911,11 @@ msgstr "لمستودع" msgid "For Work Order" msgstr "" -#: erpnext/controllers/status_updater.py:276 +#: erpnext/controllers/status_updater.py:278 msgid "For an item {0}, quantity must be negative number" msgstr "بالنسبة إلى عنصر {0} ، يجب أن تكون الكمية رقمًا سالبًا" -#: erpnext/controllers/status_updater.py:273 +#: erpnext/controllers/status_updater.py:275 msgid "For an item {0}, quantity must be positive number" msgstr "بالنسبة إلى عنصر {0} ، يجب أن تكون الكمية رقمًا موجبًا" @@ -18854,11 +18945,11 @@ msgstr "عن مورد فردي" msgid "For item {0}, only {1} asset have been created or linked to {2}. Please create or link {3} more asset with the respective document." msgstr "" -#: erpnext/controllers/status_updater.py:281 +#: erpnext/controllers/status_updater.py:283 msgid "For item {0}, rate must be a positive number. To Allow negative rates, enable {1} in {2}" msgstr "" -#: erpnext/manufacturing/doctype/work_order/work_order.py:2488 +#: erpnext/manufacturing/doctype/work_order/work_order.py:2529 msgid "For operation {0}: Quantity ({1}) can not be greater than pending quantity({2})" msgstr "" @@ -18875,7 +18966,7 @@ msgstr "" msgid "For projected and forecast quantities, the system will consider all child warehouses under the selected parent warehouse." msgstr "" -#: erpnext/stock/doctype/stock_entry/stock_entry.py:1555 +#: erpnext/stock/doctype/stock_entry/stock_entry.py:1625 msgid "For quantity {0} should not be greater than allowed quantity {1}" msgstr "" @@ -18884,12 +18975,12 @@ msgstr "" msgid "For reference" msgstr "للرجوع إليها" -#: erpnext/accounts/doctype/payment_entry/payment_entry.js:1534 +#: erpnext/accounts/doctype/payment_entry/payment_entry.js:1533 #: erpnext/public/js/controllers/accounts.js:204 msgid "For row {0} in {1}. To include {2} in Item rate, rows {3} must also be included" msgstr "" -#: erpnext/manufacturing/doctype/production_plan/production_plan.py:1677 +#: erpnext/manufacturing/doctype/production_plan/production_plan.py:1684 msgid "For row {0}: Enter Planned Qty" msgstr "بالنسبة إلى الصف {0}: أدخل الكمية المخطط لها" @@ -18908,20 +18999,20 @@ msgstr "بالنسبة لشرط "تطبيق القاعدة على أخرى& msgid "For the convenience of customers, these codes can be used in print formats like Invoices and Delivery Notes" msgstr "" -#: erpnext/stock/doctype/stock_entry/stock_entry.py:861 +#: erpnext/stock/doctype/stock_entry/stock_entry.py:929 msgid "For the item {0}, the quantity should be {1} according to the BOM {2}." msgstr "" -#: erpnext/public/js/controllers/transaction.js:1282 +#: erpnext/public/js/controllers/transaction.js:1290 msgctxt "Clear payment terms template and/or payment schedule when due date is changed" msgid "For the new {0} to take effect, would you like to clear the current {1}?" msgstr "" -#: erpnext/controllers/stock_controller.py:399 +#: erpnext/controllers/stock_controller.py:401 msgid "For the {0}, no stock is available for the return in the warehouse {1}." msgstr "" -#: erpnext/controllers/sales_and_purchase_return.py:1122 +#: erpnext/controllers/sales_and_purchase_return.py:1123 msgid "For the {0}, the quantity is required to make the return entry" msgstr "" @@ -19030,7 +19121,7 @@ msgstr "" msgid "Free item code is not selected" msgstr "لم يتم تحديد رمز العنصر المجاني" -#: erpnext/accounts/doctype/pricing_rule/utils.py:651 +#: erpnext/accounts/doctype/pricing_rule/utils.py:654 msgid "Free item not set in the pricing rule {0}" msgstr "عنصر حر غير مضبوط في قاعدة التسعير {0}" @@ -19071,6 +19162,11 @@ msgstr "اقرأ المقالات بشكل متكرر" msgid "From BOM" msgstr "من BOM" +#: erpnext/manufacturing/report/bom_stock_calculated/bom_stock_calculated.py:63 +#: erpnext/manufacturing/report/bom_stock_report/bom_stock_report.py:25 +msgid "From BOM No" +msgstr "" + #. Label of the from_company (Data) field in DocType 'Warranty Claim' #: erpnext/support/doctype/warranty_claim/warranty_claim.json msgid "From Company" @@ -19115,14 +19211,14 @@ msgstr "من التاريخ والوقت تكمن في السنة المالية msgid "From Date cannot be greater than To Date" msgstr "(من تاريخ) لا يمكن أن يكون أكبر (الي التاريخ)" -#: erpnext/crm/report/sales_pipeline_analytics/sales_pipeline_analytics.py:26 +#: erpnext/crm/report/sales_pipeline_analytics/sales_pipeline_analytics.py:27 msgid "From Date is mandatory" msgstr "" #: erpnext/accounts/report/customer_ledger_summary/customer_ledger_summary.py:53 #: erpnext/accounts/report/general_ledger/general_ledger.py:86 #: erpnext/accounts/report/pos_register/pos_register.py:115 -#: erpnext/accounts/report/tax_withholding_details/tax_withholding_details.py:39 +#: erpnext/accounts/report/tax_withholding_details/tax_withholding_details.py:41 #: erpnext/accounts/report/tds_computation_summary/tds_computation_summary.py:41 #: erpnext/stock/report/batch_wise_balance_history/batch_wise_balance_history.py:34 #: erpnext/stock/report/cogs_by_item_group/cogs_by_item_group.py:38 @@ -19175,10 +19271,16 @@ msgstr "" msgid "From External Ecomm Platform" msgstr "" +#. Label of the from_fiscal_year (Link) field in DocType 'Budget' +#: erpnext/accounts/doctype/budget/budget.json #: erpnext/accounts/report/budget_variance_report/budget_variance_report.js:43 msgid "From Fiscal Year" msgstr "من السنة المالية" +#: erpnext/accounts/doctype/budget/budget.py:110 +msgid "From Fiscal Year cannot be greater than To Fiscal Year" +msgstr "" + #. Label of the from_folio_no (Data) field in DocType 'Share Transfer' #: erpnext/accounts/doctype/share_transfer/share_transfer.json msgid "From Folio No" @@ -19501,7 +19603,7 @@ msgstr "الدفع في المستقبل المرجع" msgid "Future Payments" msgstr "المدفوعات المستقبلية" -#: erpnext/assets/doctype/asset/depreciation.py:378 +#: erpnext/assets/doctype/asset/depreciation.py:380 msgid "Future date is not allowed" msgstr "" @@ -19521,7 +19623,7 @@ msgstr "" #. Name of a DocType #: erpnext/accounts/doctype/gl_entry/gl_entry.json -#: erpnext/accounts/report/general_ledger/general_ledger.py:664 +#: erpnext/accounts/report/general_ledger/general_ledger.py:671 msgid "GL Entry" msgstr "GL الدخول" @@ -19578,7 +19680,7 @@ msgstr "" #: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:134 #: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:220 -#: erpnext/setup/doctype/company/company.py:632 +#: erpnext/setup/doctype/company/company.py:673 msgid "Gain/Loss on Asset Disposal" msgstr "الربح / الخسارة عند التخلص من الأصول" @@ -19620,13 +19722,11 @@ msgstr "" #. Option for the 'Report' (Select) field in DocType 'Process Statement Of #. Accounts' #. Name of a report -#. Label of a shortcut in the Accounting Workspace #. Label of a Link in the Financial Reports Workspace #: erpnext/accounts/doctype/account/account.js:92 #: erpnext/accounts/doctype/accounts_settings/accounts_settings.json #: erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.json #: erpnext/accounts/report/general_ledger/general_ledger.json -#: erpnext/accounts/workspace/accounting/accounting.json #: erpnext/accounts/workspace/financial_reports/financial_reports.json msgid "General Ledger" msgstr "دفتر الأستاذ العام" @@ -19696,7 +19796,7 @@ msgstr "" msgid "Generated" msgstr "" -#: erpnext/manufacturing/doctype/master_production_schedule/master_production_schedule.js:46 +#: erpnext/manufacturing/doctype/master_production_schedule/master_production_schedule.js:56 msgid "Generating Master Production Schedule..." msgstr "" @@ -19741,7 +19841,7 @@ msgstr "" msgid "Get Current Stock" msgstr "الحصول على المخزون الحالي" -#: erpnext/selling/doctype/customer/customer.js:186 +#: erpnext/selling/doctype/customer/customer.js:189 msgid "Get Customer Group Details" msgstr "" @@ -19781,14 +19881,14 @@ msgid "Get Item Locations" msgstr "الحصول على مواقع البند" #. Label of the get_items_from (Select) field in DocType 'Production Plan' -#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js:165 -#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js:190 -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.js:287 -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.js:319 -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.js:353 -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.js:1106 -#: erpnext/buying/doctype/purchase_order/purchase_order.js:602 -#: erpnext/buying/doctype/purchase_order/purchase_order.js:625 +#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js:166 +#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js:191 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.js:288 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.js:320 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.js:354 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.js:1107 +#: erpnext/buying/doctype/purchase_order/purchase_order.js:603 +#: erpnext/buying/doctype/purchase_order/purchase_order.js:626 #: erpnext/buying/doctype/request_for_quotation/request_for_quotation.js:366 #: erpnext/buying/doctype/request_for_quotation/request_for_quotation.js:388 #: erpnext/buying/doctype/request_for_quotation/request_for_quotation.js:433 @@ -19802,18 +19902,18 @@ msgstr "الحصول على مواقع البند" #: erpnext/public/js/controllers/buying.js:327 #: erpnext/selling/doctype/quotation/quotation.js:167 #: erpnext/selling/doctype/sales_order/sales_order.js:196 -#: erpnext/selling/doctype/sales_order/sales_order.js:1196 -#: erpnext/stock/doctype/delivery_note/delivery_note.js:190 -#: erpnext/stock/doctype/delivery_note/delivery_note.js:242 -#: erpnext/stock/doctype/material_request/material_request.js:128 -#: erpnext/stock/doctype/material_request/material_request.js:223 -#: erpnext/stock/doctype/purchase_receipt/purchase_receipt.js:160 -#: erpnext/stock/doctype/purchase_receipt/purchase_receipt.js:267 -#: erpnext/stock/doctype/stock_entry/stock_entry.js:328 -#: erpnext/stock/doctype/stock_entry/stock_entry.js:375 -#: erpnext/stock/doctype/stock_entry/stock_entry.js:408 -#: erpnext/stock/doctype/stock_entry/stock_entry.js:495 -#: erpnext/stock/doctype/stock_entry/stock_entry.js:648 +#: erpnext/selling/doctype/sales_order/sales_order.js:1200 +#: erpnext/stock/doctype/delivery_note/delivery_note.js:191 +#: erpnext/stock/doctype/delivery_note/delivery_note.js:243 +#: erpnext/stock/doctype/material_request/material_request.js:129 +#: erpnext/stock/doctype/material_request/material_request.js:224 +#: erpnext/stock/doctype/purchase_receipt/purchase_receipt.js:151 +#: erpnext/stock/doctype/purchase_receipt/purchase_receipt.js:241 +#: erpnext/stock/doctype/stock_entry/stock_entry.js:333 +#: erpnext/stock/doctype/stock_entry/stock_entry.js:380 +#: erpnext/stock/doctype/stock_entry/stock_entry.js:413 +#: erpnext/stock/doctype/stock_entry/stock_entry.js:500 +#: erpnext/stock/doctype/stock_entry/stock_entry.js:661 #: erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.js:164 msgid "Get Items From" msgstr "الحصول على البنود من" @@ -19828,9 +19928,9 @@ msgstr "" msgid "Get Items for Purchase Only" msgstr "" -#: erpnext/stock/doctype/material_request/material_request.js:331 -#: erpnext/stock/doctype/stock_entry/stock_entry.js:684 +#: erpnext/stock/doctype/material_request/material_request.js:332 #: erpnext/stock/doctype/stock_entry/stock_entry.js:697 +#: erpnext/stock/doctype/stock_entry/stock_entry.js:710 msgid "Get Items from BOM" msgstr "تنزيل الاصناف من BOM" @@ -19861,8 +19961,8 @@ msgstr "الحصول على المواد طلب" #. Label of the get_material_requests (Button) field in DocType 'Master #. Production Schedule' -#: erpnext/manufacturing/doctype/master_production_schedule/master_production_schedule.js:171 -#: erpnext/manufacturing/doctype/master_production_schedule/master_production_schedule.js:173 +#: erpnext/manufacturing/doctype/master_production_schedule/master_production_schedule.js:181 +#: erpnext/manufacturing/doctype/master_production_schedule/master_production_schedule.js:183 #: erpnext/manufacturing/doctype/master_production_schedule/master_production_schedule.json msgid "Get Material Requests" msgstr "" @@ -19902,8 +20002,8 @@ msgstr "" #. Label of the get_sales_orders (Button) field in DocType 'Master Production #. Schedule' #. Label of the get_sales_orders (Button) field in DocType 'Production Plan' -#: erpnext/manufacturing/doctype/master_production_schedule/master_production_schedule.js:118 -#: erpnext/manufacturing/doctype/master_production_schedule/master_production_schedule.js:120 +#: erpnext/manufacturing/doctype/master_production_schedule/master_production_schedule.js:128 +#: erpnext/manufacturing/doctype/master_production_schedule/master_production_schedule.js:130 #: erpnext/manufacturing/doctype/master_production_schedule/master_production_schedule.json #: erpnext/manufacturing/doctype/production_plan/production_plan.json msgid "Get Sales Orders" @@ -19930,7 +20030,7 @@ msgstr "" msgid "Get Sub Assembly Items" msgstr "" -#: erpnext/buying/doctype/supplier/supplier.js:113 +#: erpnext/buying/doctype/supplier/supplier.js:115 msgid "Get Supplier Group Details" msgstr "" @@ -19943,7 +20043,7 @@ msgstr "الحصول على الموردين" msgid "Get Suppliers By" msgstr "الحصول على الموردين من قبل" -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.js:1102 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.js:1103 msgid "Get Timesheets" msgstr "" @@ -19979,7 +20079,6 @@ msgid "Give free item for every N quantity" msgstr "" #. Name of a DocType -#. Label of a Link in the Settings Workspace #. Label of a shortcut in the Settings Workspace #: erpnext/setup/doctype/global_defaults/global_defaults.json #: erpnext/setup/workspace/settings/settings.json @@ -20005,7 +20104,7 @@ msgstr "" msgid "Goods" msgstr "" -#: erpnext/setup/doctype/company/company.py:342 +#: erpnext/setup/doctype/company/company.py:378 #: erpnext/stock/doctype/stock_entry/stock_entry_list.js:21 msgid "Goods In Transit" msgstr "البضائع في العبور" @@ -20014,7 +20113,7 @@ msgstr "البضائع في العبور" msgid "Goods Transferred" msgstr "نقل البضائع" -#: erpnext/stock/doctype/stock_entry/stock_entry.py:2070 +#: erpnext/stock/doctype/stock_entry/stock_entry.py:2144 msgid "Goods are already received against the outward entry {0}" msgstr "تم استلام البضائع بالفعل مقابل الإدخال الخارجي {0}" @@ -20135,7 +20234,7 @@ msgstr "" #: erpnext/accounts/report/pos_register/pos_register.py:202 #: erpnext/accounts/report/purchase_register/purchase_register.py:275 #: erpnext/accounts/report/sales_register/sales_register.py:305 -#: erpnext/accounts/report/tax_withholding_details/tax_withholding_details.py:259 +#: erpnext/accounts/report/tax_withholding_details/tax_withholding_details.py:273 #: erpnext/buying/doctype/purchase_order/purchase_order.json #: erpnext/buying/doctype/supplier_quotation/supplier_quotation.json #: erpnext/manufacturing/doctype/production_plan_sales_order/production_plan_sales_order.json @@ -20318,7 +20417,7 @@ msgstr "التجميع حسب طلب المبيعات" msgid "Group by Voucher" msgstr "المجموعة بواسطة قسيمة" -#: erpnext/stock/utils.py:440 +#: erpnext/stock/utils.py:444 msgid "Group node warehouse is not allowed to select for transactions" msgstr "لا يسمح مستودع عقدة مجموعة لتحديد للمعاملات" @@ -20380,10 +20479,12 @@ msgstr "مدير الموارد البشرية" msgid "HR User" msgstr "مستخدم الموارد البشرية" +#. Option for the 'Distribution Frequency' (Select) field in DocType 'Budget' +#: erpnext/accounts/doctype/budget/budget.json #: erpnext/accounts/report/budget_variance_report/budget_variance_report.js:64 #: erpnext/accounts/report/deferred_revenue_and_expense/deferred_revenue_and_expense.js:77 #: erpnext/manufacturing/report/exponential_smoothing_forecasting/exponential_smoothing_forecasting.js:59 -#: erpnext/public/js/financial_statements.js:353 +#: erpnext/public/js/financial_statements.js:364 #: erpnext/public/js/purchase_trends_filters.js:21 #: erpnext/public/js/sales_trends_filters.js:13 #: erpnext/selling/report/sales_partner_target_variance_based_on_item_group/sales_partner_target_variance_based_on_item_group.js:34 @@ -20457,6 +20558,12 @@ msgstr "تاريخ انتهاء الصلاحية" msgid "Has Item Scanned" msgstr "" +#. Label of the has_operating_cost (Check) field in DocType 'Landed Cost Taxes +#. and Charges' +#: erpnext/stock/doctype/landed_cost_taxes_and_charges/landed_cost_taxes_and_charges.json +msgid "Has Operating Cost" +msgstr "" + #. Label of the has_print_format (Check) field in DocType 'Cheque Print #. Template' #: erpnext/accounts/doctype/cheque_print_template/cheque_print_template.json @@ -20582,11 +20689,11 @@ msgstr "نص المساعدة" msgid "Helps you distribute the Budget/Target across months if you have seasonality in your business." msgstr "" -#: erpnext/assets/doctype/asset/depreciation.py:345 +#: erpnext/assets/doctype/asset/depreciation.py:347 msgid "Here are the error logs for the aforementioned failed depreciation entries: {0}" msgstr "" -#: erpnext/stock/stock_ledger.py:1993 +#: erpnext/stock/stock_ledger.py:2030 msgid "Here are the options to proceed:" msgstr "" @@ -20614,7 +20721,7 @@ msgstr "" msgid "Hertz" msgstr "" -#: erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py:444 +#: erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py:518 msgid "Hi," msgstr "" @@ -20680,14 +20787,14 @@ msgstr "الرقم الأعلى له أولوية أكبر" msgid "History In Company" msgstr "الحركة التاريخيه في الشركة" -#: erpnext/buying/doctype/purchase_order/purchase_order.js:379 -#: erpnext/selling/doctype/sales_order/sales_order.js:985 +#: erpnext/buying/doctype/purchase_order/purchase_order.js:380 +#: erpnext/selling/doctype/sales_order/sales_order.js:989 msgid "Hold" msgstr "معلق" #. Label of the sb_14 (Section Break) field in DocType 'Purchase Invoice' #. Label of the on_hold (Check) field in DocType 'Purchase Invoice' -#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js:97 +#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js:98 #: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json msgid "Hold Invoice" msgstr "عقد الفاتورة" @@ -20702,7 +20809,7 @@ msgstr "نوع التعليق" msgid "Holiday" msgstr "عطلة" -#: erpnext/setup/doctype/holiday_list/holiday_list.py:153 +#: erpnext/setup/doctype/holiday_list/holiday_list.py:162 msgid "Holiday Date {0} added multiple times" msgstr "" @@ -20814,7 +20921,7 @@ msgstr "" msgid "Hrs" msgstr "ساعات" -#: erpnext/setup/doctype/company/company.py:448 +#: erpnext/setup/doctype/company/company.py:484 msgid "Human Resources" msgstr "الموارد البشرية" @@ -21157,7 +21264,7 @@ msgstr "" msgid "If no taxes are set, and Taxes and Charges Template is selected, the system will automatically apply the taxes from the chosen template." msgstr "" -#: erpnext/stock/stock_ledger.py:2003 +#: erpnext/stock/stock_ledger.py:2040 msgid "If not, you can Cancel / Submit this entry" msgstr "" @@ -21177,7 +21284,7 @@ msgstr "" msgid "If set, the system does not use the user's Email or the standard outgoing Email account for sending request for quotations." msgstr "" -#: erpnext/manufacturing/doctype/work_order/work_order.js:1171 +#: erpnext/manufacturing/doctype/work_order/work_order.js:1166 msgid "If the BOM results in Scrap material, the Scrap Warehouse needs to be selected." msgstr "" @@ -21186,11 +21293,17 @@ msgstr "" msgid "If the account is frozen, entries are allowed to restricted users." msgstr "إذا الحساب مجمد، يسمح بالدخول إلى المستخدمين المحددين." -#: erpnext/stock/stock_ledger.py:1996 +#: erpnext/stock/stock_ledger.py:2033 msgid "If the item is transacting as a Zero Valuation Rate item in this entry, please enable 'Allow Zero Valuation Rate' in the {0} Item table." msgstr "إذا كان العنصر يتعامل كعنصر سعر تقييم صفري في هذا الإدخال ، فالرجاء تمكين "السماح بمعدل تقييم صفري" في جدول العناصر {0}." -#: erpnext/manufacturing/doctype/work_order/work_order.js:1190 +#. Description of the 'Projected On Hand' (Float) field in DocType 'Material +#. Request Item' +#: erpnext/stock/doctype/material_request_item/material_request_item.json +msgid "If the reorder check is set at the Group warehouse level, the available quantity becomes the sum of the projected quantities of all its child warehouses." +msgstr "" + +#: erpnext/manufacturing/doctype/work_order/work_order.js:1185 msgid "If the selected BOM has Operations mentioned in it, the system will fetch all Operations from BOM, these values can be changed." msgstr "" @@ -21249,7 +21362,7 @@ msgstr "إذا تم تكوين هذا الخيار "نعم" ، سيم msgid "If ticked, multiple materials can be used for a single Work Order. This is useful if one or more time consuming products are being manufactured." msgstr "إذا تم تحديده ، يمكن استخدام مواد متعددة لطلب عمل واحد. يكون هذا مفيدًا إذا تم تصنيع منتج أو أكثر من المنتجات التي تستغرق وقتًا طويلاً." -#: erpnext/manufacturing/doctype/manufacturing_settings/manufacturing_settings.js:36 +#: erpnext/manufacturing/doctype/manufacturing_settings/manufacturing_settings.js:24 msgid "If ticked, the BOM cost will be automatically updated based on Valuation Rate / Price List Rate / last purchase rate of raw materials." msgstr "إذا تم تحديدها ، فسيتم تحديث تكلفة قائمة مكونات الصنف تلقائيًا استنادًا إلى معدل التقييم / سعر قائمة الأسعار / معدل الشراء الأخير للمواد الخام." @@ -21267,7 +21380,7 @@ msgstr "" msgid "If yes, then this warehouse will be used to store rejected materials" msgstr "" -#: erpnext/stock/doctype/item/item.js:1027 +#: erpnext/stock/doctype/item/item.js:1046 msgid "If you are maintaining stock of this Item in your Inventory, ERPNext will make a stock ledger entry for each transaction of this item." msgstr "" @@ -21281,15 +21394,15 @@ msgstr "" msgid "If you still want to proceed, please disable 'Skip Available Sub Assembly Items' checkbox." msgstr "" -#: erpnext/manufacturing/doctype/production_plan/production_plan.py:1793 +#: erpnext/manufacturing/doctype/production_plan/production_plan.py:1799 msgid "If you still want to proceed, please enable {0}." msgstr "" -#: erpnext/accounts/doctype/pricing_rule/utils.py:373 +#: erpnext/accounts/doctype/pricing_rule/utils.py:376 msgid "If you {0} {1} quantities of the item {2}, the scheme {3} will be applied on the item." msgstr "إذا قمت {0} {1} بكميات العنصر {2} ، فسيتم تطبيق المخطط {3} على العنصر." -#: erpnext/accounts/doctype/pricing_rule/utils.py:378 +#: erpnext/accounts/doctype/pricing_rule/utils.py:381 msgid "If you {0} {1} worth item {2}, the scheme {3} will be applied on the item." msgstr "إذا كنت {0} {1} تستحق العنصر {2} ، فسيتم تطبيق النظام {3} على العنصر." @@ -21349,11 +21462,11 @@ msgstr "" msgid "Ignore Exchange Rate Revaluation and Gain / Loss Journals" msgstr "" -#: erpnext/selling/doctype/sales_order/sales_order.js:1378 +#: erpnext/selling/doctype/sales_order/sales_order.js:1382 msgid "Ignore Existing Ordered Qty" msgstr "تجاهل الكمية الموجودة المطلوبة" -#: erpnext/manufacturing/doctype/production_plan/production_plan.py:1785 +#: erpnext/manufacturing/doctype/production_plan/production_plan.py:1791 msgid "Ignore Existing Projected Quantity" msgstr "تجاهل الكمية الموجودة المتوقعة" @@ -21439,6 +21552,13 @@ msgstr "" msgid "Import Chart of Accounts from a csv file" msgstr "" +#. Label of a Link in the Home Workspace +#. Label of a Link in the Settings Workspace +#: erpnext/setup/workspace/home/home.json +#: erpnext/setup/workspace/settings/settings.json +msgid "Import Data" +msgstr "" + #: erpnext/edi/doctype/code_list/code_list.js:7 #: erpnext/edi/doctype/code_list/code_list_list.js:3 #: erpnext/edi/doctype/common_code/common_code_list.js:3 @@ -21544,7 +21664,7 @@ msgstr "" #: erpnext/manufacturing/report/bom_stock_report/bom_stock_report.html:12 #: erpnext/manufacturing/report/bom_stock_report/bom_stock_report.html:22 -#: erpnext/manufacturing/report/bom_stock_report/bom_stock_report.py:28 +#: erpnext/manufacturing/report/bom_stock_report/bom_stock_report.py:29 msgid "In Stock Qty" msgstr "في سوق الأسهم الكمية" @@ -21557,11 +21677,11 @@ msgstr "في سوق الأسهم الكمية" msgid "In Transit" msgstr "في مرحلة انتقالية" -#: erpnext/stock/doctype/material_request/material_request.js:481 +#: erpnext/stock/doctype/material_request/material_request.js:485 msgid "In Transit Transfer" msgstr "" -#: erpnext/stock/doctype/material_request/material_request.js:450 +#: erpnext/stock/doctype/material_request/material_request.js:454 msgid "In Transit Warehouse" msgstr "" @@ -21669,7 +21789,7 @@ msgstr "في المخزن" msgid "In the case of multi-tier program, Customers will be auto assigned to the concerned tier as per their spent" msgstr "" -#: erpnext/stock/doctype/item/item.js:1060 +#: erpnext/stock/doctype/item/item.js:1079 msgid "In this section, you can define Company-wide transaction-related defaults for this Item. Eg. Default Warehouse, Default Price List, Supplier, etc." msgstr "" @@ -21779,7 +21899,7 @@ msgstr "" #: erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json #: erpnext/buying/doctype/purchase_order_item/purchase_order_item.json #: erpnext/manufacturing/doctype/production_plan_item/production_plan_item.json -#: erpnext/selling/doctype/sales_order/sales_order.js:1374 +#: erpnext/selling/doctype/sales_order/sales_order.js:1378 #: erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json #: erpnext/subcontracting/doctype/subcontracting_inward_order_item/subcontracting_inward_order_item.json #: erpnext/subcontracting/doctype/subcontracting_order_item/subcontracting_order_item.json @@ -21814,7 +21934,7 @@ msgstr "تشمل الاصناف الغير مخزنية" msgid "Include POS Transactions" msgstr "تشمل معاملات نقطه البيع" -#: erpnext/accounts/doctype/pos_invoice/pos_invoice.py:194 +#: erpnext/accounts/doctype/pos_invoice/pos_invoice.py:204 msgid "Include Payment" msgstr "" @@ -21892,10 +22012,10 @@ msgstr "بما في ذلك السلع للمجموعات الفرعية" #. Accounting' #: erpnext/accounts/doctype/account/account.json #: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:140 -#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:235 +#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:236 #: erpnext/accounts/doctype/ledger_merge/ledger_merge.json #: erpnext/accounts/doctype/process_deferred_accounting/process_deferred_accounting.json -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:465 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:414 #: erpnext/accounts/report/account_balance/account_balance.js:27 #: erpnext/accounts/report/financial_statements.py:776 #: erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.py:182 @@ -21917,7 +22037,7 @@ msgstr "الإيرادات" #: erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json #: erpnext/accounts/report/account_balance/account_balance.js:53 #: erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.js:77 -#: erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py:301 +#: erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py:290 msgid "Income Account" msgstr "حساب الدخل" @@ -21965,19 +22085,19 @@ msgstr "" msgid "Incorrect Balance Qty After Transaction" msgstr "" -#: erpnext/controllers/subcontracting_controller.py:1006 +#: erpnext/controllers/subcontracting_controller.py:1037 msgid "Incorrect Batch Consumed" msgstr "" -#: erpnext/stock/doctype/item/item.py:513 +#: erpnext/stock/doctype/item/item.py:532 msgid "Incorrect Check in (group) Warehouse for Reorder" msgstr "" -#: erpnext/stock/doctype/stock_entry/stock_entry.py:866 +#: erpnext/stock/doctype/stock_entry/stock_entry.py:934 msgid "Incorrect Component Quantity" msgstr "" -#: erpnext/assets/doctype/asset/asset.py:325 +#: erpnext/assets/doctype/asset/asset.py:326 #: erpnext/assets/doctype/asset_value_adjustment/asset_value_adjustment.py:56 msgid "Incorrect Date" msgstr "تاريخ غير صحيح" @@ -21999,7 +22119,7 @@ msgstr "" msgid "Incorrect Serial No Valuation" msgstr "" -#: erpnext/controllers/subcontracting_controller.py:1019 +#: erpnext/controllers/subcontracting_controller.py:1050 msgid "Incorrect Serial Number Consumed" msgstr "" @@ -22077,12 +22197,6 @@ msgstr "لا يمكن أن تكون الزيادة 0\\n
        \\nIncrement cannot b msgid "Increment for Attribute {0} cannot be 0" msgstr "الاضافة للخاصية {0} لا يمكن أن تكون 0" -#. Label of the indent (Int) field in DocType 'Production Plan Sub Assembly -#. Item' -#: erpnext/manufacturing/doctype/production_plan_sub_assembly_item/production_plan_sub_assembly_item.json -msgid "Indent" -msgstr "" - #. Label of the indentation_level (Int) field in DocType 'Financial Report Row' #: erpnext/accounts/doctype/financial_report_row/financial_report_row.json msgid "Indent Level" @@ -22112,7 +22226,7 @@ msgstr "نفقات غير مباشرة" #. Option for the 'Account Type' (Select) field in DocType 'Account' #: erpnext/accounts/doctype/account/account.json #: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:145 -#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:241 +#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:242 msgid "Indirect Income" msgstr "دخل غير مباشرة" @@ -22128,7 +22242,7 @@ msgstr "فرد" msgid "Individual GL Entry cannot be cancelled." msgstr "" -#: erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py:343 +#: erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py:347 msgid "Individual Stock Ledger Entry cannot be cancelled." msgstr "" @@ -22180,13 +22294,13 @@ msgstr "بدأت" msgid "Inspected By" msgstr "تفتيش من قبل" -#: erpnext/controllers/stock_controller.py:1335 +#: erpnext/controllers/stock_controller.py:1440 msgid "Inspection Rejected" msgstr "" #. Label of the inspection_required (Check) field in DocType 'Stock Entry' -#: erpnext/controllers/stock_controller.py:1305 -#: erpnext/controllers/stock_controller.py:1307 +#: erpnext/controllers/stock_controller.py:1410 +#: erpnext/controllers/stock_controller.py:1412 #: erpnext/stock/doctype/stock_entry/stock_entry.json msgid "Inspection Required" msgstr "التفتيش مطلوب" @@ -22203,7 +22317,7 @@ msgstr "التفتيش المطلوبة قبل تسليم" msgid "Inspection Required before Purchase" msgstr "التفتيش المطلوبة قبل الشراء" -#: erpnext/controllers/stock_controller.py:1320 +#: erpnext/controllers/stock_controller.py:1425 msgid "Inspection Submission" msgstr "" @@ -22223,7 +22337,7 @@ msgstr "تثبيت تاريخ" #. 'Installation Note' #. Label of a Link in the Stock Workspace #: erpnext/selling/doctype/installation_note/installation_note.json -#: erpnext/stock/doctype/delivery_note/delivery_note.js:263 +#: erpnext/stock/doctype/delivery_note/delivery_note.js:264 #: erpnext/stock/workspace/stock/stock.json msgid "Installation Note" msgstr "ملاحظة التثبيت" @@ -22233,7 +22347,7 @@ msgstr "ملاحظة التثبيت" msgid "Installation Note Item" msgstr "ملاحظة تثبيت الإغلاق" -#: erpnext/stock/doctype/delivery_note/delivery_note.py:627 +#: erpnext/stock/doctype/delivery_note/delivery_note.py:631 msgid "Installation Note {0} has already been submitted" msgstr "مذكرة التسليم {0} ارسلت\\n
        \\nInstallation Note {0} has already been submitted" @@ -22267,29 +22381,34 @@ msgstr "تثبيت الإعدادات المسبقة" msgid "Instruction" msgstr "" -#: erpnext/stock/doctype/putaway_rule/putaway_rule.py:81 -#: erpnext/stock/doctype/putaway_rule/putaway_rule.py:313 +#: erpnext/stock/doctype/putaway_rule/putaway_rule.py:82 +#: erpnext/stock/doctype/putaway_rule/putaway_rule.py:325 msgid "Insufficient Capacity" msgstr "" -#: erpnext/controllers/accounts_controller.py:3752 -#: erpnext/controllers/accounts_controller.py:3776 +#: erpnext/controllers/accounts_controller.py:3825 +#: erpnext/controllers/accounts_controller.py:3849 msgid "Insufficient Permissions" msgstr "أذونات غير كافية" +#: erpnext/accounts/doctype/pos_invoice/pos_invoice.py:462 #: erpnext/stock/doctype/pick_list/pick_list.py:120 #: erpnext/stock/doctype/pick_list/pick_list.py:138 -#: erpnext/stock/doctype/pick_list/pick_list.py:1009 -#: erpnext/stock/doctype/stock_entry/stock_entry.py:841 -#: erpnext/stock/serial_batch_bundle.py:1186 erpnext/stock/stock_ledger.py:1679 -#: erpnext/stock/stock_ledger.py:2165 +#: erpnext/stock/doctype/pick_list/pick_list.py:1016 +#: erpnext/stock/doctype/stock_entry/stock_entry.py:909 +#: erpnext/stock/serial_batch_bundle.py:1186 erpnext/stock/stock_ledger.py:1714 +#: erpnext/stock/stock_ledger.py:2202 msgid "Insufficient Stock" msgstr "المالية غير كافية" -#: erpnext/stock/stock_ledger.py:2180 +#: erpnext/stock/stock_ledger.py:2217 msgid "Insufficient Stock for Batch" msgstr "" +#: erpnext/accounts/doctype/pos_invoice/pos_invoice.py:440 +msgid "Insufficient Stock for Product Bundle Items" +msgstr "" + #. Label of the insurance_details_tab (Tab Break) field in DocType 'Asset' #: erpnext/assets/doctype/asset/asset.json msgid "Insurance" @@ -22375,7 +22494,7 @@ msgstr "انتر دخول الشركة مجلة الدخول" msgid "Inter Company Order Reference" msgstr "مرجع طلب شركة Inter" -#: erpnext/selling/doctype/sales_order/sales_order.js:1133 +#: erpnext/selling/doctype/sales_order/sales_order.js:1137 msgid "Inter Company Purchase Order" msgstr "" @@ -22387,7 +22506,7 @@ msgstr "" msgid "Inter Company Reference" msgstr "بين شركة مرجع" -#: erpnext/buying/doctype/purchase_order/purchase_order.js:485 +#: erpnext/buying/doctype/purchase_order/purchase_order.js:486 msgid "Inter Company Sales Order" msgstr "" @@ -22414,16 +22533,16 @@ msgid "Interest Expense" msgstr "" #: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:146 -#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:242 +#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:243 msgid "Interest Income" msgstr "" -#: erpnext/accounts/doctype/payment_entry/payment_entry.py:3052 +#: erpnext/accounts/doctype/payment_entry/payment_entry.py:3053 msgid "Interest and/or dunning fee" msgstr "" #: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:147 -#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:243 +#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:244 msgid "Interest on Fixed Deposits" msgstr "" @@ -22443,23 +22562,23 @@ msgstr "" msgid "Internal Customer" msgstr "" -#: erpnext/selling/doctype/customer/customer.py:223 +#: erpnext/selling/doctype/customer/customer.py:224 msgid "Internal Customer for company {0} already exists" msgstr "" -#: erpnext/selling/doctype/sales_order/sales_order.js:1132 +#: erpnext/selling/doctype/sales_order/sales_order.js:1136 msgid "Internal Purchase Order" msgstr "" -#: erpnext/controllers/accounts_controller.py:733 +#: erpnext/controllers/accounts_controller.py:803 msgid "Internal Sale or Delivery Reference missing." msgstr "" -#: erpnext/buying/doctype/purchase_order/purchase_order.js:484 +#: erpnext/buying/doctype/purchase_order/purchase_order.js:485 msgid "Internal Sales Order" msgstr "" -#: erpnext/controllers/accounts_controller.py:735 +#: erpnext/controllers/accounts_controller.py:805 msgid "Internal Sales Reference Missing" msgstr "" @@ -22490,7 +22609,7 @@ msgstr "" msgid "Internal Transfer" msgstr "نقل داخلي" -#: erpnext/controllers/accounts_controller.py:744 +#: erpnext/controllers/accounts_controller.py:814 msgid "Internal Transfer Reference Missing" msgstr "" @@ -22503,7 +22622,7 @@ msgstr "" msgid "Internal Work History" msgstr "سجل العمل الداخلي" -#: erpnext/controllers/stock_controller.py:1402 +#: erpnext/controllers/stock_controller.py:1507 msgid "Internal transfers can only be done in company's default currency" msgstr "" @@ -22517,19 +22636,19 @@ msgstr "" msgid "Interval should be between 1 to 59 MInutes" msgstr "" -#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:376 -#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:384 -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1044 -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1054 +#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:378 +#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:386 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:993 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1003 #: erpnext/assets/doctype/asset_category/asset_category.py:69 #: erpnext/assets/doctype/asset_category/asset_category.py:97 -#: erpnext/controllers/accounts_controller.py:3126 -#: erpnext/controllers/accounts_controller.py:3134 +#: erpnext/controllers/accounts_controller.py:3199 +#: erpnext/controllers/accounts_controller.py:3207 msgid "Invalid Account" msgstr "حساب غير صالح" #: erpnext/accounts/doctype/payment_entry/payment_entry.py:394 -#: erpnext/accounts/doctype/payment_request/payment_request.py:868 +#: erpnext/accounts/doctype/payment_request/payment_request.py:869 msgid "Invalid Allocated Amount" msgstr "" @@ -22541,7 +22660,7 @@ msgstr "" msgid "Invalid Attribute" msgstr "خاصية غير صالحة" -#: erpnext/controllers/accounts_controller.py:555 +#: erpnext/controllers/accounts_controller.py:625 msgid "Invalid Auto Repeat Date" msgstr "" @@ -22549,7 +22668,7 @@ msgstr "" msgid "Invalid Barcode. There is no Item attached to this barcode." msgstr "الباركود غير صالح. لا يوجد عنصر مرفق بهذا الرمز الشريطي." -#: erpnext/public/js/controllers/transaction.js:3083 +#: erpnext/public/js/controllers/transaction.js:3091 msgid "Invalid Blanket Order for the selected Customer and Item" msgstr "طلب فارغ غير صالح للعميل والعنصر المحدد" @@ -22557,17 +22676,17 @@ msgstr "طلب فارغ غير صالح للعميل والعنصر المحدد msgid "Invalid Child Procedure" msgstr "إجراء الطفل غير صالح" -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:2326 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:2279 msgid "Invalid Company for Inter Company Transaction." msgstr "شركة غير صالحة للمعاملات بين الشركات." -#: erpnext/assets/doctype/asset/asset.py:296 -#: erpnext/assets/doctype/asset/asset.py:303 -#: erpnext/controllers/accounts_controller.py:3149 +#: erpnext/assets/doctype/asset/asset.py:297 +#: erpnext/assets/doctype/asset/asset.py:304 +#: erpnext/controllers/accounts_controller.py:3222 msgid "Invalid Cost Center" msgstr "" -#: erpnext/selling/doctype/sales_order/sales_order.py:403 +#: erpnext/selling/doctype/sales_order/sales_order.py:405 msgid "Invalid Delivery Date" msgstr "" @@ -22575,7 +22694,7 @@ msgstr "" msgid "Invalid Discount" msgstr "" -#: erpnext/controllers/taxes_and_totals.py:738 +#: erpnext/controllers/taxes_and_totals.py:812 msgid "Invalid Discount Amount" msgstr "" @@ -22596,12 +22715,12 @@ msgstr "" msgid "Invalid Group By" msgstr "" -#: erpnext/accounts/doctype/pos_invoice/pos_invoice.py:454 +#: erpnext/accounts/doctype/pos_invoice/pos_invoice.py:499 #: erpnext/manufacturing/doctype/production_plan/production_plan.py:934 msgid "Invalid Item" msgstr "عنصر غير صالح" -#: erpnext/stock/doctype/item/item.py:1405 +#: erpnext/stock/doctype/item/item.py:1408 msgid "Invalid Item Defaults" msgstr "" @@ -22610,12 +22729,12 @@ msgstr "" msgid "Invalid Ledger Entries" msgstr "" -#: erpnext/assets/doctype/asset/asset.py:450 +#: erpnext/assets/doctype/asset/asset.py:498 msgid "Invalid Net Purchase Amount" msgstr "" #: erpnext/accounts/doctype/pos_closing_entry/pos_closing_entry.py:77 -#: erpnext/accounts/general_ledger.py:796 +#: erpnext/accounts/general_ledger.py:803 msgid "Invalid Opening Entry" msgstr "إدخال فتح غير صالح" @@ -22623,7 +22742,7 @@ msgstr "إدخال فتح غير صالح" msgid "Invalid POS Invoices" msgstr "فواتير نقاط البيع غير صالحة" -#: erpnext/accounts/doctype/account/account.py:385 +#: erpnext/accounts/doctype/account/account.py:387 msgid "Invalid Parent Account" msgstr "حساب الوالد غير صالح" @@ -22645,11 +22764,11 @@ msgstr "" msgid "Invalid Print Format" msgstr "" -#: erpnext/stock/doctype/putaway_rule/putaway_rule.py:60 +#: erpnext/stock/doctype/putaway_rule/putaway_rule.py:61 msgid "Invalid Priority" msgstr "" -#: erpnext/manufacturing/doctype/bom/bom.py:1139 +#: erpnext/manufacturing/doctype/bom/bom.py:1157 msgid "Invalid Process Loss Configuration" msgstr "" @@ -22657,11 +22776,11 @@ msgstr "" msgid "Invalid Purchase Invoice" msgstr "" -#: erpnext/controllers/accounts_controller.py:3796 +#: erpnext/controllers/accounts_controller.py:3869 msgid "Invalid Qty" msgstr "" -#: erpnext/controllers/accounts_controller.py:1380 +#: erpnext/controllers/accounts_controller.py:1453 msgid "Invalid Quantity" msgstr "كمية غير صحيحة" @@ -22677,21 +22796,21 @@ msgstr "" msgid "Invalid Sales Invoices" msgstr "" -#: erpnext/assets/doctype/asset/asset.py:536 -#: erpnext/assets/doctype/asset/asset.py:555 +#: erpnext/assets/doctype/asset/asset.py:584 +#: erpnext/assets/doctype/asset/asset.py:603 msgid "Invalid Schedule" msgstr "" -#: erpnext/controllers/selling_controller.py:287 +#: erpnext/controllers/selling_controller.py:309 msgid "Invalid Selling Price" msgstr "سعر البيع غير صالح" -#: erpnext/stock/doctype/stock_entry/stock_entry.py:1598 +#: erpnext/stock/doctype/stock_entry/stock_entry.py:1668 msgid "Invalid Serial and Batch Bundle" msgstr "" -#: erpnext/stock/doctype/stock_entry/stock_entry.py:900 -#: erpnext/stock/doctype/stock_entry/stock_entry.py:922 +#: erpnext/stock/doctype/stock_entry/stock_entry.py:968 +#: erpnext/stock/doctype/stock_entry/stock_entry.py:990 msgid "Invalid Source and Target Warehouse" msgstr "" @@ -22699,7 +22818,7 @@ msgstr "" msgid "Invalid Value" msgstr "قيمة غير صالحة" -#: erpnext/stock/doctype/putaway_rule/putaway_rule.py:69 +#: erpnext/stock/doctype/putaway_rule/putaway_rule.py:70 #: erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py:256 msgid "Invalid Warehouse" msgstr "" @@ -22716,11 +22835,11 @@ msgstr "تعبير شرط غير صالح" msgid "Invalid filter formula. Please check the syntax." msgstr "" -#: erpnext/selling/doctype/quotation/quotation.py:272 +#: erpnext/selling/doctype/quotation/quotation.py:274 msgid "Invalid lost reason {0}, please create a new lost reason" msgstr "سبب ضائع غير صالح {0} ، يرجى إنشاء سبب ضائع جديد" -#: erpnext/stock/doctype/item/item.py:407 +#: erpnext/stock/doctype/item/item.py:408 msgid "Invalid naming series (. missing) for {0}" msgstr "سلسلة تسمية غير صالحة (. مفقود) لـ {0}" @@ -22738,8 +22857,8 @@ msgstr "" #: erpnext/accounts/doctype/payment_ledger_entry/payment_ledger_entry.py:108 #: erpnext/accounts/doctype/payment_ledger_entry/payment_ledger_entry.py:118 -#: erpnext/accounts/general_ledger.py:839 -#: erpnext/accounts/general_ledger.py:849 +#: erpnext/accounts/general_ledger.py:846 +#: erpnext/accounts/general_ledger.py:856 msgid "Invalid value {0} for {1} against account {2}" msgstr "" @@ -22747,12 +22866,12 @@ msgstr "" msgid "Invalid {0}" msgstr "غير صالح {0}" -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:2324 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:2277 msgid "Invalid {0} for Inter Company Transaction." msgstr "غير صالح {0} للمعاملات بين الشركات." #: erpnext/accounts/report/general_ledger/general_ledger.py:101 -#: erpnext/controllers/sales_and_purchase_return.py:35 +#: erpnext/controllers/sales_and_purchase_return.py:34 msgid "Invalid {0}: {1}" msgstr "{0} غير صالح : {1}\\n
        \\nInvalid {0}: {1}" @@ -22774,7 +22893,7 @@ msgstr "" msgid "Inventory Dimension" msgstr "" -#: erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py:156 +#: erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py:160 msgid "Inventory Dimension Negative Stock" msgstr "" @@ -22812,8 +22931,8 @@ msgstr "الاستثمارات" #: erpnext/accounts/doctype/discounted_invoice/discounted_invoice.json #: erpnext/accounts/doctype/loyalty_point_entry/loyalty_point_entry.json #: erpnext/accounts/doctype/subscription_invoice/subscription_invoice.json -#: erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py:177 -#: erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py:197 +#: erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py:169 +#: erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py:186 #: erpnext/accounts/report/payment_period_based_on_invoice_date/payment_period_based_on_invoice_date.py:97 msgid "Invoice" msgstr "فاتورة" @@ -22836,7 +22955,7 @@ msgstr "تاريخ الفاتورة" #. Account' #: erpnext/accounts/doctype/invoice_discounting/invoice_discounting.json #: erpnext/accounts/doctype/journal_entry_account/journal_entry_account.json -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.js:140 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.js:141 msgid "Invoice Discounting" msgstr "خصم الفواتير" @@ -22872,7 +22991,7 @@ msgstr "" msgid "Invoice Number" msgstr "رقم الفاتورة" -#: erpnext/accounts/doctype/pos_invoice/pos_invoice.py:820 +#: erpnext/accounts/doctype/pos_invoice/pos_invoice.py:865 msgid "Invoice Paid" msgstr "" @@ -22945,15 +23064,11 @@ msgstr "" msgid "Invoice can't be made for zero billing hour" msgstr "لا يمكن إجراء الفاتورة لمدة صفر ساعة" -#: erpnext/accounts/letterhead/company_letterhead.html:84 -msgid "Invoice:" -msgstr "فاتورة:" - #: erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts_accounts_receivable.html:171 #: erpnext/accounts/report/accounts_receivable/accounts_receivable.html:144 #: erpnext/accounts/report/accounts_receivable/accounts_receivable.py:1213 #: erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.py:164 -#: erpnext/accounts/report/customer_ledger_summary/customer_ledger_summary.py:165 +#: erpnext/accounts/report/customer_ledger_summary/customer_ledger_summary.py:196 msgid "Invoiced Amount" msgstr "قيمة الفواتير" @@ -22971,7 +23086,7 @@ msgstr "" #: erpnext/accounts/doctype/opening_invoice_creation_tool/opening_invoice_creation_tool.json #: erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.json #: erpnext/accounts/doctype/pos_profile/pos_profile.json -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:2375 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:2328 #: erpnext/buying/doctype/supplier/supplier.json #: erpnext/selling/report/payment_terms_status_for_sales_order/payment_terms_status_for_sales_order.py:62 msgid "Invoices" @@ -23051,7 +23166,7 @@ msgid "Is Advance" msgstr "هل مقدم" #. Label of the is_alternative (Check) field in DocType 'Quotation Item' -#: erpnext/selling/doctype/quotation/quotation.js:307 +#: erpnext/selling/doctype/quotation/quotation.js:308 #: erpnext/selling/doctype/quotation_item/quotation_item.json msgid "Is Alternative" msgstr "" @@ -23247,6 +23362,13 @@ msgstr "" msgid "Is Group Warehouse" msgstr "" +#. Label of the is_half_day (Check) field in DocType 'Holiday' +#. Label of the is_half_day (Check) field in DocType 'Holiday List' +#: erpnext/setup/doctype/holiday/holiday.json +#: erpnext/setup/doctype/holiday_list/holiday_list.json +msgid "Is Half Day" +msgstr "" + #. Label of the is_internal_customer (Check) field in DocType 'Sales Invoice' #. Label of the is_internal_customer (Check) field in DocType 'Customer' #. Label of the is_internal_customer (Check) field in DocType 'Sales Order' @@ -23341,6 +23463,19 @@ msgstr "" msgid "Is Period Closing Voucher Entry" msgstr "" +#. Label of the is_phantom_bom (Check) field in DocType 'BOM' +#: erpnext/manufacturing/doctype/bom/bom.json +msgid "Is Phantom BOM" +msgstr "" + +#. Label of the is_phantom_item (Check) field in DocType 'BOM Creator Item' +#. Label of the is_phantom_item (Check) field in DocType 'BOM Item' +#: erpnext/manufacturing/doctype/bom_creator_item/bom_creator_item.json +#: erpnext/manufacturing/doctype/bom_item/bom_item.json +#: erpnext/manufacturing/report/bom_explorer/bom_explorer.py:68 +msgid "Is Phantom Item" +msgstr "" + #. Label of the po_required (Select) field in DocType 'Buying Settings' #: erpnext/buying/doctype/buying_settings/buying_settings.json msgid "Is Purchase Order Required for Purchase Invoice & Receipt Creation?" @@ -23461,8 +23596,11 @@ msgstr "وتعاقد من الباطن" msgid "Is Subcontracted Item" msgstr "" +#. Label of the is_tax_withholding_account (Check) field in DocType 'Journal +#. Entry Account' #. Label of the is_tax_withholding_account (Check) field in DocType 'Purchase #. Taxes and Charges' +#: erpnext/accounts/doctype/journal_entry_account/journal_entry_account.json #: erpnext/accounts/doctype/purchase_taxes_and_charges/purchase_taxes_and_charges.json msgid "Is Tax Withholding Account" msgstr "" @@ -23540,7 +23678,7 @@ msgstr "إصدار إشعار الائتمان" msgid "Issue Date" msgstr "تاريخ القضية" -#: erpnext/stock/doctype/material_request/material_request.js:165 +#: erpnext/stock/doctype/material_request/material_request.js:166 msgid "Issue Material" msgstr "قضية المواد" @@ -23586,7 +23724,7 @@ msgstr "" #. Option for the 'Status' (Select) field in DocType 'Material Request' #: erpnext/accounts/doctype/share_balance/share_balance.json #: erpnext/stock/doctype/material_request/material_request.json -#: erpnext/stock/doctype/material_request/material_request_list.js:43 +#: erpnext/stock/doctype/material_request/material_request_list.js:44 msgid "Issued" msgstr "نشر" @@ -23610,11 +23748,11 @@ msgstr "قضايا" msgid "Issuing Date" msgstr "تاريخ الإصدار" -#: erpnext/stock/doctype/item/item.py:567 +#: erpnext/stock/doctype/item/item.py:589 msgid "It can take upto few hours for accurate stock values to be visible after merging items." msgstr "" -#: erpnext/public/js/controllers/transaction.js:2484 +#: erpnext/public/js/controllers/transaction.js:2492 msgid "It is needed to fetch Item Details." msgstr "هناك حاجة لجلب تفاصيل البند." @@ -23675,13 +23813,13 @@ msgstr "" #: erpnext/buying/report/supplier_quotation_comparison/supplier_quotation_comparison.js:33 #: erpnext/buying/report/supplier_quotation_comparison/supplier_quotation_comparison.py:204 #: erpnext/buying/workspace/buying/buying.json -#: erpnext/controllers/taxes_and_totals.py:1148 +#: erpnext/controllers/taxes_and_totals.py:1221 #: erpnext/manufacturing/doctype/blanket_order/blanket_order.json -#: erpnext/manufacturing/doctype/bom/bom.js:1011 +#: erpnext/manufacturing/doctype/bom/bom.js:1028 #: erpnext/manufacturing/doctype/bom/bom.json #: erpnext/manufacturing/doctype/plant_floor/plant_floor.js:109 #: erpnext/manufacturing/doctype/workstation/workstation_job_card.html:25 -#: erpnext/manufacturing/report/bom_stock_calculated/bom_stock_calculated.py:49 +#: erpnext/manufacturing/report/bom_stock_calculated/bom_stock_calculated.py:50 #: erpnext/manufacturing/report/bom_stock_report/bom_stock_report.html:9 #: erpnext/manufacturing/report/bom_stock_report/bom_stock_report.html:19 #: erpnext/manufacturing/report/bom_stock_report/bom_stock_report.py:22 @@ -23689,8 +23827,8 @@ msgstr "" #: erpnext/manufacturing/report/process_loss_report/process_loss_report.js:15 #: erpnext/manufacturing/report/process_loss_report/process_loss_report.py:74 #: erpnext/manufacturing/workspace/manufacturing/manufacturing.json -#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:212 -#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:359 +#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:234 +#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:385 #: erpnext/public/js/purchase_trends_filters.js:48 #: erpnext/public/js/purchase_trends_filters.js:63 #: erpnext/public/js/sales_trends_filters.js:23 @@ -23698,7 +23836,7 @@ msgstr "" #: erpnext/public/js/stock_analytics.js:92 #: erpnext/selling/doctype/party_specific_item/party_specific_item.json #: erpnext/selling/doctype/product_bundle_item/product_bundle_item.json -#: erpnext/selling/doctype/sales_order/sales_order.js:1601 +#: erpnext/selling/doctype/sales_order/sales_order.js:1623 #: erpnext/selling/page/point_of_sale/pos_item_cart.js:46 #: erpnext/selling/report/customer_wise_item_price/customer_wise_item_price.js:14 #: erpnext/selling/report/item_wise_sales_history/item_wise_sales_history.js:36 @@ -23710,7 +23848,7 @@ msgstr "" #: erpnext/stock/doctype/batch/batch.json erpnext/stock/doctype/item/item.json #: erpnext/stock/doctype/pick_list_item/pick_list_item.json #: erpnext/stock/doctype/putaway_rule/putaway_rule.json -#: erpnext/stock/doctype/putaway_rule/putaway_rule.py:311 +#: erpnext/stock/doctype/putaway_rule/putaway_rule.py:323 #: erpnext/stock/page/stock_balance/stock_balance.js:23 #: erpnext/stock/page/warehouse_capacity_summary/warehouse_capacity_summary.js:36 #: erpnext/stock/page/warehouse_capacity_summary/warehouse_capacity_summary_header.html:7 @@ -23914,12 +24052,12 @@ msgstr "" #: erpnext/accounts/doctype/pricing_rule_item_code/pricing_rule_item_code.json #: erpnext/accounts/doctype/promotional_scheme/promotional_scheme.json #: erpnext/accounts/doctype/promotional_scheme_product_discount/promotional_scheme_product_discount.json -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.js:1059 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.js:1060 #: erpnext/accounts/report/billed_items_to_be_received/billed_items_to_be_received.py:68 #: erpnext/accounts/report/delivered_items_to_be_billed/delivered_items_to_be_billed.py:37 #: erpnext/accounts/report/gross_profit/gross_profit.py:301 -#: erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py:150 -#: erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py:170 +#: erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py:142 +#: erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py:159 #: erpnext/accounts/report/received_items_to_be_billed/received_items_to_be_billed.py:37 #: erpnext/assets/doctype/asset/asset.json #: erpnext/assets/doctype/asset_capitalization_asset_item/asset_capitalization_asset_item.json @@ -23955,7 +24093,7 @@ msgstr "" #: erpnext/manufacturing/doctype/work_order_item/work_order_item.json #: erpnext/manufacturing/doctype/workstation/workstation.js:471 #: erpnext/manufacturing/page/bom_comparison_tool/bom_comparison_tool.js:155 -#: erpnext/manufacturing/report/bom_explorer/bom_explorer.py:49 +#: erpnext/manufacturing/report/bom_explorer/bom_explorer.py:60 #: erpnext/manufacturing/report/bom_operations_time/bom_operations_time.js:8 #: erpnext/manufacturing/report/bom_operations_time/bom_operations_time.py:103 #: erpnext/manufacturing/report/cost_of_poor_quality_report/cost_of_poor_quality_report.py:100 @@ -23964,24 +24102,24 @@ msgstr "" #: erpnext/manufacturing/report/material_requirements_planning_report/material_requirements_planning_report.js:30 #: erpnext/manufacturing/report/material_requirements_planning_report/material_requirements_planning_report.py:935 #: erpnext/manufacturing/report/material_requirements_planning_report/material_requirements_planning_report.py:971 -#: erpnext/manufacturing/report/production_planning_report/production_planning_report.py:359 +#: erpnext/manufacturing/report/production_planning_report/production_planning_report.py:364 #: erpnext/manufacturing/report/quality_inspection_summary/quality_inspection_summary.js:27 #: erpnext/manufacturing/report/quality_inspection_summary/quality_inspection_summary.py:86 #: erpnext/manufacturing/report/work_order_stock_report/work_order_stock_report.py:119 #: erpnext/projects/doctype/timesheet/timesheet.js:214 -#: erpnext/public/js/controllers/transaction.js:2779 +#: erpnext/public/js/controllers/transaction.js:2787 #: erpnext/public/js/stock_reservation.js:112 #: erpnext/public/js/stock_reservation.js:318 erpnext/public/js/utils.js:488 #: erpnext/public/js/utils.js:644 #: erpnext/regional/doctype/import_supplier_invoice/import_supplier_invoice.json #: erpnext/selling/doctype/delivery_schedule_item/delivery_schedule_item.json #: erpnext/selling/doctype/installation_note_item/installation_note_item.json -#: erpnext/selling/doctype/quotation/quotation.js:281 +#: erpnext/selling/doctype/quotation/quotation.js:282 #: erpnext/selling/doctype/quotation_item/quotation_item.json #: erpnext/selling/doctype/sales_order/sales_order.js:368 #: erpnext/selling/doctype/sales_order/sales_order.js:476 -#: erpnext/selling/doctype/sales_order/sales_order.js:1237 -#: erpnext/selling/doctype/sales_order/sales_order.js:1388 +#: erpnext/selling/doctype/sales_order/sales_order.js:1241 +#: erpnext/selling/doctype/sales_order/sales_order.js:1392 #: erpnext/selling/doctype/sales_order_item/sales_order_item.json #: erpnext/selling/report/customer_wise_item_price/customer_wise_item_price.py:29 #: erpnext/selling/report/item_wise_sales_history/item_wise_sales_history.py:27 @@ -24027,7 +24165,7 @@ msgstr "" #: erpnext/stock/report/serial_no_and_batch_traceability/serial_no_and_batch_traceability.js:8 #: erpnext/stock/report/serial_no_and_batch_traceability/serial_no_and_batch_traceability.py:429 #: erpnext/stock/report/serial_no_ledger/serial_no_ledger.js:7 -#: erpnext/stock/report/stock_ageing/stock_ageing.py:130 +#: erpnext/stock/report/stock_ageing/stock_ageing.py:132 #: erpnext/stock/report/stock_projected_qty/stock_projected_qty.py:104 #: erpnext/stock/report/stock_qty_vs_serial_no_count/stock_qty_vs_serial_no_count.py:26 #: erpnext/subcontracting/doctype/subcontracting_inward_order_item/subcontracting_inward_order_item.json @@ -24046,7 +24184,7 @@ msgstr "" msgid "Item Code" msgstr "رمز السلعة" -#: erpnext/manufacturing/doctype/bom_creator/bom_creator.js:60 +#: erpnext/manufacturing/doctype/bom_creator/bom_creator.js:61 msgid "Item Code (Final Product)" msgstr "" @@ -24058,11 +24196,11 @@ msgstr "" msgid "Item Code cannot be changed for Serial No." msgstr "لا يمكن تغيير رمز السلعة للرقم التسلسلي" -#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:451 +#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:453 msgid "Item Code required at Row No {0}" msgstr "رمز العنصر المطلوب في الصف رقم {0}\\n
        \\nItem Code required at Row No {0}" -#: erpnext/selling/page/point_of_sale/pos_controller.js:845 +#: erpnext/selling/page/point_of_sale/pos_controller.js:849 #: erpnext/selling/page/point_of_sale/pos_item_details.js:275 msgid "Item Code: {0} is not available under warehouse {1}." msgstr "رمز العنصر: {0} غير متوفر ضمن المستودع {1}." @@ -24169,9 +24307,9 @@ msgstr "بيانات الصنف" #: erpnext/accounts/report/inactive_sales_items/inactive_sales_items.js:21 #: erpnext/accounts/report/inactive_sales_items/inactive_sales_items.py:28 #: erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.js:28 -#: erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py:164 +#: erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py:156 #: erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.js:65 -#: erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py:184 +#: erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py:173 #: erpnext/accounts/report/purchase_register/purchase_register.js:58 #: erpnext/accounts/report/sales_register/sales_register.js:70 #: erpnext/buying/doctype/purchase_order_item/purchase_order_item.json @@ -24223,7 +24361,7 @@ msgstr "بيانات الصنف" #: erpnext/stock/report/itemwise_recommended_reorder_level/itemwise_recommended_reorder_level.py:55 #: erpnext/stock/report/product_bundle_balance/product_bundle_balance.js:37 #: erpnext/stock/report/product_bundle_balance/product_bundle_balance.py:100 -#: erpnext/stock/report/stock_ageing/stock_ageing.py:139 +#: erpnext/stock/report/stock_ageing/stock_ageing.py:141 #: erpnext/stock/report/stock_analytics/stock_analytics.js:8 #: erpnext/stock/report/stock_analytics/stock_analytics.py:38 #: erpnext/stock/report/stock_balance/stock_balance.js:32 @@ -24394,8 +24532,8 @@ msgstr "مادة المصنع" #: erpnext/accounts/report/delivered_items_to_be_billed/delivered_items_to_be_billed.py:71 #: erpnext/accounts/report/gross_profit/gross_profit.py:308 #: erpnext/accounts/report/inactive_sales_items/inactive_sales_items.py:33 -#: erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py:156 -#: erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py:176 +#: erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py:148 +#: erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py:165 #: erpnext/accounts/report/received_items_to_be_billed/received_items_to_be_billed.py:71 #: erpnext/assets/doctype/asset/asset.json #: erpnext/assets/doctype/asset_capitalization_asset_item/asset_capitalization_asset_item.json @@ -24431,7 +24569,7 @@ msgstr "مادة المصنع" #: erpnext/manufacturing/doctype/work_order/work_order.json #: erpnext/manufacturing/doctype/work_order_item/work_order_item.json #: erpnext/manufacturing/notification/material_request_receipt_notification/material_request_receipt_notification.html:8 -#: erpnext/manufacturing/report/bom_explorer/bom_explorer.py:55 +#: erpnext/manufacturing/report/bom_explorer/bom_explorer.py:66 #: erpnext/manufacturing/report/bom_operations_time/bom_operations_time.py:109 #: erpnext/manufacturing/report/bom_stock_report/bom_stock_report.py:23 #: erpnext/manufacturing/report/cost_of_poor_quality_report/cost_of_poor_quality_report.py:106 @@ -24439,13 +24577,13 @@ msgstr "مادة المصنع" #: erpnext/manufacturing/report/material_requirements_planning_report/material_requirements_planning_report.py:942 #: erpnext/manufacturing/report/material_requirements_planning_report/material_requirements_planning_report.py:978 #: erpnext/manufacturing/report/production_plan_summary/production_plan_summary.py:153 -#: erpnext/manufacturing/report/production_planning_report/production_planning_report.py:366 +#: erpnext/manufacturing/report/production_planning_report/production_planning_report.py:371 #: erpnext/manufacturing/report/quality_inspection_summary/quality_inspection_summary.py:92 #: erpnext/manufacturing/report/work_order_consumed_materials/work_order_consumed_materials.py:138 -#: erpnext/public/js/controllers/transaction.js:2785 +#: erpnext/public/js/controllers/transaction.js:2793 #: erpnext/public/js/utils.js:734 #: erpnext/selling/doctype/quotation_item/quotation_item.json -#: erpnext/selling/doctype/sales_order/sales_order.js:1243 +#: erpnext/selling/doctype/sales_order/sales_order.js:1247 #: erpnext/selling/doctype/sales_order_item/sales_order_item.json #: erpnext/selling/report/customer_wise_item_price/customer_wise_item_price.py:35 #: erpnext/selling/report/item_wise_sales_history/item_wise_sales_history.py:33 @@ -24481,7 +24619,7 @@ msgstr "مادة المصنع" #: erpnext/stock/report/itemwise_recommended_reorder_level/itemwise_recommended_reorder_level.py:54 #: erpnext/stock/report/serial_and_batch_summary/serial_and_batch_summary.py:131 #: erpnext/stock/report/serial_no_and_batch_traceability/serial_no_and_batch_traceability.py:436 -#: erpnext/stock/report/stock_ageing/stock_ageing.py:136 +#: erpnext/stock/report/stock_ageing/stock_ageing.py:138 #: erpnext/stock/report/stock_analytics/stock_analytics.py:31 #: erpnext/stock/report/stock_balance/stock_balance.py:404 #: erpnext/stock/report/stock_ledger/stock_ledger.py:213 @@ -24504,6 +24642,10 @@ msgstr "اسم السلعة" msgid "Item Naming By" msgstr "تسمية السلعة بواسطة" +#: erpnext/accounts/doctype/pos_invoice/pos_invoice.py:451 +msgid "Item Out of Stock" +msgstr "" + #. Label of a Link in the Buying Workspace #. Label of the item_price_tab (Tab Break) field in DocType 'Selling Settings' #. Label of a Link in the Selling Workspace @@ -24572,10 +24714,18 @@ msgid "Item Reference" msgstr "" #. Name of a DocType +#. Label of the item_reorder_section (Section Break) field in DocType 'Material +#. Request Item' #: erpnext/stock/doctype/item_reorder/item_reorder.json +#: erpnext/stock/doctype/material_request_item/material_request_item.json msgid "Item Reorder" msgstr "البند إعادة ترتيب" +#. Label of the item_row (Data) field in DocType 'Item Wise Tax Detail' +#: erpnext/accounts/doctype/item_wise_tax_detail/item_wise_tax_detail.json +msgid "Item Row" +msgstr "" + #: erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py:145 msgid "Item Row {0}: {1} {2} does not exist in above '{1}' table" msgstr "صنف الصف {0}: {1} {2} غير موجود في جدول '{1}' أعلاه" @@ -24689,11 +24839,6 @@ msgstr "الصنف لتصنيع" msgid "Item UOM" msgstr "وحدة قياس الصنف" -#: erpnext/accounts/doctype/pos_invoice/pos_invoice.py:410 -#: erpnext/accounts/doctype/pos_invoice/pos_invoice.py:417 -msgid "Item Unavailable" -msgstr "العنصر غير متوفر" - #. Name of a DocType #: erpnext/stock/doctype/item_variant/item_variant.json msgid "Item Variant" @@ -24719,11 +24864,11 @@ msgstr "الصنف تفاصيل متغير" msgid "Item Variant Settings" msgstr "إعدادات متنوع السلعة" -#: erpnext/stock/doctype/item/item.js:876 +#: erpnext/stock/doctype/item/item.js:895 msgid "Item Variant {0} already exists with same attributes" msgstr "متغير الصنف {0} موجود بالفعل مع نفس الخصائص" -#: erpnext/stock/doctype/item/item.py:768 +#: erpnext/stock/doctype/item/item.py:771 msgid "Item Variants updated" msgstr "تم تحديث متغيرات العنصر" @@ -24766,15 +24911,39 @@ msgstr "مواصفات الموقع الإلكتروني للصنف" msgid "Item Weight Details" msgstr "تفاصيل وزن الصنف" -#. Label of the item_wise_tax_detail (Code) field in DocType 'Purchase Taxes -#. and Charges' -#. Label of the item_wise_tax_detail (Code) field in DocType 'Sales Taxes and -#. Charges' -#: erpnext/accounts/doctype/purchase_taxes_and_charges/purchase_taxes_and_charges.json -#: erpnext/accounts/doctype/sales_taxes_and_charges/sales_taxes_and_charges.json +#. Name of a DocType +#: erpnext/accounts/doctype/item_wise_tax_detail/item_wise_tax_detail.json msgid "Item Wise Tax Detail" msgstr "تفصيل ضريبة وفقاً للصنف" +#. Label of the item_wise_tax_details (Table) field in DocType 'POS Invoice' +#. Label of the item_wise_tax_details (Table) field in DocType 'Purchase +#. Invoice' +#. Label of the item_wise_tax_details (Table) field in DocType 'Sales Invoice' +#. Label of the item_wise_tax_details (Table) field in DocType 'Purchase Order' +#. Label of the item_wise_tax_details (Table) field in DocType 'Supplier +#. Quotation' +#. Label of the item_wise_tax_details (Table) field in DocType 'Quotation' +#. Label of the item_wise_tax_details (Table) field in DocType 'Sales Order' +#. Label of the item_wise_tax_details (Table) field in DocType 'Delivery Note' +#. Label of the item_wise_tax_details (Table) field in DocType 'Purchase +#. Receipt' +#: erpnext/accounts/doctype/pos_invoice/pos_invoice.json +#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.json +#: erpnext/buying/doctype/purchase_order/purchase_order.json +#: erpnext/buying/doctype/supplier_quotation/supplier_quotation.json +#: erpnext/selling/doctype/quotation/quotation.json +#: erpnext/selling/doctype/sales_order/sales_order.json +#: erpnext/stock/doctype/delivery_note/delivery_note.json +#: erpnext/stock/doctype/purchase_receipt/purchase_receipt.json +msgid "Item Wise Tax Details" +msgstr "" + +#: erpnext/controllers/taxes_and_totals.py:542 +msgid "Item Wise Tax Details do not match with Taxes and Charges at the following rows:" +msgstr "" + #. Label of the section_break_rrrx (Section Break) field in DocType 'Sales #. Forecast' #. Option for the 'Based On' (Select) field in DocType 'Repost Item Valuation' @@ -24788,15 +24957,15 @@ msgstr "" msgid "Item and Warranty Details" msgstr "البند والضمان تفاصيل" -#: erpnext/stock/doctype/stock_entry/stock_entry.py:3065 +#: erpnext/stock/doctype/stock_entry/stock_entry.py:3147 msgid "Item for row {0} does not match Material Request" msgstr "عنصر الصف {0} لا يتطابق مع طلب المواد" -#: erpnext/stock/doctype/item/item.py:785 +#: erpnext/stock/doctype/item/item.py:788 msgid "Item has variants." msgstr "البند لديه متغيرات." -#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:408 +#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:436 msgid "Item is mandatory in Raw Materials table." msgstr "" @@ -24809,7 +24978,7 @@ msgid "Item must be added using 'Get Items from Purchase Receipts' button" msgstr "الصنف يجب اضافته مستخدما مفتاح \"احصل علي الأصناف من المشتريات المستلمة \"" #: erpnext/buying/report/subcontracted_item_to_be_received/subcontracted_item_to_be_received.py:42 -#: erpnext/selling/doctype/sales_order/sales_order.js:1608 +#: erpnext/selling/doctype/sales_order/sales_order.js:1630 msgid "Item name" msgstr "اسم السلعة" @@ -24818,11 +24987,11 @@ msgstr "اسم السلعة" msgid "Item operation" msgstr "عملية الصنف" -#: erpnext/controllers/accounts_controller.py:3819 +#: erpnext/controllers/accounts_controller.py:3892 msgid "Item qty can not be updated as raw materials are already processed." msgstr "" -#: erpnext/stock/doctype/stock_entry/stock_entry.py:1005 +#: erpnext/stock/doctype/stock_entry/stock_entry.py:1073 msgid "Item rate has been updated to zero as Allow Zero Valuation Rate is checked for item {0}" msgstr "" @@ -24840,15 +25009,15 @@ msgstr "الصنف الذي سيتم تصنيعه أو إعادة تعبئته" msgid "Item valuation rate is recalculated considering landed cost voucher amount" msgstr "" -#: erpnext/stock/utils.py:555 +#: erpnext/stock/utils.py:559 msgid "Item valuation reposting in progress. Report might show incorrect item valuation." msgstr "" -#: erpnext/stock/doctype/item/item.py:942 +#: erpnext/stock/doctype/item/item.py:945 msgid "Item variant {0} exists with same attributes" msgstr "متغير العنصر {0} موجود بنفس السمات\\n
        \\nItem variant {0} exists with same attributes" -#: erpnext/manufacturing/doctype/bom_creator/bom_creator.py:83 +#: erpnext/manufacturing/doctype/bom_creator/bom_creator.py:85 msgid "Item {0} cannot be added as a sub-assembly of itself" msgstr "" @@ -24856,36 +25025,36 @@ msgstr "" msgid "Item {0} cannot be ordered more than {1} against Blanket Order {2}." msgstr "" -#: erpnext/assets/doctype/asset/asset.py:278 -#: erpnext/stock/doctype/item/item.py:632 +#: erpnext/assets/doctype/asset/asset.py:279 +#: erpnext/stock/doctype/item/item.py:635 msgid "Item {0} does not exist" msgstr "العنصر {0} غير موجود\\n
        \\nItem {0} does not exist" -#: erpnext/manufacturing/doctype/bom/bom.py:596 +#: erpnext/manufacturing/doctype/bom/bom.py:607 msgid "Item {0} does not exist in the system or has expired" msgstr "الصنف{0} غير موجود في النظام أو انتهت صلاحيته" -#: erpnext/controllers/stock_controller.py:513 +#: erpnext/controllers/stock_controller.py:515 msgid "Item {0} does not exist." msgstr "العنصر {0} غير موجود\\n
        \\nItem {0} does not exist." -#: erpnext/controllers/selling_controller.py:810 +#: erpnext/controllers/selling_controller.py:835 msgid "Item {0} entered multiple times." msgstr "" -#: erpnext/controllers/sales_and_purchase_return.py:222 +#: erpnext/controllers/sales_and_purchase_return.py:221 msgid "Item {0} has already been returned" msgstr "تمت إرجاع الصنف{0} من قبل" -#: erpnext/assets/doctype/asset/asset.py:280 +#: erpnext/assets/doctype/asset/asset.py:281 msgid "Item {0} has been disabled" msgstr "الصنف{0} تم تعطيله" -#: erpnext/selling/doctype/sales_order/sales_order.py:779 +#: erpnext/selling/doctype/sales_order/sales_order.py:778 msgid "Item {0} has no Serial No. Only serialized items can have delivery based on Serial No" msgstr "" -#: erpnext/stock/doctype/item/item.py:1121 +#: erpnext/stock/doctype/item/item.py:1124 msgid "Item {0} has reached its end of life on {1}" msgstr "الصنف{0} قد وصل إلى نهاية عمره في {1}" @@ -24897,11 +25066,11 @@ msgstr "تم تجاهل الصنف {0} لأنه ليس بند مخزون" msgid "Item {0} is already reserved/delivered against Sales Order {1}." msgstr "" -#: erpnext/stock/doctype/item/item.py:1141 +#: erpnext/stock/doctype/item/item.py:1144 msgid "Item {0} is cancelled" msgstr "تم إلغاء العنصر {0}\\n
        \\nItem {0} is cancelled" -#: erpnext/stock/doctype/item/item.py:1125 +#: erpnext/stock/doctype/item/item.py:1128 msgid "Item {0} is disabled" msgstr "تم تعطيل البند {0}" @@ -24909,7 +25078,7 @@ msgstr "تم تعطيل البند {0}" msgid "Item {0} is not a serialized Item" msgstr "البند {0} ليس بند لديه رقم تسلسلي" -#: erpnext/stock/doctype/item/item.py:1133 +#: erpnext/stock/doctype/item/item.py:1136 msgid "Item {0} is not a stock Item" msgstr "العنصر {0} ليس عنصر مخزون\\n
        \\nItem {0} is not a stock Item" @@ -24917,11 +25086,11 @@ msgstr "العنصر {0} ليس عنصر مخزون\\n
        \\nItem {0} is not a s msgid "Item {0} is not a subcontracted item" msgstr "" -#: erpnext/stock/doctype/stock_entry/stock_entry.py:1982 +#: erpnext/stock/doctype/stock_entry/stock_entry.py:2054 msgid "Item {0} is not active or end of life has been reached" msgstr "البند {0} غير نشط أو تم التوصل إلى نهاية الحياة" -#: erpnext/assets/doctype/asset/asset.py:282 +#: erpnext/assets/doctype/asset/asset.py:283 msgid "Item {0} must be a Fixed Asset Item" msgstr "البند {0} يجب أن يكون بند أصول ثابتة" @@ -24933,11 +25102,11 @@ msgstr "" msgid "Item {0} must be a Sub-contracted Item" msgstr "البند {0} يجب أن يكون عنصر التعاقد الفرعي" -#: erpnext/assets/doctype/asset/asset.py:284 +#: erpnext/assets/doctype/asset/asset.py:285 msgid "Item {0} must be a non-stock item" msgstr "الصنف {0} يجب ألا يكون صنف مخزن
        Item {0} must be a non-stock item" -#: erpnext/stock/doctype/stock_entry/stock_entry.py:1336 +#: erpnext/stock/doctype/stock_entry/stock_entry.py:1406 msgid "Item {0} not found in 'Raw Materials Supplied' table in {1} {2}" msgstr "" @@ -24945,7 +25114,7 @@ msgstr "" msgid "Item {0} not found." msgstr "" -#: erpnext/buying/doctype/purchase_order/purchase_order.py:360 +#: erpnext/buying/doctype/purchase_order/purchase_order.py:362 msgid "Item {0}: Ordered qty {1} cannot be less than minimum order qty {2} (defined in Item)." msgstr "البند {0} الكمية المطلوبة {1} لا يمكن أن تكون أقل من الحد الأدنى للطلب {2} (المحددة في البند)." @@ -24953,7 +25122,7 @@ msgstr "البند {0} الكمية المطلوبة {1} لا يمكن أن تك msgid "Item {0}: {1} qty produced. " msgstr "العنصر {0}: {1} الكمية المنتجة." -#: erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py:1441 +#: erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py:1442 msgid "Item {} does not exist." msgstr "" @@ -24994,91 +25163,10 @@ msgstr "سجل حركة مبيعات وفقاً للصنف" msgid "Item/Item Code required to get Item Tax Template." msgstr "" -#: erpnext/manufacturing/doctype/bom/bom.py:346 +#: erpnext/manufacturing/doctype/bom/bom.py:349 msgid "Item: {0} does not exist in the system" msgstr "الصنف: {0} غير موجود في النظام" -#. Label of the items_section (Section Break) field in DocType 'POS Invoice' -#. Label of the items (Table) field in DocType 'POS Invoice' -#. Label of the sec_warehouse (Section Break) field in DocType 'Purchase -#. Invoice' -#. Label of the items (Table) field in DocType 'Purchase Invoice' -#. Label of the items_section (Section Break) field in DocType 'Sales Invoice' -#. Label of the items (Table) field in DocType 'Sales Invoice' -#. Label of the items (Table) field in DocType 'Purchase Order' -#. Label of the items (Table) field in DocType 'Request for Quotation' -#. Label of the items (Table) field in DocType 'Supplier Quotation' -#. Label of the items_section (Tab Break) field in DocType 'Opportunity' -#. Label of the items (Table) field in DocType 'Opportunity' -#. Label of the items (Table) field in DocType 'Maintenance Schedule' -#. Label of the items (Table) field in DocType 'BOM' -#. Label of the items (Table) field in DocType 'BOM Creator' -#. Label of the items (Table) field in DocType 'Job Card' -#. Label of the items (Table) field in DocType 'Master Production Schedule' -#. Label of the items (Table) field in DocType 'Sales Forecast' -#. Label of the items (Table) field in DocType 'Installation Note' -#. Label of the item_section (Section Break) field in DocType 'Product Bundle' -#. Label of the items (Table) field in DocType 'Product Bundle' -#. Label of the items (Table) field in DocType 'Quotation' -#. Label of the sec_warehouse (Section Break) field in DocType 'Sales Order' -#. Label of the items (Table) field in DocType 'Sales Order' -#. Label of the items_section (Section Break) field in DocType 'Delivery Note' -#. Label of the purchase_receipt_items (Section Break) field in DocType 'Landed -#. Cost Voucher' -#. Label of the items (Table) field in DocType 'Material Request' -#. Label of the warehouse_section (Section Break) field in DocType 'Material -#. Request' -#. Label of the items (Table) field in DocType 'Packing Slip' -#. Label of the sec_warehouse (Section Break) field in DocType 'Purchase -#. Receipt' -#. Label of the items (Table) field in DocType 'Purchase Receipt' -#. Label of the items (Table) field in DocType 'Stock Entry' -#. Label of the items_section (Section Break) field in DocType 'Stock Entry' -#. Label of the items (Table) field in DocType 'Stock Reconciliation' -#. Label of the items (Table) field in DocType 'Subcontracting Inward Order' -#. Label of the items_section (Section Break) field in DocType 'Subcontracting -#. Inward Order' -#. Label of the items (Table) field in DocType 'Subcontracting Order' -#. Label of the items (Table) field in DocType 'Subcontracting Receipt' -#: erpnext/accounts/doctype/pos_invoice/pos_invoice.json -#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.json -#: erpnext/buying/doctype/purchase_order/purchase_order.json -#: erpnext/buying/doctype/request_for_quotation/request_for_quotation.json -#: erpnext/buying/doctype/supplier_quotation/supplier_quotation.json -#: erpnext/crm/doctype/opportunity/opportunity.json -#: erpnext/maintenance/doctype/maintenance_schedule/maintenance_schedule.json -#: erpnext/manufacturing/doctype/bom/bom.json -#: erpnext/manufacturing/doctype/bom_creator/bom_creator.json -#: erpnext/manufacturing/doctype/job_card/job_card.json -#: erpnext/manufacturing/doctype/master_production_schedule/master_production_schedule.json -#: erpnext/manufacturing/doctype/sales_forecast/sales_forecast.json -#: erpnext/public/js/utils.js:466 -#: erpnext/selling/doctype/installation_note/installation_note.json -#: erpnext/selling/doctype/product_bundle/product_bundle.json -#: erpnext/selling/doctype/quotation/quotation.json -#: erpnext/selling/doctype/sales_order/sales_order.js:1229 -#: erpnext/selling/doctype/sales_order/sales_order.json -#: erpnext/selling/page/point_of_sale/pos_past_order_summary.js:19 -#: erpnext/setup/doctype/item_group/item_group.js:87 -#: erpnext/stock/doctype/delivery_note/delivery_note.js:494 -#: erpnext/stock/doctype/delivery_note/delivery_note.json -#: erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.json -#: erpnext/stock/doctype/material_request/material_request.json -#: erpnext/stock/doctype/packing_slip/packing_slip.json -#: erpnext/stock/doctype/purchase_receipt/purchase_receipt.json -#: erpnext/stock/doctype/stock_entry/stock_entry.json -#: erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.json -#: erpnext/stock/report/stock_balance/stock_balance.js:39 -#: erpnext/stock/report/stock_ledger/stock_ledger.js:43 -#: erpnext/subcontracting/doctype/subcontracting_inward_order/subcontracting_inward_order.json -#: erpnext/subcontracting/doctype/subcontracting_order/subcontracting_order.json -#: erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.json -#: erpnext/templates/form_grid/item_grid.html:6 -#: erpnext/templates/generators/bom.html:38 erpnext/templates/pages/rfq.html:37 -msgid "Items" -msgstr "الاصناف" - #. Label of a Card Break in the Buying Workspace #: erpnext/buying/workspace/buying/buying.json msgid "Items & Pricing" @@ -25093,8 +25181,8 @@ msgstr "" msgid "Items Filter" msgstr "تصفية الاصناف" -#: erpnext/manufacturing/doctype/production_plan/production_plan.py:1639 -#: erpnext/selling/doctype/sales_order/sales_order.js:1645 +#: erpnext/manufacturing/doctype/production_plan/production_plan.py:1646 +#: erpnext/selling/doctype/sales_order/sales_order.js:1668 msgid "Items Required" msgstr "العناصر المطلوبة" @@ -25110,19 +25198,19 @@ msgstr "اصناف يمكن طلبه" msgid "Items and Pricing" msgstr "السلع والتسعيرات" -#: erpnext/controllers/accounts_controller.py:4053 +#: erpnext/controllers/accounts_controller.py:4126 msgid "Items cannot be updated as Subcontracting Inward Order(s) exist against this Subcontracted Sales Order." msgstr "" -#: erpnext/controllers/accounts_controller.py:4046 +#: erpnext/controllers/accounts_controller.py:4119 msgid "Items cannot be updated as Subcontracting Order is created against the Purchase Order {0}." msgstr "" -#: erpnext/selling/doctype/sales_order/sales_order.js:1424 +#: erpnext/selling/doctype/sales_order/sales_order.js:1428 msgid "Items for Raw Material Request" msgstr "عناصر لطلب المواد الخام" -#: erpnext/stock/doctype/stock_entry/stock_entry.py:1001 +#: erpnext/stock/doctype/stock_entry/stock_entry.py:1069 msgid "Items rate has been updated to zero as Allow Zero Valuation Rate is checked for the following items: {0}" msgstr "" @@ -25132,7 +25220,7 @@ msgstr "" msgid "Items to Be Repost" msgstr "" -#: erpnext/manufacturing/doctype/production_plan/production_plan.py:1638 +#: erpnext/manufacturing/doctype/production_plan/production_plan.py:1645 msgid "Items to Manufacture are required to pull the Raw Materials associated with it." msgstr "العناصر المطلوب تصنيعها لسحب المواد الخام المرتبطة بها." @@ -25152,7 +25240,7 @@ msgstr "" msgid "Items under this warehouse will be suggested" msgstr "وسيتم اقتراح العناصر الموجودة تحت هذا المستودع" -#: erpnext/controllers/stock_controller.py:123 +#: erpnext/controllers/stock_controller.py:125 msgid "Items {0} do not exist in the Item master." msgstr "" @@ -25195,9 +25283,9 @@ msgstr "" #: erpnext/buying/doctype/purchase_order_item/purchase_order_item.json #: erpnext/manufacturing/doctype/bom/bom.json #: erpnext/manufacturing/doctype/job_card/job_card.json -#: erpnext/manufacturing/doctype/job_card/job_card.py:882 +#: erpnext/manufacturing/doctype/job_card/job_card.py:877 #: erpnext/manufacturing/doctype/operation/operation.json -#: erpnext/manufacturing/doctype/work_order/work_order.js:389 +#: erpnext/manufacturing/doctype/work_order/work_order.js:396 #: erpnext/manufacturing/doctype/work_order/work_order.json #: erpnext/manufacturing/report/cost_of_poor_quality_report/cost_of_poor_quality_report.js:29 #: erpnext/manufacturing/report/cost_of_poor_quality_report/cost_of_poor_quality_report.py:86 @@ -25256,7 +25344,7 @@ msgstr "سجل وقت بطاقة العمل" msgid "Job Card and Capacity Planning" msgstr "" -#: erpnext/manufacturing/doctype/job_card/job_card.py:1308 +#: erpnext/manufacturing/doctype/job_card/job_card.py:1335 msgid "Job Card {0} has been completed" msgstr "" @@ -25332,11 +25420,11 @@ msgstr "" msgid "Job Worker Warehouse" msgstr "" -#: erpnext/manufacturing/doctype/work_order/work_order.py:2539 +#: erpnext/manufacturing/doctype/work_order/work_order.py:2580 msgid "Job card {0} created" msgstr "تم إنشاء بطاقة العمل {0}" -#: erpnext/utilities/bulk_transaction.py:53 +#: erpnext/utilities/bulk_transaction.py:74 msgid "Job: {0} has been triggered for processing failed transactions" msgstr "" @@ -25359,7 +25447,7 @@ msgstr "" msgid "Journal Entries" msgstr "" -#: erpnext/accounts/utils.py:1023 +#: erpnext/accounts/utils.py:1027 msgid "Journal Entries {0} are un-linked" msgstr "إدخالات قيد اليومية {0} غير مترابطة" @@ -25372,7 +25460,6 @@ msgstr "إدخالات قيد اليومية {0} غير مترابطة" #. Option for the 'Invoice Type' (Select) field in DocType 'Payment #. Reconciliation Invoice' #. Label of a Link in the Accounting Workspace -#. Label of a shortcut in the Accounting Workspace #. Label of a Link in the Payables Workspace #. Label of a shortcut in the Payables Workspace #. Label of a shortcut in the Receivables Workspace @@ -25418,7 +25505,7 @@ msgstr "حساب قالب إدخال دفتر اليومية" msgid "Journal Entry Type" msgstr "نوع إدخال دفتر اليومية" -#: erpnext/accounts/doctype/journal_entry/journal_entry.py:625 +#: erpnext/accounts/doctype/journal_entry/journal_entry.py:540 msgid "Journal Entry for Asset scrapping cannot be cancelled. Please restore the Asset." msgstr "" @@ -25427,11 +25514,11 @@ msgstr "" msgid "Journal Entry for Scrap" msgstr "قيد دفتر يومية للتخريد" -#: erpnext/accounts/doctype/journal_entry/journal_entry.py:332 +#: erpnext/accounts/doctype/journal_entry/journal_entry.py:333 msgid "Journal Entry type should be set as Depreciation Entry for asset depreciation" msgstr "" -#: erpnext/accounts/doctype/journal_entry/journal_entry.py:780 +#: erpnext/accounts/doctype/journal_entry/journal_entry.py:695 msgid "Journal Entry {0} does not have account {1} or already matched against other voucher" msgstr "قيد دفتر اليومية {0} ليس لديه حساب {1} أو قد تم مطابقته مسبقا مع إيصال أخرى" @@ -25549,7 +25636,7 @@ msgstr "" msgid "Kilowatt-Hour" msgstr "" -#: erpnext/manufacturing/doctype/job_card/job_card.py:884 +#: erpnext/manufacturing/doctype/job_card/job_card.py:879 msgid "Kindly cancel the Manufacturing Entries first against the work order {0}." msgstr "" @@ -25567,11 +25654,14 @@ msgstr "" msgid "Knot" msgstr "" +#. Option for the 'Default Stock Valuation Method' (Select) field in DocType +#. 'Company' #. Option for the 'Valuation Method' (Select) field in DocType 'Item' #. Option for the 'Default Valuation Method' (Select) field in DocType 'Stock #. Settings' #. Option for the 'Pick Serial / Batch Based On' (Select) field in DocType #. 'Stock Settings' +#: erpnext/setup/doctype/company/company.json #: erpnext/stock/doctype/item/item.json #: erpnext/stock/doctype/stock_settings/stock_settings.json msgid "LIFO" @@ -25618,9 +25708,9 @@ msgstr "" #. Name of a DocType #. Label of a Link in the Stock Workspace -#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js:677 +#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js:678 #: erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.json -#: erpnext/stock/doctype/purchase_receipt/purchase_receipt.js:104 +#: erpnext/stock/doctype/purchase_receipt/purchase_receipt.js:95 #: erpnext/stock/workspace/stock/stock.json msgid "Landed Cost Voucher" msgstr "هبطت التكلفة قسيمة" @@ -25668,7 +25758,7 @@ msgstr "تاريخ الاتصال الأخير" msgid "Last Completion Date" msgstr "تاريخ الانتهاء الأخير" -#: erpnext/accounts/doctype/account/account.py:656 +#: erpnext/accounts/doctype/account/account.py:658 msgid "Last GL Entry update was done {}. This operation is not allowed while system is actively being used. Please wait for 5 minutes before retrying." msgstr "" @@ -25703,7 +25793,7 @@ msgstr "تاريخ أخر أمر بيع" #: erpnext/buying/doctype/purchase_order_item/purchase_order_item.json #: erpnext/manufacturing/doctype/bom/bom.json #: erpnext/manufacturing/doctype/bom_creator/bom_creator.json -#: erpnext/manufacturing/report/bom_stock_calculated/bom_stock_calculated.py:98 +#: erpnext/manufacturing/report/bom_stock_calculated/bom_stock_calculated.py:106 #: erpnext/stock/doctype/item/item.json #: erpnext/stock/report/item_prices/item_prices.py:56 msgid "Last Purchase Rate" @@ -25738,7 +25828,7 @@ msgstr "آخر سعر الشراء" msgid "Last Scanned Warehouse" msgstr "" -#: erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py:328 +#: erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py:332 msgid "Last Stock Transaction for item {0} under warehouse {1} was on {2}." msgstr "كانت آخر معاملة مخزون للبند {0} تحت المستودع {1} في {2}." @@ -25750,7 +25840,7 @@ msgstr "لا يمكن أن يكون تاريخ فحص الكربون الأخي msgid "Last transacted" msgstr "" -#: erpnext/stock/report/stock_ageing/stock_ageing.py:175 +#: erpnext/stock/report/stock_ageing/stock_ageing.py:177 msgid "Latest" msgstr "اخير" @@ -25893,11 +25983,6 @@ msgstr "" msgid "Leads help you get business, add all your contacts and more as your leads" msgstr "العروض تساعدك للحصول على الأعمال التجارية،وإضافة كافة جهات الاتصال الخاصة بك والمزيد من عروضك" -#. Label of a shortcut in the Accounting Workspace -#: erpnext/accounts/workspace/accounting/accounting.json -msgid "Learn Accounting" -msgstr "" - #. Label of a shortcut in the Stock Workspace #: erpnext/stock/workspace/stock/stock.json msgid "Learn Inventory Management" @@ -26077,7 +26162,7 @@ msgstr "رقم الرخصة" msgid "License Plate" msgstr "" -#: erpnext/controllers/status_updater.py:459 +#: erpnext/controllers/status_updater.py:461 msgid "Limit Crossed" msgstr "الحدود تجاوزت" @@ -26125,7 +26210,7 @@ msgstr "" msgid "Link existing Quality Procedure." msgstr "ربط إجراءات الجودة الحالية." -#: erpnext/buying/doctype/purchase_order/purchase_order.js:644 +#: erpnext/buying/doctype/purchase_order/purchase_order.js:645 msgid "Link to Material Request" msgstr "رابط لطلب المواد" @@ -26134,11 +26219,11 @@ msgstr "رابط لطلب المواد" msgid "Link to Material Requests" msgstr "رابط لطلبات المواد" -#: erpnext/buying/doctype/supplier/supplier.js:125 +#: erpnext/buying/doctype/supplier/supplier.js:127 msgid "Link with Customer" msgstr "" -#: erpnext/selling/doctype/customer/customer.js:198 +#: erpnext/selling/doctype/customer/customer.js:201 msgid "Link with Supplier" msgstr "" @@ -26159,20 +26244,20 @@ msgstr "الفواتير المرتبطة" msgid "Linked Location" msgstr "الموقع المرتبط" -#: erpnext/stock/doctype/item/item.py:994 +#: erpnext/stock/doctype/item/item.py:997 msgid "Linked with submitted documents" msgstr "" -#: erpnext/buying/doctype/supplier/supplier.js:210 -#: erpnext/selling/doctype/customer/customer.js:260 +#: erpnext/buying/doctype/supplier/supplier.js:220 +#: erpnext/selling/doctype/customer/customer.js:279 msgid "Linking Failed" msgstr "" -#: erpnext/buying/doctype/supplier/supplier.js:209 +#: erpnext/buying/doctype/supplier/supplier.js:219 msgid "Linking to Customer Failed. Please try again." msgstr "" -#: erpnext/selling/doctype/customer/customer.js:259 +#: erpnext/selling/doctype/customer/customer.js:278 msgid "Linking to Supplier Failed. Please try again." msgstr "" @@ -26231,7 +26316,7 @@ msgid "Loan Start Date and Loan Period are mandatory to save the Invoice Discoun msgstr "تاريخ بدء القرض وفترة القرض إلزامية لحفظ خصم الفاتورة" #: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:176 -#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:299 +#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:300 msgid "Loans (Liabilities)" msgstr "القروض (الخصوم)" @@ -26277,7 +26362,7 @@ msgid "Logo" msgstr "شعار" #: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:183 -#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:317 +#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:318 msgid "Long-term Provisions" msgstr "" @@ -26340,7 +26425,7 @@ msgstr "تفاصيل السبب المفقود" #. 'Quotation' #: erpnext/crm/doctype/opportunity/opportunity.json #: erpnext/crm/report/lost_opportunity/lost_opportunity.py:49 -#: erpnext/public/js/utils/sales_common.js:548 +#: erpnext/public/js/utils/sales_common.js:573 #: erpnext/selling/doctype/quotation/quotation.json msgid "Lost Reasons" msgstr "أسباب ضائعة" @@ -26432,7 +26517,7 @@ msgstr "نقاط الولاء: {0}" #: erpnext/accounts/doctype/loyalty_point_entry/loyalty_point_entry.json #: erpnext/accounts/doctype/loyalty_program/loyalty_program.json #: erpnext/accounts/doctype/pos_invoice/pos_invoice.json -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.js:1157 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.js:1158 #: erpnext/accounts/doctype/sales_invoice/sales_invoice.json #: erpnext/selling/doctype/customer/customer.json #: erpnext/selling/page/point_of_sale/pos_item_cart.js:952 @@ -26484,11 +26569,11 @@ msgstr "" msgid "MPS Generated" msgstr "" -#: erpnext/manufacturing/doctype/master_production_schedule/master_production_schedule.py:432 +#: erpnext/manufacturing/doctype/master_production_schedule/master_production_schedule.py:448 msgid "MRP Log documents are being created in the background." msgstr "" -#: erpnext/accounts/doctype/bank_statement_import/bank_statement_import.py:156 +#: erpnext/accounts/doctype/bank_statement_import/bank_statement_import.py:157 msgid "MT940 file detected. Please enable 'Import MT940 Format' to proceed." msgstr "" @@ -26512,10 +26597,10 @@ msgstr "عطل الآلة" msgid "Machine operator errors" msgstr "أخطاء مشغل الآلة" -#: erpnext/setup/doctype/company/company.py:685 -#: erpnext/setup/doctype/company/company.py:700 -#: erpnext/setup/doctype/company/company.py:701 -#: erpnext/setup/doctype/company/company.py:702 +#: erpnext/setup/doctype/company/company.py:726 +#: erpnext/setup/doctype/company/company.py:741 +#: erpnext/setup/doctype/company/company.py:742 +#: erpnext/setup/doctype/company/company.py:743 msgid "Main" msgstr "رئيسي" @@ -26622,12 +26707,12 @@ msgstr "صلاحية الصيانة" #. Label of the maintenance_schedule (Link) field in DocType 'Maintenance #. Visit' #. Label of a Link in the Support Workspace -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.js:156 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.js:157 #: erpnext/crm/workspace/crm/crm.json #: erpnext/maintenance/doctype/maintenance_schedule/maintenance_schedule.json #: erpnext/maintenance/doctype/maintenance_visit/maintenance_visit.js:81 #: erpnext/maintenance/doctype/maintenance_visit/maintenance_visit.json -#: erpnext/selling/doctype/sales_order/sales_order.js:1110 +#: erpnext/selling/doctype/sales_order/sales_order.js:1114 #: erpnext/support/workspace/support/support.json msgid "Maintenance Schedule" msgstr "جدول الصيانة" @@ -26733,7 +26818,7 @@ msgstr "نوع الصيانة" #: erpnext/crm/workspace/crm/crm.json #: erpnext/maintenance/doctype/maintenance_schedule/maintenance_schedule.js:87 #: erpnext/maintenance/doctype/maintenance_visit/maintenance_visit.json -#: erpnext/selling/doctype/sales_order/sales_order.js:1103 +#: erpnext/selling/doctype/sales_order/sales_order.js:1107 #: erpnext/support/doctype/warranty_claim/warranty_claim.js:47 #: erpnext/support/workspace/support/support.json msgid "Maintenance Visit" @@ -26755,9 +26840,9 @@ msgstr "المواد الرئيسية والاختيارية التي تم در #. Label of the make (Data) field in DocType 'Vehicle' #: erpnext/accounts/doctype/journal_entry/journal_entry.js:109 -#: erpnext/manufacturing/doctype/job_card/job_card.js:523 -#: erpnext/manufacturing/doctype/work_order/work_order.js:798 -#: erpnext/manufacturing/doctype/work_order/work_order.js:832 +#: erpnext/manufacturing/doctype/job_card/job_card.js:535 +#: erpnext/manufacturing/doctype/work_order/work_order.js:808 +#: erpnext/manufacturing/doctype/work_order/work_order.js:842 #: erpnext/setup/doctype/vehicle/vehicle.json msgid "Make" msgstr "سنة الصنع" @@ -26777,7 +26862,7 @@ msgstr "انشئ قيد اهلاك" msgid "Make Difference Entry" msgstr "جعل دخول الفرق" -#: erpnext/stock/doctype/item/item.js:565 +#: erpnext/stock/doctype/item/item.js:584 msgid "Make Lead Time" msgstr "" @@ -26799,7 +26884,7 @@ msgstr "إنشاء فاتورة شراء" msgid "Make Quotation" msgstr "" -#: erpnext/stock/doctype/purchase_receipt/purchase_receipt.js:353 +#: erpnext/stock/doctype/purchase_receipt/purchase_receipt.js:327 #: erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.js:127 msgid "Make Return Entry" msgstr "" @@ -26815,12 +26900,12 @@ msgstr "انشاء فاتورة المبيعات" msgid "Make Serial No / Batch from Work Order" msgstr "" -#: erpnext/manufacturing/doctype/job_card/job_card.js:92 -#: erpnext/stock/doctype/purchase_receipt/purchase_receipt.js:279 +#: erpnext/manufacturing/doctype/job_card/job_card.js:101 +#: erpnext/stock/doctype/purchase_receipt/purchase_receipt.js:253 msgid "Make Stock Entry" msgstr "جعل دخول الأسهم" -#: erpnext/manufacturing/doctype/job_card/job_card.js:397 +#: erpnext/manufacturing/doctype/job_card/job_card.js:409 msgid "Make Subcontracting PO" msgstr "" @@ -26832,15 +26917,15 @@ msgstr "" msgid "Make project from a template." msgstr "جعل المشروع من قالب." -#: erpnext/stock/doctype/item/item.js:673 +#: erpnext/stock/doctype/item/item.js:692 msgid "Make {0} Variant" msgstr "" -#: erpnext/stock/doctype/item/item.js:675 +#: erpnext/stock/doctype/item/item.js:694 msgid "Make {0} Variants" msgstr "" -#: erpnext/accounts/doctype/journal_entry/journal_entry.py:167 +#: erpnext/accounts/doctype/journal_entry/journal_entry.py:168 msgid "Making Journal Entries against advance accounts: {0} is not recommended. These Journals won't be available for Reconciliation." msgstr "" @@ -26853,8 +26938,8 @@ msgstr "" #: erpnext/assets/doctype/asset/asset.js:150 #: erpnext/assets/doctype/asset/asset.js:160 #: erpnext/assets/doctype/asset/asset.js:176 -#: erpnext/setup/doctype/company/company.js:154 -#: erpnext/setup/doctype/company/company.js:165 +#: erpnext/setup/doctype/company/company.js:161 +#: erpnext/setup/doctype/company/company.js:172 msgid "Manage" msgstr "" @@ -26867,7 +26952,7 @@ msgstr "إدارة تكلفة العمليات" msgid "Manage your orders" msgstr "إدارة طلباتك" -#: erpnext/setup/doctype/company/company.py:454 +#: erpnext/setup/doctype/company/company.py:490 msgid "Management" msgstr "الإدارة" @@ -26883,7 +26968,7 @@ msgstr "" msgid "Mandatory Accounting Dimension" msgstr "" -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1852 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1805 msgid "Mandatory Field" msgstr "" @@ -26899,15 +26984,15 @@ msgstr "إلزامي للميزانية العمومية" msgid "Mandatory For Profit and Loss Account" msgstr "إلزامي لحساب الربح والخسارة" -#: erpnext/selling/doctype/quotation/quotation.py:610 +#: erpnext/selling/doctype/quotation/quotation.py:612 msgid "Mandatory Missing" msgstr "إلزامي مفقود" -#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:633 +#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:635 msgid "Mandatory Purchase Order" msgstr "أمر شراء إلزامي" -#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:654 +#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:656 msgid "Mandatory Purchase Receipt" msgstr "إيصال الشراء الإلزامي" @@ -26985,8 +27070,8 @@ msgstr "لا يمكن إنشاء الإدخال اليدوي! قم بتعطيل #: erpnext/stock/doctype/material_request_item/material_request_item.json #: erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json #: erpnext/stock/doctype/stock_entry/stock_entry.json -#: erpnext/stock/doctype/stock_entry/stock_entry.py:1082 -#: erpnext/stock/doctype/stock_entry/stock_entry.py:1098 +#: erpnext/stock/doctype/stock_entry/stock_entry.py:1150 +#: erpnext/stock/doctype/stock_entry/stock_entry.py:1166 #: erpnext/stock/doctype/stock_entry_type/stock_entry_type.json #: erpnext/subcontracting/doctype/subcontracting_order_item/subcontracting_order_item.json #: erpnext/subcontracting/doctype/subcontracting_receipt_item/subcontracting_receipt_item.json @@ -27021,7 +27106,7 @@ msgstr "الكمية المصنعة" #: erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json #: erpnext/buying/doctype/purchase_order_item/purchase_order_item.json #: erpnext/buying/doctype/supplier_quotation_item/supplier_quotation_item.json -#: erpnext/manufacturing/report/bom_stock_calculated/bom_stock_calculated.py:62 +#: erpnext/manufacturing/report/bom_stock_calculated/bom_stock_calculated.py:70 #: erpnext/stock/doctype/item/item.json #: erpnext/stock/doctype/item_manufacturer/item_manufacturer.json #: erpnext/stock/doctype/manufacturer/manufacturer.json @@ -27051,7 +27136,7 @@ msgstr "الصانع" #: erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json #: erpnext/buying/doctype/purchase_order_item/purchase_order_item.json #: erpnext/buying/doctype/supplier_quotation_item/supplier_quotation_item.json -#: erpnext/manufacturing/report/bom_stock_calculated/bom_stock_calculated.py:68 +#: erpnext/manufacturing/report/bom_stock_calculated/bom_stock_calculated.py:76 #: erpnext/stock/doctype/item_manufacturer/item_manufacturer.json #: erpnext/stock/doctype/material_request_item/material_request_item.json #: erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json @@ -27125,7 +27210,7 @@ msgstr "تاريخ التصنيع" msgid "Manufacturing Manager" msgstr "مدير التصنيع" -#: erpnext/stock/doctype/stock_entry/stock_entry.py:2206 +#: erpnext/stock/doctype/stock_entry/stock_entry.py:2288 msgid "Manufacturing Quantity is mandatory" msgstr "كمية التصنيع إلزامية\\n
        \\nManufacturing Quantity is mandatory" @@ -27137,10 +27222,8 @@ msgstr "قسم التصنيع" #. Name of a DocType #. Label of a Link in the Manufacturing Workspace -#. Label of a Link in the Settings Workspace #: erpnext/manufacturing/doctype/manufacturing_settings/manufacturing_settings.json #: erpnext/manufacturing/workspace/manufacturing/manufacturing.json -#: erpnext/setup/workspace/settings/settings.json msgid "Manufacturing Settings" msgstr "إعدادات التصنيع" @@ -27189,10 +27272,6 @@ msgstr "" msgid "Manufacturing User" msgstr "مستخدم التصنيع" -#: erpnext/stock/doctype/purchase_receipt/purchase_receipt.js:183 -msgid "Mapping Purchase Receipt ..." -msgstr "" - #: erpnext/subcontracting/doctype/subcontracting_inward_order/subcontracting_inward_order.js:106 msgid "Mapping Subcontracting Inward Order ..." msgstr "" @@ -27301,13 +27380,13 @@ msgstr "" msgid "Market Segment" msgstr "سوق القطاع" -#: erpnext/setup/doctype/company/company.py:406 +#: erpnext/setup/doctype/company/company.py:442 msgid "Marketing" msgstr "التسويق" #: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:112 #: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:191 -#: erpnext/setup/doctype/company/company.py:641 +#: erpnext/setup/doctype/company/company.py:682 msgid "Marketing Expenses" msgstr "نفقات تسويقية" @@ -27345,7 +27424,7 @@ msgstr "الرئيسية" msgid "Material" msgstr "مواد" -#: erpnext/manufacturing/doctype/work_order/work_order.js:823 +#: erpnext/manufacturing/doctype/work_order/work_order.js:833 msgid "Material Consumption" msgstr "اهلاك المواد" @@ -27353,12 +27432,12 @@ msgstr "اهلاك المواد" #. Option for the 'Purpose' (Select) field in DocType 'Stock Entry Type' #: erpnext/setup/setup_wizard/operations/install_fixtures.py:114 #: erpnext/stock/doctype/stock_entry/stock_entry.json -#: erpnext/stock/doctype/stock_entry/stock_entry.py:1083 +#: erpnext/stock/doctype/stock_entry/stock_entry.py:1151 #: erpnext/stock/doctype/stock_entry_type/stock_entry_type.json msgid "Material Consumption for Manufacture" msgstr "اهلاك المواد للتصنيع" -#: erpnext/stock/doctype/stock_entry/stock_entry.js:532 +#: erpnext/stock/doctype/stock_entry/stock_entry.js:537 msgid "Material Consumption is not set in Manufacturing Settings." msgstr "لم يتم تعيين اهلاك المواد في إعدادات التصنيع." @@ -27383,7 +27462,7 @@ msgstr "صرف مواد" #. Option for the 'Purpose' (Select) field in DocType 'Stock Entry' #. Option for the 'Purpose' (Select) field in DocType 'Stock Entry Type' #: erpnext/setup/setup_wizard/operations/install_fixtures.py:77 -#: erpnext/stock/doctype/material_request/material_request.js:173 +#: erpnext/stock/doctype/material_request/material_request.js:174 #: erpnext/stock/doctype/stock_entry/stock_entry.json #: erpnext/stock/doctype/stock_entry_type/stock_entry_type.json msgid "Material Receipt" @@ -27420,7 +27499,7 @@ msgstr "أستلام مواد" #. Label of the material_request (Link) field in DocType 'Subcontracting Order #. Service Item' #: erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json -#: erpnext/buying/doctype/purchase_order/purchase_order.js:581 +#: erpnext/buying/doctype/purchase_order/purchase_order.js:582 #: erpnext/buying/doctype/purchase_order_item/purchase_order_item.json #: erpnext/buying/doctype/request_for_quotation/request_for_quotation.js:347 #: erpnext/buying/doctype/request_for_quotation_item/request_for_quotation_item.json @@ -27429,25 +27508,25 @@ msgstr "أستلام مواد" #: erpnext/buying/report/requested_items_to_order_and_receive/requested_items_to_order_and_receive.js:33 #: erpnext/buying/report/requested_items_to_order_and_receive/requested_items_to_order_and_receive.py:184 #: erpnext/buying/workspace/buying/buying.json -#: erpnext/manufacturing/doctype/job_card/job_card.js:151 +#: erpnext/manufacturing/doctype/job_card/job_card.js:160 #: erpnext/manufacturing/doctype/production_plan/production_plan.js:159 #: erpnext/manufacturing/doctype/production_plan/production_plan.json #: erpnext/manufacturing/doctype/production_plan_item/production_plan_item.json #: erpnext/manufacturing/doctype/production_plan_material_request/production_plan_material_request.json #: erpnext/manufacturing/doctype/production_plan_sub_assembly_item/production_plan_sub_assembly_item.json #: erpnext/manufacturing/doctype/work_order/work_order.json -#: erpnext/selling/doctype/sales_order/sales_order.js:1074 +#: erpnext/selling/doctype/sales_order/sales_order.js:1078 #: erpnext/selling/doctype/sales_order_item/sales_order_item.json #: erpnext/selling/report/pending_so_items_for_purchase_request/pending_so_items_for_purchase_request.py:36 #: erpnext/stock/doctype/delivery_note_item/delivery_note_item.json #: erpnext/stock/doctype/material_request/material_request.json -#: erpnext/stock/doctype/material_request/material_request.py:419 -#: erpnext/stock/doctype/material_request/material_request.py:469 +#: erpnext/stock/doctype/material_request/material_request.py:423 +#: erpnext/stock/doctype/material_request/material_request.py:473 #: erpnext/stock/doctype/pick_list/pick_list.json #: erpnext/stock/doctype/pick_list_item/pick_list_item.json #: erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json -#: erpnext/stock/doctype/stock_entry/stock_entry.js:229 -#: erpnext/stock/doctype/stock_entry/stock_entry.js:332 +#: erpnext/stock/doctype/stock_entry/stock_entry.js:234 +#: erpnext/stock/doctype/stock_entry/stock_entry.js:337 #: erpnext/stock/doctype/stock_entry_detail/stock_entry_detail.json #: erpnext/stock/workspace/stock/stock.json #: erpnext/subcontracting/doctype/subcontracting_order_item/subcontracting_order_item.json @@ -27525,11 +27604,11 @@ msgstr "المادة طلب خطة البند" msgid "Material Request Type" msgstr "نوع طلب المواد" -#: erpnext/selling/doctype/sales_order/sales_order.py:1922 +#: erpnext/selling/doctype/sales_order/sales_order.py:1794 msgid "Material Request not created, as quantity for Raw Materials already available." msgstr "لم يتم إنشاء طلب المواد ، ككمية للمواد الخام المتاحة بالفعل." -#: erpnext/stock/doctype/material_request/material_request.py:136 +#: erpnext/stock/doctype/material_request/material_request.py:137 msgid "Material Request of maximum {0} can be made for Item {1} against Sales Order {2}" msgstr "المادة يمكن طلب الحد الأقصى {0} للبند {1} من أمر المبيعات {2}\\n
        \\nMaterial Request of maximum {0} can be made for Item {1} against Sales Order {2}" @@ -27539,11 +27618,11 @@ msgstr "المادة يمكن طلب الحد الأقصى {0} للبند {1} م msgid "Material Request used to make this Stock Entry" msgstr "طلب المواد المستخدمة لانشاء الحركة المخزنية" -#: erpnext/controllers/subcontracting_controller.py:1272 +#: erpnext/controllers/subcontracting_controller.py:1303 msgid "Material Request {0} is cancelled or stopped" msgstr "طلب المواد {0} تم إلغاؤه أو إيقافه" -#: erpnext/selling/doctype/sales_order/sales_order.js:1440 +#: erpnext/selling/doctype/sales_order/sales_order.js:1444 msgid "Material Request {0} submitted." msgstr "تم تقديم طلب المواد {0}." @@ -27555,7 +27634,7 @@ msgstr "المواد المطلوبة" #. Label of the material_requests (Table) field in DocType 'Master Production #. Schedule' #. Label of the material_requests (Table) field in DocType 'Production Plan' -#: erpnext/accounts/doctype/budget/budget.py:337 +#: erpnext/accounts/doctype/budget/budget.py:624 #: erpnext/manufacturing/doctype/master_production_schedule/master_production_schedule.json #: erpnext/manufacturing/doctype/production_plan/production_plan.json msgid "Material Requests" @@ -27593,11 +27672,11 @@ msgstr "" #. Option for the 'Purpose' (Select) field in DocType 'Pick List' #. Option for the 'Purpose' (Select) field in DocType 'Stock Entry' #. Option for the 'Purpose' (Select) field in DocType 'Stock Entry Type' -#: erpnext/manufacturing/doctype/job_card/job_card.js:165 +#: erpnext/manufacturing/doctype/job_card/job_card.js:174 #: erpnext/manufacturing/doctype/material_request_plan_item/material_request_plan_item.json #: erpnext/setup/setup_wizard/operations/install_fixtures.py:83 #: erpnext/stock/doctype/item/item.json -#: erpnext/stock/doctype/material_request/material_request.js:151 +#: erpnext/stock/doctype/material_request/material_request.js:152 #: erpnext/stock/doctype/material_request/material_request.json #: erpnext/stock/doctype/pick_list/pick_list.json #: erpnext/stock/doctype/stock_entry/stock_entry.json @@ -27605,7 +27684,7 @@ msgstr "" msgid "Material Transfer" msgstr "نقل المواد" -#: erpnext/stock/doctype/material_request/material_request.js:157 +#: erpnext/stock/doctype/material_request/material_request.js:158 msgid "Material Transfer (In Transit)" msgstr "" @@ -27648,16 +27727,16 @@ msgstr "المواد المنقولة للعقود من الباطن" msgid "Material from Customer" msgstr "" -#: erpnext/buying/doctype/purchase_order/purchase_order.js:430 +#: erpnext/buying/doctype/purchase_order/purchase_order.js:431 #: erpnext/subcontracting/doctype/subcontracting_order/subcontracting_order.js:536 msgid "Material to Supplier" msgstr "مواد للمورد" -#: erpnext/controllers/subcontracting_controller.py:1493 +#: erpnext/controllers/subcontracting_controller.py:1524 msgid "Materials are already received against the {0} {1}" msgstr "" -#: erpnext/manufacturing/doctype/job_card/job_card.py:738 +#: erpnext/manufacturing/doctype/job_card/job_card.py:733 msgid "Materials needs to be transferred to the work in progress warehouse for the job card {0}" msgstr "" @@ -27726,7 +27805,7 @@ msgstr "أقصى درجة" msgid "Max discount allowed for item: {0} is {1}%" msgstr "" -#: erpnext/manufacturing/doctype/work_order/work_order.js:972 +#: erpnext/manufacturing/doctype/work_order/work_order.js:985 #: erpnext/stock/doctype/pick_list/pick_list.js:198 msgid "Max: {0}" msgstr "الحد الأقصى: {0}" @@ -27748,11 +27827,11 @@ msgstr "" msgid "Maximum Payment Amount" msgstr "" -#: erpnext/stock/doctype/stock_entry/stock_entry.py:3603 +#: erpnext/stock/doctype/stock_entry/stock_entry.py:3707 msgid "Maximum Samples - {0} can be retained for Batch {1} and Item {2}." msgstr "الحد الأقصى للعينات - {0} يمكن الاحتفاظ بالدفعة {1} والبند {2}." -#: erpnext/stock/doctype/stock_entry/stock_entry.py:3594 +#: erpnext/stock/doctype/stock_entry/stock_entry.py:3698 msgid "Maximum Samples - {0} have already been retained for Batch {1} and Item {2} in Batch {3}." msgstr "الحد الأقصى للعينات - {0} تم الاحتفاظ به مسبقا للدفعة {1} و العنصر {2} في الدفعة {3}." @@ -27769,7 +27848,7 @@ msgstr "الاستخدام الأقصى" msgid "Maximum Value" msgstr "" -#: erpnext/controllers/selling_controller.py:256 +#: erpnext/controllers/selling_controller.py:278 msgid "Maximum discount for Item {0} is {1}%" msgstr "" @@ -27807,7 +27886,7 @@ msgstr "" msgid "Megawatt" msgstr "" -#: erpnext/stock/stock_ledger.py:2009 +#: erpnext/stock/stock_ledger.py:2046 msgid "Mention Valuation Rate in the Item master." msgstr "اذكر معدل التقييم في مدير السلعة." @@ -27865,7 +27944,7 @@ msgstr "دمج مع حساب موجود" msgid "Merged" msgstr "" -#: erpnext/accounts/doctype/account/account.py:599 +#: erpnext/accounts/doctype/account/account.py:601 msgid "Merging is only possible if following properties are same in both records. Is Group, Root Type, Company and Account Currency" msgstr "" @@ -28093,7 +28172,7 @@ msgstr "الكمية الادنى لايمكن ان تكون اكبر من ال msgid "Min Qty should be greater than Recurse Over Qty" msgstr "" -#: erpnext/stock/doctype/item/item.js:827 +#: erpnext/stock/doctype/item/item.js:846 msgid "Min Value: {0}, Max Value: {1}, in Increments of: {2}" msgstr "" @@ -28169,29 +28248,29 @@ msgstr "الدقائق" msgid "Miscellaneous Expenses" msgstr "نفقات متنوعة" -#: erpnext/controllers/buying_controller.py:696 +#: erpnext/controllers/buying_controller.py:709 msgid "Mismatch" msgstr "" -#: erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py:1442 +#: erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py:1443 msgid "Missing" msgstr "" #: erpnext/accounts/doctype/pos_opening_entry/pos_opening_entry.py:97 #: erpnext/accounts/doctype/pos_profile/pos_profile.py:200 -#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:593 -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:2391 -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:3047 +#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:595 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:2344 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:2947 #: erpnext/assets/doctype/asset_category/asset_category.py:116 msgid "Missing Account" msgstr "حساب مفقود" -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:456 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:405 msgid "Missing Asset" msgstr "" #: erpnext/accounts/doctype/gl_entry/gl_entry.py:186 -#: erpnext/assets/doctype/asset/asset.py:312 +#: erpnext/assets/doctype/asset/asset.py:313 msgid "Missing Cost Center" msgstr "" @@ -28203,11 +28282,11 @@ msgstr "" msgid "Missing Filters" msgstr "" -#: erpnext/assets/doctype/asset/asset.py:357 +#: erpnext/assets/doctype/asset/asset.py:358 msgid "Missing Finance Book" msgstr "" -#: erpnext/stock/doctype/stock_entry/stock_entry.py:1533 +#: erpnext/stock/doctype/stock_entry/stock_entry.py:1603 msgid "Missing Finished Good" msgstr "" @@ -28215,7 +28294,7 @@ msgstr "" msgid "Missing Formula" msgstr "" -#: erpnext/stock/doctype/stock_entry/stock_entry.py:873 +#: erpnext/stock/doctype/stock_entry/stock_entry.py:941 msgid "Missing Item" msgstr "" @@ -28223,7 +28302,7 @@ msgstr "" msgid "Missing Payments App" msgstr "" -#: erpnext/assets/doctype/asset_repair/asset_repair.py:258 +#: erpnext/assets/doctype/asset_repair/asset_repair.py:297 msgid "Missing Serial No Bundle" msgstr "" @@ -28235,8 +28314,8 @@ msgstr "قالب بريد إلكتروني مفقود للإرسال. يرجى msgid "Missing required filter: {0}" msgstr "" -#: erpnext/manufacturing/doctype/bom/bom.py:1098 -#: erpnext/manufacturing/doctype/work_order/work_order.py:1447 +#: erpnext/manufacturing/doctype/bom/bom.py:1116 +#: erpnext/manufacturing/doctype/work_order/work_order.py:1451 msgid "Missing value" msgstr "" @@ -28251,8 +28330,8 @@ msgstr "ظروف مختلطة" msgid "Mobile: " msgstr "المحمول: " -#: erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py:218 -#: erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py:251 +#: erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py:210 +#: erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py:240 #: erpnext/accounts/report/purchase_register/purchase_register.py:201 #: erpnext/accounts/report/sales_register/sales_register.py:224 msgid "Mode Of Payment" @@ -28341,11 +28420,6 @@ msgstr "" msgid "Module (for Export)" msgstr "" -#. Label of a Card Break in the Settings Workspace -#: erpnext/setup/workspace/settings/settings.json -msgid "Module Settings" -msgstr "" - #. Label of the monitor_progress (Section Break) field in DocType 'Project' #: erpnext/projects/doctype/project/project.json msgid "Monitor Progress" @@ -28383,10 +28457,8 @@ msgstr "شهر (أشهر) بعد نهاية شهر الفاتورة" msgid "Monthly Completed Work Orders" msgstr "أوامر العمل المكتملة شهريًا" -#. Label of the monthly_distribution (Link) field in DocType 'Budget' #. Name of a DocType #. Label of a Link in the Accounting Workspace -#: erpnext/accounts/doctype/budget/budget.json #: erpnext/accounts/doctype/cost_center/cost_center_tree.js:69 #: erpnext/accounts/doctype/monthly_distribution/monthly_distribution.json #: erpnext/accounts/workspace/accounting/accounting.json @@ -28454,9 +28526,12 @@ msgstr "" msgid "Movement" msgstr "" +#. Option for the 'Default Stock Valuation Method' (Select) field in DocType +#. 'Company' #. Option for the 'Valuation Method' (Select) field in DocType 'Item' #. Option for the 'Default Valuation Method' (Select) field in DocType 'Stock #. Settings' +#: erpnext/setup/doctype/company/company.json #: erpnext/stock/doctype/item/item.json #: erpnext/stock/doctype/stock_settings/stock_settings.json msgid "Moving Average" @@ -28476,19 +28551,19 @@ msgstr "" msgid "Multi Currency" msgstr "متعدد العملات" -#: erpnext/manufacturing/doctype/bom_creator/bom_creator.js:41 +#: erpnext/manufacturing/doctype/bom_creator/bom_creator.js:42 msgid "Multi-level BOM Creator" msgstr "" -#: erpnext/selling/doctype/customer/customer.py:384 +#: erpnext/selling/doctype/customer/customer.py:393 msgid "Multiple Loyalty Programs found for Customer {}. Please select manually." msgstr "" -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1221 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1170 msgid "Multiple POS Opening Entry" msgstr "" -#: erpnext/accounts/doctype/pricing_rule/utils.py:343 +#: erpnext/accounts/doctype/pricing_rule/utils.py:346 msgid "Multiple Price Rules exists with same criteria, please resolve conflict by assigning priority. Price Rules: {0}" msgstr "توجد قواعد أسعار متعددة بنفس المعايير، يرجى حل النزاع عن طريق تعيين الأولوية. قاعدة السعر: {0}" @@ -28502,15 +28577,15 @@ msgstr "برنامج متعدد الطبقات" msgid "Multiple Variants" msgstr "متغيرات متعددة" -#: erpnext/stock/doctype/warehouse/warehouse.py:150 +#: erpnext/stock/doctype/warehouse/warehouse.py:152 msgid "Multiple Warehouse Accounts" msgstr "" -#: erpnext/controllers/accounts_controller.py:1230 +#: erpnext/controllers/accounts_controller.py:1299 msgid "Multiple fiscal years exist for the date {0}. Please set company in Fiscal Year" msgstr "يوجد سنوات مالية متعددة لنفس التاريخ {0}. الرجاء تحديد الشركة لهذه السنة المالية\\n
        \\nMultiple fiscal years exist for the date {0}. Please set company in Fiscal Year" -#: erpnext/stock/doctype/stock_entry/stock_entry.py:1540 +#: erpnext/stock/doctype/stock_entry/stock_entry.py:1610 msgid "Multiple items cannot be marked as finished item" msgstr "" @@ -28519,7 +28594,7 @@ msgid "Music" msgstr "" #. Label of the must_be_whole_number (Check) field in DocType 'UOM' -#: erpnext/manufacturing/doctype/work_order/work_order.py:1394 +#: erpnext/manufacturing/doctype/work_order/work_order.py:1398 #: erpnext/setup/doctype/uom/uom.json #: erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py:267 #: erpnext/utilities/transaction_base.py:563 @@ -28638,7 +28713,7 @@ msgstr "تحليل الاحتياجات" msgid "Negative Quantity is not allowed" msgstr "الكمية السلبية غير مسموح بها\\n
        \\nnegative Quantity is not allowed" -#: erpnext/stock/serial_batch_bundle.py:1498 +#: erpnext/stock/serial_batch_bundle.py:1509 msgid "Negative Stock Error" msgstr "" @@ -28793,11 +28868,11 @@ msgstr "صافي الربح (الخسارة" msgid "Net Purchase Amount" msgstr "" -#: erpnext/assets/doctype/asset/asset.py:385 +#: erpnext/assets/doctype/asset/asset.py:386 msgid "Net Purchase Amount is mandatory" msgstr "" -#: erpnext/assets/doctype/asset/asset.py:445 +#: erpnext/assets/doctype/asset/asset.py:493 msgid "Net Purchase Amount should be equal to purchase amount of one single Asset." msgstr "" @@ -28945,7 +29020,7 @@ msgstr "الوزن الصافي" msgid "Net Weight UOM" msgstr "الوزن الصافي لوحدة القياس" -#: erpnext/controllers/accounts_controller.py:1586 +#: erpnext/controllers/accounts_controller.py:1659 msgid "Net total calculation precision loss" msgstr "" @@ -29037,6 +29112,10 @@ msgstr "دخل جديد" msgid "New Invoice" msgstr "" +#: erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.js:337 +msgid "New Journal Entry will be posted for the difference amount. The Posting Date can be modified." +msgstr "" + #: erpnext/assets/doctype/location/location_tree.js:23 msgid "New Location" msgstr "موقع جديد" @@ -29087,7 +29166,7 @@ msgstr "المسلسل الجديد غير ممكن للمستودع . يجب ا msgid "New Task" msgstr "" -#: erpnext/manufacturing/doctype/bom/bom.js:177 +#: erpnext/manufacturing/doctype/bom/bom.js:178 msgid "New Version" msgstr "" @@ -29100,7 +29179,7 @@ msgstr "اسم المخزن الجديد" msgid "New Workplace" msgstr "مكان العمل الجديد" -#: erpnext/selling/doctype/customer/customer.py:353 +#: erpnext/selling/doctype/customer/customer.py:362 msgid "New credit limit is less than current outstanding amount for the customer. Credit limit has to be atleast {0}" msgstr "حد الائتمان الجديد أقل من المبلغ المستحق الحالي للعميل. حد الائتمان يجب أن يكون على الأقل {0}\\n
        \\nNew credit limit is less than current outstanding amount for the customer. Credit limit has to be atleast {0}" @@ -29114,10 +29193,14 @@ msgstr "" msgid "New invoices will be generated as per schedule even if current invoices are unpaid or past due date" msgstr "سيتم إنشاء فواتير جديدة وفقًا للجدول الزمني حتى إذا كانت الفواتير الحالية غير مدفوعة أو تجاوز تاريخ الاستحقاق" -#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js:250 +#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js:251 msgid "New release date should be in the future" msgstr "يجب أن يكون تاريخ الإصدار الجديد في المستقبل" +#: erpnext/accounts/doctype/budget/budget.js:91 +msgid "New revised budget created successfully" +msgstr "" + #: erpnext/templates/pages/projects.html:37 msgid "New task" msgstr "مهمة جديدة" @@ -29172,7 +29255,7 @@ msgstr "لا رد فعل" msgid "No Answer" msgstr "" -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:2493 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:2446 msgid "No Customer found for Inter Company Transactions which represents company {0}" msgstr "لم يتم العثور على زبون للمعاملات بين الشركات التي تمثل الشركة {0}" @@ -29197,15 +29280,15 @@ msgstr "أي عنصر مع الباركود {0}" msgid "No Item with Serial No {0}" msgstr "أي عنصر مع المسلسل لا {0}" -#: erpnext/controllers/subcontracting_controller.py:1407 +#: erpnext/controllers/subcontracting_controller.py:1438 msgid "No Items selected for transfer." msgstr "" -#: erpnext/selling/doctype/sales_order/sales_order.js:1222 +#: erpnext/selling/doctype/sales_order/sales_order.js:1226 msgid "No Items with Bill of Materials to Manufacture" msgstr "لا توجد بنود في قائمة المواد للتصنيع" -#: erpnext/selling/doctype/sales_order/sales_order.js:1360 +#: erpnext/selling/doctype/sales_order/sales_order.js:1364 msgid "No Items with Bill of Materials." msgstr "لا توجد عناصر مع جدول المواد." @@ -29221,14 +29304,14 @@ msgstr "" msgid "No Outstanding Invoices found for this party" msgstr "" -#: erpnext/accounts/doctype/pos_invoice/pos_invoice.py:624 +#: erpnext/accounts/doctype/pos_invoice/pos_invoice.py:669 msgid "No POS Profile found. Please create a New POS Profile first" msgstr "" -#: erpnext/accounts/doctype/journal_entry/journal_entry.py:1627 -#: erpnext/accounts/doctype/journal_entry/journal_entry.py:1687 -#: erpnext/accounts/doctype/journal_entry/journal_entry.py:1701 -#: erpnext/stock/doctype/item/item.py:1366 +#: erpnext/accounts/doctype/journal_entry/journal_entry.py:1766 +#: erpnext/accounts/doctype/journal_entry/journal_entry.py:1826 +#: erpnext/accounts/doctype/journal_entry/journal_entry.py:1840 +#: erpnext/stock/doctype/item/item.py:1369 msgid "No Permission" msgstr "لا يوجد تصريح" @@ -29241,8 +29324,8 @@ msgstr "" msgid "No Records for these settings." msgstr "" -#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:335 -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1132 +#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:337 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1081 msgid "No Remarks" msgstr "لا ملاحظات" @@ -29250,7 +29333,7 @@ msgstr "لا ملاحظات" msgid "No Selection" msgstr "" -#: erpnext/controllers/sales_and_purchase_return.py:857 +#: erpnext/controllers/sales_and_purchase_return.py:858 msgid "No Serial / Batches are available for return" msgstr "" @@ -29262,11 +29345,11 @@ msgstr "" msgid "No Summary" msgstr "" -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:2477 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:2430 msgid "No Supplier found for Inter Company Transactions which represents company {0}" msgstr "لم يتم العثور على مورد للمعاملات بين الشركات التي تمثل الشركة {0}" -#: erpnext/accounts/doctype/tax_withholding_category/tax_withholding_category.py:221 +#: erpnext/accounts/doctype/tax_withholding_category/tax_withholding_category.py:224 msgid "No Tax Withholding data found for the current posting date." msgstr "" @@ -29283,16 +29366,16 @@ msgid "No Unreconciled Payments found for this party" msgstr "" #: erpnext/manufacturing/doctype/production_plan/production_plan.py:768 -#: erpnext/subcontracting/doctype/subcontracting_inward_order/subcontracting_inward_order.py:245 +#: erpnext/subcontracting/doctype/subcontracting_inward_order/subcontracting_inward_order.py:249 msgid "No Work Orders were created" msgstr "" -#: erpnext/stock/doctype/purchase_receipt/purchase_receipt.py:813 -#: erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py:799 +#: erpnext/stock/doctype/purchase_receipt/purchase_receipt.py:828 +#: erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py:854 msgid "No accounting entries for the following warehouses" msgstr "لا القيود المحاسبية للمستودعات التالية" -#: erpnext/selling/doctype/sales_order/sales_order.py:785 +#: erpnext/selling/doctype/sales_order/sales_order.py:784 msgid "No active BOM found for item {0}. Delivery by Serial No cannot be ensured" msgstr "لم يتم العثور على BOM نشط للعنصر {0}. لا يمكن ضمان التسليم عن طريق الرقم التسلسلي" @@ -29300,7 +29383,7 @@ msgstr "لم يتم العثور على BOM نشط للعنصر {0}. لا يمك msgid "No additional fields available" msgstr "" -#: erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py:1357 +#: erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py:1360 msgid "No available quantity to reserve for item {0} in warehouse {1}" msgstr "" @@ -29324,7 +29407,7 @@ msgstr "" msgid "No description given" msgstr "لم يتم اعطاء وصف" -#: erpnext/accounts/doctype/journal_entry/journal_entry.py:218 +#: erpnext/accounts/doctype/journal_entry/journal_entry.py:219 msgid "No difference found for stock account {0}" msgstr "" @@ -29332,7 +29415,7 @@ msgstr "" msgid "No employee was scheduled for call popup" msgstr "" -#: erpnext/controllers/subcontracting_controller.py:1316 +#: erpnext/controllers/subcontracting_controller.py:1347 msgid "No item available for transfer." msgstr "" @@ -29433,11 +29516,11 @@ msgstr "لا الزيارات" msgid "No of Workstations" msgstr "" -#: erpnext/manufacturing/doctype/master_production_schedule/master_production_schedule.py:307 +#: erpnext/manufacturing/doctype/master_production_schedule/master_production_schedule.py:323 msgid "No open Material Requests found for the given criteria." msgstr "" -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1215 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1164 msgid "No open POS Opening Entry found for POS Profile {0}." msgstr "" @@ -29457,7 +29540,7 @@ msgstr "لم يتم العثور على فواتير معلقة" msgid "No outstanding invoices require exchange rate revaluation" msgstr "لا تتطلب الفواتير المستحقة إعادة تقييم سعر الصرف" -#: erpnext/accounts/doctype/payment_entry/payment_entry.py:2492 +#: erpnext/accounts/doctype/payment_entry/payment_entry.py:2493 msgid "No outstanding {0} found for the {1} {2} which qualify the filters you have specified." msgstr "" @@ -29518,11 +29601,11 @@ msgstr "" msgid "No values" msgstr "لا توجد قيم" -#: erpnext/accounts/report/tax_withholding_details/tax_withholding_details.py:347 +#: erpnext/accounts/report/tax_withholding_details/tax_withholding_details.py:361 msgid "No {0} Accounts found for this company." msgstr "" -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:2541 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:2494 msgid "No {0} found for Inter Company Transactions." msgstr "لم يتم العثور على {0} معاملات Inter Company." @@ -29557,12 +29640,12 @@ msgstr "" msgid "Non Profit" msgstr "غير ربحية" -#: erpnext/manufacturing/doctype/bom/bom.py:1469 +#: erpnext/manufacturing/doctype/bom/bom.py:1506 msgid "Non stock items" msgstr "البنود غير الأسهم" #: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:182 -#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:316 +#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:317 msgid "Non-Current Liabilities" msgstr "" @@ -29575,8 +29658,8 @@ msgid "None of the items have any change in quantity or value." msgstr "لا يوجد أي من البنود لديها أي تغيير في كمية أو قيمة.\\n
        \\nNone of the items have any change in quantity or value." #. Name of a UOM -#: erpnext/setup/setup_wizard/data/uom_data.json erpnext/stock/utils.py:705 -#: erpnext/stock/utils.py:707 +#: erpnext/setup/setup_wizard/data/uom_data.json erpnext/stock/utils.py:711 +#: erpnext/stock/utils.py:713 msgid "Nos" msgstr "" @@ -29587,8 +29670,8 @@ msgstr "" msgid "Not Applicable" msgstr "لا ينطبق" -#: erpnext/selling/page/point_of_sale/pos_controller.js:844 -#: erpnext/selling/page/point_of_sale/pos_controller.js:873 +#: erpnext/selling/page/point_of_sale/pos_controller.js:848 +#: erpnext/selling/page/point_of_sale/pos_controller.js:877 msgid "Not Available" msgstr "غير متوفرة" @@ -29649,7 +29732,7 @@ msgstr "لا تسمح بتعيين عنصر بديل للعنصر {0}" msgid "Not allowed to create accounting dimension for {0}" msgstr "غير مسموح بإنشاء بعد محاسبي لـ {0}" -#: erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py:265 +#: erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py:269 msgid "Not allowed to update stock transactions older than {0}" msgstr "غير مسموح بتحديث معاملات الأسهم الأقدم من {0}\\n
        \\nNot allowed to update stock transactions older than {0}" @@ -29687,7 +29770,7 @@ msgstr "" msgid "Note: Email will not be sent to disabled users" msgstr "ملاحظة: لن يتم إرسال الايميل إلى المستخدم الغير نشط" -#: erpnext/manufacturing/doctype/bom/bom.py:680 +#: erpnext/manufacturing/doctype/bom/bom.py:691 msgid "Note: If you want to use the finished good {0} as a raw material, then enable the 'Do Not Explode' checkbox in the Items table against the same raw material." msgstr "" @@ -29695,7 +29778,7 @@ msgstr "" msgid "Note: Item {0} added multiple times" msgstr "ملاحظة: تمت إضافة العنصر {0} عدة مرات" -#: erpnext/controllers/accounts_controller.py:641 +#: erpnext/controllers/accounts_controller.py:711 msgid "Note: Payment Entry will not be created since 'Cash or Bank Account' was not specified" msgstr "ملاحظة : لن يتم إنشاء تدوين المدفوعات نظرا لأن \" حساب النقد او المصرف\" لم يتم تحديده" @@ -29703,11 +29786,11 @@ msgstr "ملاحظة : لن يتم إنشاء تدوين المدفوعات نظ msgid "Note: This Cost Center is a Group. Cannot make accounting entries against groups." msgstr "ملاحظة: مركز التكلفة هذا هو مجموعة. لا يمكن إجراء القيود المحاسبية مقابل المجموعات." -#: erpnext/stock/doctype/item/item.py:623 +#: erpnext/stock/doctype/item/item.py:626 msgid "Note: To merge the items, create a separate Stock Reconciliation for the old item {0}" msgstr "" -#: erpnext/accounts/doctype/journal_entry/journal_entry.py:1084 +#: erpnext/accounts/doctype/journal_entry/journal_entry.py:999 msgid "Note: {0}" msgstr "ملاحظة : {0}" @@ -30058,7 +30141,7 @@ msgstr "الشيكات الصحفية على الجهاز" msgid "Once set, this invoice will be on hold till the set date" msgstr "بمجرد تعيينها ، ستكون هذه الفاتورة قيد الانتظار حتى التاريخ المحدد" -#: erpnext/manufacturing/doctype/work_order/work_order.js:707 +#: erpnext/manufacturing/doctype/work_order/work_order.js:717 msgid "Once the Work Order is Closed. It can't be resumed." msgstr "" @@ -30113,7 +30196,7 @@ msgstr "" msgid "Only Include Allocated Payments" msgstr "" -#: erpnext/accounts/doctype/account/account.py:134 +#: erpnext/accounts/doctype/account/account.py:136 msgid "Only Parent can be of type {0}" msgstr "" @@ -30133,12 +30216,16 @@ msgstr "" #. Description of the 'Is Group' (Check) field in DocType 'Customer Group' #. Description of the 'Is Group' (Check) field in DocType 'Item Group' +#. Description of the 'Is Group' (Check) field in DocType 'Supplier Group' +#. Description of the 'Is Group' (Check) field in DocType 'Territory' #: erpnext/setup/doctype/customer_group/customer_group.json #: erpnext/setup/doctype/item_group/item_group.json +#: erpnext/setup/doctype/supplier_group/supplier_group.json +#: erpnext/setup/doctype/territory/territory.json msgid "Only leaf nodes are allowed in transaction" msgstr "المصنف ليس مجموعة فقط مسموح به في المعاملات" -#: erpnext/stock/doctype/stock_entry/stock_entry.py:1097 +#: erpnext/stock/doctype/stock_entry/stock_entry.py:1165 msgid "Only one {0} entry can be created against the Work Order {1}" msgstr "" @@ -30183,7 +30270,7 @@ msgstr "" msgid "Open Activities HTML" msgstr "" -#: erpnext/manufacturing/doctype/bom/bom_item_preview.html:21 +#: erpnext/manufacturing/doctype/bom/bom_item_preview.html:24 msgid "Open BOM {0}" msgstr "" @@ -30217,7 +30304,7 @@ msgstr "القضايا المفتوحة" msgid "Open Issues " msgstr "القضايا المفتوحة" -#: erpnext/manufacturing/doctype/bom/bom_item_preview.html:25 +#: erpnext/manufacturing/doctype/bom/bom_item_preview.html:28 #: erpnext/manufacturing/doctype/work_order/work_order_preview.html:28 msgid "Open Item {0}" msgstr "" @@ -30332,7 +30419,7 @@ msgstr "مبلغ الافتتاح" #. Option for the 'Balance Type' (Select) field in DocType 'Financial Report #. Row' #: erpnext/accounts/doctype/financial_report_row/financial_report_row.json -#: erpnext/accounts/report/customer_ledger_summary/customer_ledger_summary.py:158 +#: erpnext/accounts/report/customer_ledger_summary/customer_ledger_summary.py:189 msgid "Opening Balance" msgstr "الرصيد الافتتاحي" @@ -30349,7 +30436,7 @@ msgid "Opening Balance Details" msgstr "تفاصيل الرصيد الافتتاحي" #: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:192 -#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:342 +#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:343 msgid "Opening Balance Equity" msgstr "الرصيد الافتتاحي لحقوق الملكية" @@ -30372,18 +30459,18 @@ msgstr "تاريخ الفتح" msgid "Opening Entry" msgstr "فتح مدخل" -#: erpnext/accounts/general_ledger.py:795 +#: erpnext/accounts/general_ledger.py:802 msgid "Opening Entry can not be created after Period Closing Voucher is created." msgstr "" -#: erpnext/accounts/doctype/opening_invoice_creation_tool/opening_invoice_creation_tool.py:283 +#: erpnext/accounts/doctype/opening_invoice_creation_tool/opening_invoice_creation_tool.py:286 msgid "Opening Invoice Creation In Progress" msgstr "جاري إنشاء الفاتورة الافتتاحية" #. Name of a DocType #. Label of a Link in the Accounting Workspace #. Label of a Link in the Home Workspace -#: erpnext/accounts/doctype/account/account_tree.js:197 +#: erpnext/accounts/doctype/account/account_tree.js:205 #: erpnext/accounts/doctype/opening_invoice_creation_tool/opening_invoice_creation_tool.json #: erpnext/accounts/workspace/accounting/accounting.json #: erpnext/setup/workspace/home/home.json @@ -30399,8 +30486,8 @@ msgstr "أداة إنشاء فاتورة بند افتتاحية" msgid "Opening Invoice Item" msgstr "فتح الفاتورة البند" -#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:1642 -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1961 +#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:1644 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1914 msgid "Opening Invoice has rounding adjustment of {0}.

        '{1}' account is required to post these values. Please set it in Company: {2}.

        Or, '{3}' can be enabled to not post any rounding adjustment." msgstr "" @@ -30436,7 +30523,7 @@ msgstr "" #. Label of the opening_stock (Float) field in DocType 'Item' #. Option for the 'Purpose' (Select) field in DocType 'Stock Reconciliation' -#: erpnext/stock/doctype/item/item.json erpnext/stock/doctype/item/item.py:297 +#: erpnext/stock/doctype/item/item.json erpnext/stock/doctype/item/item.py:299 #: erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.json msgid "Opening Stock" msgstr "مخزون أول المدة" @@ -30488,7 +30575,7 @@ msgstr "تكاليف التشغيل (عملة الشركة)" msgid "Operating Cost Per BOM Quantity" msgstr "" -#: erpnext/manufacturing/doctype/bom/bom.py:1545 +#: erpnext/manufacturing/doctype/bom/bom.py:1590 msgid "Operating Cost as per Work Order / BOM" msgstr "تكلفة التشغيل حسب أمر العمل / BOM" @@ -30536,7 +30623,7 @@ msgstr "وصف العملية" msgid "Operation ID" msgstr "معرف العملية" -#: erpnext/manufacturing/doctype/work_order/work_order.js:326 +#: erpnext/manufacturing/doctype/work_order/work_order.js:333 msgid "Operation Id" msgstr "معرف العملية" @@ -30564,7 +30651,7 @@ msgstr "رقم صف العملية" msgid "Operation Time" msgstr "وقت العملية" -#: erpnext/manufacturing/doctype/work_order/work_order.py:1453 +#: erpnext/manufacturing/doctype/work_order/work_order.py:1457 msgid "Operation Time must be greater than 0 for Operation {0}" msgstr "زمن العملية يجب أن يكون أكبر من 0 للعملية {0}\\n
        \\nOperation Time must be greater than 0 for Operation {0}" @@ -30579,11 +30666,11 @@ msgstr "اكتمال عملية لكيفية العديد من السلع تام msgid "Operation time does not depend on quantity to produce" msgstr "" -#: erpnext/manufacturing/doctype/job_card/job_card.js:565 +#: erpnext/manufacturing/doctype/job_card/job_card.js:577 msgid "Operation {0} added multiple times in the work order {1}" msgstr "تمت إضافة العملية {0} عدة مرات في أمر العمل {1}" -#: erpnext/manufacturing/doctype/job_card/job_card.py:1101 +#: erpnext/manufacturing/doctype/job_card/job_card.py:1126 msgid "Operation {0} does not belong to the work order {1}" msgstr "العملية {0} لا تنتمي إلى أمر العمل {1}" @@ -30599,9 +30686,9 @@ msgstr "العملية {0} أطول من أي ساعات عمل متاحة في #. Label of the operations (Table) field in DocType 'Work Order' #. Label of the operation (Section Break) field in DocType 'Email Digest' #: erpnext/manufacturing/doctype/bom/bom.json -#: erpnext/manufacturing/doctype/work_order/work_order.js:307 +#: erpnext/manufacturing/doctype/work_order/work_order.js:314 #: erpnext/manufacturing/doctype/work_order/work_order.json -#: erpnext/setup/doctype/company/company.py:424 +#: erpnext/setup/doctype/company/company.py:460 #: erpnext/setup/doctype/email_digest/email_digest.json #: erpnext/templates/generators/bom.html:61 msgid "Operations" @@ -30613,7 +30700,7 @@ msgstr "العمليات" msgid "Operations Routing" msgstr "" -#: erpnext/manufacturing/doctype/bom/bom.py:1107 +#: erpnext/manufacturing/doctype/bom/bom.py:1125 msgid "Operations cannot be left blank" msgstr "لا يمكن ترك (العمليات) فارغة" @@ -30727,7 +30814,7 @@ msgstr "فرصة سبب ضياع التفاصيل" #. Label of the opportunity_owner (Link) field in DocType 'Opportunity' #: erpnext/crm/doctype/opportunity/opportunity.json #: erpnext/crm/report/opportunity_summary_by_sales_stage/opportunity_summary_by_sales_stage.py:32 -#: erpnext/crm/report/sales_pipeline_analytics/sales_pipeline_analytics.py:65 +#: erpnext/crm/report/sales_pipeline_analytics/sales_pipeline_analytics.py:66 msgid "Opportunity Owner" msgstr "" @@ -30771,7 +30858,7 @@ msgstr "تم إنشاء الفرصة {0}" msgid "Optimize Route" msgstr "تحسين الطريق" -#: erpnext/accounts/doctype/account/account_tree.js:174 +#: erpnext/accounts/doctype/account/account_tree.js:182 msgid "Optional. Sets company's default currency, if not specified." msgstr "اختياري. تحديد العملة الافتراضية للشركة، إذا لم يتم تحديدها." @@ -30779,6 +30866,10 @@ msgstr "اختياري. تحديد العملة الافتراضية للشرك msgid "Optional. This setting will be used to filter in various transactions." msgstr "اختياري . سيتم استخدام هذا الإعداد لفلترت المعاملات المختلفة." +#: erpnext/accounts/doctype/account/account_tree.js:169 +msgid "Optional. Used with Financial Report Template" +msgstr "" + #: erpnext/selling/report/territory_wise_sales/territory_wise_sales.py:43 msgid "Order Amount" msgstr "كمية الطلب" @@ -30821,7 +30912,7 @@ msgstr "" #: erpnext/buying/report/subcontract_order_summary/subcontract_order_summary.py:142 #: erpnext/manufacturing/report/production_plan_summary/production_plan_summary.py:175 -#: erpnext/manufacturing/report/production_planning_report/production_planning_report.py:378 +#: erpnext/manufacturing/report/production_planning_report/production_planning_report.py:383 msgid "Order Qty" msgstr "الكمية النظام" @@ -30872,7 +30963,7 @@ msgstr "" #: erpnext/selling/doctype/quotation/quotation.json #: erpnext/selling/doctype/quotation/quotation_list.js:34 #: erpnext/stock/doctype/material_request/material_request.json -#: erpnext/stock/doctype/material_request/material_request_list.js:39 +#: erpnext/stock/doctype/material_request/material_request_list.js:40 msgid "Ordered" msgstr "تم طلبه" @@ -30909,7 +31000,7 @@ msgstr "الكمية التي تم طلبها" #: erpnext/buying/doctype/supplier/supplier_dashboard.py:11 #: erpnext/selling/doctype/customer/customer_dashboard.py:20 -#: erpnext/selling/doctype/sales_order/sales_order.py:957 +#: erpnext/selling/doctype/sales_order/sales_order.py:956 #: erpnext/setup/doctype/company/company_dashboard.py:23 msgid "Orders" msgstr "أوامر" @@ -31052,7 +31143,7 @@ msgstr "لا تغطيه الضمان" msgid "Out of stock" msgstr "" -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1228 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1177 #: erpnext/selling/page/point_of_sale/pos_controller.js:208 msgid "Outdated POS Opening Entry" msgstr "" @@ -31143,7 +31234,7 @@ msgstr "نحو الخارج" msgid "Over Billing Allowance (%)" msgstr "" -#: erpnext/stock/doctype/purchase_receipt/purchase_receipt.py:1271 +#: erpnext/stock/doctype/purchase_receipt/purchase_receipt.py:1286 msgid "Over Billing Allowance exceeded for Purchase Receipt Item {0} ({1}) by {2}%" msgstr "" @@ -31161,11 +31252,11 @@ msgstr "" msgid "Over Picking Allowance" msgstr "" -#: erpnext/controllers/stock_controller.py:1568 +#: erpnext/controllers/stock_controller.py:1677 msgid "Over Receipt" msgstr "" -#: erpnext/controllers/status_updater.py:464 +#: erpnext/controllers/status_updater.py:466 msgid "Over Receipt/Delivery of {0} {1} ignored for item {2} because you have {3} role." msgstr "" @@ -31180,11 +31271,11 @@ msgstr "" msgid "Over Transfer Allowance (%)" msgstr "" -#: erpnext/controllers/status_updater.py:466 +#: erpnext/controllers/status_updater.py:468 msgid "Overbilling of {0} {1} ignored for item {2} because you have {3} role." msgstr "" -#: erpnext/controllers/accounts_controller.py:2102 +#: erpnext/controllers/accounts_controller.py:2175 msgid "Overbilling of {} ignored because you have {} role." msgstr "" @@ -31200,7 +31291,7 @@ msgstr "" #: erpnext/accounts/doctype/pos_invoice/pos_invoice.json #: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json #: erpnext/accounts/doctype/sales_invoice/sales_invoice.json -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:275 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:277 #: erpnext/assets/doctype/asset_maintenance_log/asset_maintenance_log.json #: erpnext/assets/doctype/asset_maintenance_task/asset_maintenance_task.json #: erpnext/manufacturing/report/production_analytics/production_analytics.py:125 @@ -31421,7 +31512,7 @@ msgstr "" msgid "POS Invoice isn't created by user {}" msgstr "لم ينشئ المستخدم فاتورة نقاط البيع {}" -#: erpnext/accounts/doctype/pos_invoice/pos_invoice.py:194 +#: erpnext/accounts/doctype/pos_invoice/pos_invoice.py:204 msgid "POS Invoice should have the field {0} checked." msgstr "" @@ -31434,11 +31525,11 @@ msgstr "فواتير نقاط البيع" msgid "POS Invoices can't be added when Sales Invoice is enabled" msgstr "" -#: erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.py:667 +#: erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.py:662 msgid "POS Invoices will be consolidated in a background process" msgstr "" -#: erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.py:669 +#: erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.py:664 msgid "POS Invoices will be unconsolidated in a background process" msgstr "" @@ -31456,7 +31547,7 @@ msgstr "مجموعة المواد لنقطة البيع" msgid "POS Opening Entry" msgstr "دخول فتح نقاط البيع" -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1229 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1178 msgid "POS Opening Entry - {0} is outdated. Please close the POS and create a new POS Opening Entry." msgstr "" @@ -31477,7 +31568,7 @@ msgstr "تفاصيل دخول فتح نقاط البيع" msgid "POS Opening Entry Exists" msgstr "" -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1214 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1163 msgid "POS Opening Entry Missing" msgstr "" @@ -31511,7 +31602,7 @@ msgstr "طريقة الدفع في نقاط البيع" msgid "POS Profile" msgstr "الملف الشخصي لنقطة البيع" -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1222 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1171 msgid "POS Profile - {0} has multiple open POS Opening Entries. Please close or cancel the existing entries before proceeding." msgstr "" @@ -31529,11 +31620,11 @@ msgstr "نقاط البيع الشخصية الملف الشخصي" msgid "POS Profile doesn't match {}" msgstr "" -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1182 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1131 msgid "POS Profile is mandatory to mark this invoice as POS Transaction." msgstr "" -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1406 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1355 msgid "POS Profile required to make POS Entry" msgstr "ملف نقطة البيع مطلوب للقيام بإدخال خاص بنقطة البيع" @@ -31640,7 +31731,7 @@ msgstr "عنصر معبأ" msgid "Packed Items" msgstr "عناصر معبأة" -#: erpnext/controllers/stock_controller.py:1406 +#: erpnext/controllers/stock_controller.py:1511 msgid "Packed Items cannot be transferred internally" msgstr "" @@ -31664,7 +31755,7 @@ msgstr "قائمة التعبئة" #. Name of a DocType #. Label of a Link in the Stock Workspace -#: erpnext/stock/doctype/delivery_note/delivery_note.js:299 +#: erpnext/stock/doctype/delivery_note/delivery_note.js:300 #: erpnext/stock/doctype/packing_slip/packing_slip.json #: erpnext/stock/workspace/stock/stock.json msgid "Packing Slip" @@ -31675,7 +31766,7 @@ msgstr "قائمة بمحتويات الشحنة" msgid "Packing Slip Item" msgstr "مادة كشف التعبئة" -#: erpnext/stock/doctype/delivery_note/delivery_note.py:643 +#: erpnext/stock/doctype/delivery_note/delivery_note.py:647 msgid "Packing Slip(s) cancelled" msgstr "تم إلغاء قائمة الشحنة" @@ -31698,7 +31789,7 @@ msgstr "" #: erpnext/accounts/doctype/pos_invoice/pos_invoice.json #: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json #: erpnext/accounts/doctype/sales_invoice/sales_invoice.json -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:281 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:283 msgid "Paid" msgstr "مدفوع" @@ -31719,7 +31810,7 @@ msgstr "مدفوع" #: erpnext/accounts/report/accounts_receivable/accounts_receivable.html:146 #: erpnext/accounts/report/accounts_receivable/accounts_receivable.py:1214 #: erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.py:165 -#: erpnext/accounts/report/customer_ledger_summary/customer_ledger_summary.py:172 +#: erpnext/accounts/report/customer_ledger_summary/customer_ledger_summary.py:203 #: erpnext/accounts/report/pos_register/pos_register.py:209 #: erpnext/selling/page/point_of_sale/pos_payment.js:691 #: erpnext/selling/report/payment_terms_status_for_sales_order/payment_terms_status_for_sales_order.py:56 @@ -31752,7 +31843,7 @@ msgstr "" msgid "Paid Amount After Tax (Company Currency)" msgstr "" -#: erpnext/accounts/doctype/payment_entry/payment_entry.py:2005 +#: erpnext/accounts/doctype/payment_entry/payment_entry.py:2006 msgid "Paid Amount cannot be greater than total negative outstanding amount {0}" msgstr "المبلغ المدفوع لا يمكن أن يكون أكبر من إجمالي المبلغ القائم السالب {0}" @@ -31766,8 +31857,8 @@ msgstr "" msgid "Paid To Account Type" msgstr "" -#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:325 -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1178 +#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:327 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1127 msgid "Paid amount + Write Off Amount can not be greater than Grand Total" msgstr "المبلغ المدفوع + المبلغ المشطوب لا يمكن ان يكون أكبر من المجموع الكلي\\n
        \\nPaid amount + Write Off Amount can not be greater than Grand Total" @@ -31857,7 +31948,7 @@ msgstr "دفعة الأم" msgid "Parent Company" msgstr "الشركة الام" -#: erpnext/setup/doctype/company/company.py:559 +#: erpnext/setup/doctype/company/company.py:595 msgid "Parent Company must be a group company" msgstr "يجب أن تكون الشركة الأم شركة مجموعة" @@ -31923,7 +32014,7 @@ msgstr "الإجراء الرئيسي" msgid "Parent Row No" msgstr "" -#: erpnext/manufacturing/doctype/bom_creator/bom_creator.py:506 +#: erpnext/manufacturing/doctype/bom_creator/bom_creator.py:511 msgid "Parent Row No not found for {0}" msgstr "" @@ -31942,11 +32033,11 @@ msgstr "مجموعة موردي الآباء" msgid "Parent Task" msgstr "المهمة الرئيسية" -#: erpnext/projects/doctype/task/task.py:167 +#: erpnext/projects/doctype/task/task.py:168 msgid "Parent Task {0} is not a Template Task" msgstr "" -#: erpnext/projects/doctype/task/task.py:190 +#: erpnext/projects/doctype/task/task.py:191 msgid "Parent Task {0} must be a Group Task" msgstr "" @@ -31966,7 +32057,7 @@ msgstr "الأم الأرض" msgid "Parent Warehouse" msgstr "المستودع الأصل" -#: erpnext/accounts/doctype/bank_statement_import/bank_statement_import.py:166 +#: erpnext/accounts/doctype/bank_statement_import/bank_statement_import.py:167 msgid "Parsed file is not in valid MT940 format or contains no transactions." msgstr "" @@ -31979,11 +32070,11 @@ msgstr "" msgid "Partial Material Transferred" msgstr "" -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1201 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1150 msgid "Partial Payment in POS Transactions are not allowed." msgstr "" -#: erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py:1720 +#: erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py:1723 msgid "Partial Stock Reservation" msgstr "" @@ -32041,8 +32132,8 @@ msgstr "مدفوعاً جزئياً" #. Option for the 'Status' (Select) field in DocType 'Subcontracting Order' #: erpnext/stock/doctype/material_request/material_request.json #: erpnext/stock/doctype/material_request/material_request_list.js:16 -#: erpnext/stock/doctype/material_request/material_request_list.js:26 -#: erpnext/stock/doctype/material_request/material_request_list.js:35 +#: erpnext/stock/doctype/material_request/material_request_list.js:27 +#: erpnext/stock/doctype/material_request/material_request_list.js:36 #: erpnext/subcontracting/doctype/subcontracting_order/subcontracting_order.json msgid "Partially Received" msgstr "تلقى جزئيا" @@ -32066,7 +32157,7 @@ msgstr "" msgid "Partially Used" msgstr "" -#: erpnext/stock/doctype/material_request/material_request_list.js:28 +#: erpnext/stock/doctype/material_request/material_request_list.js:29 msgid "Partially ordered" msgstr "طلبت جزئيا" @@ -32175,7 +32266,7 @@ msgstr "" #: erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.py:147 #: erpnext/accounts/report/general_and_payment_ledger_comparison/general_and_payment_ledger_comparison.py:228 #: erpnext/accounts/report/general_ledger/general_ledger.js:74 -#: erpnext/accounts/report/general_ledger/general_ledger.py:743 +#: erpnext/accounts/report/general_ledger/general_ledger.py:750 #: erpnext/accounts/report/payment_ledger/payment_ledger.js:51 #: erpnext/accounts/report/payment_ledger/payment_ledger.py:161 #: erpnext/accounts/report/payment_period_based_on_invoice_date/payment_period_based_on_invoice_date.js:46 @@ -32223,7 +32314,7 @@ msgstr "عملة حساب الطرف" msgid "Party Account No. (Bank Statement)" msgstr "" -#: erpnext/controllers/accounts_controller.py:2376 +#: erpnext/controllers/accounts_controller.py:2449 msgid "Party Account {0} currency ({1}) and document currency ({2}) should be same" msgstr "" @@ -32269,7 +32360,7 @@ msgstr "" msgid "Party Link" msgstr "" -#: erpnext/controllers/sales_and_purchase_return.py:50 +#: erpnext/controllers/sales_and_purchase_return.py:49 msgid "Party Mismatch" msgstr "" @@ -32280,7 +32371,7 @@ msgstr "" #: erpnext/accounts/doctype/payment_entry/payment_entry.json #: erpnext/accounts/doctype/payment_request/payment_request.json #: erpnext/accounts/report/general_ledger/general_ledger.js:110 -#: erpnext/accounts/report/general_ledger/general_ledger.py:752 +#: erpnext/accounts/report/general_ledger/general_ledger.py:759 #: erpnext/crm/doctype/contract/contract.json #: erpnext/selling/doctype/party_specific_item/party_specific_item.json #: erpnext/selling/report/address_and_contacts/address_and_contacts.js:22 @@ -32344,7 +32435,7 @@ msgstr "" #: erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.py:141 #: erpnext/accounts/report/general_and_payment_ledger_comparison/general_and_payment_ledger_comparison.py:219 #: erpnext/accounts/report/general_ledger/general_ledger.js:65 -#: erpnext/accounts/report/general_ledger/general_ledger.py:742 +#: erpnext/accounts/report/general_ledger/general_ledger.py:749 #: erpnext/accounts/report/payment_ledger/payment_ledger.js:41 #: erpnext/accounts/report/payment_ledger/payment_ledger.py:157 #: erpnext/accounts/report/payment_period_based_on_invoice_date/payment_period_based_on_invoice_date.js:35 @@ -32432,7 +32523,7 @@ msgstr "" msgid "Pause" msgstr "وقفة" -#: erpnext/manufacturing/doctype/job_card/job_card.js:242 +#: erpnext/manufacturing/doctype/job_card/job_card.js:254 msgid "Pause Job" msgstr "" @@ -32484,7 +32575,7 @@ msgstr "واجب الدفع" #: erpnext/accounts/report/accounts_payable/accounts_payable.js:39 #: erpnext/accounts/report/accounts_receivable/accounts_receivable.py:1160 -#: erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py:211 +#: erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py:203 #: erpnext/accounts/report/purchase_register/purchase_register.py:194 #: erpnext/accounts/report/purchase_register/purchase_register.py:235 msgid "Payable Account" @@ -32510,15 +32601,15 @@ msgstr "إعدادات الدافع" #: erpnext/accounts/doctype/invoice_discounting/invoice_discounting_dashboard.py:10 #: erpnext/accounts/doctype/payment_request/payment_request_dashboard.py:12 #: erpnext/accounts/doctype/pos_invoice/pos_invoice.js:82 -#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js:118 +#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js:119 #: erpnext/accounts/doctype/purchase_invoice/purchase_invoice_dashboard.py:20 #: erpnext/accounts/doctype/purchase_invoice/purchase_invoice_list.js:55 -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.js:95 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.js:96 #: erpnext/accounts/doctype/sales_invoice/sales_invoice_dashboard.py:25 #: erpnext/accounts/doctype/sales_invoice/sales_invoice_list.js:42 -#: erpnext/buying/doctype/purchase_order/purchase_order.js:462 +#: erpnext/buying/doctype/purchase_order/purchase_order.js:463 #: erpnext/buying/doctype/purchase_order/purchase_order_dashboard.py:24 -#: erpnext/selling/doctype/sales_order/sales_order.js:1155 +#: erpnext/selling/doctype/sales_order/sales_order.js:1159 #: erpnext/selling/doctype/sales_order/sales_order_dashboard.py:31 msgid "Payment" msgstr "دفع" @@ -32593,7 +32684,7 @@ msgstr "تاريخ استحقاق السداد" msgid "Payment Entries" msgstr "ادخال دفعات" -#: erpnext/accounts/utils.py:1110 +#: erpnext/accounts/utils.py:1114 msgid "Payment Entries {0} are un-linked" msgstr "تدوين مدفوعات {0} غير مترابطة" @@ -32607,7 +32698,6 @@ msgstr "تدوين مدفوعات {0} غير مترابطة" #. Option for the 'Payment Order Type' (Select) field in DocType 'Payment #. Order' #. Label of a Link in the Accounting Workspace -#. Label of a shortcut in the Accounting Workspace #. Label of a Link in the Payables Workspace #. Label of a shortcut in the Payables Workspace #. Label of a Link in the Receivables Workspace @@ -32641,7 +32731,7 @@ msgstr "دفع الدخول المرجعي" msgid "Payment Entry already exists" msgstr "تدوين المدفوعات موجود بالفعل" -#: erpnext/accounts/utils.py:609 +#: erpnext/accounts/utils.py:613 msgid "Payment Entry has been modified after you pulled it. Please pull it again." msgstr "تم تعديل تدوين مدفوعات بعد سحبه. يرجى سحبه مرة أخرى." @@ -32650,7 +32740,7 @@ msgstr "تم تعديل تدوين مدفوعات بعد سحبه. يرجى سح msgid "Payment Entry is already created" msgstr "تدوين المدفوعات تم انشاؤه بالفعل" -#: erpnext/controllers/accounts_controller.py:1537 +#: erpnext/controllers/accounts_controller.py:1610 msgid "Payment Entry {0} is linked against Order {1}, check if it should be pulled as advance in this invoice." msgstr "" @@ -32686,7 +32776,7 @@ msgstr "بوابة الدفع" msgid "Payment Gateway Account" msgstr "دفع حساب البوابة" -#: erpnext/accounts/utils.py:1377 +#: erpnext/accounts/utils.py:1384 msgid "Payment Gateway Account not created, please create one manually." msgstr "حساب بوابة الدفع لم يتم انشاءه، يرجى إنشاء واحد يدويا." @@ -32849,17 +32939,17 @@ msgstr "المراجع الدفع" #. Name of a DocType #. Label of a Link in the Receivables Workspace #: erpnext/accounts/doctype/accounts_settings/accounts_settings.json -#: erpnext/accounts/doctype/payment_entry/payment_entry.js:1708 +#: erpnext/accounts/doctype/payment_entry/payment_entry.js:1707 #: erpnext/accounts/doctype/payment_entry_reference/payment_entry_reference.json #: erpnext/accounts/doctype/payment_order/payment_order.js:19 #: erpnext/accounts/doctype/payment_order/payment_order.json #: erpnext/accounts/doctype/payment_order_reference/payment_order_reference.json #: erpnext/accounts/doctype/payment_request/payment_request.json -#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js:134 -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.js:133 +#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js:135 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.js:134 #: erpnext/accounts/workspace/receivables/receivables.json -#: erpnext/buying/doctype/purchase_order/purchase_order.js:470 -#: erpnext/selling/doctype/sales_order/sales_order.js:1148 +#: erpnext/buying/doctype/purchase_order/purchase_order.js:471 +#: erpnext/selling/doctype/sales_order/sales_order.js:1152 msgid "Payment Request" msgstr "طلب الدفع من قبل المورد" @@ -32911,7 +33001,7 @@ msgstr "" #: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json #: erpnext/accounts/doctype/sales_invoice/sales_invoice.json #: erpnext/buying/doctype/purchase_order/purchase_order.json -#: erpnext/controllers/accounts_controller.py:2651 +#: erpnext/controllers/accounts_controller.py:2724 #: erpnext/selling/doctype/quotation/quotation.json #: erpnext/selling/doctype/sales_order/sales_order.json msgid "Payment Schedule" @@ -33039,15 +33129,15 @@ msgstr "نوع الدفع يجب أن يكون إما استلام , دفع أو msgid "Payment URL" msgstr "" -#: erpnext/accounts/utils.py:1098 +#: erpnext/accounts/utils.py:1102 msgid "Payment Unlink Error" msgstr "" -#: erpnext/accounts/doctype/journal_entry/journal_entry.py:952 +#: erpnext/accounts/doctype/journal_entry/journal_entry.py:867 msgid "Payment against {0} {1} cannot be greater than Outstanding Amount {2}" msgstr "الدفعة مقابل {0} {1} لا يمكن أن تكون أكبر من المبلغ القائم {2}" -#: erpnext/accounts/doctype/pos_invoice/pos_invoice.py:756 +#: erpnext/accounts/doctype/pos_invoice/pos_invoice.py:801 msgid "Payment amount cannot be less than or equal to 0" msgstr "لا يمكن أن يكون مبلغ الدفعة أقل من أو يساوي 0" @@ -33064,7 +33154,7 @@ msgstr "" msgid "Payment of {0} received successfully. Waiting for other requests to complete..." msgstr "" -#: erpnext/accounts/doctype/pos_invoice/pos_invoice.py:379 +#: erpnext/accounts/doctype/pos_invoice/pos_invoice.py:389 msgid "Payment related to {0} is not completed" msgstr "الدفع المتعلق بـ {0} لم يكتمل" @@ -33123,7 +33213,7 @@ msgid "Payroll Entry" msgstr "" #: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:156 -#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:261 +#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:262 msgid "Payroll Payable" msgstr "رواتب واجبة الدفع" @@ -33173,9 +33263,9 @@ msgstr "في انتظار المبلغ" #. Label of the pending_qty (Float) field in DocType 'Production Plan Item' #: erpnext/buying/report/purchase_order_analysis/purchase_order_analysis.py:254 #: erpnext/manufacturing/doctype/production_plan_item/production_plan_item.json -#: erpnext/manufacturing/doctype/work_order/work_order.js:331 +#: erpnext/manufacturing/doctype/work_order/work_order.js:338 #: erpnext/manufacturing/report/production_plan_summary/production_plan_summary.py:182 -#: erpnext/selling/doctype/sales_order/sales_order.js:1615 +#: erpnext/selling/doctype/sales_order/sales_order.js:1637 #: erpnext/selling/report/pending_so_items_for_purchase_request/pending_so_items_for_purchase_request.py:45 msgid "Pending Qty" msgstr "الكمية التي قيد الانتظار" @@ -33208,7 +33298,7 @@ msgstr "أمر عمل معلق" msgid "Pending activities for today" msgstr "الأنشطة في انتظار لهذا اليوم" -#: erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py:236 +#: erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py:248 msgid "Pending processing" msgstr "" @@ -33306,7 +33396,7 @@ msgstr "تحليل التصور" msgid "Period Based On" msgstr "الفترة على أساس" -#: erpnext/accounts/general_ledger.py:807 +#: erpnext/accounts/general_ledger.py:814 msgid "Period Closed" msgstr "" @@ -33430,7 +33520,7 @@ msgstr "" msgid "Periodic Accounting Entry" msgstr "" -#: erpnext/accounts/doctype/journal_entry/journal_entry.py:244 +#: erpnext/accounts/doctype/journal_entry/journal_entry.py:245 msgid "Periodic Accounting Entry is not allowed for company {0} with perpetual inventory enabled" msgstr "" @@ -33450,7 +33540,7 @@ msgstr "" #: erpnext/assets/doctype/asset_maintenance_task/asset_maintenance_task.json #: erpnext/maintenance/doctype/maintenance_schedule_item/maintenance_schedule_item.json #: erpnext/manufacturing/report/exponential_smoothing_forecasting/exponential_smoothing_forecasting.js:54 -#: erpnext/public/js/financial_statements.js:348 +#: erpnext/public/js/financial_statements.js:359 msgid "Periodicity" msgstr "دورية" @@ -33487,6 +33577,15 @@ msgstr "البريد الالكتروني الشخصية" msgid "Petrol" msgstr "بنزين" +#: erpnext/manufacturing/doctype/bom/bom_item_preview.html:16 +#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:321 +msgid "Phantom Item" +msgstr "" + +#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:430 +msgid "Phantom Item is mandatory" +msgstr "" + #: erpnext/setup/setup_wizard/operations/install_fixtures.py:234 msgid "Pharmaceutical" msgstr "الأدوية" @@ -33504,7 +33603,7 @@ msgstr "" #. Label of the phone_no (Data) field in DocType 'Company' #. Label of the phone_no (Data) field in DocType 'Warehouse' -#: erpnext/setup/doctype/company/company.json +#: erpnext/public/js/print.js:66 erpnext/setup/doctype/company/company.json #: erpnext/stock/doctype/warehouse/warehouse.json msgid "Phone No" msgstr "رقم الهاتف" @@ -33522,9 +33621,9 @@ msgstr "رقم الهاتف" #. Option for the 'From Voucher Type' (Select) field in DocType 'Stock #. Reservation Entry' #. Label of a Link in the Stock Workspace -#: erpnext/selling/doctype/sales_order/sales_order.js:1018 -#: erpnext/stock/doctype/delivery_note/delivery_note.js:202 -#: erpnext/stock/doctype/material_request/material_request.js:142 +#: erpnext/selling/doctype/sales_order/sales_order.js:1022 +#: erpnext/stock/doctype/delivery_note/delivery_note.js:203 +#: erpnext/stock/doctype/material_request/material_request.js:143 #: erpnext/stock/doctype/pick_list/pick_list.json #: erpnext/stock/doctype/stock_entry/stock_entry.json #: erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.json @@ -33859,13 +33958,13 @@ msgstr "الرجاء تحديد شركة" msgid "Please Select a Company." msgstr "الرجاء تحديد شركة." -#: erpnext/stock/doctype/delivery_note/delivery_note.js:165 -#: erpnext/stock/doctype/delivery_note/delivery_note.js:207 +#: erpnext/stock/doctype/delivery_note/delivery_note.js:166 +#: erpnext/stock/doctype/delivery_note/delivery_note.js:208 msgid "Please Select a Customer" msgstr "الرجاء تحديد عميل" -#: erpnext/stock/doctype/purchase_receipt/purchase_receipt.js:139 -#: erpnext/stock/doctype/purchase_receipt/purchase_receipt.js:245 +#: erpnext/stock/doctype/purchase_receipt/purchase_receipt.js:130 +#: erpnext/stock/doctype/purchase_receipt/purchase_receipt.js:219 #: erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.js:145 msgid "Please Select a Supplier" msgstr "الرجاء تحديد مورد" @@ -33878,7 +33977,7 @@ msgstr "" msgid "Please Set Supplier Group in Buying Settings." msgstr "يرجى تعيين مجموعة الموردين في إعدادات الشراء." -#: erpnext/accounts/doctype/payment_entry/payment_entry.js:1879 +#: erpnext/accounts/doctype/payment_entry/payment_entry.js:1878 msgid "Please Specify Account" msgstr "" @@ -33898,7 +33997,7 @@ msgstr "" msgid "Please add Root Account for - {0}" msgstr "" -#: erpnext/accounts/doctype/opening_invoice_creation_tool/opening_invoice_creation_tool.py:299 +#: erpnext/accounts/doctype/opening_invoice_creation_tool/opening_invoice_creation_tool.py:302 msgid "Please add a Temporary Opening account in Chart of Accounts" msgstr "الرجاء إضافة حساب فتح مؤقت في مخطط الحسابات" @@ -33906,15 +34005,15 @@ msgstr "الرجاء إضافة حساب فتح مؤقت في مخطط الحس msgid "Please add atleast one Serial No / Batch No" msgstr "" -#: erpnext/accounts/doctype/bank_statement_import/bank_statement_import.py:84 +#: erpnext/accounts/doctype/bank_statement_import/bank_statement_import.py:85 msgid "Please add the Bank Account column" msgstr "" -#: erpnext/accounts/doctype/account/account_tree.js:235 +#: erpnext/accounts/doctype/account/account_tree.js:243 msgid "Please add the account to root level Company - {0}" msgstr "" -#: erpnext/accounts/doctype/account/account.py:231 +#: erpnext/accounts/doctype/account/account.py:233 msgid "Please add the account to root level Company - {}" msgstr "الرجاء إضافة الحساب إلى شركة على مستوى الجذر - {}" @@ -33922,7 +34021,7 @@ msgstr "الرجاء إضافة الحساب إلى شركة على مستوى msgid "Please add {1} role to user {0}." msgstr "" -#: erpnext/controllers/stock_controller.py:1579 +#: erpnext/controllers/stock_controller.py:1688 msgid "Please adjust the qty or edit {0} to proceed." msgstr "" @@ -33930,32 +34029,32 @@ msgstr "" msgid "Please attach CSV file" msgstr "" -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:3184 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:3084 msgid "Please cancel and amend the Payment Entry" msgstr "" -#: erpnext/accounts/utils.py:1097 +#: erpnext/accounts/utils.py:1101 msgid "Please cancel payment entry manually first" msgstr "" #: erpnext/accounts/doctype/gl_entry/gl_entry.py:328 -#: erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py:344 +#: erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py:348 msgid "Please cancel related transaction." msgstr "" -#: erpnext/accounts/doctype/journal_entry/journal_entry.py:1026 +#: erpnext/accounts/doctype/journal_entry/journal_entry.py:941 msgid "Please check Multi Currency option to allow accounts with other currency" msgstr "يرجى اختيار الخيار عملات متعددة للسماح بحسابات مع عملة أخرى" -#: erpnext/accounts/deferred_revenue.py:543 +#: erpnext/accounts/deferred_revenue.py:544 msgid "Please check Process Deferred Accounting {0} and submit manually after resolving errors." msgstr "" -#: erpnext/manufacturing/doctype/bom/bom.js:86 +#: erpnext/manufacturing/doctype/bom/bom.js:87 msgid "Please check either with operations or FG Based Operating Cost." msgstr "" -#: erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py:450 +#: erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py:524 msgid "Please check the error message and take necessary actions to fix the error and then restart the reposting again." msgstr "" @@ -33980,23 +34079,23 @@ msgstr "الرجاء النقر على \"إنشاء جدول\" لجلب الرق msgid "Please click on 'Generate Schedule' to get schedule" msgstr "الرجاء الضغط علي ' إنشاء الجدول ' للحصول علي جدول\\n
        \\nPlease click on 'Generate Schedule' to get schedule" -#: erpnext/selling/doctype/customer/customer.py:576 +#: erpnext/selling/doctype/customer/customer.py:585 msgid "Please contact any of the following users to extend the credit limits for {0}: {1}" msgstr "" -#: erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py:338 +#: erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py:342 msgid "Please contact any of the following users to {} this transaction." msgstr "" -#: erpnext/selling/doctype/customer/customer.py:569 +#: erpnext/selling/doctype/customer/customer.py:578 msgid "Please contact your administrator to extend the credit limits for {0}." msgstr "" -#: erpnext/accounts/doctype/account/account.py:382 +#: erpnext/accounts/doctype/account/account.py:384 msgid "Please convert the parent account in corresponding child company to a group account." msgstr "الرجاء تحويل الحساب الرئيسي في الشركة الفرعية المقابلة إلى حساب مجموعة." -#: erpnext/selling/doctype/quotation/quotation.py:608 +#: erpnext/selling/doctype/quotation/quotation.py:610 msgid "Please create Customer from Lead {0}." msgstr "الرجاء إنشاء عميل من العميل المحتمل {0}." @@ -34008,23 +34107,23 @@ msgstr "" msgid "Please create a new Accounting Dimension if required." msgstr "" -#: erpnext/controllers/accounts_controller.py:734 +#: erpnext/controllers/accounts_controller.py:804 msgid "Please create purchase from internal sale or delivery document itself" msgstr "" -#: erpnext/assets/doctype/asset/asset.py:395 +#: erpnext/assets/doctype/asset/asset.py:396 msgid "Please create purchase receipt or purchase invoice for the item {0}" msgstr "الرجاء إنشاء إيصال شراء أو فاتورة شراء للعنصر {0}" -#: erpnext/stock/doctype/item/item.py:651 +#: erpnext/stock/doctype/item/item.py:654 msgid "Please delete Product Bundle {0}, before merging {1} into {2}" msgstr "" -#: erpnext/assets/doctype/asset/depreciation.py:552 +#: erpnext/assets/doctype/asset/depreciation.py:554 msgid "Please disable workflow temporarily for Journal Entry {0}" msgstr "" -#: erpnext/assets/doctype/asset/asset.py:449 +#: erpnext/assets/doctype/asset/asset.py:497 msgid "Please do not book expense of multiple assets against one single Asset." msgstr "" @@ -34032,11 +34131,11 @@ msgstr "" msgid "Please do not create more than 500 items at a time" msgstr "يرجى عدم إنشاء أكثر من 500 عنصر في وقت واحد" -#: erpnext/accounts/doctype/budget/budget.py:133 +#: erpnext/accounts/doctype/budget/budget.py:182 msgid "Please enable Applicable on Booking Actual Expenses" msgstr "يرجى تمكين Applicable على Booking Actual Expenses" -#: erpnext/accounts/doctype/budget/budget.py:129 +#: erpnext/accounts/doctype/budget/budget.py:178 msgid "Please enable Applicable on Purchase Order and Applicable on Booking Actual Expenses" msgstr "يرجى تمكين Applicable على أمر الشراء والتطبيق على المصروفات الفعلية للحجز" @@ -34052,32 +34151,32 @@ msgstr "" msgid "Please enable {0} in the {1}." msgstr "" -#: erpnext/controllers/selling_controller.py:812 +#: erpnext/controllers/selling_controller.py:837 msgid "Please enable {} in {} to allow same item in multiple rows" msgstr "" -#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:373 +#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:375 msgid "Please ensure that the {0} account is a Balance Sheet account. You can change the parent account to a Balance Sheet account or select a different account." msgstr "" -#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:381 +#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:383 msgid "Please ensure that the {0} account {1} is a Payable account. You can change the account type to Payable or select a different account." msgstr "" -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1038 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:987 msgid "Please ensure {} account is a Balance Sheet account." msgstr "" -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1048 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:997 msgid "Please ensure {} account {} is a Receivable account." msgstr "" -#: erpnext/stock/doctype/stock_entry/stock_entry.py:595 +#: erpnext/stock/doctype/stock_entry/stock_entry.py:663 msgid "Please enter Difference Account or set default Stock Adjustment Account for company {0}" msgstr "الرجاء إدخال حساب الفرق أو تعيين حساب تسوية المخزون الافتراضي للشركة {0}" -#: erpnext/accounts/doctype/pos_invoice/pos_invoice.py:509 -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1313 +#: erpnext/accounts/doctype/pos_invoice/pos_invoice.py:554 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1262 msgid "Please enter Account for Change Amount" msgstr "الرجاء إدخال الحساب لمبلغ التغيير\\n
        \\nPlease enter Account for Change Amount" @@ -34089,7 +34188,7 @@ msgstr "الرجاء إدخال صلاحية المخول بالتصديق أو msgid "Please enter Cost Center" msgstr "يرجى إدخال مركز التكلفة\\n
        \\nPlease enter Cost Center" -#: erpnext/selling/doctype/sales_order/sales_order.py:407 +#: erpnext/selling/doctype/sales_order/sales_order.py:409 msgid "Please enter Delivery Date" msgstr "الرجاء إدخال تاريخ التسليم" @@ -34106,7 +34205,7 @@ msgstr "الرجاء إدخال حساب النفقات\\n
        \\nPlease enter Ex msgid "Please enter Item Code to get Batch Number" msgstr "الرجاء إدخال رمز العنصر للحصول على رقم الدفعة\\n
        \\nPlease enter Item Code to get Batch Number" -#: erpnext/public/js/controllers/transaction.js:2940 +#: erpnext/public/js/controllers/transaction.js:2948 msgid "Please enter Item Code to get batch no" msgstr "الرجاء إدخال كود البند للحصول على رقم الدفعة" @@ -34138,7 +34237,7 @@ msgstr "الرجاء إدخال إيصال الشراء أولا\\n
        \\nPlease msgid "Please enter Receipt Document" msgstr "الرجاء إدخال مستند الاستلام\\n
        \\nPlease enter Receipt Document" -#: erpnext/accounts/doctype/journal_entry/journal_entry.py:1090 +#: erpnext/accounts/doctype/journal_entry/journal_entry.py:1005 msgid "Please enter Reference date" msgstr "الرجاء إدخال تاريخ المرجع\\n
        \\nPlease enter Reference date" @@ -34158,8 +34257,8 @@ msgstr "" msgid "Please enter Warehouse and Date" msgstr "الرجاء إدخال المستودع والتاريخ" -#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:658 -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1309 +#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:660 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1258 msgid "Please enter Write Off Account" msgstr "الرجاء إدخال حساب الشطب" @@ -34179,7 +34278,7 @@ msgstr "" msgid "Please enter company name first" msgstr "الرجاء إدخال اسم الشركة اولاً" -#: erpnext/controllers/accounts_controller.py:2877 +#: erpnext/controllers/accounts_controller.py:2950 msgid "Please enter default currency in Company Master" msgstr "الرجاء إدخال العملة الافتراضية في شركة الرئيسية" @@ -34207,7 +34306,7 @@ msgstr "من فضلك ادخل تاريخ ترك العمل." msgid "Please enter serial nos" msgstr "" -#: erpnext/setup/doctype/company/company.js:207 +#: erpnext/setup/doctype/company/company.js:214 msgid "Please enter the company name to confirm" msgstr "الرجاء إدخال اسم الشركة للتأكيد" @@ -34215,11 +34314,11 @@ msgstr "الرجاء إدخال اسم الشركة للتأكيد" msgid "Please enter the first delivery date" msgstr "" -#: erpnext/accounts/doctype/pos_invoice/pos_invoice.py:759 +#: erpnext/accounts/doctype/pos_invoice/pos_invoice.py:804 msgid "Please enter the phone number first" msgstr "الرجاء إدخال رقم الهاتف أولاً" -#: erpnext/controllers/buying_controller.py:1164 +#: erpnext/controllers/buying_controller.py:1177 msgid "Please enter the {schedule_date}." msgstr "" @@ -34267,16 +34366,16 @@ msgstr "يرجى التأكد من أن الموظفين أعلاه يقدمون msgid "Please make sure the file you are using has 'Parent Account' column present in the header." msgstr "" -#: erpnext/setup/doctype/company/company.js:209 +#: erpnext/setup/doctype/company/company.js:216 msgid "Please make sure you really want to delete all the transactions for this company. Your master data will remain as it is. This action cannot be undone." msgstr "يرجى التأكد من أنك تريد حقا حذف جميع المعاملات لهذه الشركة. ستبقى بياناتك الرئيسية (الماستر) كما هيا. لا يمكن التراجع عن هذا الإجراء." -#: erpnext/stock/doctype/item/item.js:578 +#: erpnext/stock/doctype/item/item.js:597 msgid "Please mention 'Weight UOM' along with Weight." msgstr "" -#: erpnext/accounts/general_ledger.py:641 #: erpnext/accounts/general_ledger.py:648 +#: erpnext/accounts/general_ledger.py:655 msgid "Please mention '{0}' in Company: {1}" msgstr "" @@ -34317,12 +34416,12 @@ msgstr "" msgid "Please select Template Type to download template" msgstr "يرجى تحديد نوع القالب لتنزيل القالب" -#: erpnext/controllers/taxes_and_totals.py:744 -#: erpnext/public/js/controllers/taxes_and_totals.js:815 +#: erpnext/controllers/taxes_and_totals.py:818 +#: erpnext/public/js/controllers/taxes_and_totals.js:781 msgid "Please select Apply Discount On" msgstr "الرجاء اختيار (تطبيق تخفيض على)" -#: erpnext/selling/doctype/sales_order/sales_order.py:1868 +#: erpnext/selling/doctype/sales_order/sales_order.py:1740 msgid "Please select BOM against item {0}" msgstr "الرجاء اختيار بوم ضد العنصر {0}" @@ -34330,7 +34429,7 @@ msgstr "الرجاء اختيار بوم ضد العنصر {0}" msgid "Please select BOM for Item in Row {0}" msgstr "الرجاء تحديد قائمة المواد للبند في الصف {0}" -#: erpnext/controllers/buying_controller.py:623 +#: erpnext/controllers/buying_controller.py:636 msgid "Please select BOM in BOM field for Item {item_code}." msgstr "يرجى تحديد قائمة المواد في الحقل (قائمة المواد) للبند {item_code}." @@ -34342,13 +34441,13 @@ msgstr "" msgid "Please select Category first" msgstr "الرجاء تحديد التصنيف أولا\\n
        \\nPlease select Category first" -#: erpnext/accounts/doctype/payment_entry/payment_entry.js:1486 +#: erpnext/accounts/doctype/payment_entry/payment_entry.js:1485 #: erpnext/public/js/controllers/accounts.js:94 #: erpnext/public/js/controllers/accounts.js:145 msgid "Please select Charge Type first" msgstr "يرجى تحديد نوع الرسوم أولا" -#: erpnext/accounts/doctype/journal_entry/journal_entry.js:455 +#: erpnext/accounts/doctype/journal_entry/journal_entry.js:459 msgid "Please select Company" msgstr "الرجاء اختيار شركة \\n
        \\nPlease select Company" @@ -34357,7 +34456,7 @@ msgstr "الرجاء اختيار شركة \\n
        \\nPlease select Company" msgid "Please select Company and Posting Date to getting entries" msgstr "يرجى تحديد الشركة وتاريخ النشر للحصول على إدخالات" -#: erpnext/accounts/doctype/journal_entry/journal_entry.js:697 +#: erpnext/accounts/doctype/journal_entry/journal_entry.js:701 #: erpnext/manufacturing/doctype/plant_floor/plant_floor.js:28 msgid "Please select Company first" msgstr "الرجاء تحديد الشركة أولا\\n
        \\nPlease select Company first" @@ -34366,16 +34465,17 @@ msgstr "الرجاء تحديد الشركة أولا\\n
        \\nPlease select Com msgid "Please select Completion Date for Completed Asset Maintenance Log" msgstr "يرجى تحديد تاريخ الانتهاء لاستكمال سجل صيانة الأصول" +#: erpnext/accounts/doctype/pos_invoice/pos_invoice.py:200 #: erpnext/maintenance/doctype/maintenance_visit/maintenance_visit.js:84 #: erpnext/maintenance/doctype/maintenance_visit/maintenance_visit.js:125 msgid "Please select Customer first" msgstr "يرجى اختيار العميل أولا" -#: erpnext/setup/doctype/company/company.py:490 +#: erpnext/setup/doctype/company/company.py:526 msgid "Please select Existing Company for creating Chart of Accounts" msgstr "الرجاء اختيار الشركة الحالية لإنشاء دليل الحسابات" -#: erpnext/subcontracting/doctype/subcontracting_inward_order/subcontracting_inward_order.py:206 +#: erpnext/subcontracting/doctype/subcontracting_inward_order/subcontracting_inward_order.py:210 #: erpnext/subcontracting/doctype/subcontracting_order/subcontracting_order.py:314 msgid "Please select Finished Good Item for Service Item {0}" msgstr "" @@ -34397,7 +34497,7 @@ msgstr "يرجى تحديد حالة الصيانة على أنها اكتملت msgid "Please select Party Type first" msgstr "يرجى تحديد نوع الطرف أولا" -#: erpnext/accounts/doctype/journal_entry/journal_entry.py:250 +#: erpnext/accounts/doctype/journal_entry/journal_entry.py:251 msgid "Please select Periodic Accounting Entry Difference Account" msgstr "" @@ -34405,19 +34505,19 @@ msgstr "" msgid "Please select Posting Date before selecting Party" msgstr "الرجاء تجديد تاريخ النشر قبل تحديد المستفيد\\n
        \\nPlease select Posting Date before selecting Party" -#: erpnext/accounts/doctype/journal_entry/journal_entry.js:698 +#: erpnext/accounts/doctype/journal_entry/journal_entry.js:702 msgid "Please select Posting Date first" msgstr "الرجاء تحديد تاريخ النشر أولا\\n
        \\nPlease select Posting Date first" -#: erpnext/manufacturing/doctype/bom/bom.py:1152 +#: erpnext/manufacturing/doctype/bom/bom.py:1170 msgid "Please select Price List" msgstr "الرجاء اختيار قائمة الأسعار\\n
        \\nPlease select Price List" -#: erpnext/selling/doctype/sales_order/sales_order.py:1870 +#: erpnext/selling/doctype/sales_order/sales_order.py:1742 msgid "Please select Qty against item {0}" msgstr "الرجاء اختيار الكمية ضد العنصر {0}" -#: erpnext/stock/doctype/item/item.py:319 +#: erpnext/stock/doctype/item/item.py:320 msgid "Please select Sample Retention Warehouse in Stock Settings first" msgstr "يرجى تحديد نموذج الاحتفاظ مستودع في إعدادات المخزون أولا" @@ -34429,32 +34529,32 @@ msgstr "" msgid "Please select Start Date and End Date for Item {0}" msgstr "الرجاء تحديد تاريخ البدء وتاريخ الانتهاء للبند {0}" -#: erpnext/accounts/doctype/journal_entry/journal_entry.py:269 +#: erpnext/accounts/doctype/journal_entry/journal_entry.py:270 msgid "Please select Stock Asset Account" msgstr "" -#: erpnext/stock/doctype/stock_entry/stock_entry.py:1457 +#: erpnext/stock/doctype/stock_entry/stock_entry.py:1527 msgid "Please select Subcontracting Order instead of Purchase Order {0}" msgstr "" -#: erpnext/controllers/accounts_controller.py:2726 +#: erpnext/controllers/accounts_controller.py:2799 msgid "Please select Unrealized Profit / Loss account or add default Unrealized Profit / Loss account account for company {0}" msgstr "" -#: erpnext/manufacturing/doctype/bom/bom.py:1384 +#: erpnext/manufacturing/doctype/bom/bom.py:1418 msgid "Please select a BOM" msgstr "يرجى تحديد بوم" #: erpnext/accounts/party.py:430 -#: erpnext/stock/doctype/pick_list/pick_list.py:1583 +#: erpnext/stock/doctype/pick_list/pick_list.py:1591 msgid "Please select a Company" msgstr "الرجاء اختيار الشركة" #: erpnext/accounts/doctype/payment_entry/payment_entry.js:267 -#: erpnext/manufacturing/doctype/bom/bom.js:631 -#: erpnext/manufacturing/doctype/bom/bom.py:261 +#: erpnext/manufacturing/doctype/bom/bom.js:648 +#: erpnext/manufacturing/doctype/bom/bom.py:264 #: erpnext/public/js/controllers/accounts.js:277 -#: erpnext/public/js/controllers/transaction.js:3219 +#: erpnext/public/js/controllers/transaction.js:3244 msgid "Please select a Company first." msgstr "الرجاء تحديد شركة أولاً." @@ -34478,11 +34578,11 @@ msgstr "الرجاء اختيار مورد" msgid "Please select a Warehouse" msgstr "" -#: erpnext/manufacturing/doctype/job_card/job_card.py:1417 +#: erpnext/manufacturing/doctype/job_card/job_card.py:1444 msgid "Please select a Work Order first." msgstr "" -#: erpnext/setup/doctype/holiday_list/holiday_list.py:80 +#: erpnext/setup/doctype/holiday_list/holiday_list.py:89 msgid "Please select a country" msgstr "" @@ -34531,7 +34631,7 @@ msgstr "" msgid "Please select a value for {0} quotation_to {1}" msgstr "يرجى اختيار قيمة ل {0} عرض مسعر إلى {1}" -#: erpnext/assets/doctype/asset_repair/asset_repair.js:154 +#: erpnext/assets/doctype/asset_repair/asset_repair.js:194 msgid "Please select an item code before setting the warehouse." msgstr "" @@ -34543,15 +34643,15 @@ msgstr "" msgid "Please select at least one row to fix" msgstr "" -#: erpnext/selling/doctype/sales_order/sales_order.js:1284 +#: erpnext/selling/doctype/sales_order/sales_order.js:1288 msgid "Please select atleast one item to continue" msgstr "" -#: erpnext/manufacturing/doctype/work_order/work_order.js:374 +#: erpnext/manufacturing/doctype/work_order/work_order.js:381 msgid "Please select atleast one operation to create Job Card" msgstr "" -#: erpnext/accounts/doctype/journal_entry/journal_entry.py:1761 +#: erpnext/accounts/doctype/journal_entry/journal_entry.py:1901 msgid "Please select correct account" msgstr "يرجى اختيارالحساب الصحيح" @@ -34597,6 +34697,10 @@ msgstr "يرجى تحديد الشركة" msgid "Please select the Multiple Tier Program type for more than one collection rules." msgstr "يرجى تحديد نوع البرنامج متعدد الطبقات لأكثر من قواعد مجموعة واحدة." +#: erpnext/stock/doctype/item/item.js:316 +msgid "Please select the Warehouse first" +msgstr "" + #: erpnext/accounts/doctype/coupon_code/coupon_code.py:48 msgid "Please select the customer." msgstr "يرجى اختيار العميل." @@ -34616,13 +34720,13 @@ msgstr "" msgid "Please select valid document type." msgstr "" -#: erpnext/setup/doctype/holiday_list/holiday_list.py:51 +#: erpnext/setup/doctype/holiday_list/holiday_list.py:52 msgid "Please select weekly off day" msgstr "الرجاء اختيار يوم العطلة الاسبوعي" #: erpnext/accounts/doctype/payment_entry/payment_entry.js:1201 #: erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py:606 -#: erpnext/accounts/doctype/tax_withholding_category/tax_withholding_category.py:93 +#: erpnext/accounts/doctype/tax_withholding_category/tax_withholding_category.py:96 msgid "Please select {0} first" msgstr "الرجاء تحديد {0} أولا\\n
        \\nPlease select {0} first" @@ -34630,15 +34734,15 @@ msgstr "الرجاء تحديد {0} أولا\\n
        \\nPlease select {0} first" msgid "Please set 'Apply Additional Discount On'" msgstr "يرجى تحديد 'تطبيق خصم إضافي على'" -#: erpnext/assets/doctype/asset/depreciation.py:779 +#: erpnext/assets/doctype/asset/depreciation.py:781 msgid "Please set 'Asset Depreciation Cost Center' in Company {0}" msgstr "يرجى تحديد \"مركز تكلفة اهلاك الأصول\" للشركة {0}" -#: erpnext/assets/doctype/asset/depreciation.py:777 +#: erpnext/assets/doctype/asset/depreciation.py:779 msgid "Please set 'Gain/Loss Account on Asset Disposal' in Company {0}" msgstr "يرجى تحديد \"احساب لربح / الخسارة عند التخلص من الأصول\" للشركة {0}" -#: erpnext/accounts/general_ledger.py:547 +#: erpnext/accounts/general_ledger.py:554 msgid "Please set '{0}' in Company: {1}" msgstr "" @@ -34646,7 +34750,7 @@ msgstr "" msgid "Please set Account" msgstr "" -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1852 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1805 msgid "Please set Account for Change Amount" msgstr "" @@ -34654,7 +34758,7 @@ msgstr "" msgid "Please set Account in Warehouse {0} or Default Inventory Account in Company {1}" msgstr "يرجى تعيين Account in Warehouse {0} أو Account Inventory Account in Company {1}" -#: erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.py:321 +#: erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.py:333 msgid "Please set Accounting Dimension {} in {}" msgstr "" @@ -34668,7 +34772,7 @@ msgstr "" #: erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.js:58 #: erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.js:68 #: erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.js:78 -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.js:780 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.js:781 msgid "Please set Company" msgstr "يرجى تعيين الشركة" @@ -34676,7 +34780,7 @@ msgstr "يرجى تعيين الشركة" msgid "Please set Customer Address to determine if the transaction is an export." msgstr "" -#: erpnext/assets/doctype/asset/depreciation.py:741 +#: erpnext/assets/doctype/asset/depreciation.py:743 msgid "Please set Depreciation related Accounts in Asset Category {0} or Company {1}" msgstr "يرجى تحديد الحسابات المتعلقة بالاهلاك في فئة الأصول {0} أو الشركة {1}" @@ -34684,21 +34788,21 @@ msgstr "يرجى تحديد الحسابات المتعلقة بالاهلاك msgid "Please set Email/Phone for the contact" msgstr "" -#: erpnext/regional/italy/utils.py:277 +#: erpnext/regional/italy/utils.py:250 #, python-format msgid "Please set Fiscal Code for the customer '%s'" msgstr "" -#: erpnext/regional/italy/utils.py:285 +#: erpnext/regional/italy/utils.py:258 #, python-format msgid "Please set Fiscal Code for the public administration '%s'" msgstr "" -#: erpnext/assets/doctype/asset/depreciation.py:727 +#: erpnext/assets/doctype/asset/depreciation.py:729 msgid "Please set Fixed Asset Account in Asset Category {0}" msgstr "" -#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:590 +#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:592 msgid "Please set Fixed Asset Account in {} against {}." msgstr "" @@ -34706,7 +34810,7 @@ msgstr "" msgid "Please set Parent Row No for item {0}" msgstr "" -#: erpnext/controllers/buying_controller.py:339 +#: erpnext/controllers/buying_controller.py:352 msgid "Please set Purchase Expense Contra Account in Company {0}" msgstr "" @@ -34715,7 +34819,7 @@ msgstr "" msgid "Please set Root Type" msgstr "" -#: erpnext/regional/italy/utils.py:292 +#: erpnext/regional/italy/utils.py:265 #, python-format msgid "Please set Tax ID for the customer '%s'" msgstr "" @@ -34736,36 +34840,32 @@ msgstr "" msgid "Please set a Company" msgstr "الرجاء تعيين شركة" -#: erpnext/assets/doctype/asset/asset.py:309 +#: erpnext/assets/doctype/asset/asset.py:310 msgid "Please set a Cost Center for the Asset or set an Asset Depreciation Cost Center for the Company {}" msgstr "" -#: erpnext/selling/doctype/sales_order/sales_order.py:1622 -msgid "Please set a Supplier against the Items to be considered in the Purchase Order." -msgstr "يرجى تعيين مورد مقابل العناصر التي يجب مراعاتها في أمر الشراء." - -#: erpnext/projects/doctype/project/project.py:729 +#: erpnext/projects/doctype/project/project.py:730 msgid "Please set a default Holiday List for Company {0}" msgstr "" -#: erpnext/setup/doctype/employee/employee.py:269 +#: erpnext/setup/doctype/employee/employee.py:273 msgid "Please set a default Holiday List for Employee {0} or Company {1}" msgstr "يرجى تعيين قائمة العطل الافتراضية للموظف {0} أو الشركة {1}\\n
        \\nPlease set a default Holiday List for Employee {0} or Company {1}" -#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:1111 +#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:1113 msgid "Please set account in Warehouse {0}" msgstr "يرجى تعيين الحساب في مستودع {0}" -#: erpnext/manufacturing/doctype/master_production_schedule/master_production_schedule.js:58 +#: erpnext/manufacturing/doctype/master_production_schedule/master_production_schedule.js:68 msgid "Please set actual demand or sales forecast to generate Material Requirements Planning Report." msgstr "" -#: erpnext/regional/italy/utils.py:247 +#: erpnext/regional/italy/utils.py:220 #, python-format msgid "Please set an Address on the Company '%s'" msgstr "" -#: erpnext/controllers/stock_controller.py:870 +#: erpnext/controllers/stock_controller.py:872 msgid "Please set an Expense Account in the Items table" msgstr "" @@ -34773,35 +34873,35 @@ msgstr "" msgid "Please set an email id for the Lead {0}" msgstr "رجاء ادخال ايميل العميل المحتمل" -#: erpnext/regional/italy/utils.py:303 +#: erpnext/regional/italy/utils.py:276 msgid "Please set at least one row in the Taxes and Charges Table" msgstr "يرجى ضبط صف واحد على الأقل في جدول الضرائب والرسوم" -#: erpnext/regional/italy/utils.py:267 +#: erpnext/regional/italy/utils.py:240 msgid "Please set both the Tax ID and Fiscal Code on Company {0}" msgstr "" -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:2388 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:2341 msgid "Please set default Cash or Bank account in Mode of Payment {0}" msgstr "الرجاء تحديد الحساب البنكي أو النقدي الافتراضي في نوع الدفع\\n
        \\nPlease set default Cash or Bank account in Mode of Payment {0}" #: erpnext/accounts/doctype/pos_opening_entry/pos_opening_entry.py:94 #: erpnext/accounts/doctype/pos_profile/pos_profile.py:197 -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:3044 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:2944 msgid "Please set default Cash or Bank account in Mode of Payment {}" msgstr "الرجاء تعيين حساب نقدي أو مصرفي افتراضي في طريقة الدفع {}" #: erpnext/accounts/doctype/pos_opening_entry/pos_opening_entry.py:96 #: erpnext/accounts/doctype/pos_profile/pos_profile.py:199 -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:3046 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:2946 msgid "Please set default Cash or Bank account in Mode of Payments {}" msgstr "الرجاء تعيين حساب نقدي أو مصرفي افتراضي في طريقة الدفع {}" -#: erpnext/accounts/utils.py:2359 +#: erpnext/accounts/utils.py:2385 msgid "Please set default Exchange Gain/Loss Account in Company {}" msgstr "" -#: erpnext/assets/doctype/asset_repair/asset_repair.py:343 +#: erpnext/assets/doctype/asset_repair/asset_repair.py:386 msgid "Please set default Expense Account in Company {0}" msgstr "" @@ -34809,16 +34909,16 @@ msgstr "" msgid "Please set default UOM in Stock Settings" msgstr "يرجى تعيين الافتراضي UOM في إعدادات الأسهم" -#: erpnext/controllers/stock_controller.py:729 +#: erpnext/controllers/stock_controller.py:731 msgid "Please set default cost of goods sold account in company {0} for booking rounding gain and loss during stock transfer" msgstr "" -#: erpnext/controllers/stock_controller.py:188 +#: erpnext/controllers/stock_controller.py:190 msgid "Please set default inventory account for item {0}, or their item group or brand." msgstr "" #: erpnext/accounts/doctype/payment_entry/payment_entry.py:274 -#: erpnext/accounts/utils.py:1119 +#: erpnext/accounts/utils.py:1123 msgid "Please set default {0} in Company {1}" msgstr "يرجى تعيين {0} الافتراضي للشركة {1}" @@ -34826,19 +34926,19 @@ msgstr "يرجى تعيين {0} الافتراضي للشركة {1}" msgid "Please set filter based on Item or Warehouse" msgstr "يرجى ضبط الفلتر على أساس البند أو المخزن" -#: erpnext/controllers/accounts_controller.py:2292 +#: erpnext/controllers/accounts_controller.py:2365 msgid "Please set one of the following:" msgstr "" -#: erpnext/assets/doctype/asset/asset.py:527 +#: erpnext/assets/doctype/asset/asset.py:575 msgid "Please set opening number of booked depreciations" msgstr "" -#: erpnext/public/js/controllers/transaction.js:2627 +#: erpnext/public/js/controllers/transaction.js:2635 msgid "Please set recurring after saving" msgstr "يرجى تحديد (تكرار) بعد الحفظ" -#: erpnext/regional/italy/utils.py:297 +#: erpnext/regional/italy/utils.py:270 msgid "Please set the Customer Address" msgstr "يرجى ضبط عنوان العميل" @@ -34846,15 +34946,15 @@ msgstr "يرجى ضبط عنوان العميل" msgid "Please set the Default Cost Center in {0} company." msgstr "يرجى تعيين مركز التكلفة الافتراضي في الشركة {0}." -#: erpnext/manufacturing/doctype/work_order/work_order.js:624 +#: erpnext/manufacturing/doctype/work_order/work_order.js:634 msgid "Please set the Item Code first" msgstr "يرجى تعيين رمز العنصر أولا" -#: erpnext/manufacturing/doctype/job_card/job_card.py:1479 +#: erpnext/manufacturing/doctype/job_card/job_card.py:1507 msgid "Please set the Target Warehouse in the Job Card" msgstr "" -#: erpnext/manufacturing/doctype/job_card/job_card.py:1483 +#: erpnext/manufacturing/doctype/job_card/job_card.py:1511 msgid "Please set the WIP Warehouse in the Job Card" msgstr "" @@ -34881,7 +34981,7 @@ msgstr "" msgid "Please set {0} for Batched Item {1}, which is used to set {2} on Submit." msgstr "يرجى تعيين {0} للعنصر المجمّع {1} ، والذي يتم استخدامه لتعيين {2} عند الإرسال." -#: erpnext/regional/italy/utils.py:449 +#: erpnext/regional/italy/utils.py:422 msgid "Please set {0} for address {1}" msgstr "يرجى ضبط {0} للعنوان {1}" @@ -34893,7 +34993,7 @@ msgstr "" msgid "Please set {0} in Company {1} to account for Exchange Gain / Loss" msgstr "" -#: erpnext/controllers/accounts_controller.py:523 +#: erpnext/controllers/accounts_controller.py:593 msgid "Please set {0} to {1}, the same account that was used in the original invoice {2}." msgstr "" @@ -34901,7 +35001,7 @@ msgstr "" msgid "Please setup and enable a group account with the Account Type - {0} for the company {1}" msgstr "" -#: erpnext/assets/doctype/asset/depreciation.py:350 +#: erpnext/assets/doctype/asset/depreciation.py:352 msgid "Please share this email with your support team so that they can find and fix the issue." msgstr "" @@ -34910,13 +35010,13 @@ msgid "Please specify Company" msgstr "يرجى تحديد شركة" #: erpnext/accounts/doctype/pos_invoice/pos_invoice.js:120 -#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js:439 -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.js:517 +#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js:440 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.js:518 msgid "Please specify Company to proceed" msgstr "الرجاء تحديد الشركة للمضى قدما\\n
        \\nPlease specify Company to proceed" -#: erpnext/accounts/doctype/payment_entry/payment_entry.js:1509 -#: erpnext/controllers/accounts_controller.py:3108 +#: erpnext/accounts/doctype/payment_entry/payment_entry.js:1508 +#: erpnext/controllers/accounts_controller.py:3181 #: erpnext/public/js/controllers/accounts.js:117 msgid "Please specify a valid Row ID for row {0} in table {1}" msgstr "يرجى تحديد هوية الصف صالحة لصف {0} في الجدول {1}" @@ -34941,7 +35041,7 @@ msgstr "يرجى التحديد من / إلى النطاق\\n
        \\nPlease speci msgid "Please supply the specified items at the best possible rates" msgstr "يرجى تزويدنا بالبنود المحددة بأفضل الأسعار الممكنة" -#: erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py:235 +#: erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py:247 msgid "Please try again in an hour." msgstr "" @@ -34949,7 +35049,7 @@ msgstr "" msgid "Please uncheck 'Show in Bucket View' to create Orders" msgstr "" -#: erpnext/assets/doctype/asset_repair/asset_repair.py:203 +#: erpnext/assets/doctype/asset_repair/asset_repair.py:237 msgid "Please update Repair Status." msgstr "" @@ -35114,10 +35214,10 @@ msgstr "نفقات بريدية" #: erpnext/accounts/report/bank_reconciliation_statement/bank_reconciliation_statement.py:61 #: erpnext/accounts/report/billed_items_to_be_received/billed_items_to_be_received.py:66 #: erpnext/accounts/report/cheques_and_deposits_incorrectly_cleared/cheques_and_deposits_incorrectly_cleared.py:151 -#: erpnext/accounts/report/general_ledger/general_ledger.py:670 +#: erpnext/accounts/report/general_ledger/general_ledger.py:677 #: erpnext/accounts/report/gross_profit/gross_profit.py:289 -#: erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py:183 -#: erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py:203 +#: erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py:175 +#: erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py:192 #: erpnext/accounts/report/payment_ledger/payment_ledger.py:143 #: erpnext/accounts/report/payment_period_based_on_invoice_date/payment_period_based_on_invoice_date.py:94 #: erpnext/accounts/report/pos_register/pos_register.py:172 @@ -35150,7 +35250,7 @@ msgstr "نفقات بريدية" #: erpnext/stock/report/serial_and_batch_summary/serial_and_batch_summary.py:86 #: erpnext/stock/report/serial_no_and_batch_traceability/serial_no_and_batch_traceability.py:502 #: erpnext/stock/report/serial_no_ledger/serial_no_ledger.py:24 -#: erpnext/stock/report/stock_and_account_value_comparison/stock_and_account_value_comparison.py:113 +#: erpnext/stock/report/stock_and_account_value_comparison/stock_and_account_value_comparison.py:116 #: erpnext/stock/report/stock_ledger_invariant_check/stock_ledger_invariant_check.py:144 #: erpnext/stock/report/stock_ledger_variance/stock_ledger_variance.py:36 #: erpnext/templates/form_grid/bank_reconciliation_grid.html:6 @@ -35163,8 +35263,8 @@ msgstr "تاريخ الترحيل" msgid "Posting Date Inheritance for Exchange Gain / Loss" msgstr "" -#: erpnext/stock/doctype/purchase_receipt/purchase_receipt.py:256 -#: erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py:136 +#: erpnext/stock/doctype/purchase_receipt/purchase_receipt.py:271 +#: erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py:142 msgid "Posting Date cannot be future date" msgstr "لا يمكن أن يكون تاريخ النشر تاريخا مستقبلا\\n
        \\nPosting Date cannot be future date" @@ -35222,18 +35322,18 @@ msgstr "" #: erpnext/stock/report/incorrect_stock_value_report/incorrect_stock_value_report.py:105 #: erpnext/stock/report/serial_no_ledger/serial_no_ledger.js:63 #: erpnext/stock/report/serial_no_ledger/serial_no_ledger.py:25 -#: erpnext/stock/report/stock_and_account_value_comparison/stock_and_account_value_comparison.py:114 +#: erpnext/stock/report/stock_and_account_value_comparison/stock_and_account_value_comparison.py:117 #: erpnext/stock/report/stock_ledger_invariant_check/stock_ledger_invariant_check.py:149 #: erpnext/stock/report/stock_ledger_variance/stock_ledger_variance.py:41 #: erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.json msgid "Posting Time" msgstr "نشر التوقيت" -#: erpnext/stock/doctype/stock_entry/stock_entry.py:2154 +#: erpnext/stock/doctype/stock_entry/stock_entry.py:2236 msgid "Posting date and posting time is mandatory" msgstr "تاريخ النشر و وقت النشر الزامي\\n
        \\nPosting date and posting time is mandatory" -#: erpnext/controllers/sales_and_purchase_return.py:67 +#: erpnext/controllers/sales_and_purchase_return.py:66 msgid "Posting timestamp must be after {0}" msgstr "الطابع الزمني للترحيل يجب أن يكون بعد {0}" @@ -35624,7 +35724,7 @@ msgstr "" msgid "Price is not set for the item." msgstr "" -#: erpnext/manufacturing/doctype/bom/bom.py:492 +#: erpnext/manufacturing/doctype/bom/bom.py:503 msgid "Price not found for item {0} in price list {1}" msgstr "لم يتم العثور على السعر للعنصر {0} في قائمة الأسعار {1}" @@ -35922,7 +36022,7 @@ msgstr "إعدادات الطباعة" msgid "Priorities" msgstr "أولويات" -#: erpnext/stock/doctype/putaway_rule/putaway_rule.py:60 +#: erpnext/stock/doctype/putaway_rule/putaway_rule.py:61 msgid "Priority cannot be lesser than 1." msgstr "" @@ -35997,7 +36097,7 @@ msgstr "وصف العملية" msgid "Process Loss" msgstr "" -#: erpnext/manufacturing/doctype/bom/bom.py:1135 +#: erpnext/manufacturing/doctype/bom/bom.py:1153 msgid "Process Loss Percentage cannot be greater than 100" msgstr "" @@ -36019,7 +36119,7 @@ msgstr "" msgid "Process Loss Qty" msgstr "" -#: erpnext/manufacturing/doctype/job_card/job_card.js:319 +#: erpnext/manufacturing/doctype/job_card/job_card.js:331 msgid "Process Loss Quantity" msgstr "" @@ -36247,7 +36347,7 @@ msgstr "" #. Label of a Card Break in the Manufacturing Workspace #: erpnext/manufacturing/doctype/workstation/workstation.json #: erpnext/manufacturing/workspace/manufacturing/manufacturing.json -#: erpnext/setup/doctype/company/company.py:430 +#: erpnext/setup/doctype/company/company.py:466 msgid "Production" msgstr "الإنتاج" @@ -36394,7 +36494,7 @@ msgstr "الربح هذا العام" #: erpnext/accounts/doctype/account/account.json #: erpnext/accounts/doctype/process_period_closing_voucher_detail/process_period_closing_voucher_detail.json #: erpnext/accounts/workspace/accounting/accounting.json -#: erpnext/public/js/financial_statements.js:261 +#: erpnext/public/js/financial_statements.js:272 msgid "Profit and Loss" msgstr "الربح والخسارة" @@ -36433,7 +36533,7 @@ msgstr "الربحية" msgid "Profitability Analysis" msgstr "تحليل الربحية" -#: erpnext/projects/doctype/task/task.py:153 +#: erpnext/projects/doctype/task/task.py:154 #, python-format msgid "Progress % for a task cannot be more than 100." msgstr "" @@ -36442,7 +36542,7 @@ msgstr "" msgid "Progress (%)" msgstr "" -#: erpnext/projects/doctype/project/project.py:368 +#: erpnext/projects/doctype/project/project.py:370 msgid "Project Collaboration Invitation" msgstr "دعوة للمشاركة في المشاريع" @@ -36484,7 +36584,7 @@ msgstr "حالة المشروع" msgid "Project Summary" msgstr "ملخص المشروع" -#: erpnext/projects/doctype/project/project.py:667 +#: erpnext/projects/doctype/project/project.py:668 msgid "Project Summary for {0}" msgstr "ملخص المشروع لـ {0}" @@ -36560,6 +36660,12 @@ msgstr "مشروع تتبع حركة الأسهم الحكمة" msgid "Project-wise data is not available for Quotation" msgstr "البيانات الخاصة بالمشروع غير متوفرة للعرض المسعر" +#. Label of the projected_on_hand (Float) field in DocType 'Material Request +#. Item' +#: erpnext/stock/doctype/material_request_item/material_request_item.json +msgid "Projected On Hand" +msgstr "" + #. Label of the projected_qty (Float) field in DocType 'Material Request Plan #. Item' #. Label of the projected_qty (Float) field in DocType 'Production Plan Sub @@ -36598,7 +36704,7 @@ msgstr "الكمية المتوقعة" #. Name of a Workspace #. Label of a Card Break in the Projects Workspace -#: erpnext/config/projects.py:7 erpnext/projects/doctype/project/project.py:446 +#: erpnext/config/projects.py:7 erpnext/projects/doctype/project/project.py:447 #: erpnext/projects/workspace/projects/projects.json #: erpnext/selling/doctype/customer/customer_dashboard.py:26 #: erpnext/selling/doctype/sales_order/sales_order_dashboard.py:28 @@ -36615,10 +36721,8 @@ msgstr "مدير المشاريع" #. Name of a DocType #. Label of a Link in the Projects Workspace -#. Label of a Link in the Settings Workspace #: erpnext/projects/doctype/projects_settings/projects_settings.json #: erpnext/projects/workspace/projects/projects.json -#: erpnext/setup/workspace/settings/settings.json msgid "Projects Settings" msgstr "إعدادات المشاريع" @@ -36741,7 +36845,7 @@ msgstr "تزويد بعنوان البريد الإلكتروني المسجل msgid "Providing" msgstr "توفير" -#: erpnext/setup/doctype/company/company.py:529 +#: erpnext/setup/doctype/company/company.py:565 msgid "Provisional Account" msgstr "" @@ -36807,7 +36911,7 @@ msgstr "" #: erpnext/accounts/doctype/tax_rule/tax_rule.json #: erpnext/manufacturing/doctype/material_request_plan_item/material_request_plan_item.json #: erpnext/projects/doctype/project/project_dashboard.py:16 -#: erpnext/setup/doctype/company/company.py:418 erpnext/setup/install.py:334 +#: erpnext/setup/doctype/company/company.py:454 erpnext/setup/install.py:334 #: erpnext/stock/doctype/item/item.json #: erpnext/stock/doctype/item_lead_time/item_lead_time.json #: erpnext/stock/doctype/item_reorder/item_reorder.json @@ -36876,8 +36980,8 @@ msgstr "" msgid "Purchase Expense Contra Account" msgstr "" -#: erpnext/controllers/buying_controller.py:349 -#: erpnext/controllers/buying_controller.py:363 +#: erpnext/controllers/buying_controller.py:362 +#: erpnext/controllers/buying_controller.py:376 msgid "Purchase Expense for Item {0}" msgstr "" @@ -36886,7 +36990,6 @@ msgstr "" #. Option for the 'Invoice Type' (Select) field in DocType 'Payment #. Reconciliation Invoice' #. Name of a DocType -#. Label of a shortcut in the Accounting Workspace #. Label of a Link in the Payables Workspace #. Label of a shortcut in the Payables Workspace #. Label of the purchase_invoice (Link) field in DocType 'Asset' @@ -36909,11 +37012,10 @@ msgstr "" #: erpnext/accounts/print_format/purchase_auditing_voucher/purchase_auditing_voucher.html:5 #: erpnext/accounts/report/billed_items_to_be_received/billed_items_to_be_received.js:22 #: erpnext/accounts/report/billed_items_to_be_received/billed_items_to_be_received.py:53 -#: erpnext/accounts/workspace/accounting/accounting.json #: erpnext/accounts/workspace/payables/payables.json #: erpnext/assets/doctype/asset/asset.json #: erpnext/assets/doctype/asset_repair_purchase_invoice/asset_repair_purchase_invoice.json -#: erpnext/buying/doctype/purchase_order/purchase_order.js:453 +#: erpnext/buying/doctype/purchase_order/purchase_order.js:454 #: erpnext/buying/doctype/purchase_order/purchase_order_list.js:63 #: erpnext/buying/doctype/supplier_quotation/supplier_quotation_list.js:21 #: erpnext/buying/workspace/buying/buying.json @@ -36921,12 +37023,12 @@ msgstr "" #: erpnext/setup/doctype/authorization_rule/authorization_rule.json #: erpnext/stock/doctype/landed_cost_item/landed_cost_item.json #: erpnext/stock/doctype/landed_cost_purchase_receipt/landed_cost_purchase_receipt.json -#: erpnext/stock/doctype/purchase_receipt/purchase_receipt.js:134 -#: erpnext/stock/doctype/purchase_receipt/purchase_receipt.js:286 +#: erpnext/stock/doctype/purchase_receipt/purchase_receipt.js:125 +#: erpnext/stock/doctype/purchase_receipt/purchase_receipt.js:260 #: erpnext/stock/doctype/purchase_receipt/purchase_receipt_list.js:30 #: erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json #: erpnext/stock/doctype/quality_inspection/quality_inspection.json -#: erpnext/stock/doctype/stock_entry/stock_entry.js:313 +#: erpnext/stock/doctype/stock_entry/stock_entry.js:318 msgid "Purchase Invoice" msgstr "فاتورة شراء" @@ -36956,16 +37058,16 @@ msgstr "اصناف فاتورة المشتريات" msgid "Purchase Invoice Trends" msgstr "اتجهات فاتورة الشراء" -#: erpnext/assets/doctype/asset/asset.py:271 +#: erpnext/assets/doctype/asset/asset.py:272 msgid "Purchase Invoice cannot be made against an existing asset {0}" msgstr "لا يمكن إجراء فاتورة الشراء مقابل أصل موجود {0}" -#: erpnext/stock/doctype/purchase_receipt/purchase_receipt.py:433 -#: erpnext/stock/doctype/purchase_receipt/purchase_receipt.py:447 +#: erpnext/stock/doctype/purchase_receipt/purchase_receipt.py:448 +#: erpnext/stock/doctype/purchase_receipt/purchase_receipt.py:462 msgid "Purchase Invoice {0} is already submitted" msgstr "فاتورة الشراء {0} تم ترحيلها من قبل" -#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:2027 +#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:2029 msgid "Purchase Invoices" msgstr "فواتير الشراء" @@ -36988,11 +37090,12 @@ msgstr "فواتير الشراء" #. Label of the purchase_order (Link) field in DocType 'Stock Entry' #. Label of the purchase_order (Link) field in DocType 'Subcontracting Receipt #. Item' +#. Label of a shortcut in the Subcontracting Workspace #: erpnext/accounts/doctype/journal_entry_account/journal_entry_account.json -#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js:144 +#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js:145 #: erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json #: erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json -#: erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py:239 +#: erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py:231 #: erpnext/accounts/report/purchase_register/purchase_register.py:216 #: erpnext/buying/doctype/purchase_order/purchase_order.json #: erpnext/buying/doctype/purchase_receipt_item_supplied/purchase_receipt_item_supplied.json @@ -37003,20 +37106,21 @@ msgstr "فواتير الشراء" #: erpnext/buying/report/purchase_order_analysis/purchase_order_analysis.js:48 #: erpnext/buying/report/purchase_order_analysis/purchase_order_analysis.py:203 #: erpnext/buying/workspace/buying/buying.json -#: erpnext/controllers/buying_controller.py:895 +#: erpnext/controllers/buying_controller.py:908 #: erpnext/crm/doctype/contract/contract.json #: erpnext/manufacturing/doctype/blanket_order/blanket_order.js:54 #: erpnext/manufacturing/doctype/production_plan_sub_assembly_item/production_plan_sub_assembly_item.json #: erpnext/selling/doctype/sales_order/sales_order.js:174 -#: erpnext/selling/doctype/sales_order/sales_order.js:1093 +#: erpnext/selling/doctype/sales_order/sales_order.js:1097 #: erpnext/selling/doctype/sales_order_item/sales_order_item.json #: erpnext/setup/doctype/authorization_rule/authorization_rule.json #: erpnext/stock/doctype/delivery_note_item/delivery_note_item.json -#: erpnext/stock/doctype/material_request/material_request.js:181 -#: erpnext/stock/doctype/purchase_receipt/purchase_receipt.js:240 +#: erpnext/stock/doctype/material_request/material_request.js:182 +#: erpnext/stock/doctype/purchase_receipt/purchase_receipt.js:214 #: erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json #: erpnext/stock/doctype/stock_entry/stock_entry.json #: erpnext/subcontracting/doctype/subcontracting_receipt_item/subcontracting_receipt_item.json +#: erpnext/subcontracting/workspace/subcontracting/subcontracting.json msgid "Purchase Order" msgstr "أمر الشراء" @@ -37076,7 +37180,7 @@ msgstr "صنف امر الشراء" msgid "Purchase Order Item Supplied" msgstr "الأصناف المزوده بامر الشراء" -#: erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py:914 +#: erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py:969 msgid "Purchase Order Item reference is missing in Subcontracting Receipt {0}" msgstr "" @@ -37089,11 +37193,11 @@ msgstr "لم يتم استلام طلبات الشراء في الوقت الم msgid "Purchase Order Pricing Rule" msgstr "قاعدة تسعير أمر الشراء" -#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:629 +#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:631 msgid "Purchase Order Required" msgstr "أمر الشراء مطلوب" -#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:624 +#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:626 msgid "Purchase Order Required for item {}" msgstr "طلب الشراء مطلوب للعنصر {}" @@ -37105,11 +37209,11 @@ msgstr "طلب الشراء مطلوب للعنصر {}" msgid "Purchase Order Trends" msgstr "اتجهات امر الشراء" -#: erpnext/selling/doctype/sales_order/sales_order.js:1577 +#: erpnext/selling/doctype/sales_order/sales_order.js:1581 msgid "Purchase Order already created for all Sales Order items" msgstr "تم إنشاء أمر الشراء بالفعل لجميع بنود أوامر المبيعات" -#: erpnext/stock/doctype/purchase_receipt/purchase_receipt.py:322 +#: erpnext/stock/doctype/purchase_receipt/purchase_receipt.py:337 msgid "Purchase Order number required for Item {0}" msgstr "عدد طلب الشراء مطلوب للبند\\n
        \\nPurchase Order number required for Item {0}" @@ -37117,11 +37221,11 @@ msgstr "عدد طلب الشراء مطلوب للبند\\n
        \\nPurchase Order msgid "Purchase Order {0} created" msgstr "" -#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:667 +#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:669 msgid "Purchase Order {0} is not submitted" msgstr "طلب الشراء {0} يجب أن يعتمد\\n
        \\nPurchase Order {0} is not submitted" -#: erpnext/buying/doctype/purchase_order/purchase_order.py:932 +#: erpnext/buying/doctype/purchase_order/purchase_order.py:931 msgid "Purchase Orders" msgstr "طلبات الشراء" @@ -37131,7 +37235,7 @@ msgstr "طلبات الشراء" msgid "Purchase Orders Items Overdue" msgstr "أوامر الشراء البنود المتأخرة" -#: erpnext/buying/doctype/purchase_order/purchase_order.py:321 +#: erpnext/buying/doctype/purchase_order/purchase_order.py:323 msgid "Purchase Orders are not allowed for {0} due to a scorecard standing of {1}." msgstr "لا يسمح بأوامر الشراء {0} بسبب وضع بطاقة النقاط {1}." @@ -37146,7 +37250,7 @@ msgstr "أوامر الشراء إلى الفاتورة" msgid "Purchase Orders to Receive" msgstr "أوامر الشراء لتلقي" -#: erpnext/controllers/accounts_controller.py:1934 +#: erpnext/controllers/accounts_controller.py:2007 msgid "Purchase Orders {0} are un-linked" msgstr "" @@ -37169,17 +37273,17 @@ msgstr "قائمة أسعار الشراء" #. Reservation Entry' #. Label of a Link in the Stock Workspace #. Label of a shortcut in the Stock Workspace -#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js:169 -#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js:653 -#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js:663 +#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js:170 +#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js:654 +#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js:664 #: erpnext/accounts/doctype/purchase_invoice/purchase_invoice_list.js:49 #: erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json -#: erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py:246 +#: erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py:238 #: erpnext/accounts/report/purchase_register/purchase_register.py:223 #: erpnext/accounts/report/received_items_to_be_billed/received_items_to_be_billed.js:22 #: erpnext/accounts/report/received_items_to_be_billed/received_items_to_be_billed.py:21 #: erpnext/assets/doctype/asset/asset.json -#: erpnext/buying/doctype/purchase_order/purchase_order.js:420 +#: erpnext/buying/doctype/purchase_order/purchase_order.js:421 #: erpnext/buying/doctype/purchase_order/purchase_order_list.js:69 #: erpnext/setup/doctype/authorization_rule/authorization_rule.json #: erpnext/stock/doctype/landed_cost_item/landed_cost_item.json @@ -37228,11 +37332,11 @@ msgstr "شراء السلعة استلام الموردة" msgid "Purchase Receipt No" msgstr "لا شراء استلام" -#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:650 +#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:652 msgid "Purchase Receipt Required" msgstr "إيصال استلام المشتريات مطلوب" -#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:645 +#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:647 msgid "Purchase Receipt Required for item {}" msgstr "إيصال الشراء مطلوب للعنصر {}" @@ -37245,15 +37349,15 @@ msgstr "إيصال الشراء مطلوب للعنصر {}" msgid "Purchase Receipt Trends" msgstr "شراء اتجاهات الإيصال" -#: erpnext/stock/doctype/purchase_receipt/purchase_receipt.js:381 +#: erpnext/stock/doctype/purchase_receipt/purchase_receipt.js:355 msgid "Purchase Receipt doesn't have any Item for which Retain Sample is enabled." msgstr "لا يحتوي إيصال الشراء على أي عنصر تم تمكين الاحتفاظ عينة به." -#: erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py:991 +#: erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py:1046 msgid "Purchase Receipt {0} created." msgstr "" -#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:674 +#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:676 msgid "Purchase Receipt {0} is not submitted" msgstr "إيصال استلام المشتريات {0} لم يتم تقديمه" @@ -37264,13 +37368,13 @@ msgstr "إيصال استلام المشتريات {0} لم يتم تقديمه" msgid "Purchase Register" msgstr "سجل شراء" -#: erpnext/stock/doctype/purchase_receipt/purchase_receipt.js:276 +#: erpnext/stock/doctype/purchase_receipt/purchase_receipt.js:250 msgid "Purchase Return" msgstr "شراء العودة" #. Label of the purchase_tax_template (Link) field in DocType 'Tax Rule' #: erpnext/accounts/doctype/tax_rule/tax_rule.json -#: erpnext/setup/doctype/company/company.js:138 +#: erpnext/setup/doctype/company/company.js:145 msgid "Purchase Tax Template" msgstr "قالب الضرائب على المشتريات" @@ -37340,7 +37444,7 @@ msgstr "طلبات الشراء تساعدك على تخطيط ومتابعة ع msgid "Purchased" msgstr "اشترى" -#: erpnext/regional/report/vat_audit_report/vat_audit_report.py:185 +#: erpnext/regional/report/vat_audit_report/vat_audit_report.py:146 msgid "Purchases" msgstr "" @@ -37360,17 +37464,17 @@ msgstr "المشتريات" #. Label of the purpose (Select) field in DocType 'Stock Entry Type' #. Label of the purpose (Select) field in DocType 'Stock Reconciliation' #: erpnext/assets/doctype/asset_movement/asset_movement.json -#: erpnext/manufacturing/doctype/master_production_schedule/master_production_schedule.js:153 +#: erpnext/manufacturing/doctype/master_production_schedule/master_production_schedule.js:163 #: erpnext/stock/doctype/material_request/material_request.json #: erpnext/stock/doctype/pick_list/pick_list.json -#: erpnext/stock/doctype/stock_entry/stock_entry.js:348 +#: erpnext/stock/doctype/stock_entry/stock_entry.js:353 #: erpnext/stock/doctype/stock_entry/stock_entry.json #: erpnext/stock/doctype/stock_entry_type/stock_entry_type.json #: erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.json msgid "Purpose" msgstr "غرض" -#: erpnext/stock/doctype/stock_entry/stock_entry.py:414 +#: erpnext/stock/doctype/stock_entry/stock_entry.py:477 msgid "Purpose must be one of {0}" msgstr "الهدف يجب ان يكون واحد ل {0}\\n
        \\nPurpose must be one of {0}" @@ -37392,7 +37496,7 @@ msgstr "" msgid "Putaway Rule" msgstr "" -#: erpnext/stock/doctype/putaway_rule/putaway_rule.py:52 +#: erpnext/stock/doctype/putaway_rule/putaway_rule.py:53 msgid "Putaway Rule already exists for Item {0} in Warehouse {1}." msgstr "" @@ -37435,7 +37539,7 @@ msgstr "" #: erpnext/controllers/trends.py:268 erpnext/controllers/trends.py:280 #: erpnext/controllers/trends.py:285 #: erpnext/crm/doctype/opportunity_item/opportunity_item.json -#: erpnext/manufacturing/doctype/bom/bom.js:1031 +#: erpnext/manufacturing/doctype/bom/bom.js:1048 #: erpnext/manufacturing/doctype/bom_creator_item/bom_creator_item.json #: erpnext/manufacturing/doctype/bom_item/bom_item.json #: erpnext/manufacturing/doctype/bom_scrap_item/bom_scrap_item.json @@ -37445,11 +37549,11 @@ msgstr "" #: erpnext/manufacturing/doctype/production_plan_item_reference/production_plan_item_reference.json #: erpnext/manufacturing/doctype/work_order_item/work_order_item.json #: erpnext/manufacturing/doctype/workstation/workstation_job_card.html:28 -#: erpnext/manufacturing/report/bom_explorer/bom_explorer.py:57 -#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:213 -#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:307 -#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:372 -#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:470 +#: erpnext/manufacturing/report/bom_explorer/bom_explorer.py:69 +#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:235 +#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:333 +#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:398 +#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:499 #: erpnext/public/js/stock_reservation.js:134 #: erpnext/public/js/stock_reservation.js:336 erpnext/public/js/utils.js:771 #: erpnext/selling/doctype/delivery_schedule_item/delivery_schedule_item.json @@ -37458,8 +37562,8 @@ msgstr "" #: erpnext/selling/doctype/sales_order/sales_order.js:494 #: erpnext/selling/doctype/sales_order/sales_order.js:584 #: erpnext/selling/doctype/sales_order/sales_order.js:631 -#: erpnext/selling/doctype/sales_order/sales_order.js:1261 -#: erpnext/selling/doctype/sales_order/sales_order.js:1413 +#: erpnext/selling/doctype/sales_order/sales_order.js:1265 +#: erpnext/selling/doctype/sales_order/sales_order.js:1417 #: erpnext/selling/report/sales_order_analysis/sales_order_analysis.py:255 #: erpnext/stock/doctype/landed_cost_item/landed_cost_item.json #: erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.json @@ -37548,23 +37652,27 @@ msgstr "الكمية المستهلكة لكل وحدة" msgid "Qty In Stock" msgstr "" -#: erpnext/manufacturing/report/bom_stock_calculated/bom_stock_calculated.py:74 +#: erpnext/manufacturing/report/bom_stock_calculated/bom_stock_calculated.py:82 msgid "Qty Per Unit" msgstr "" #. Label of the for_quantity (Float) field in DocType 'Job Card' #. Label of the qty (Float) field in DocType 'Work Order' -#: erpnext/manufacturing/doctype/bom/bom.js:330 +#: erpnext/manufacturing/doctype/bom/bom.js:337 #: erpnext/manufacturing/doctype/job_card/job_card.json #: erpnext/manufacturing/doctype/work_order/work_order.json #: erpnext/manufacturing/report/process_loss_report/process_loss_report.py:82 msgid "Qty To Manufacture" msgstr "الكمية للتصنيع" -#: erpnext/manufacturing/doctype/work_order/work_order.py:1390 +#: erpnext/manufacturing/doctype/work_order/work_order.py:1394 msgid "Qty To Manufacture ({0}) cannot be a fraction for the UOM {2}. To allow this, disable '{1}' in the UOM {2}." msgstr "" +#: erpnext/manufacturing/doctype/job_card/job_card.py:224 +msgid "Qty To Manufacture in the job card cannot be greater than Qty To Manufacture in the work order for the operation {0}.

        Solution: Either you can reduce the Qty To Manufacture in the job card or set the 'Overproduction Percentage For Work Order' in the {1}." +msgstr "" + #. Label of the qty_to_produce (Float) field in DocType 'Batch' #: erpnext/stock/doctype/batch/batch.json msgid "Qty To Produce" @@ -37612,7 +37720,7 @@ msgstr "الكمية حسب السهم لوحدة قياس السهم" msgid "Qty for which recursion isn't applicable." msgstr "" -#: erpnext/manufacturing/doctype/work_order/work_order.js:970 +#: erpnext/manufacturing/doctype/work_order/work_order.js:983 msgid "Qty for {0}" msgstr "الكمية ل {0}" @@ -37663,8 +37771,8 @@ msgstr "الكمية للتسليم" msgid "Qty to Fetch" msgstr "" -#: erpnext/manufacturing/doctype/job_card/job_card.js:291 -#: erpnext/manufacturing/doctype/job_card/job_card.py:774 +#: erpnext/manufacturing/doctype/job_card/job_card.js:303 +#: erpnext/manufacturing/doctype/job_card/job_card.py:769 msgid "Qty to Manufacture" msgstr "الكمية للتصنيع" @@ -37804,7 +37912,7 @@ msgstr "هدف جودة الهدف" #: erpnext/accounts/doctype/pos_invoice_item/pos_invoice_item.json #: erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json #: erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json -#: erpnext/manufacturing/doctype/bom/bom.js:207 +#: erpnext/manufacturing/doctype/bom/bom.js:208 #: erpnext/manufacturing/doctype/bom/bom.json #: erpnext/manufacturing/doctype/job_card/job_card.json #: erpnext/quality_management/workspace/quality/quality.json @@ -37880,11 +37988,11 @@ msgid "Quality Inspection Template Name" msgstr "قالب فحص الجودة اسم" #: erpnext/public/js/controllers/transaction.js:375 -#: erpnext/stock/doctype/stock_entry/stock_entry.js:174 +#: erpnext/stock/doctype/stock_entry/stock_entry.js:179 msgid "Quality Inspection(s)" msgstr "" -#: erpnext/setup/doctype/company/company.py:460 +#: erpnext/setup/doctype/company/company.py:496 msgid "Quality Management" msgstr "إدارة الجودة" @@ -38002,9 +38110,9 @@ msgstr "هدف مراجعة الجودة" #: erpnext/buying/report/purchase_analytics/purchase_analytics.js:28 #: erpnext/buying/report/supplier_quotation_comparison/supplier_quotation_comparison.py:213 #: erpnext/manufacturing/doctype/blanket_order_item/blanket_order_item.json -#: erpnext/manufacturing/doctype/bom/bom.js:417 +#: erpnext/manufacturing/doctype/bom/bom.js:424 #: erpnext/manufacturing/doctype/bom/bom.json -#: erpnext/manufacturing/doctype/bom_creator/bom_creator.js:68 +#: erpnext/manufacturing/doctype/bom_creator/bom_creator.js:69 #: erpnext/manufacturing/doctype/bom_creator/bom_creator.json #: erpnext/manufacturing/doctype/plant_floor/plant_floor.js:194 #: erpnext/manufacturing/doctype/plant_floor/plant_floor.js:218 @@ -38020,11 +38128,11 @@ msgstr "هدف مراجعة الجودة" #: erpnext/selling/report/sales_partner_transaction_summary/sales_partner_transaction_summary.py:67 #: erpnext/stock/dashboard/item_dashboard.js:248 #: erpnext/stock/doctype/delivery_note_item/delivery_note_item.json -#: erpnext/stock/doctype/material_request/material_request.js:350 +#: erpnext/stock/doctype/material_request/material_request.js:354 #: erpnext/stock/doctype/material_request_item/material_request_item.json #: erpnext/stock/doctype/packing_slip_item/packing_slip_item.json #: erpnext/stock/doctype/pick_list_item/pick_list_item.json -#: erpnext/stock/doctype/stock_entry/stock_entry.js:677 +#: erpnext/stock/doctype/stock_entry/stock_entry.js:690 #: erpnext/stock/doctype/stock_entry_detail/stock_entry_detail.json #: erpnext/stock/doctype/stock_reconciliation_item/stock_reconciliation_item.json #: erpnext/stock/report/batch_item_expiry_status/batch_item_expiry_status.py:36 @@ -38122,7 +38230,7 @@ msgstr "كمية وقيم" msgid "Quantity and Warehouse" msgstr "الكمية والنماذج" -#: erpnext/stock/doctype/material_request/material_request.py:201 +#: erpnext/stock/doctype/material_request/material_request.py:202 msgid "Quantity cannot be greater than {0} for Item {1}" msgstr "" @@ -38134,7 +38242,7 @@ msgstr "" msgid "Quantity must be greater than zero, and less or equal to {0}" msgstr "" -#: erpnext/manufacturing/doctype/work_order/work_order.js:1018 +#: erpnext/manufacturing/doctype/work_order/work_order.js:1013 #: erpnext/stock/doctype/pick_list/pick_list.js:204 msgid "Quantity must not be more than {0}" msgstr "الكمية يجب ألا تكون أكثر من {0}" @@ -38144,13 +38252,13 @@ msgstr "الكمية يجب ألا تكون أكثر من {0}" msgid "Quantity of item obtained after manufacturing / repacking from given quantities of raw materials" msgstr "الكمية من البنود التي تم الحصول عليها بعد التصنيع / إعادة التعبئة من الكميات المعطاء من المواد الخام" -#: erpnext/manufacturing/doctype/bom/bom.py:660 +#: erpnext/manufacturing/doctype/bom/bom.py:671 msgid "Quantity required for Item {0} in row {1}" msgstr "الكمية مطلوبة للبند {0} في الصف {1}\\n
        \\nQuantity required for Item {0} in row {1}" -#: erpnext/manufacturing/doctype/bom/bom.py:604 -#: erpnext/manufacturing/doctype/job_card/job_card.js:372 -#: erpnext/manufacturing/doctype/job_card/job_card.js:442 +#: erpnext/manufacturing/doctype/bom/bom.py:615 +#: erpnext/manufacturing/doctype/job_card/job_card.js:384 +#: erpnext/manufacturing/doctype/job_card/job_card.js:454 #: erpnext/manufacturing/doctype/workstation/workstation.js:303 msgid "Quantity should be greater than 0" msgstr "الكمية يجب أن تكون أبر من 0\\n
        \\nQuantity should be greater than 0" @@ -38159,15 +38267,15 @@ msgstr "الكمية يجب أن تكون أبر من 0\\n
        \\nQuantity should msgid "Quantity to Make" msgstr "كمية لجعل" -#: erpnext/manufacturing/doctype/work_order/work_order.js:336 +#: erpnext/manufacturing/doctype/work_order/work_order.js:343 msgid "Quantity to Manufacture" msgstr "كمية لتصنيع" -#: erpnext/manufacturing/doctype/work_order/work_order.py:2481 +#: erpnext/manufacturing/doctype/work_order/work_order.py:2522 msgid "Quantity to Manufacture can not be zero for the operation {0}" msgstr "لا يمكن أن تكون الكمية للتصنيع صفراً للتشغيل {0}" -#: erpnext/manufacturing/doctype/work_order/work_order.py:1382 +#: erpnext/manufacturing/doctype/work_order/work_order.py:1386 msgid "Quantity to Manufacture must be greater than 0." msgstr "\"الكمية لتصنيع\" يجب أن تكون أكبر من 0." @@ -38175,7 +38283,7 @@ msgstr "\"الكمية لتصنيع\" يجب أن تكون أكبر من 0." msgid "Quantity to Produce" msgstr "كمية لإنتاج" -#: erpnext/manufacturing/report/bom_stock_report/bom_stock_report.py:36 +#: erpnext/manufacturing/report/bom_stock_report/bom_stock_report.py:37 msgid "Quantity to Produce should be greater than zero." msgstr "" @@ -38208,11 +38316,11 @@ msgstr "" msgid "Query Route String" msgstr "سلسلة مسار الاستعلام" -#: erpnext/accounts/doctype/accounts_settings/accounts_settings.py:148 +#: erpnext/accounts/doctype/accounts_settings/accounts_settings.py:139 msgid "Queue Size should be between 5 and 100" msgstr "" -#: erpnext/accounts/doctype/journal_entry/journal_entry.js:586 +#: erpnext/accounts/doctype/journal_entry/journal_entry.js:590 msgid "Quick Journal Entry" msgstr "قيد دفتر يومية سريع" @@ -38251,7 +38359,7 @@ msgstr "" #. Label of the prevdoc_docname (Link) field in DocType 'Sales Order Item' #. Label of a Link in the Selling Workspace #. Option for the 'Transaction' (Select) field in DocType 'Authorization Rule' -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.js:294 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.js:295 #: erpnext/buying/doctype/supplier_quotation/supplier_quotation.js:36 #: erpnext/buying/report/supplier_quotation_comparison/supplier_quotation_comparison.html:20 #: erpnext/crm/doctype/contract/contract.json @@ -38262,7 +38370,7 @@ msgstr "" #: erpnext/crm/report/lead_details/lead_details.js:37 #: erpnext/manufacturing/doctype/blanket_order/blanket_order.js:38 #: erpnext/selling/doctype/quotation/quotation.json -#: erpnext/selling/doctype/sales_order/sales_order.js:1171 +#: erpnext/selling/doctype/sales_order/sales_order.js:1175 #: erpnext/selling/doctype/sales_order_item/sales_order_item.json #: erpnext/selling/workspace/selling/selling.json #: erpnext/setup/doctype/authorization_rule/authorization_rule.json @@ -38310,15 +38418,15 @@ msgstr "مناقصة لـ" msgid "Quotation Trends" msgstr "مؤشرات المناقصة" -#: erpnext/selling/doctype/sales_order/sales_order.py:471 +#: erpnext/selling/doctype/sales_order/sales_order.py:473 msgid "Quotation {0} is cancelled" msgstr "العرض المسعر {0} تم إلغائه" -#: erpnext/selling/doctype/sales_order/sales_order.py:384 +#: erpnext/selling/doctype/sales_order/sales_order.py:386 msgid "Quotation {0} not of type {1}" msgstr "عرض مسعر {0} ليس من النوع {1}" -#: erpnext/selling/doctype/quotation/quotation.py:345 +#: erpnext/selling/doctype/quotation/quotation.py:347 #: erpnext/selling/page/sales_funnel/sales_funnel.py:57 msgid "Quotations" msgstr "عروض مسعرة" @@ -38371,7 +38479,7 @@ msgstr "التي أثارها (بريد إلكتروني)" #. Product Discount' #. Label of the rate (Currency) field in DocType 'Purchase Invoice Item' #. Label of the rate (Currency) field in DocType 'Sales Invoice Item' -#. Label of the rate (Int) field in DocType 'Share Balance' +#. Label of the rate (Currency) field in DocType 'Share Balance' #. Label of the rate (Currency) field in DocType 'Share Transfer' #. Label of the rate (Currency) field in DocType 'Asset Capitalization Service #. Item' @@ -38420,8 +38528,8 @@ msgstr "التي أثارها (بريد إلكتروني)" #: erpnext/accounts/doctype/share_transfer/share_transfer.json #: erpnext/accounts/print_format/sales_invoice_print/sales_invoice_print.html:92 #: erpnext/accounts/report/billed_items_to_be_received/billed_items_to_be_received.py:78 -#: erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py:268 -#: erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py:323 +#: erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py:260 +#: erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py:312 #: erpnext/accounts/report/share_ledger/share_ledger.py:56 #: erpnext/assets/doctype/asset_capitalization_service_item/asset_capitalization_service_item.json #: erpnext/buying/doctype/purchase_order_item/purchase_order_item.json @@ -38618,7 +38726,7 @@ msgstr "المعدل الذي يتم تحويل العملة إلى عملة ا msgid "Rate at which this tax is applied" msgstr "السعر الذي يتم فيه تطبيق هذه الضريبة" -#: erpnext/controllers/accounts_controller.py:3930 +#: erpnext/controllers/accounts_controller.py:4003 msgid "Rate of '{}' items cannot be changed" msgstr "" @@ -38690,7 +38798,7 @@ msgstr "" msgid "Raw Material" msgstr "المواد الخام" -#: erpnext/manufacturing/report/production_planning_report/production_planning_report.py:402 +#: erpnext/manufacturing/report/production_planning_report/production_planning_report.py:407 msgid "Raw Material Code" msgstr "كود المواد الخام" @@ -38735,7 +38843,7 @@ msgstr "" msgid "Raw Material Item Code" msgstr "قانون المواد الخام المدينة" -#: erpnext/manufacturing/report/production_planning_report/production_planning_report.py:409 +#: erpnext/manufacturing/report/production_planning_report/production_planning_report.py:414 msgid "Raw Material Name" msgstr "اسم المادة الخام" @@ -38758,13 +38866,13 @@ msgstr "مستودع المواد الخام" #. Label of the materials_section (Section Break) field in DocType 'BOM' #. Label of the section_break_8 (Section Break) field in DocType 'Job Card' #. Label of the mr_items (Table) field in DocType 'Production Plan' -#: erpnext/manufacturing/doctype/bom/bom.js:370 -#: erpnext/manufacturing/doctype/bom/bom.js:1004 +#: erpnext/manufacturing/doctype/bom/bom.js:377 +#: erpnext/manufacturing/doctype/bom/bom.js:1021 #: erpnext/manufacturing/doctype/bom/bom.json #: erpnext/manufacturing/doctype/job_card/job_card.json #: erpnext/manufacturing/doctype/production_plan/production_plan.json #: erpnext/manufacturing/doctype/workstation/workstation.js:462 -#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:353 +#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:379 msgid "Raw Materials" msgstr "مواد أولية" @@ -38819,7 +38927,7 @@ msgstr "المواد الخام الموردة" msgid "Raw Materials Supplied Cost" msgstr "المواد الخام الموردة التكلفة" -#: erpnext/manufacturing/doctype/bom/bom.py:652 +#: erpnext/manufacturing/doctype/bom/bom.py:663 msgid "Raw Materials cannot be blank." msgstr "لا يمكن ترك المواد الخام فارغة." @@ -38833,12 +38941,18 @@ msgstr "" msgid "Raw SQL" msgstr "" -#: erpnext/buying/doctype/purchase_order/purchase_order.js:410 +#. Description of the 'Validate Consumed Qty (as per BOM)' (Check) field in +#. DocType 'Buying Settings' +#: erpnext/buying/doctype/buying_settings/buying_settings.json +msgid "Raw materials consumed qty will be validated based on FG BOM required qty" +msgstr "" + +#: erpnext/buying/doctype/purchase_order/purchase_order.js:411 #: erpnext/manufacturing/doctype/production_plan/production_plan.js:124 -#: erpnext/manufacturing/doctype/work_order/work_order.js:726 -#: erpnext/selling/doctype/sales_order/sales_order.js:964 +#: erpnext/manufacturing/doctype/work_order/work_order.js:736 +#: erpnext/selling/doctype/sales_order/sales_order.js:968 #: erpnext/selling/doctype/sales_order/sales_order_list.js:70 -#: erpnext/stock/doctype/material_request/material_request.js:228 +#: erpnext/stock/doctype/material_request/material_request.js:229 #: erpnext/subcontracting/doctype/subcontracting_inward_order/subcontracting_inward_order.js:116 #: erpnext/subcontracting/doctype/subcontracting_order/subcontracting_order.js:164 msgid "Re-open" @@ -38924,7 +39038,7 @@ msgid "Real Estate" msgstr "" #. Label of the hold_comment (Small Text) field in DocType 'Purchase Invoice' -#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js:274 +#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js:275 #: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json msgid "Reason For Putting On Hold" msgstr "سبب لوضع في الانتظار" @@ -38934,8 +39048,8 @@ msgstr "سبب لوضع في الانتظار" msgid "Reason for Failure" msgstr "" -#: erpnext/buying/doctype/purchase_order/purchase_order.js:741 -#: erpnext/selling/doctype/sales_order/sales_order.js:1738 +#: erpnext/buying/doctype/purchase_order/purchase_order.js:742 +#: erpnext/selling/doctype/sales_order/sales_order.js:1752 msgid "Reason for Hold" msgstr "سبب الانتظار" @@ -38944,7 +39058,7 @@ msgstr "سبب الانتظار" msgid "Reason for Leaving" msgstr "سبب ترك العمل" -#: erpnext/selling/doctype/sales_order/sales_order.js:1753 +#: erpnext/selling/doctype/sales_order/sales_order.js:1767 msgid "Reason for hold:" msgstr "" @@ -39017,7 +39131,7 @@ msgstr "القبض / حساب الدائنة" #: erpnext/accounts/report/accounts_receivable/accounts_receivable.js:68 #: erpnext/accounts/report/accounts_receivable/accounts_receivable.py:1158 -#: erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py:244 +#: erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py:233 #: erpnext/accounts/report/sales_register/sales_register.py:217 #: erpnext/accounts/report/sales_register/sales_register.py:271 msgid "Receivable Account" @@ -39143,7 +39257,7 @@ msgstr "" msgid "Received Quantity" msgstr "الكمية المستلمة" -#: erpnext/stock/doctype/stock_entry/stock_entry.js:297 +#: erpnext/stock/doctype/stock_entry/stock_entry.js:302 msgid "Received Stock Entries" msgstr "تلقى إدخالات الأسهم" @@ -39207,7 +39321,7 @@ msgstr "" msgid "Reconcile Effect On" msgstr "" -#: erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.js:361 +#: erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.js:363 msgid "Reconcile Entries" msgstr "التوفيق بين المدخلات" @@ -39378,11 +39492,11 @@ msgstr "الرمز المرجعي" msgid "Ref Date" msgstr "تاريخ المرجع" -#: erpnext/accounts/doctype/journal_entry/journal_entry.py:1088 +#: erpnext/accounts/doctype/journal_entry/journal_entry.py:1003 msgid "Reference #{0} dated {1}" msgstr "المرجع # {0} بتاريخ {1}" -#: erpnext/public/js/controllers/transaction.js:2740 +#: erpnext/public/js/controllers/transaction.js:2748 msgid "Reference Date for Early Payment Discount" msgstr "" @@ -39421,7 +39535,7 @@ msgstr "" msgid "Reference No" msgstr "" -#: erpnext/accounts/doctype/journal_entry/journal_entry.py:702 +#: erpnext/accounts/doctype/journal_entry/journal_entry.py:617 msgid "Reference No & Reference Date is required for {0}" msgstr "رقم المرجع وتاريخه مطلوبان ل {0}\\n
        \\nReference No & Reference Date is required for {0}" @@ -39429,11 +39543,11 @@ msgstr "رقم المرجع وتاريخه مطلوبان ل {0}\\n
        \\nRefere msgid "Reference No and Reference Date is mandatory for Bank transaction" msgstr "رقم المرجع و تاريخ المرجع إلزامي للمعاملة المصرفية" -#: erpnext/accounts/doctype/journal_entry/journal_entry.py:707 +#: erpnext/accounts/doctype/journal_entry/journal_entry.py:622 msgid "Reference No is mandatory if you entered Reference Date" msgstr "رقم المرجع إلزامي اذا أدخلت تاريخ المرجع\\n
        \\nReference No is mandatory if you entered Reference Date" -#: erpnext/accounts/report/tax_withholding_details/tax_withholding_details.py:266 +#: erpnext/accounts/report/tax_withholding_details/tax_withholding_details.py:280 msgid "Reference No." msgstr "رقم المرجع." @@ -39521,11 +39635,11 @@ msgstr "المرجع: {0}، رمز العنصر: {1} والعميل: {2}" msgid "References" msgstr "المراجع" -#: erpnext/stock/doctype/delivery_note/delivery_note.py:387 +#: erpnext/stock/doctype/delivery_note/delivery_note.py:391 msgid "References to Sales Invoices are Incomplete" msgstr "" -#: erpnext/stock/doctype/delivery_note/delivery_note.py:382 +#: erpnext/stock/doctype/delivery_note/delivery_note.py:386 msgid "References to Sales Orders are Incomplete" msgstr "" @@ -39547,7 +39661,7 @@ msgstr "شريك مبيعات الإحالة" msgid "Refresh Plaid Link" msgstr "" -#: erpnext/stock/reorder_item.py:394 +#: erpnext/stock/reorder_item.py:402 msgid "Regards," msgstr "مع تحياتي،" @@ -39638,7 +39752,7 @@ msgstr "" #: erpnext/buying/doctype/purchase_order/purchase_order_dashboard.py:23 #: erpnext/buying/doctype/supplier_quotation/supplier_quotation_dashboard.py:14 #: erpnext/stock/doctype/delivery_note/delivery_note_dashboard.py:22 -#: erpnext/stock/doctype/purchase_receipt/purchase_receipt_dashboard.py:23 +#: erpnext/stock/doctype/purchase_receipt/purchase_receipt_dashboard.py:26 msgid "Related" msgstr "ذات صلة" @@ -39649,15 +39763,15 @@ msgstr "علاقة" #. Label of the release_date (Date) field in DocType 'Purchase Invoice' #. Label of the release_date (Date) field in DocType 'Supplier' -#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js:266 -#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js:310 +#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js:267 +#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js:311 #: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json #: erpnext/buying/doctype/supplier/supplier.json #: erpnext/manufacturing/report/material_requirements_planning_report/material_requirements_planning_report.py:1061 msgid "Release Date" msgstr "تاريخ النشر" -#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:316 +#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:318 msgid "Release date must be in the future" msgstr "يجب أن يكون تاريخ الإصدار في المستقبل" @@ -39732,7 +39846,7 @@ msgstr "كلام" #: erpnext/accounts/report/accounts_receivable/accounts_receivable.py:1264 #: erpnext/accounts/report/general_ledger/general_ledger.html:90 #: erpnext/accounts/report/general_ledger/general_ledger.html:116 -#: erpnext/accounts/report/general_ledger/general_ledger.py:785 +#: erpnext/accounts/report/general_ledger/general_ledger.py:792 #: erpnext/accounts/report/payment_period_based_on_invoice_date/payment_period_based_on_invoice_date.py:112 #: erpnext/accounts/report/purchase_register/purchase_register.py:296 #: erpnext/accounts/report/sales_register/sales_register.py:335 @@ -39759,7 +39873,7 @@ msgstr "" msgid "Remarks:" msgstr "ملاحظات:" -#: erpnext/manufacturing/doctype/bom_creator/bom_creator.py:94 +#: erpnext/manufacturing/doctype/bom_creator/bom_creator.py:96 msgid "Remove Parent Row No in Items Table" msgstr "" @@ -39786,7 +39900,7 @@ msgstr "إعادة تسمية سمة السمة في سمة البند." msgid "Rename Log" msgstr "إعادة تسمية الدخول" -#: erpnext/accounts/doctype/account/account.py:554 +#: erpnext/accounts/doctype/account/account.py:556 msgid "Rename Not Allowed" msgstr "إعادة تسمية غير مسموح به" @@ -39803,7 +39917,7 @@ msgstr "" msgid "Rename jobs for doctype {0} have not been enqueued." msgstr "" -#: erpnext/accounts/doctype/account/account.py:546 +#: erpnext/accounts/doctype/account/account.py:548 msgid "Renaming it is only allowed via parent company {0}, to avoid mismatch." msgstr "يُسمح بإعادة تسميته فقط عبر الشركة الأم {0} ، لتجنب عدم التطابق." @@ -39821,11 +39935,15 @@ msgstr "" msgid "Rented" msgstr "مؤجر" +#. Label of the reorder_level (Float) field in DocType 'Material Request Item' +#: erpnext/stock/doctype/material_request_item/material_request_item.json #: erpnext/stock/report/itemwise_recommended_reorder_level/itemwise_recommended_reorder_level.py:64 #: erpnext/stock/report/stock_projected_qty/stock_projected_qty.py:211 msgid "Reorder Level" msgstr "مستوى اعادة الطلب" +#. Label of the reorder_qty (Float) field in DocType 'Material Request Item' +#: erpnext/stock/doctype/material_request_item/material_request_item.json #: erpnext/stock/report/stock_projected_qty/stock_projected_qty.py:218 msgid "Reorder Qty" msgstr "الكمية المحددة عند اعادة الطلب" @@ -39871,10 +39989,6 @@ msgstr "" msgid "Repair Status" msgstr "حالة الإصلاح" -#: erpnext/assets/doctype/asset_repair/asset_repair.py:136 -msgid "Repair cost cannot be greater than purchase invoice base net total {0}" -msgstr "" - #: erpnext/selling/report/customer_acquisition_and_loyalty/customer_acquisition_and_loyalty.py:37 msgid "Repeat Customer Revenue" msgstr "ايرادات الزبائن المكررين" @@ -39924,7 +40038,7 @@ msgstr "" msgid "Report Template" msgstr "" -#: erpnext/accounts/doctype/account/account.py:460 +#: erpnext/accounts/doctype/account/account.py:462 msgid "Report Type is mandatory" msgstr "نوع التقرير إلزامي\\n
        \\nReport Type is mandatory" @@ -39987,6 +40101,16 @@ msgstr "" msgid "Repost Item Valuation" msgstr "" +#: erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py:337 +msgid "Repost Item Valuation restarted for selected failed records." +msgstr "" + +#. Label of the repost_only_accounting_ledgers (Check) field in DocType 'Repost +#. Item Valuation' +#: erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.json +msgid "Repost Only Accounting Ledgers" +msgstr "" + #. Name of a DocType #: erpnext/accounts/doctype/repost_payment_ledger/repost_payment_ledger.json msgid "Repost Payment Ledger" @@ -40014,7 +40138,7 @@ msgstr "" msgid "Repost started in the background" msgstr "" -#: erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.js:115 +#: erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.js:119 msgid "Reposting Completed {0}%" msgstr "" @@ -40030,16 +40154,22 @@ msgstr "" msgid "Reposting Info" msgstr "" -#: erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.js:123 +#: erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.js:127 msgid "Reposting Progress" msgstr "" -#: erpnext/stock/report/stock_and_account_value_comparison/stock_and_account_value_comparison.py:179 +#. Label of the reposting_reference (Data) field in DocType 'Repost Item +#. Valuation' +#: erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.json +msgid "Reposting Reference" +msgstr "" + +#: erpnext/stock/report/stock_and_account_value_comparison/stock_and_account_value_comparison.py:182 #: erpnext/stock/report/stock_ledger_invariant_check/stock_ledger_invariant_check.py:327 msgid "Reposting entries created: {0}" msgstr "" -#: erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.js:99 +#: erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.js:103 msgid "Reposting has been started in the background." msgstr "" @@ -40131,7 +40261,7 @@ msgstr "طلب المعلومات" #: erpnext/buying/report/supplier_quotation_comparison/supplier_quotation_comparison.js:70 #: erpnext/buying/report/supplier_quotation_comparison/supplier_quotation_comparison.py:272 #: erpnext/buying/workspace/buying/buying.json -#: erpnext/stock/doctype/material_request/material_request.js:187 +#: erpnext/stock/doctype/material_request/material_request.js:188 msgid "Request for Quotation" msgstr "طلب للحصول على الاقتباس" @@ -40148,7 +40278,7 @@ msgstr "طلب تسعيرة البند" msgid "Request for Quotation Supplier" msgstr "طلب تسعيرة مزود" -#: erpnext/selling/doctype/sales_order/sales_order.js:1080 +#: erpnext/selling/doctype/sales_order/sales_order.js:1084 msgid "Request for Raw Materials" msgstr "طلب المواد الخام" @@ -40262,13 +40392,13 @@ msgstr "" #: erpnext/manufacturing/doctype/material_request_plan_item/material_request_plan_item.json #: erpnext/manufacturing/doctype/production_plan_sub_assembly_item/production_plan_sub_assembly_item.json #: erpnext/manufacturing/doctype/work_order_item/work_order_item.json -#: erpnext/manufacturing/report/bom_stock_calculated/bom_stock_calculated.py:86 +#: erpnext/manufacturing/report/bom_stock_calculated/bom_stock_calculated.py:94 #: erpnext/manufacturing/report/bom_stock_report/bom_stock_report.html:11 #: erpnext/manufacturing/report/bom_stock_report/bom_stock_report.html:21 -#: erpnext/manufacturing/report/bom_stock_report/bom_stock_report.py:27 +#: erpnext/manufacturing/report/bom_stock_report/bom_stock_report.py:28 #: erpnext/manufacturing/report/bom_variance_report/bom_variance_report.py:58 #: erpnext/manufacturing/report/material_requirements_planning_report/material_requirements_planning_report.py:1041 -#: erpnext/manufacturing/report/production_planning_report/production_planning_report.py:421 +#: erpnext/manufacturing/report/production_planning_report/production_planning_report.py:426 #: erpnext/manufacturing/report/work_order_consumed_materials/work_order_consumed_materials.py:139 #: erpnext/subcontracting/doctype/subcontracting_inward_order_received_item/subcontracting_inward_order_received_item.json #: erpnext/subcontracting/doctype/subcontracting_order_supplied_item/subcontracting_order_supplied_item.json @@ -40302,7 +40432,7 @@ msgstr "يتطلب وفاء" msgid "Research" msgstr "ابحاث" -#: erpnext/setup/doctype/company/company.py:466 +#: erpnext/setup/doctype/company/company.py:502 msgid "Research & Development" msgstr "البحث و التطوير" @@ -40347,7 +40477,7 @@ msgstr "" msgid "Reservation Based On" msgstr "" -#: erpnext/manufacturing/doctype/work_order/work_order.js:884 +#: erpnext/manufacturing/doctype/work_order/work_order.js:894 #: erpnext/selling/doctype/sales_order/sales_order.js:92 #: erpnext/stock/doctype/pick_list/pick_list.js:148 #: erpnext/subcontracting/doctype/subcontracting_order/subcontracting_order.js:180 @@ -40392,6 +40522,10 @@ msgstr "" msgid "Reserved" msgstr "محجوز" +#: erpnext/controllers/stock_controller.py:1269 +msgid "Reserved Batch Conflict" +msgstr "" + #. Label of the reserved_qty (Float) field in DocType 'Bin' #. Label of the reserved_qty (Float) field in DocType 'Stock Reservation Entry' #. Label of the stock_reserved_qty (Float) field in DocType 'Subcontracting @@ -40452,14 +40586,14 @@ msgstr "الكمية المحجوزة" msgid "Reserved Quantity for Production" msgstr "الكمية المحجوزة للإنتاج" -#: erpnext/stock/stock_ledger.py:2280 +#: erpnext/stock/stock_ledger.py:2317 msgid "Reserved Serial No." msgstr "" #. Label of the reserved_stock (Float) field in DocType 'Bin' #. Name of a report #: erpnext/manufacturing/doctype/plant_floor/stock_summary_template.html:24 -#: erpnext/manufacturing/doctype/work_order/work_order.js:900 +#: erpnext/manufacturing/doctype/work_order/work_order.js:910 #: erpnext/public/js/stock_reservation.js:236 #: erpnext/selling/doctype/sales_order/sales_order.js:120 #: erpnext/selling/doctype/sales_order/sales_order.js:457 @@ -40468,13 +40602,13 @@ msgstr "" #: erpnext/stock/doctype/pick_list/pick_list.js:168 #: erpnext/stock/report/reserved_stock/reserved_stock.json #: erpnext/stock/report/stock_balance/stock_balance.py:497 -#: erpnext/stock/stock_ledger.py:2264 +#: erpnext/stock/stock_ledger.py:2301 #: erpnext/subcontracting/doctype/subcontracting_order/subcontracting_order.js:205 #: erpnext/subcontracting/doctype/subcontracting_order/subcontracting_order.js:333 msgid "Reserved Stock" msgstr "" -#: erpnext/stock/stock_ledger.py:2309 +#: erpnext/stock/stock_ledger.py:2346 msgid "Reserved Stock for Batch" msgstr "" @@ -40486,7 +40620,7 @@ msgstr "" msgid "Reserved Stock for Sub-assembly" msgstr "" -#: erpnext/controllers/buying_controller.py:632 +#: erpnext/controllers/buying_controller.py:645 msgid "Reserved Warehouse is mandatory for the Item {item_code} in Raw Materials supplied." msgstr "" @@ -40675,10 +40809,14 @@ msgstr "مسؤول" msgid "Rest Of The World" msgstr "باقي أنحاء العالم" -#: erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.js:82 +#: erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.js:84 msgid "Restart" msgstr "" +#: erpnext/stock/doctype/repost_item_valuation/repost_item_valuation_list.js:23 +msgid "Restart Failed Entries" +msgstr "" + #: erpnext/accounts/doctype/subscription/subscription.js:54 msgid "Restart Subscription" msgstr "إعادة تشغيل الاشتراك" @@ -40730,13 +40868,13 @@ msgid "Result Title Field" msgstr "النتيجة عنوان الحقل" #: erpnext/accounts/doctype/process_period_closing_voucher/process_period_closing_voucher.js:43 -#: erpnext/buying/doctype/purchase_order/purchase_order.js:385 +#: erpnext/buying/doctype/purchase_order/purchase_order.js:386 #: erpnext/manufacturing/doctype/workstation/workstation_job_card.html:63 -#: erpnext/selling/doctype/sales_order/sales_order.js:950 +#: erpnext/selling/doctype/sales_order/sales_order.js:954 msgid "Resume" msgstr "استئنف" -#: erpnext/manufacturing/doctype/job_card/job_card.js:226 +#: erpnext/manufacturing/doctype/job_card/job_card.js:238 msgid "Resume Job" msgstr "" @@ -40762,15 +40900,15 @@ msgid "Retain Sample" msgstr "الاحتفاظ عينة" #: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:196 -#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:347 +#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:348 msgid "Retained Earnings" msgstr "أرباح محتجزة" -#: erpnext/stock/doctype/purchase_receipt/purchase_receipt.js:292 +#: erpnext/stock/doctype/purchase_receipt/purchase_receipt.js:266 msgid "Retention Stock Entry" msgstr "الاحتفاظ الأسهم" -#: erpnext/stock/doctype/stock_entry/stock_entry.js:550 +#: erpnext/stock/doctype/stock_entry/stock_entry.js:555 msgid "Retention Stock Entry already created or Sample Quantity not provided" msgstr "الاحتفاظ الأسهم دخول بالفعل إنشاء أو عينة الكمية غير المقدمة" @@ -40786,13 +40924,17 @@ msgstr "" #. Option for the 'Status' (Select) field in DocType 'POS Invoice' #. Option for the 'Status' (Select) field in DocType 'Purchase Invoice' #. Option for the 'Status' (Select) field in DocType 'Sales Invoice' +#. Option for the 'Status' (Select) field in DocType 'Delivery Note' +#. Option for the 'Status' (Select) field in DocType 'Purchase Receipt' #. Option for the 'Status' (Select) field in DocType 'Subcontracting Receipt' #: erpnext/accounts/doctype/pos_invoice/pos_invoice.js:79 #: erpnext/accounts/doctype/pos_invoice/pos_invoice.json #: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json #: erpnext/accounts/doctype/sales_invoice/sales_invoice.json -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:277 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:279 +#: erpnext/stock/doctype/delivery_note/delivery_note.json #: erpnext/stock/doctype/delivery_note/delivery_note_list.js:16 +#: erpnext/stock/doctype/purchase_receipt/purchase_receipt.json #: erpnext/stock/doctype/purchase_receipt/purchase_receipt_list.js:15 #: erpnext/subcontracting/doctype/subcontracting_inward_order/subcontracting_inward_order.js:138 #: erpnext/subcontracting/doctype/subcontracting_inward_order/subcontracting_inward_order.js:167 @@ -40801,11 +40943,11 @@ msgstr "" msgid "Return" msgstr "عودة" -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.js:108 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.js:109 msgid "Return / Credit Note" msgstr "ارجاع / اشعار دائن" -#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js:125 +#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js:126 msgid "Return / Debit Note" msgstr "ارجاع / اشعار مدين" @@ -40841,7 +40983,7 @@ msgstr "العودة ضد شراء إيصال" msgid "Return Against Subcontracting Receipt" msgstr "" -#: erpnext/manufacturing/doctype/work_order/work_order.js:277 +#: erpnext/manufacturing/doctype/work_order/work_order.js:284 msgid "Return Components" msgstr "" @@ -40856,14 +40998,14 @@ msgstr "" msgid "Return Issued" msgstr "" -#: erpnext/stock/doctype/purchase_receipt/purchase_receipt.js:352 +#: erpnext/stock/doctype/purchase_receipt/purchase_receipt.js:326 #: erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.js:126 msgid "Return Qty" msgstr "" #. Label of the return_qty_from_rejected_warehouse (Check) field in DocType #. 'Purchase Receipt Item' -#: erpnext/stock/doctype/purchase_receipt/purchase_receipt.js:328 +#: erpnext/stock/doctype/purchase_receipt/purchase_receipt.js:302 #: erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json #: erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.js:102 msgid "Return Qty from Rejected Warehouse" @@ -40877,7 +41019,7 @@ msgstr "" msgid "Return Raw Material to Customer" msgstr "" -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1499 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1448 msgid "Return invoice of asset cancelled" msgstr "" @@ -40895,8 +41037,11 @@ msgid "Return on Equity Ratio" msgstr "" #. Option for the 'Tracking Status' (Select) field in DocType 'Shipment' +#. Option for the 'Status' (Select) field in DocType 'Subcontracting Inward +#. Order' #: erpnext/selling/page/point_of_sale/pos_past_order_summary.js:138 #: erpnext/stock/doctype/shipment/shipment.json +#: erpnext/subcontracting/doctype/subcontracting_inward_order/subcontracting_inward_order.json msgid "Returned" msgstr "" @@ -40959,7 +41104,7 @@ msgstr "" #: erpnext/accounts/doctype/purchase_invoice/purchase_invoice_dashboard.py:25 #: erpnext/accounts/doctype/sales_invoice/sales_invoice_dashboard.py:35 #: erpnext/stock/doctype/delivery_note/delivery_note_dashboard.py:24 -#: erpnext/stock/doctype/purchase_receipt/purchase_receipt_dashboard.py:30 +#: erpnext/stock/doctype/purchase_receipt/purchase_receipt_dashboard.py:33 #: erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt_dashboard.py:27 msgid "Returns" msgstr "النتائج" @@ -40972,7 +41117,7 @@ msgid "Revaluation Journals" msgstr "" #: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:197 -#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:352 +#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:353 msgid "Revaluation Surplus" msgstr "" @@ -41028,6 +41173,19 @@ msgstr "مراجعة والعمل" msgid "Reviews" msgstr "التعليقات" +#: erpnext/accounts/doctype/budget/budget.js:37 +msgid "Revise Budget" +msgstr "" + +#. Label of the revision_of (Data) field in DocType 'Budget' +#: erpnext/accounts/doctype/budget/budget.json +msgid "Revision Of" +msgstr "" + +#: erpnext/accounts/doctype/budget/budget.js:98 +msgid "Revision cancelled" +msgstr "" + #. Label of the rgt (Int) field in DocType 'Account' #. Label of the rgt (Int) field in DocType 'Company' #: erpnext/accounts/doctype/account/account.json @@ -41090,17 +41248,23 @@ msgstr "" msgid "Role Allowed to Override Stop Action" msgstr "" -#. Label of the frozen_accounts_modifier (Link) field in DocType 'Accounts -#. Settings' -#: erpnext/accounts/doctype/accounts_settings/accounts_settings.json -msgid "Role Allowed to Set Frozen Accounts and Edit Frozen Entries" -msgstr "الدور مسموح به لتعيين حسابات مجمدة وتعديل الإدخالات المجمدة" - #. Label of the credit_controller (Link) field in DocType 'Accounts Settings' #: erpnext/accounts/doctype/accounts_settings/accounts_settings.json msgid "Role allowed to bypass Credit Limit" msgstr "" +#. Label of the role_to_notify_on_depreciation_failure (Link) field in DocType +#. 'Accounts Settings' +#: erpnext/accounts/doctype/accounts_settings/accounts_settings.json +msgid "Role to Notify on Depreciation Failure" +msgstr "" + +#. Label of the role_allowed_for_frozen_entries (Link) field in DocType +#. 'Company' +#: erpnext/setup/doctype/company/company.json +msgid "Roles Allowed to Set and Edit Frozen Account Entries" +msgstr "" + #. Label of the root (Link) field in DocType 'Bisect Nodes' #: erpnext/accounts/doctype/bisect_nodes/bisect_nodes.json msgid "Root" @@ -41123,11 +41287,11 @@ msgstr "نوع الجذر" msgid "Root Type for {0} must be one of the Asset, Liability, Income, Expense and Equity" msgstr "" -#: erpnext/accounts/doctype/account/account.py:457 +#: erpnext/accounts/doctype/account/account.py:459 msgid "Root Type is mandatory" msgstr "نوع الجذر إلزامي\\n
        \\nRoot Type is mandatory" -#: erpnext/accounts/doctype/account/account.py:213 +#: erpnext/accounts/doctype/account/account.py:215 msgid "Root cannot be edited." msgstr "الجذرلا يمكن تعديل." @@ -41297,8 +41461,8 @@ msgstr "" msgid "Rounding Loss Allowance should be between 0 and 1" msgstr "" -#: erpnext/controllers/stock_controller.py:741 -#: erpnext/controllers/stock_controller.py:756 +#: erpnext/controllers/stock_controller.py:743 +#: erpnext/controllers/stock_controller.py:758 msgid "Rounding gain/loss Entry for Stock Transfer" msgstr "" @@ -41307,7 +41471,7 @@ msgstr "" #. Name of a DocType #. Label of a Link in the Manufacturing Workspace #: erpnext/manufacturing/doctype/bom/bom.json -#: erpnext/manufacturing/doctype/bom_creator/bom_creator.js:93 +#: erpnext/manufacturing/doctype/bom_creator/bom_creator.js:94 #: erpnext/manufacturing/doctype/bom_creator/bom_creator.json #: erpnext/manufacturing/doctype/routing/routing.json #: erpnext/manufacturing/workspace/manufacturing/manufacturing.json @@ -41323,7 +41487,7 @@ msgstr "اسم التوجيه" msgid "Row # {0}:" msgstr "" -#: erpnext/controllers/sales_and_purchase_return.py:226 +#: erpnext/controllers/sales_and_purchase_return.py:225 msgid "Row # {0}: Cannot return more than {1} for Item {2}" msgstr "الصف # {0}: لا يمكن الارجاع أكثر من {1} للبند {2}" @@ -41335,29 +41499,29 @@ msgstr "" msgid "Row # {0}: Please enter quantity for Item {1} as it is not zero." msgstr "" -#: erpnext/controllers/sales_and_purchase_return.py:151 +#: erpnext/controllers/sales_and_purchase_return.py:150 msgid "Row # {0}: Rate cannot be greater than the rate used in {1} {2}" msgstr "الصف # {0}: لا يمكن أن يكون المعدل أكبر من المعدل المستخدم في {1} {2}" -#: erpnext/controllers/sales_and_purchase_return.py:135 +#: erpnext/controllers/sales_and_purchase_return.py:134 msgid "Row # {0}: Returned Item {1} does not exist in {2} {3}" msgstr "الصف رقم {0}: العنصر الذي تم إرجاعه {1} غير موجود في {2} {3}" -#: erpnext/manufacturing/doctype/work_order/work_order.py:256 +#: erpnext/manufacturing/doctype/work_order/work_order.py:257 msgid "Row #1: Sequence ID must be 1 for Operation {0}." msgstr "" -#: erpnext/accounts/doctype/pos_invoice/pos_invoice.py:518 -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:2044 +#: erpnext/accounts/doctype/pos_invoice/pos_invoice.py:563 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1997 msgid "Row #{0} (Payment Table): Amount must be negative" msgstr "الصف # {0} (جدول الدفع): يجب أن يكون المبلغ سلبيًا" -#: erpnext/accounts/doctype/pos_invoice/pos_invoice.py:516 -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:2039 +#: erpnext/accounts/doctype/pos_invoice/pos_invoice.py:561 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1992 msgid "Row #{0} (Payment Table): Amount must be positive" msgstr "الصف رقم {0} (جدول الدفع): يجب أن يكون المبلغ موجبا" -#: erpnext/stock/doctype/item/item.py:494 +#: erpnext/stock/doctype/item/item.py:513 msgid "Row #{0}: A reorder entry already exists for warehouse {1} with reorder type {2}." msgstr "" @@ -41369,16 +41533,16 @@ msgstr "" msgid "Row #{0}: Acceptance Criteria Formula is required." msgstr "" -#: erpnext/controllers/subcontracting_controller.py:124 -#: erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py:527 +#: erpnext/controllers/subcontracting_controller.py:125 +#: erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py:534 msgid "Row #{0}: Accepted Warehouse and Rejected Warehouse cannot be same" msgstr "" -#: erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py:520 +#: erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py:527 msgid "Row #{0}: Accepted Warehouse is mandatory for the accepted Item {1}" msgstr "" -#: erpnext/controllers/accounts_controller.py:1218 +#: erpnext/controllers/accounts_controller.py:1287 msgid "Row #{0}: Account {1} does not belong to company {2}" msgstr "الصف # {0}: الحساب {1} لا ينتمي إلى الشركة {2}" @@ -41399,19 +41563,19 @@ msgstr "" msgid "Row #{0}: Amount must be a positive number" msgstr "" -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:443 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:392 msgid "Row #{0}: Asset {1} cannot be sold, it is already {2}" msgstr "" -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:448 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:397 msgid "Row #{0}: Asset {1} is already sold" msgstr "" -#: erpnext/buying/doctype/purchase_order/purchase_order.py:369 +#: erpnext/buying/doctype/purchase_order/purchase_order.py:371 msgid "Row #{0}: BOM is not specified for subcontracting item {0}" msgstr "" -#: erpnext/selling/doctype/sales_order/sales_order.py:286 +#: erpnext/selling/doctype/sales_order/sales_order.py:288 msgid "Row #{0}: BOM not found for FG Item {1}" msgstr "" @@ -41439,31 +41603,31 @@ msgstr "" msgid "Row #{0}: Cannot cancel this Stock Entry as returned quantity cannot be greater than delivered quantity for Item {1} in the linked Subcontracting Inward Order" msgstr "" -#: erpnext/controllers/accounts_controller.py:3686 +#: erpnext/controllers/accounts_controller.py:3759 msgid "Row #{0}: Cannot delete item {1} which has already been billed." msgstr "الصف # {0}: لا يمكن حذف العنصر {1} الذي تم تحرير فاتورة به بالفعل." -#: erpnext/controllers/accounts_controller.py:3660 +#: erpnext/controllers/accounts_controller.py:3733 msgid "Row #{0}: Cannot delete item {1} which has already been delivered" msgstr "الصف # {0}: لا يمكن حذف العنصر {1} الذي تم تسليمه بالفعل" -#: erpnext/controllers/accounts_controller.py:3679 +#: erpnext/controllers/accounts_controller.py:3752 msgid "Row #{0}: Cannot delete item {1} which has already been received" msgstr "الصف # {0}: لا يمكن حذف العنصر {1} الذي تم استلامه بالفعل" -#: erpnext/controllers/accounts_controller.py:3666 +#: erpnext/controllers/accounts_controller.py:3739 msgid "Row #{0}: Cannot delete item {1} which has work order assigned to it." msgstr "الصف # {0}: لا يمكن حذف العنصر {1} الذي تم تعيين ترتيب العمل إليه." -#: erpnext/controllers/accounts_controller.py:3672 +#: erpnext/controllers/accounts_controller.py:3745 msgid "Row #{0}: Cannot delete item {1} which is assigned to customer's purchase order." msgstr "الصف # {0}: لا يمكن حذف العنصر {1} الذي تم تعيينه لأمر شراء العميل." -#: erpnext/controllers/accounts_controller.py:3939 +#: erpnext/controllers/accounts_controller.py:4012 msgid "Row #{0}: Cannot set Rate if the billed amount is greater than the amount for Item {1}." msgstr "" -#: erpnext/manufacturing/doctype/job_card/job_card.py:982 +#: erpnext/manufacturing/doctype/job_card/job_card.py:1007 msgid "Row #{0}: Cannot transfer more than Required Qty {1} for Item {2} against Job Card {3}" msgstr "" @@ -41509,11 +41673,11 @@ msgstr "" msgid "Row #{0}: Customer Provided Item {1} cannot be added multiple times in the Subcontracting Inward process." msgstr "" -#: erpnext/manufacturing/doctype/work_order/work_order.py:333 +#: erpnext/manufacturing/doctype/work_order/work_order.py:334 msgid "Row #{0}: Customer Provided Item {1} cannot be added multiple times." msgstr "" -#: erpnext/manufacturing/doctype/work_order/work_order.py:358 +#: erpnext/manufacturing/doctype/work_order/work_order.py:359 msgid "Row #{0}: Customer Provided Item {1} does not exist in the Required Items table linked to the Subcontracting Inward Order." msgstr "" @@ -41521,7 +41685,7 @@ msgstr "" msgid "Row #{0}: Customer Provided Item {1} exceeds quantity available through Subcontracting Inward Order" msgstr "" -#: erpnext/manufacturing/doctype/work_order/work_order.py:346 +#: erpnext/manufacturing/doctype/work_order/work_order.py:347 msgid "Row #{0}: Customer Provided Item {1} has insufficient quantity in the Subcontracting Inward Order. Available quantity is {2}." msgstr "" @@ -41538,11 +41702,11 @@ msgstr "" msgid "Row #{0}: Dates overlapping with other row" msgstr "" -#: erpnext/buying/doctype/purchase_order/purchase_order.py:393 +#: erpnext/buying/doctype/purchase_order/purchase_order.py:395 msgid "Row #{0}: Default BOM not found for FG Item {1}" msgstr "" -#: erpnext/assets/doctype/asset/asset.py:554 +#: erpnext/assets/doctype/asset/asset.py:602 msgid "Row #{0}: Depreciation Start Date is required" msgstr "الصف #{0}: تاريخ بداية الإهلاك مطلوب" @@ -41550,34 +41714,38 @@ msgstr "الصف #{0}: تاريخ بداية الإهلاك مطلوب" msgid "Row #{0}: Duplicate entry in References {1} {2}" msgstr "الصف # {0}: إدخال مكرر في المراجع {1} {2}" -#: erpnext/selling/doctype/sales_order/sales_order.py:316 +#: erpnext/selling/doctype/sales_order/sales_order.py:318 msgid "Row #{0}: Expected Delivery Date cannot be before Purchase Order Date" msgstr "الصف # {0}: تاريخ التسليم المتوقع لا يمكن أن يكون قبل تاريخ أمر الشراء" -#: erpnext/controllers/stock_controller.py:872 +#: erpnext/controllers/stock_controller.py:874 msgid "Row #{0}: Expense Account not set for the Item {1}. {2}" msgstr "" -#: erpnext/buying/doctype/purchase_order/purchase_order.py:398 -#: erpnext/selling/doctype/sales_order/sales_order.py:289 +#: erpnext/assets/doctype/asset_repair/asset_repair.py:146 +msgid "Row #{0}: Expense account {1} is not valid for Purchase Invoice {2}. Only expense accounts from non-stock items are allowed." +msgstr "" + +#: erpnext/buying/doctype/purchase_order/purchase_order.py:400 +#: erpnext/selling/doctype/sales_order/sales_order.py:291 msgid "Row #{0}: Finished Good Item Qty can not be zero" msgstr "" -#: erpnext/buying/doctype/purchase_order/purchase_order.py:380 -#: erpnext/selling/doctype/sales_order/sales_order.py:269 +#: erpnext/buying/doctype/purchase_order/purchase_order.py:382 +#: erpnext/selling/doctype/sales_order/sales_order.py:271 msgid "Row #{0}: Finished Good Item is not specified for service item {1}" msgstr "" -#: erpnext/buying/doctype/purchase_order/purchase_order.py:387 -#: erpnext/selling/doctype/sales_order/sales_order.py:276 +#: erpnext/buying/doctype/purchase_order/purchase_order.py:389 +#: erpnext/selling/doctype/sales_order/sales_order.py:278 msgid "Row #{0}: Finished Good Item {1} must be a sub-contracted item" msgstr "" -#: erpnext/stock/doctype/stock_entry/stock_entry.py:370 +#: erpnext/stock/doctype/stock_entry/stock_entry.py:433 msgid "Row #{0}: Finished Good must be {1}" msgstr "" -#: erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py:508 +#: erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py:515 msgid "Row #{0}: Finished Good reference is mandatory for Scrap Item {1}." msgstr "" @@ -41586,11 +41754,11 @@ msgstr "" msgid "Row #{0}: For Customer Provided Item {1}, Source Warehouse must be {2}" msgstr "" -#: erpnext/accounts/doctype/journal_entry/journal_entry.py:750 +#: erpnext/accounts/doctype/journal_entry/journal_entry.py:665 msgid "Row #{0}: For {1}, you can select reference document only if account gets credited" msgstr "" -#: erpnext/accounts/doctype/journal_entry/journal_entry.py:760 +#: erpnext/accounts/doctype/journal_entry/journal_entry.py:675 msgid "Row #{0}: For {1}, you can select reference document only if account gets debited" msgstr "" @@ -41598,7 +41766,7 @@ msgstr "" msgid "Row #{0}: From Date cannot be before To Date" msgstr "" -#: erpnext/manufacturing/doctype/job_card/job_card.py:764 +#: erpnext/manufacturing/doctype/job_card/job_card.py:759 msgid "Row #{0}: From Time and To Time fields are required" msgstr "" @@ -41610,14 +41778,22 @@ msgstr "الصف # {0}: تمت إضافة العنصر" msgid "Row #{0}: Item {1} does not exist" msgstr "" -#: erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py:1624 +#: erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py:1627 msgid "Row #{0}: Item {1} has been picked, please reserve stock from the Pick List." msgstr "" -#: erpnext/controllers/stock_controller.py:107 +#: erpnext/accounts/doctype/pos_invoice/pos_invoice.py:448 +msgid "Row #{0}: Item {1} has no stock in warehouse {2}." +msgstr "" + +#: erpnext/controllers/stock_controller.py:109 msgid "Row #{0}: Item {1} has zero rate but 'Allow Zero Valuation Rate' is not enabled." msgstr "" +#: erpnext/accounts/doctype/pos_invoice/pos_invoice.py:455 +msgid "Row #{0}: Item {1} in warehouse {2}: Available {3}, Needed {4}." +msgstr "" + #: erpnext/controllers/subcontracting_inward_controller.py:63 msgid "Row #{0}: Item {1} is not a Customer Provided Item." msgstr "" @@ -41651,27 +41827,27 @@ msgstr "" msgid "Row #{0}: Journal Entry {1} does not have account {2} or already matched against another voucher" msgstr "الصف {1} : قيد اليومية {1} لا يحتوى على الحساب {2} أو بالفعل يوجد في قسيمة مقابلة أخرى\\n
        \\nRow #{0}: Journal Entry {1} does not have account {2} or already matched against another voucher" -#: erpnext/assets/doctype/asset/asset.py:548 +#: erpnext/assets/doctype/asset/asset.py:596 msgid "Row #{0}: Next Depreciation Date cannot be before Available-for-use Date" msgstr "" -#: erpnext/assets/doctype/asset/asset.py:543 +#: erpnext/assets/doctype/asset/asset.py:591 msgid "Row #{0}: Next Depreciation Date cannot be before Purchase Date" msgstr "" -#: erpnext/selling/doctype/sales_order/sales_order.py:658 +#: erpnext/selling/doctype/sales_order/sales_order.py:657 msgid "Row #{0}: Not allowed to change Supplier as Purchase Order already exists" msgstr "الصف رقم {0}: غير مسموح تغيير المورد لأن أمر الشراء موجود مسبقاً\\n
        \\nRow #{0}: Not allowed to change Supplier as Purchase Order already exists" -#: erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py:1707 +#: erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py:1710 msgid "Row #{0}: Only {1} available to reserve for the Item {2}" msgstr "" -#: erpnext/assets/doctype/asset/asset.py:520 +#: erpnext/assets/doctype/asset/asset.py:568 msgid "Row #{0}: Opening Accumulated Depreciation must be less than or equal to {1}" msgstr "" -#: erpnext/stock/doctype/stock_entry/stock_entry.py:753 +#: erpnext/stock/doctype/stock_entry/stock_entry.py:821 msgid "Row #{0}: Operation {1} is not completed for {2} qty of finished goods in Work Order {3}. Please update operation status via Job Card {4}." msgstr "الصف # {0}: العملية {1} لم تكتمل لـ {2} الكمية من السلع تامة الصنع في أمر العمل {3}. يرجى تحديث حالة التشغيل عبر بطاقة العمل {4}." @@ -41696,11 +41872,11 @@ msgstr "" msgid "Row #{0}: Please select the Sub Assembly Warehouse" msgstr "" -#: erpnext/stock/doctype/item/item.py:501 +#: erpnext/stock/doctype/item/item.py:520 msgid "Row #{0}: Please set reorder quantity" msgstr "الصف # {0}: يرجى تعيين إعادة ترتيب الكمية\\n
        \\nRow #{0}: Please set reorder quantity" -#: erpnext/controllers/accounts_controller.py:546 +#: erpnext/controllers/accounts_controller.py:616 msgid "Row #{0}: Please update deferred revenue/expense account in item row or default account in company master" msgstr "" @@ -41717,15 +41893,15 @@ msgstr "" msgid "Row #{0}: Qty should be less than or equal to Available Qty to Reserve (Actual Qty - Reserved Qty) {1} for Iem {2} against Batch {3} in Warehouse {4}." msgstr "" -#: erpnext/controllers/stock_controller.py:1301 +#: erpnext/controllers/stock_controller.py:1406 msgid "Row #{0}: Quality Inspection is required for Item {1}" msgstr "" -#: erpnext/controllers/stock_controller.py:1316 +#: erpnext/controllers/stock_controller.py:1421 msgid "Row #{0}: Quality Inspection {1} is not submitted for the item: {2}" msgstr "" -#: erpnext/controllers/stock_controller.py:1331 +#: erpnext/controllers/stock_controller.py:1436 msgid "Row #{0}: Quality Inspection {1} was rejected for item {2}" msgstr "" @@ -41733,8 +41909,8 @@ msgstr "" msgid "Row #{0}: Quantity cannot be a non-positive number. Please increase the quantity or remove the Item {1}" msgstr "" -#: erpnext/controllers/accounts_controller.py:1377 -#: erpnext/controllers/accounts_controller.py:3793 +#: erpnext/controllers/accounts_controller.py:1450 +#: erpnext/controllers/accounts_controller.py:3866 msgid "Row #{0}: Quantity for Item {1} cannot be zero." msgstr "الصف # {0}: كمية البند {1} لا يمكن أن يكون صفرا" @@ -41742,12 +41918,12 @@ msgstr "الصف # {0}: كمية البند {1} لا يمكن أن يكون صف msgid "Row #{0}: Quantity of Item {1} cannot be more than {2} {3} against Subcontracting Inward Order {4}" msgstr "" -#: erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py:1692 +#: erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py:1695 msgid "Row #{0}: Quantity to reserve for the Item {1} should be greater than 0." msgstr "" -#: erpnext/controllers/accounts_controller.py:801 -#: erpnext/controllers/accounts_controller.py:813 +#: erpnext/controllers/accounts_controller.py:871 +#: erpnext/controllers/accounts_controller.py:883 #: erpnext/utilities/transaction_base.py:114 #: erpnext/utilities/transaction_base.py:120 msgid "Row #{0}: Rate must be same as {1}: {2} ({3} / {4})" @@ -41761,15 +41937,19 @@ msgstr "الصف {0} : نوع المستند المرجع يجب أن يكون msgid "Row #{0}: Reference Document Type must be one of Sales Order, Sales Invoice, Journal Entry or Dunning" msgstr "الصف # {0}: يجب أن يكون نوع المستند المرجعي أحد أوامر المبيعات أو فاتورة المبيعات أو إدخال دفتر اليومية أو المطالبة" -#: erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py:501 +#: erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py:508 msgid "Row #{0}: Rejected Qty cannot be set for Scrap Item {1}." msgstr "" -#: erpnext/controllers/subcontracting_controller.py:117 +#: erpnext/controllers/subcontracting_controller.py:118 msgid "Row #{0}: Rejected Warehouse is mandatory for the rejected Item {1}" msgstr "" -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:451 +#: erpnext/assets/doctype/asset_repair/asset_repair.py:164 +msgid "Row #{0}: Repair cost {1} exceeds available amount {2} for Purchase Invoice {3} and Account {4}" +msgstr "" + +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:400 msgid "Row #{0}: Return Against is required for returning asset" msgstr "" @@ -41781,22 +41961,22 @@ msgstr "" msgid "Row #{0}: Returned quantity cannot be greater than available quantity to return for Item {1}" msgstr "" -#: erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py:496 +#: erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py:503 msgid "Row #{0}: Scrap Item Qty cannot be zero" msgstr "" -#: erpnext/controllers/selling_controller.py:274 +#: erpnext/controllers/selling_controller.py:296 msgid "Row #{0}: Selling rate for item {1} is lower than its {2}.\n" "\t\t\t\t\tSelling {3} should be atleast {4}.

        Alternatively,\n" "\t\t\t\t\tyou can disable selling price validation in {5} to bypass\n" "\t\t\t\t\tthis validation." msgstr "" -#: erpnext/manufacturing/doctype/work_order/work_order.py:262 +#: erpnext/manufacturing/doctype/work_order/work_order.py:263 msgid "Row #{0}: Sequence ID must be {1} or {2} for Operation {3}." msgstr "" -#: erpnext/controllers/stock_controller.py:259 +#: erpnext/controllers/stock_controller.py:261 msgid "Row #{0}: Serial No {1} does not belong to Batch {2}" msgstr "الصف # {0}: الرقم التسلسلي {1} لا ينتمي إلى الدُفعة {2}" @@ -41812,19 +41992,19 @@ msgstr "" msgid "Row #{0}: Serial No(s) {1} are not a part of the linked Subcontracting Inward Order. Please select valid Serial No(s)." msgstr "" -#: erpnext/controllers/accounts_controller.py:574 +#: erpnext/controllers/accounts_controller.py:644 msgid "Row #{0}: Service End Date cannot be before Invoice Posting Date" msgstr "الصف # {0}: لا يمكن أن يكون تاريخ انتهاء الخدمة قبل تاريخ ترحيل الفاتورة" -#: erpnext/controllers/accounts_controller.py:568 +#: erpnext/controllers/accounts_controller.py:638 msgid "Row #{0}: Service Start Date cannot be greater than Service End Date" msgstr "الصف # {0}: لا يمكن أن يكون تاريخ بدء الخدمة أكبر من تاريخ انتهاء الخدمة" -#: erpnext/controllers/accounts_controller.py:562 +#: erpnext/controllers/accounts_controller.py:632 msgid "Row #{0}: Service Start and End Date is required for deferred accounting" msgstr "الصف # {0}: مطلوب بداية وتاريخ انتهاء الخدمة للمحاسبة المؤجلة" -#: erpnext/selling/doctype/sales_order/sales_order.py:479 +#: erpnext/selling/doctype/sales_order/sales_order.py:481 msgid "Row #{0}: Set Supplier for item {1}" msgstr "الصف # {0}: حدد المورد للبند {1}" @@ -41836,19 +42016,19 @@ msgstr "" msgid "Row #{0}: Source Warehouse must be same as Customer Warehouse {1} from the linked Subcontracting Inward Order" msgstr "" -#: erpnext/manufacturing/doctype/work_order/work_order.py:367 +#: erpnext/manufacturing/doctype/work_order/work_order.py:368 msgid "Row #{0}: Source Warehouse {1} for item {2} cannot be a customer warehouse." msgstr "" -#: erpnext/manufacturing/doctype/work_order/work_order.py:322 +#: erpnext/manufacturing/doctype/work_order/work_order.py:323 msgid "Row #{0}: Source Warehouse {1} for item {2} must be same as Source Warehouse {3} in the Work Order." msgstr "" -#: erpnext/stock/doctype/stock_entry/stock_entry.py:897 +#: erpnext/stock/doctype/stock_entry/stock_entry.py:965 msgid "Row #{0}: Source and Target Warehouse cannot be the same for Material Transfer" msgstr "" -#: erpnext/stock/doctype/stock_entry/stock_entry.py:919 +#: erpnext/stock/doctype/stock_entry/stock_entry.py:987 msgid "Row #{0}: Source, Target Warehouse and Inventory Dimensions cannot be the exact same for Material Transfer" msgstr "" @@ -41864,7 +42044,7 @@ msgstr "" msgid "Row #{0}: Status is mandatory" msgstr "" -#: erpnext/accounts/doctype/journal_entry/journal_entry.py:527 +#: erpnext/accounts/doctype/journal_entry/journal_entry.py:442 msgid "Row #{0}: Status must be {1} for Invoice Discounting {2}" msgstr "الصف # {0}: يجب أن تكون الحالة {1} بالنسبة لخصم الفاتورة {2}" @@ -41872,19 +42052,19 @@ msgstr "الصف # {0}: يجب أن تكون الحالة {1} بالنسبة ل msgid "Row #{0}: Stock cannot be reserved for Item {1} against a disabled Batch {2}." msgstr "" -#: erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py:1637 +#: erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py:1640 msgid "Row #{0}: Stock cannot be reserved for a non-stock Item {1}" msgstr "" -#: erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py:1650 +#: erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py:1653 msgid "Row #{0}: Stock cannot be reserved in group warehouse {1}." msgstr "" -#: erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py:1664 +#: erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py:1667 msgid "Row #{0}: Stock is already reserved for the Item {1}." msgstr "" -#: erpnext/stock/doctype/delivery_note/delivery_note.py:541 +#: erpnext/stock/doctype/delivery_note/delivery_note.py:545 msgid "Row #{0}: Stock is reserved for item {1} in warehouse {2}." msgstr "" @@ -41892,12 +42072,12 @@ msgstr "" msgid "Row #{0}: Stock not available to reserve for Item {1} against Batch {2} in Warehouse {3}." msgstr "" -#: erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py:1230 -#: erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py:1678 +#: erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py:1233 +#: erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py:1681 msgid "Row #{0}: Stock not available to reserve for the Item {1} in Warehouse {2}." msgstr "" -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1295 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1244 msgid "Row #{0}: Stock quantity {1} ({2}) for item {3} cannot exceed {4}" msgstr "" @@ -41905,11 +42085,11 @@ msgstr "" msgid "Row #{0}: Target Warehouse must be same as Customer Warehouse {1} from the linked Subcontracting Inward Order" msgstr "" -#: erpnext/controllers/stock_controller.py:272 +#: erpnext/controllers/stock_controller.py:274 msgid "Row #{0}: The batch {1} has already expired." msgstr "الصف رقم {0}: انتهت صلاحية الدفعة {1} بالفعل." -#: erpnext/stock/doctype/item/item.py:510 +#: erpnext/stock/doctype/item/item.py:529 msgid "Row #{0}: The warehouse {1} is not a child warehouse of a group warehouse {2}" msgstr "" @@ -41917,7 +42097,7 @@ msgstr "" msgid "Row #{0}: Timings conflicts with row {1}" msgstr "الصف # {0}: التوقيت يتعارض مع الصف {1}" -#: erpnext/assets/doctype/asset/asset.py:533 +#: erpnext/assets/doctype/asset/asset.py:581 msgid "Row #{0}: Total Number of Depreciations cannot be less than or equal to Opening Number of Booked Depreciations" msgstr "" @@ -41929,7 +42109,7 @@ msgstr "" msgid "Row #{0}: You cannot use the inventory dimension '{1}' in Stock Reconciliation to modify the quantity or valuation rate. Stock reconciliation with inventory dimensions is intended solely for performing opening entries." msgstr "" -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:455 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:404 msgid "Row #{0}: You must select an Asset for Item {1}." msgstr "" @@ -41953,39 +42133,39 @@ msgstr "" msgid "Row #{1}: Warehouse is mandatory for stock Item {0}" msgstr "" -#: erpnext/controllers/buying_controller.py:298 +#: erpnext/controllers/buying_controller.py:311 msgid "Row #{idx}: Cannot select Supplier Warehouse while suppling raw materials to subcontractor." msgstr "" -#: erpnext/controllers/buying_controller.py:563 +#: erpnext/controllers/buying_controller.py:576 msgid "Row #{idx}: Item rate has been updated as per valuation rate since its an internal stock transfer." msgstr "" -#: erpnext/controllers/buying_controller.py:1037 +#: erpnext/controllers/buying_controller.py:1050 msgid "Row #{idx}: Please enter a location for the asset item {item_code}." msgstr "" -#: erpnext/controllers/buying_controller.py:693 +#: erpnext/controllers/buying_controller.py:706 msgid "Row #{idx}: Received Qty must be equal to Accepted + Rejected Qty for Item {item_code}." msgstr "" -#: erpnext/controllers/buying_controller.py:706 +#: erpnext/controllers/buying_controller.py:719 msgid "Row #{idx}: {field_label} can not be negative for item {item_code}." msgstr "" -#: erpnext/controllers/buying_controller.py:652 +#: erpnext/controllers/buying_controller.py:665 msgid "Row #{idx}: {field_label} is mandatory." msgstr "" -#: erpnext/controllers/buying_controller.py:674 +#: erpnext/controllers/buying_controller.py:687 msgid "Row #{idx}: {field_label} is not allowed in Purchase Return." msgstr "" -#: erpnext/controllers/buying_controller.py:289 +#: erpnext/controllers/buying_controller.py:302 msgid "Row #{idx}: {from_warehouse_field} and {to_warehouse_field} cannot be same." msgstr "" -#: erpnext/controllers/buying_controller.py:1156 +#: erpnext/controllers/buying_controller.py:1169 msgid "Row #{idx}: {schedule_date} cannot be before {transaction_date}." msgstr "" @@ -41993,23 +42173,19 @@ msgstr "" msgid "Row #{}: Currency of {} - {} doesn't matches company currency." msgstr "الصف # {}: عملة {} - {} لا تطابق عملة الشركة." -#: erpnext/assets/doctype/asset/asset.py:356 +#: erpnext/assets/doctype/asset/asset.py:357 msgid "Row #{}: Finance Book should not be empty since you're using multiple." msgstr "" -#: erpnext/accounts/doctype/pos_invoice/pos_invoice.py:407 -msgid "Row #{}: Item Code: {} is not available under warehouse {}." -msgstr "الصف # {}: رمز العنصر: {} غير متوفر ضمن المستودع {}." - -#: erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.py:93 +#: erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.py:92 msgid "Row #{}: POS Invoice {} has been {}" msgstr "الصف رقم {}: فاتورة نقاط البيع {} كانت {}" -#: erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.py:74 +#: erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.py:73 msgid "Row #{}: POS Invoice {} is not against customer {}" msgstr "الصف رقم {}: فاتورة نقاط البيع {} ليست ضد العميل {}" -#: erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.py:89 +#: erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.py:88 msgid "Row #{}: POS Invoice {} is not submitted yet" msgstr "الصف رقم {}: فاتورة نقاط البيع {} لم يتم تقديمها بعد" @@ -42017,23 +42193,19 @@ msgstr "الصف رقم {}: فاتورة نقاط البيع {} لم يتم تق msgid "Row #{}: Please assign task to a member." msgstr "" -#: erpnext/assets/doctype/asset/asset.py:348 +#: erpnext/assets/doctype/asset/asset.py:349 msgid "Row #{}: Please use a different Finance Book." msgstr "" -#: erpnext/accounts/doctype/pos_invoice/pos_invoice.py:478 +#: erpnext/accounts/doctype/pos_invoice/pos_invoice.py:523 msgid "Row #{}: Serial No {} cannot be returned since it was not transacted in original invoice {}" msgstr "الصف # {}: لا يمكن إرجاع الرقم التسلسلي {} لأنه لم يتم التعامل معه في الفاتورة الأصلية {}" -#: erpnext/accounts/doctype/pos_invoice/pos_invoice.py:414 -msgid "Row #{}: Stock quantity not enough for Item Code: {} under warehouse {}." -msgstr "" - -#: erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.py:104 +#: erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.py:103 msgid "Row #{}: The original Invoice {} of return invoice {} is not consolidated." msgstr "" -#: erpnext/accounts/doctype/pos_invoice/pos_invoice.py:451 +#: erpnext/accounts/doctype/pos_invoice/pos_invoice.py:496 msgid "Row #{}: You cannot add positive quantities in a return invoice. Please remove item {} to complete the return." msgstr "" @@ -42050,15 +42222,15 @@ msgstr "رقم الصف {}: {}" msgid "Row #{}: {} {} does not exist." msgstr "الصف رقم {}: {} {} غير موجود." -#: erpnext/stock/doctype/item/item.py:1398 +#: erpnext/stock/doctype/item/item.py:1401 msgid "Row #{}: {} {} doesn't belong to Company {}. Please select valid {}." msgstr "" -#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:440 +#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:442 msgid "Row No {0}: Warehouse is required. Please set a Default Warehouse for Item {1} and Company {2}" msgstr "" -#: erpnext/manufacturing/doctype/job_card/job_card.py:692 +#: erpnext/manufacturing/doctype/job_card/job_card.py:687 msgid "Row {0} : Operation is required against the raw material item {1}" msgstr "الصف {0}: العملية مطلوبة مقابل عنصر المادة الخام {1}" @@ -42066,19 +42238,19 @@ msgstr "الصف {0}: العملية مطلوبة مقابل عنصر الماد msgid "Row {0} picked quantity is less than the required quantity, additional {1} {2} required." msgstr "" -#: erpnext/stock/doctype/stock_entry/stock_entry.py:1388 +#: erpnext/stock/doctype/stock_entry/stock_entry.py:1458 msgid "Row {0}# Item {1} cannot be transferred more than {2} against {3} {4}" msgstr "" -#: erpnext/stock/doctype/stock_entry/stock_entry.py:1412 +#: erpnext/stock/doctype/stock_entry/stock_entry.py:1482 msgid "Row {0}# Item {1} not found in 'Raw Materials Supplied' table in {2} {3}" msgstr "" -#: erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py:266 +#: erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py:273 msgid "Row {0}: Accepted Qty and Rejected Qty can't be zero at the same time." msgstr "" -#: erpnext/accounts/doctype/journal_entry/journal_entry.py:665 +#: erpnext/accounts/doctype/journal_entry/journal_entry.py:580 msgid "Row {0}: Account {1} and Party Type {2} have different account types" msgstr "" @@ -42086,11 +42258,11 @@ msgstr "" msgid "Row {0}: Activity Type is mandatory." msgstr "الصف {0}: نوع النشاط إلزامي." -#: erpnext/accounts/doctype/journal_entry/journal_entry.py:731 +#: erpnext/accounts/doctype/journal_entry/journal_entry.py:646 msgid "Row {0}: Advance against Customer must be credit" msgstr "الصف {0}: الدفعة المقدمة مقابل الزبائن يجب أن تكون دائن" -#: erpnext/accounts/doctype/journal_entry/journal_entry.py:733 +#: erpnext/accounts/doctype/journal_entry/journal_entry.py:648 msgid "Row {0}: Advance against Supplier must be debit" msgstr "الصف {0}:المورد المقابل المتقدم يجب أن يكون مدين\\n
        \\nRow {0}: Advance against Supplier must be debit" @@ -42102,23 +42274,28 @@ msgstr "" msgid "Row {0}: Allocated amount {1} must be less than or equal to remaining payment amount {2}" msgstr "" -#: erpnext/stock/doctype/stock_entry/stock_entry.py:1077 +#: erpnext/stock/doctype/stock_entry/stock_entry.py:1145 msgid "Row {0}: As {1} is enabled, raw materials cannot be added to {2} entry. Use {3} entry to consume raw materials." msgstr "" -#: erpnext/stock/doctype/material_request/material_request.py:874 +#: erpnext/stock/doctype/material_request/material_request.py:881 msgid "Row {0}: Bill of Materials not found for the Item {1}" msgstr "صف {0}: من مواد مشروع القانون لم يتم العثور على هذا البند {1}" -#: erpnext/accounts/doctype/journal_entry/journal_entry.py:984 +#: erpnext/accounts/doctype/journal_entry/journal_entry.py:899 msgid "Row {0}: Both Debit and Credit values cannot be zero" msgstr "" -#: erpnext/controllers/selling_controller.py:266 +#: erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py:550 +msgid "Row {0}: Consumed Qty {1} {2} must be less than or equal to Available Qty For Consumption\n" +"\t\t\t\t\t{3} {4} in Consumed Items Table." +msgstr "" + +#: erpnext/controllers/selling_controller.py:288 msgid "Row {0}: Conversion Factor is mandatory" msgstr "الصف {0}: معامل التحويل إلزامي" -#: erpnext/controllers/accounts_controller.py:3146 +#: erpnext/controllers/accounts_controller.py:3219 msgid "Row {0}: Cost Center {1} does not belong to Company {2}" msgstr "" @@ -42126,27 +42303,27 @@ msgstr "" msgid "Row {0}: Cost center is required for an item {1}" msgstr "الصف {0}: مركز التكلفة مطلوب لعنصر {1}" -#: erpnext/accounts/doctype/journal_entry/journal_entry.py:830 +#: erpnext/accounts/doctype/journal_entry/journal_entry.py:745 msgid "Row {0}: Credit entry can not be linked with a {1}" msgstr "صف {0}: لا يمكن ربط قيد دائن مع {1}" -#: erpnext/manufacturing/doctype/bom/bom.py:466 +#: erpnext/manufacturing/doctype/bom/bom.py:475 msgid "Row {0}: Currency of the BOM #{1} should be equal to the selected currency {2}" msgstr "الصف {0}: العملة للـ BOM #{1} يجب أن يساوي العملة المختارة {2}
        Row {0}: Currency of the BOM #{1} should be equal to the selected currency {2}" -#: erpnext/accounts/doctype/journal_entry/journal_entry.py:825 +#: erpnext/accounts/doctype/journal_entry/journal_entry.py:740 msgid "Row {0}: Debit entry can not be linked with a {1}" msgstr "الصف {0}: لا يمكن ربط قيد مدين مع {1}" -#: erpnext/controllers/selling_controller.py:834 +#: erpnext/controllers/selling_controller.py:859 msgid "Row {0}: Delivery Warehouse ({1}) and Customer Warehouse ({2}) can not be same" msgstr "الصف {0}: لا يمكن أن يكون مستودع التسليم ({1}) ومستودع العميل ({2}) متماثلين" -#: erpnext/controllers/subcontracting_controller.py:157 +#: erpnext/controllers/subcontracting_controller.py:158 msgid "Row {0}: Delivery Warehouse cannot be same as Customer Warehouse for Item {1}." msgstr "" -#: erpnext/controllers/accounts_controller.py:2639 +#: erpnext/controllers/accounts_controller.py:2712 msgid "Row {0}: Due Date in the Payment Terms table cannot be before Posting Date" msgstr "الصف {0}: لا يمكن أن يكون تاريخ الاستحقاق في جدول شروط الدفع قبل تاريخ الترحيل" @@ -42154,24 +42331,24 @@ msgstr "الصف {0}: لا يمكن أن يكون تاريخ الاستحقاق msgid "Row {0}: Either Delivery Note Item or Packed Item reference is mandatory." msgstr "" -#: erpnext/accounts/doctype/journal_entry/journal_entry.py:1075 -#: erpnext/controllers/taxes_and_totals.py:1228 +#: erpnext/accounts/doctype/journal_entry/journal_entry.py:990 +#: erpnext/controllers/taxes_and_totals.py:1349 msgid "Row {0}: Exchange Rate is mandatory" msgstr "الصف {0}: سعر صرف إلزامي" -#: erpnext/assets/doctype/asset/asset.py:495 +#: erpnext/assets/doctype/asset/asset.py:543 msgid "Row {0}: Expected Value After Useful Life must be less than Net Purchase Amount" msgstr "" -#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:530 +#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:532 msgid "Row {0}: Expense Head changed to {1} as no Purchase Receipt is created against Item {2}." msgstr "" -#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:487 +#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:489 msgid "Row {0}: Expense Head changed to {1} because account {2} is not linked to warehouse {3} or it is not the default inventory account" msgstr "" -#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:512 +#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:514 msgid "Row {0}: Expense Head changed to {1} because expense is booked against this account in Purchase Receipt {2}" msgstr "" @@ -42183,16 +42360,16 @@ msgstr "الصف {0}: للمورد {1} ، مطلوب عنوان البريد ا msgid "Row {0}: From Time and To Time is mandatory." msgstr "صف {0}: (من الوقت) و (إلى وقت) تكون إلزامية." -#: erpnext/manufacturing/doctype/job_card/job_card.py:264 +#: erpnext/manufacturing/doctype/job_card/job_card.py:259 #: erpnext/projects/doctype/timesheet/timesheet.py:212 msgid "Row {0}: From Time and To Time of {1} is overlapping with {2}" msgstr "الصف {0}: من وقت إلى وقت {1} يتداخل مع {2}" -#: erpnext/controllers/stock_controller.py:1397 +#: erpnext/controllers/stock_controller.py:1502 msgid "Row {0}: From Warehouse is mandatory for internal transfers" msgstr "" -#: erpnext/manufacturing/doctype/job_card/job_card.py:255 +#: erpnext/manufacturing/doctype/job_card/job_card.py:250 msgid "Row {0}: From time must be less than to time" msgstr "الصف {0}: من وقت يجب أن يكون أقل من الوقت" @@ -42200,31 +42377,31 @@ msgstr "الصف {0}: من وقت يجب أن يكون أقل من الوقت" msgid "Row {0}: Hours value must be greater than zero." msgstr "صف {0}: يجب أن تكون قيمة الساعات أكبر من الصفر." -#: erpnext/accounts/doctype/journal_entry/journal_entry.py:850 +#: erpnext/accounts/doctype/journal_entry/journal_entry.py:765 msgid "Row {0}: Invalid reference {1}" msgstr "الصف {0}: مرجع غير صالحة {1}" -#: erpnext/controllers/taxes_and_totals.py:140 +#: erpnext/controllers/taxes_and_totals.py:138 msgid "Row {0}: Item Tax template updated as per validity and rate applied" msgstr "" -#: erpnext/controllers/selling_controller.py:599 +#: erpnext/controllers/selling_controller.py:624 msgid "Row {0}: Item rate has been updated as per valuation rate since its an internal stock transfer" msgstr "" -#: erpnext/controllers/subcontracting_controller.py:150 +#: erpnext/controllers/subcontracting_controller.py:151 msgid "Row {0}: Item {1} must be a stock item." msgstr "" -#: erpnext/controllers/subcontracting_controller.py:165 +#: erpnext/controllers/subcontracting_controller.py:166 msgid "Row {0}: Item {1} must be a subcontracted item." msgstr "" -#: erpnext/controllers/subcontracting_controller.py:186 +#: erpnext/controllers/subcontracting_controller.py:187 msgid "Row {0}: Item {1}'s quantity cannot be higher than the available quantity." msgstr "" -#: erpnext/stock/doctype/delivery_note/delivery_note.py:598 +#: erpnext/stock/doctype/delivery_note/delivery_note.py:602 msgid "Row {0}: Packed Qty must be equal to {1} Qty." msgstr "" @@ -42232,11 +42409,11 @@ msgstr "" msgid "Row {0}: Packing Slip is already created for Item {1}." msgstr "" -#: erpnext/accounts/doctype/journal_entry/journal_entry.py:876 +#: erpnext/accounts/doctype/journal_entry/journal_entry.py:791 msgid "Row {0}: Party / Account does not match with {1} / {2} in {3} {4}" msgstr "الصف {0}: حزب / حساب لا يتطابق مع {1} / {2} في {3} {4}" -#: erpnext/accounts/doctype/journal_entry/journal_entry.py:654 +#: erpnext/accounts/doctype/journal_entry/journal_entry.py:569 msgid "Row {0}: Party Type and Party is required for Receivable / Payable account {1}" msgstr "الصف {0}: نوع الطرف المعني والطرف المعني مطلوب للحسابات المدينة / الدائنة {0}" @@ -42244,11 +42421,11 @@ msgstr "الصف {0}: نوع الطرف المعني والطرف المعني msgid "Row {0}: Payment Term is mandatory" msgstr "" -#: erpnext/accounts/doctype/journal_entry/journal_entry.py:724 +#: erpnext/accounts/doctype/journal_entry/journal_entry.py:639 msgid "Row {0}: Payment against Sales/Purchase Order should always be marked as advance" msgstr "الصف {0}: الدفع لطلب الشراء/البيع يجب أن يكون دائما معلم كمتقدم\\n
        \\nRow {0}: Payment against Sales/Purchase Order should always be marked as advance" -#: erpnext/accounts/doctype/journal_entry/journal_entry.py:717 +#: erpnext/accounts/doctype/journal_entry/journal_entry.py:632 msgid "Row {0}: Please check 'Is Advance' against Account {1} if this is an advance entry." msgstr "الصف {0}: يرجى اختيار \"دفعة مقدمة\" مقابل الحساب {1} إذا كان هذا الادخال دفعة مقدمة." @@ -42256,31 +42433,31 @@ msgstr "الصف {0}: يرجى اختيار \"دفعة مقدمة\" مقابل msgid "Row {0}: Please provide a valid Delivery Note Item or Packed Item reference." msgstr "" -#: erpnext/controllers/subcontracting_controller.py:211 +#: erpnext/controllers/subcontracting_controller.py:212 msgid "Row {0}: Please select a BOM for Item {1}." msgstr "" -#: erpnext/controllers/subcontracting_controller.py:199 +#: erpnext/controllers/subcontracting_controller.py:200 msgid "Row {0}: Please select an active BOM for Item {1}." msgstr "" -#: erpnext/controllers/subcontracting_controller.py:205 +#: erpnext/controllers/subcontracting_controller.py:206 msgid "Row {0}: Please select an valid BOM for Item {1}." msgstr "" -#: erpnext/regional/italy/utils.py:310 +#: erpnext/regional/italy/utils.py:283 msgid "Row {0}: Please set at Tax Exemption Reason in Sales Taxes and Charges" msgstr "الصف {0}: يرجى تعيين سبب الإعفاء الضريبي في ضرائب ورسوم المبيعات" -#: erpnext/regional/italy/utils.py:337 +#: erpnext/regional/italy/utils.py:310 msgid "Row {0}: Please set the Mode of Payment in Payment Schedule" msgstr "الصف {0}: يرجى ضبط طريقة الدفع في جدول الدفع" -#: erpnext/regional/italy/utils.py:342 +#: erpnext/regional/italy/utils.py:315 msgid "Row {0}: Please set the correct code on Mode of Payment {1}" msgstr "الصف {0}: يرجى ضبط الكود الصحيح على طريقة الدفع {1}" -#: erpnext/projects/doctype/timesheet_detail/timesheet_detail.py:104 +#: erpnext/projects/doctype/timesheet_detail/timesheet_detail.py:114 msgid "Row {0}: Project must be same as the one set in the Timesheet: {1}." msgstr "" @@ -42292,7 +42469,7 @@ msgstr "" msgid "Row {0}: Qty cannot be greater than {1} for the Item {2}." msgstr "" -#: erpnext/stock/doctype/stock_entry/stock_entry.py:461 +#: erpnext/stock/doctype/stock_entry/stock_entry.py:524 msgid "Row {0}: Qty in Stock UOM can not be zero." msgstr "" @@ -42304,7 +42481,7 @@ msgstr "" msgid "Row {0}: Quantity cannot be negative." msgstr "" -#: erpnext/stock/doctype/stock_entry/stock_entry.py:827 +#: erpnext/stock/doctype/stock_entry/stock_entry.py:895 msgid "Row {0}: Quantity not available for {4} in warehouse {1} at posting time of the entry ({2} {3})" msgstr "الصف {0}: الكمية غير متوفرة {4} في المستودع {1} في وقت نشر الإدخال ({2} {3})" @@ -42312,23 +42489,27 @@ msgstr "الصف {0}: الكمية غير متوفرة {4} في المستودع msgid "Row {0}: Shift cannot be changed since the depreciation has already been processed" msgstr "" -#: erpnext/stock/doctype/stock_entry/stock_entry.py:1425 +#: erpnext/stock/doctype/stock_entry/stock_entry.py:1495 msgid "Row {0}: Subcontracted Item is mandatory for the raw material {1}" msgstr "الصف {0}: العنصر المتعاقد عليه من الباطن إلزامي للمادة الخام {1}" -#: erpnext/controllers/stock_controller.py:1388 +#: erpnext/controllers/stock_controller.py:1493 msgid "Row {0}: Target Warehouse is mandatory for internal transfers" msgstr "" -#: erpnext/projects/doctype/timesheet_detail/timesheet_detail.py:115 +#: erpnext/projects/doctype/timesheet_detail/timesheet_detail.py:125 msgid "Row {0}: Task {1} does not belong to Project {2}" msgstr "" -#: erpnext/stock/doctype/stock_entry/stock_entry.py:506 +#: erpnext/assets/doctype/asset_repair/asset_repair.js:158 +msgid "Row {0}: The entire expense amount for account {1} in {2} has already been allocated." +msgstr "" + +#: erpnext/stock/doctype/stock_entry/stock_entry.py:570 msgid "Row {0}: The item {1}, quantity must be positive number" msgstr "الصف {0}: العنصر {1} ، يجب أن تكون الكمية رقمًا موجبًا" -#: erpnext/controllers/accounts_controller.py:3123 +#: erpnext/controllers/accounts_controller.py:3196 msgid "Row {0}: The {3} Account {1} does not belong to the company {2}" msgstr "" @@ -42336,16 +42517,16 @@ msgstr "" msgid "Row {0}: To set {1} periodicity, difference between from and to date must be greater than or equal to {2}" msgstr "" -#: erpnext/stock/doctype/stock_entry/stock_entry.py:455 +#: erpnext/stock/doctype/stock_entry/stock_entry.py:518 msgid "Row {0}: UOM Conversion Factor is mandatory" msgstr "الصف {0}: عامل تحويل UOM إلزامي\\n
        \\nRow {0}: UOM Conversion Factor is mandatory" -#: erpnext/manufacturing/doctype/bom/bom.py:1118 -#: erpnext/manufacturing/doctype/work_order/work_order.py:396 +#: erpnext/manufacturing/doctype/bom/bom.py:1136 +#: erpnext/manufacturing/doctype/work_order/work_order.py:397 msgid "Row {0}: Workstation or Workstation Type is mandatory for an operation {1}" msgstr "" -#: erpnext/controllers/accounts_controller.py:1099 +#: erpnext/controllers/accounts_controller.py:1169 msgid "Row {0}: user has not applied the rule {1} on the item {2}" msgstr "الصف {0}: لم يطبق المستخدم القاعدة {1} على العنصر {2}" @@ -42357,11 +42538,11 @@ msgstr "" msgid "Row {0}: {1} must be greater than 0" msgstr "الصف {0}: يجب أن يكون {1} أكبر من 0" -#: erpnext/controllers/accounts_controller.py:711 +#: erpnext/controllers/accounts_controller.py:781 msgid "Row {0}: {1} {2} cannot be same as {3} (Party Account) {4}" msgstr "" -#: erpnext/accounts/doctype/journal_entry/journal_entry.py:890 +#: erpnext/accounts/doctype/journal_entry/journal_entry.py:805 msgid "Row {0}: {1} {2} does not match with {3}" msgstr "الصف {0}: {1} {2} لا يتطابق مع {3}" @@ -42373,7 +42554,7 @@ msgstr "" msgid "Row {1}: Quantity ({0}) cannot be a fraction. To allow this, disable '{2}' in UOM {3}." msgstr "الصف {1}: لا يمكن أن تكون الكمية ({0}) كسرًا. للسماح بذلك ، قم بتعطيل '{2}' في UOM {3}." -#: erpnext/controllers/buying_controller.py:1019 +#: erpnext/controllers/buying_controller.py:1032 msgid "Row {idx}: Asset Naming Series is mandatory for the auto creation of assets for item {item_code}." msgstr "" @@ -42399,15 +42580,15 @@ msgstr "تمت إزالة الصفوف في {0}" msgid "Rows with Same Account heads will be merged on Ledger" msgstr "" -#: erpnext/controllers/accounts_controller.py:2650 +#: erpnext/controllers/accounts_controller.py:2723 msgid "Rows with duplicate due dates in other rows were found: {0}" msgstr "تم العثور على صفوف ذات تواريخ استحقاق مكررة في صفوف أخرى: {0}" -#: erpnext/accounts/doctype/journal_entry/journal_entry.js:124 +#: erpnext/accounts/doctype/journal_entry/journal_entry.js:128 msgid "Rows: {0} have 'Payment Entry' as reference_type. This should not be set manually." msgstr "" -#: erpnext/controllers/accounts_controller.py:275 +#: erpnext/controllers/accounts_controller.py:281 msgid "Rows: {0} in {1} section are Invalid. Reference Name should point to a valid Payment Entry or Journal Entry." msgstr "" @@ -42563,7 +42744,7 @@ msgstr "طريقة تحصيل الراتب" #. Option for the 'Order Type' (Select) field in DocType 'Sales Order' #. Label of the sales_details (Tab Break) field in DocType 'Item' #: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:142 -#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:237 +#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:238 #: erpnext/accounts/doctype/item_tax_template/item_tax_template_dashboard.py:9 #: erpnext/accounts/doctype/opening_invoice_creation_tool/opening_invoice_creation_tool.json #: erpnext/accounts/doctype/payment_term/payment_term_dashboard.py:8 @@ -42574,11 +42755,11 @@ msgstr "طريقة تحصيل الراتب" #: erpnext/crm/doctype/opportunity/opportunity.js:288 #: erpnext/crm/doctype/opportunity/opportunity.py:158 #: erpnext/projects/doctype/project/project_dashboard.py:15 -#: erpnext/regional/report/vat_audit_report/vat_audit_report.py:185 +#: erpnext/regional/report/vat_audit_report/vat_audit_report.py:146 #: erpnext/selling/doctype/quotation/quotation.json #: erpnext/selling/doctype/sales_order/sales_order.json -#: erpnext/setup/doctype/company/company.py:412 -#: erpnext/setup/doctype/company/company.py:599 +#: erpnext/setup/doctype/company/company.py:448 +#: erpnext/setup/doctype/company/company.py:640 #: erpnext/setup/doctype/company/company_dashboard.py:9 #: erpnext/setup/doctype/sales_person/sales_person_dashboard.py:12 #: erpnext/setup/install.py:329 @@ -42587,7 +42768,7 @@ msgstr "طريقة تحصيل الراتب" msgid "Sales" msgstr "مبيعات" -#: erpnext/setup/doctype/company/company.py:599 +#: erpnext/setup/doctype/company/company.py:640 msgid "Sales Account" msgstr "حساب مبيعات" @@ -42661,7 +42842,6 @@ msgstr "" #. DocType 'POS Settings' #. Name of a DocType #. Label of the sales_invoice (Link) field in DocType 'Sales Invoice Reference' -#. Label of a shortcut in the Accounting Workspace #. Label of a Link in the Receivables Workspace #. Label of a shortcut in the Receivables Workspace #. Option for the 'Document Type' (Select) field in DocType 'Contract' @@ -42679,23 +42859,21 @@ msgstr "" #: erpnext/accounts/doctype/pos_settings/pos_settings.json #: erpnext/accounts/doctype/sales_invoice/sales_invoice.json #: erpnext/accounts/doctype/sales_invoice_reference/sales_invoice_reference.json -#: erpnext/accounts/letterhead/company_letterhead_grey.html:97 #: erpnext/accounts/print_format/sales_auditing_voucher/sales_auditing_voucher.html:5 #: erpnext/accounts/report/gross_profit/gross_profit.js:30 #: erpnext/accounts/report/gross_profit/gross_profit.py:276 #: erpnext/accounts/report/gross_profit/gross_profit.py:283 -#: erpnext/accounts/workspace/accounting/accounting.json #: erpnext/accounts/workspace/receivables/receivables.json #: erpnext/crm/doctype/contract/contract.json #: erpnext/projects/doctype/timesheet/timesheet.json #: erpnext/projects/doctype/timesheet_detail/timesheet_detail.json #: erpnext/selling/doctype/quotation/quotation_list.js:22 -#: erpnext/selling/doctype/sales_order/sales_order.js:1059 +#: erpnext/selling/doctype/sales_order/sales_order.js:1063 #: erpnext/selling/doctype/sales_order/sales_order_list.js:75 #: erpnext/selling/workspace/selling/selling.json #: erpnext/setup/doctype/authorization_rule/authorization_rule.json #: erpnext/setup/workspace/home/home.json -#: erpnext/stock/doctype/delivery_note/delivery_note.js:350 +#: erpnext/stock/doctype/delivery_note/delivery_note.js:351 #: erpnext/stock/doctype/delivery_note/delivery_note_list.js:65 #: erpnext/stock/doctype/quality_inspection/quality_inspection.json msgid "Sales Invoice" @@ -42773,15 +42951,15 @@ msgstr "" msgid "Sales Invoice isn't created by user {}" msgstr "" -#: erpnext/accounts/doctype/pos_invoice/pos_invoice.py:423 +#: erpnext/accounts/doctype/pos_invoice/pos_invoice.py:468 msgid "Sales Invoice mode is activated in POS. Please create Sales Invoice instead." msgstr "" -#: erpnext/stock/doctype/delivery_note/delivery_note.py:618 +#: erpnext/stock/doctype/delivery_note/delivery_note.py:622 msgid "Sales Invoice {0} has already been submitted" msgstr "سبق أن تم ترحيل فاتورة المبيعات {0}" -#: erpnext/selling/doctype/sales_order/sales_order.py:574 +#: erpnext/selling/doctype/sales_order/sales_order.py:576 msgid "Sales Invoice {0} must be deleted before cancelling this Sales Order" msgstr "" @@ -42828,15 +43006,16 @@ msgstr "" #. Label of the sales_order (Link) field in DocType 'Purchase Receipt Item' #. Option for the 'Voucher Type' (Select) field in DocType 'Stock Reservation #. Entry' +#. Label of a shortcut in the Subcontracting Workspace #: erpnext/accounts/doctype/journal_entry_account/journal_entry_account.json #: erpnext/accounts/doctype/pos_invoice_item/pos_invoice_item.json -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.js:272 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.js:273 #: erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json -#: erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py:287 +#: erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py:276 #: erpnext/accounts/report/sales_register/sales_register.py:238 #: erpnext/buying/doctype/purchase_order_item/purchase_order_item.json #: erpnext/buying/doctype/supplier_quotation_item/supplier_quotation_item.json -#: erpnext/controllers/selling_controller.py:504 +#: erpnext/controllers/selling_controller.py:526 #: erpnext/crm/doctype/contract/contract.json #: erpnext/maintenance/doctype/maintenance_schedule/maintenance_schedule.js:65 #: erpnext/maintenance/doctype/maintenance_schedule_item/maintenance_schedule_item.json @@ -42862,9 +43041,9 @@ msgstr "" #: erpnext/selling/report/sales_order_analysis/sales_order_analysis.py:222 #: erpnext/selling/workspace/selling/selling.json #: erpnext/setup/doctype/authorization_rule/authorization_rule.json -#: erpnext/stock/doctype/delivery_note/delivery_note.js:160 -#: erpnext/stock/doctype/delivery_note/delivery_note.js:226 -#: erpnext/stock/doctype/material_request/material_request.js:221 +#: erpnext/stock/doctype/delivery_note/delivery_note.js:161 +#: erpnext/stock/doctype/delivery_note/delivery_note.js:227 +#: erpnext/stock/doctype/material_request/material_request.js:222 #: erpnext/stock/doctype/material_request_item/material_request_item.json #: erpnext/stock/doctype/pick_list_item/pick_list_item.json #: erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json @@ -42873,6 +43052,7 @@ msgstr "" #: erpnext/stock/report/delayed_item_report/delayed_item_report.py:159 #: erpnext/stock/report/delayed_order_report/delayed_order_report.js:30 #: erpnext/stock/report/delayed_order_report/delayed_order_report.py:74 +#: erpnext/subcontracting/workspace/subcontracting/subcontracting.json msgid "Sales Order" msgstr "طلب المبيعات" @@ -42922,7 +43102,7 @@ msgstr "تاريخ طلب المبيعات" #: erpnext/manufacturing/doctype/work_order/work_order.json #: erpnext/selling/doctype/delivery_schedule_item/delivery_schedule_item.json #: erpnext/selling/doctype/sales_order/sales_order.js:336 -#: erpnext/selling/doctype/sales_order/sales_order.js:1268 +#: erpnext/selling/doctype/sales_order/sales_order.js:1272 #: erpnext/selling/doctype/sales_order_item/sales_order_item.json #: erpnext/stock/doctype/material_request_item/material_request_item.json #: erpnext/stock/doctype/pick_list_item/pick_list_item.json @@ -42963,24 +43143,24 @@ msgstr "" msgid "Sales Order Trends" msgstr "مجرى طلبات البيع" -#: erpnext/stock/doctype/delivery_note/delivery_note.py:270 +#: erpnext/stock/doctype/delivery_note/delivery_note.py:274 msgid "Sales Order required for Item {0}" msgstr "طلب البيع مطلوب للبند {0}\\n
        \\nSales Order required for Item {0}" -#: erpnext/selling/doctype/sales_order/sales_order.py:340 +#: erpnext/selling/doctype/sales_order/sales_order.py:342 msgid "Sales Order {0} already exists against Customer's Purchase Order {1}. To allow multiple Sales Orders, Enable {2} in {3}" msgstr "" -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1420 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1369 msgid "Sales Order {0} is not submitted" msgstr "لا يتم اعتماد أمر التوريد {0}\\n
        \\nSales Order {0} is not submitted" -#: erpnext/manufacturing/doctype/work_order/work_order.py:447 +#: erpnext/manufacturing/doctype/work_order/work_order.py:448 msgid "Sales Order {0} is not valid" msgstr "أمر البيع {0} غير موجود\\n
        \\nSales Order {0} is not valid" -#: erpnext/controllers/selling_controller.py:485 -#: erpnext/manufacturing/doctype/work_order/work_order.py:452 +#: erpnext/controllers/selling_controller.py:507 +#: erpnext/manufacturing/doctype/work_order/work_order.py:453 msgid "Sales Order {0} is {1}" msgstr "طلب المبيعات {0} هو {1}" @@ -43151,7 +43331,7 @@ msgstr "ملخص دفع المبيعات" msgid "Sales Person" msgstr "مندوب مبيعات" -#: erpnext/controllers/selling_controller.py:248 +#: erpnext/controllers/selling_controller.py:270 msgid "Sales Person {0} is disabled." msgstr "" @@ -43218,7 +43398,7 @@ msgid "Sales Representative" msgstr "" #: erpnext/accounts/report/gross_profit/gross_profit.py:893 -#: erpnext/stock/doctype/delivery_note/delivery_note.js:273 +#: erpnext/stock/doctype/delivery_note/delivery_note.js:274 msgid "Sales Return" msgstr "مبيعات المعاده" @@ -43228,7 +43408,7 @@ msgstr "مبيعات المعاده" #: erpnext/crm/doctype/opportunity/opportunity.json #: erpnext/crm/doctype/sales_stage/sales_stage.json #: erpnext/crm/report/lost_opportunity/lost_opportunity.py:51 -#: erpnext/crm/report/sales_pipeline_analytics/sales_pipeline_analytics.py:69 +#: erpnext/crm/report/sales_pipeline_analytics/sales_pipeline_analytics.py:70 #: erpnext/crm/workspace/crm/crm.json msgid "Sales Stage" msgstr "مرحلة المبيعات" @@ -43239,7 +43419,7 @@ msgstr "ملخص المبيعات" #. Label of the sales_tax_template (Link) field in DocType 'Tax Rule' #: erpnext/accounts/doctype/tax_rule/tax_rule.json -#: erpnext/setup/doctype/company/company.js:126 +#: erpnext/setup/doctype/company/company.js:133 msgid "Sales Tax Template" msgstr "قالب ضريبة المبيعات" @@ -43375,12 +43555,12 @@ msgstr "مستودع الاحتفاظ بالعينات" #. Label of the sample_size (Float) field in DocType 'Quality Inspection' #: erpnext/manufacturing/report/quality_inspection_summary/quality_inspection_summary.py:93 -#: erpnext/public/js/controllers/transaction.js:2798 +#: erpnext/public/js/controllers/transaction.js:2806 #: erpnext/stock/doctype/quality_inspection/quality_inspection.json msgid "Sample Size" msgstr "حجم العينة" -#: erpnext/stock/doctype/stock_entry/stock_entry.py:3585 +#: erpnext/stock/doctype/stock_entry/stock_entry.py:3689 msgid "Sample quantity {0} cannot be more than received quantity {1}" msgstr "كمية العينة {0} لا يمكن أن تكون أكثر من الكمية المستلمة {1}" @@ -43510,7 +43690,7 @@ msgstr "" msgid "Scheduler is Inactive. Can't trigger jobs now." msgstr "" -#: erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.py:676 +#: erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.py:671 msgid "Scheduler is inactive. Cannot enqueue job." msgstr "" @@ -43636,7 +43816,7 @@ msgstr "الخردة المواد التكلفة (شركة العملات)" msgid "Scrap Warehouse" msgstr "الخردة مستودع" -#: erpnext/assets/doctype/asset/depreciation.py:380 +#: erpnext/assets/doctype/asset/depreciation.py:382 msgid "Scrap date cannot be before purchase date" msgstr "" @@ -43699,13 +43879,13 @@ msgstr "" msgid "Secretary" msgstr "" -#: erpnext/accounts/report/tax_withholding_details/tax_withholding_details.py:180 +#: erpnext/accounts/report/tax_withholding_details/tax_withholding_details.py:194 #: erpnext/accounts/report/tds_computation_summary/tds_computation_summary.py:117 msgid "Section Code" msgstr "كود القسم" #: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:177 -#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:300 +#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:301 msgid "Secured Loans" msgstr "القروض المضمونة" @@ -43738,28 +43918,28 @@ msgstr "" msgid "Select Alternate Item" msgstr "اختر البند البديل" -#: erpnext/selling/doctype/quotation/quotation.js:325 +#: erpnext/selling/doctype/quotation/quotation.js:326 msgid "Select Alternative Items for Sales Order" msgstr "" -#: erpnext/stock/doctype/item/item.js:689 +#: erpnext/stock/doctype/item/item.js:708 msgid "Select Attribute Values" msgstr "حدد قيم السمات" -#: erpnext/selling/doctype/sales_order/sales_order.js:1251 +#: erpnext/selling/doctype/sales_order/sales_order.js:1255 msgid "Select BOM" msgstr "حدد مكتب الإدارة" -#: erpnext/selling/doctype/sales_order/sales_order.js:1232 +#: erpnext/selling/doctype/sales_order/sales_order.js:1236 msgid "Select BOM and Qty for Production" msgstr "اختر فاتورة المواد و الكمية للانتاج" -#: erpnext/selling/doctype/sales_order/sales_order.js:1383 +#: erpnext/selling/doctype/sales_order/sales_order.js:1387 msgid "Select BOM, Qty and For Warehouse" msgstr "اختر قائمة المواد، الكمية، وإلى المخزن" -#: erpnext/assets/doctype/asset_repair/asset_repair.js:194 -#: erpnext/public/js/utils/sales_common.js:418 +#: erpnext/assets/doctype/asset_repair/asset_repair.js:234 +#: erpnext/public/js/utils/sales_common.js:443 #: erpnext/stock/doctype/pick_list/pick_list.js:385 msgid "Select Batch No" msgstr "" @@ -43780,11 +43960,15 @@ msgstr "اختر الماركة ..." msgid "Select Columns and Filters" msgstr "" -#: erpnext/accounts/doctype/journal_entry/journal_entry.js:132 +#: erpnext/accounts/doctype/journal_entry/journal_entry.js:136 msgid "Select Company" msgstr "حدد الشركة" -#: erpnext/manufacturing/doctype/job_card/job_card.js:520 +#: erpnext/public/js/print.js:102 +msgid "Select Company Address" +msgstr "" + +#: erpnext/manufacturing/doctype/job_card/job_card.js:532 msgid "Select Corrective Operation" msgstr "" @@ -43820,7 +44004,7 @@ msgstr "" msgid "Select Dispatch Address " msgstr "" -#: erpnext/manufacturing/doctype/job_card/job_card.js:212 +#: erpnext/manufacturing/doctype/job_card/job_card.js:221 msgid "Select Employees" msgstr "حدد الموظفين" @@ -43835,23 +44019,23 @@ msgstr "" #. Forecast' #: erpnext/manufacturing/doctype/master_production_schedule/master_production_schedule.json #: erpnext/manufacturing/doctype/sales_forecast/sales_forecast.json -#: erpnext/selling/doctype/sales_order/sales_order.js:1584 -#: erpnext/selling/doctype/sales_order/sales_order.js:1596 +#: erpnext/selling/doctype/sales_order/sales_order.js:1588 +#: erpnext/selling/doctype/sales_order/sales_order.js:1616 msgid "Select Items" msgstr "اختيار العناصر" -#: erpnext/selling/doctype/sales_order/sales_order.js:1470 +#: erpnext/selling/doctype/sales_order/sales_order.js:1474 msgid "Select Items based on Delivery Date" msgstr "حدد العناصر بناءً على تاريخ التسليم" -#: erpnext/public/js/controllers/transaction.js:2837 +#: erpnext/public/js/controllers/transaction.js:2845 msgid "Select Items for Quality Inspection" msgstr "" #. Label of the select_items_to_manufacture_section (Section Break) field in #. DocType 'Production Plan' #: erpnext/manufacturing/doctype/production_plan/production_plan.json -#: erpnext/selling/doctype/sales_order/sales_order.js:1279 +#: erpnext/selling/doctype/sales_order/sales_order.js:1283 msgid "Select Items to Manufacture" msgstr "حدد العناصر لتصنيع" @@ -43865,7 +44049,7 @@ msgstr "" msgid "Select Job Worker Address" msgstr "" -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.js:1154 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.js:1155 #: erpnext/selling/page/point_of_sale/pos_item_cart.js:955 msgid "Select Loyalty Program" msgstr "اختر برنامج الولاء" @@ -43874,19 +44058,19 @@ msgstr "اختر برنامج الولاء" msgid "Select Possible Supplier" msgstr "اختار المورد المحتمل" -#: erpnext/manufacturing/doctype/work_order/work_order.js:1024 +#: erpnext/manufacturing/doctype/work_order/work_order.js:1019 #: erpnext/stock/doctype/pick_list/pick_list.js:214 msgid "Select Quantity" msgstr "إختيار الكمية" -#: erpnext/assets/doctype/asset_repair/asset_repair.js:194 -#: erpnext/public/js/utils/sales_common.js:418 +#: erpnext/assets/doctype/asset_repair/asset_repair.js:234 +#: erpnext/public/js/utils/sales_common.js:443 #: erpnext/stock/doctype/pick_list/pick_list.js:385 msgid "Select Serial No" msgstr "" -#: erpnext/assets/doctype/asset_repair/asset_repair.js:197 -#: erpnext/public/js/utils/sales_common.js:421 +#: erpnext/assets/doctype/asset_repair/asset_repair.js:237 +#: erpnext/public/js/utils/sales_common.js:446 #: erpnext/stock/doctype/pick_list/pick_list.js:388 msgid "Select Serial and Batch" msgstr "" @@ -43937,7 +44121,7 @@ msgstr "حدد شركة" msgid "Select a Company this Employee belongs to." msgstr "" -#: erpnext/buying/doctype/supplier/supplier.js:180 +#: erpnext/buying/doctype/supplier/supplier.js:190 msgid "Select a Customer" msgstr "" @@ -43949,11 +44133,11 @@ msgstr "حدد أولوية افتراضية." msgid "Select a Payment Method." msgstr "" -#: erpnext/selling/doctype/customer/customer.js:230 +#: erpnext/selling/doctype/customer/customer.js:249 msgid "Select a Supplier" msgstr "حدد المورد" -#: erpnext/stock/doctype/material_request/material_request.js:401 +#: erpnext/stock/doctype/material_request/material_request.js:405 msgid "Select a Supplier from the Default Suppliers of the items below. On selection, a Purchase Order will be made against items belonging to the selected Supplier only." msgstr "حدد موردًا من الموردين الافتراضيين للعناصر أدناه. عند التحديد ، سيتم إجراء طلب الشراء مقابل العناصر التي تنتمي إلى المورد المحدد فقط." @@ -43961,7 +44145,7 @@ msgstr "حدد موردًا من الموردين الافتراضيين للع msgid "Select a company" msgstr "اختر شركة" -#: erpnext/stock/doctype/item/item.js:1022 +#: erpnext/stock/doctype/item/item.js:1041 msgid "Select an Item Group." msgstr "" @@ -43973,11 +44157,11 @@ msgstr "حدد حسابا للطباعة بعملة الحساب" msgid "Select an invoice to load summary data" msgstr "" -#: erpnext/selling/doctype/quotation/quotation.js:340 +#: erpnext/selling/doctype/quotation/quotation.js:341 msgid "Select an item from each set to be used in the Sales Order." msgstr "" -#: erpnext/stock/doctype/item/item.js:702 +#: erpnext/stock/doctype/item/item.js:721 msgid "Select at least one value from each of the attributes." msgstr "" @@ -43991,7 +44175,7 @@ msgstr "اختر الشركة أولا" msgid "Select company name first." msgstr "حدد اسم الشركة الأول." -#: erpnext/controllers/accounts_controller.py:2898 +#: erpnext/controllers/accounts_controller.py:2971 msgid "Select finance book for the item {0} at row {1}" msgstr "حدد دفتر تمويل للعنصر {0} في الصف {1}" @@ -43999,7 +44183,7 @@ msgstr "حدد دفتر تمويل للعنصر {0} في الصف {1}" msgid "Select item group" msgstr "حدد مجموعة العناصر" -#: erpnext/manufacturing/doctype/bom/bom.js:397 +#: erpnext/manufacturing/doctype/bom/bom.js:404 msgid "Select template item" msgstr "حدد عنصر القالب" @@ -44012,11 +44196,11 @@ msgstr "حدد الحساب البنكي للتوفيق." msgid "Select the Default Workstation where the Operation will be performed. This will be fetched in BOMs and Work Orders." msgstr "" -#: erpnext/manufacturing/doctype/work_order/work_order.js:1126 +#: erpnext/manufacturing/doctype/work_order/work_order.js:1121 msgid "Select the Item to be manufactured." msgstr "" -#: erpnext/manufacturing/doctype/bom/bom.js:911 +#: erpnext/manufacturing/doctype/bom/bom.js:928 msgid "Select the Item to be manufactured. The Item name, UoM, Company, and Currency will be fetched automatically." msgstr "" @@ -44037,11 +44221,11 @@ msgstr "" msgid "Select the date and your timezone" msgstr "" -#: erpnext/manufacturing/doctype/bom/bom.js:930 +#: erpnext/manufacturing/doctype/bom/bom.js:947 msgid "Select the raw materials (Items) required to manufacture the Item" msgstr "" -#: erpnext/manufacturing/doctype/bom/bom.js:452 +#: erpnext/manufacturing/doctype/bom/bom.js:459 msgid "Select variant item code for the template item {0}" msgstr "حدد رمز عنصر متغير لعنصر النموذج {0}" @@ -44064,7 +44248,7 @@ msgstr "حدد، لجعل العميل قابلا للبحث باستخدام ه msgid "Selected POS Opening Entry should be open." msgstr "يجب أن يكون الإدخال الافتتاحي المحدد لنقاط البيع مفتوحًا." -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:2536 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:2489 msgid "Selected Price List should have buying and selling fields checked." msgstr "قائمة الأسعار المختارة يجب أن يكون لديها حقول بيع وشراء محددة." @@ -44144,7 +44328,6 @@ msgstr "معدل البيع" #. Name of a DocType #. Label of a Link in the Selling Workspace -#. Label of a Link in the Settings Workspace #. Label of a shortcut in the Settings Workspace #: erpnext/selling/doctype/selling_settings/selling_settings.json #: erpnext/selling/workspace/selling/selling.json @@ -44270,7 +44453,7 @@ msgstr "" msgid "Serial / Batch Bundle" msgstr "" -#: erpnext/accounts/doctype/pos_invoice/pos_invoice.py:442 +#: erpnext/accounts/doctype/pos_invoice/pos_invoice.py:487 msgid "Serial / Batch Bundle Missing" msgstr "" @@ -44331,7 +44514,7 @@ msgstr "" #: erpnext/manufacturing/doctype/job_card/job_card.json #: erpnext/manufacturing/report/cost_of_poor_quality_report/cost_of_poor_quality_report.js:74 #: erpnext/manufacturing/report/cost_of_poor_quality_report/cost_of_poor_quality_report.py:114 -#: erpnext/public/js/controllers/transaction.js:2811 +#: erpnext/public/js/controllers/transaction.js:2819 #: erpnext/public/js/utils/serial_no_batch_selector.js:421 #: erpnext/selling/doctype/installation_note_item/installation_note_item.json #: erpnext/stock/doctype/delivery_note_item/delivery_note_item.json @@ -44369,7 +44552,7 @@ msgstr "" msgid "Serial No / Batch" msgstr "رقم المسلسل / الدفعة" -#: erpnext/controllers/selling_controller.py:93 +#: erpnext/controllers/selling_controller.py:106 msgid "Serial No Already Assigned" msgstr "" @@ -44388,10 +44571,14 @@ msgstr "" msgid "Serial No Range" msgstr "" -#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:2288 +#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:2317 msgid "Serial No Reserved" msgstr "" +#: erpnext/stock/doctype/item/item.py:426 +msgid "Serial No Series Overlap" +msgstr "" + #. Name of a report #. Label of a Link in the Stock Workspace #: erpnext/stock/report/serial_no_service_contract_expiry/serial_no_service_contract_expiry.json @@ -44464,7 +44651,7 @@ msgstr "الرقم المتسلسل {0} لا ينتمي إلى البند {1}\\n msgid "Serial No {0} does not exist" msgstr "الرقم المتسلسل {0} غير موجود\\n
        \\nSerial No {0} does not exist" -#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:2988 +#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:3021 msgid "Serial No {0} does not exists" msgstr "" @@ -44476,7 +44663,7 @@ msgstr "" msgid "Serial No {0} is already added" msgstr "" -#: erpnext/controllers/selling_controller.py:90 +#: erpnext/controllers/selling_controller.py:103 msgid "Serial No {0} is already assigned to customer {1}. Can only be returned against the customer {1}" msgstr "" @@ -44496,7 +44683,7 @@ msgstr "الرقم التسلسلي {0} تحت الضمان حتى {1}\\n
        \\n msgid "Serial No {0} not found" msgstr "لم يتم العثور علي الرقم التسلسلي {0}\\n
        \\nSerial No {0} not found" -#: erpnext/selling/page/point_of_sale/pos_controller.js:875 +#: erpnext/selling/page/point_of_sale/pos_controller.js:879 msgid "Serial No: {0} has already been transacted into another POS Invoice." msgstr "الرقم التسلسلي: تم بالفعل معاملة {0} في فاتورة نقطة بيع أخرى." @@ -44517,11 +44704,11 @@ msgstr "" msgid "Serial Nos and Batches" msgstr "الرقم التسلسلي ودفعات" -#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:1607 +#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:1636 msgid "Serial Nos are created successfully" msgstr "" -#: erpnext/stock/stock_ledger.py:2270 +#: erpnext/stock/stock_ledger.py:2307 msgid "Serial Nos are reserved in Stock Reservation Entries, you need to unreserve them before proceeding." msgstr "" @@ -44599,15 +44786,15 @@ msgstr "" msgid "Serial and Batch Bundle" msgstr "" -#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:1829 +#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:1858 msgid "Serial and Batch Bundle created" msgstr "" -#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:1901 +#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:1930 msgid "Serial and Batch Bundle updated" msgstr "" -#: erpnext/controllers/stock_controller.py:153 +#: erpnext/controllers/stock_controller.py:155 msgid "Serial and Batch Bundle {0} is already used in {1} {2}." msgstr "" @@ -44659,7 +44846,7 @@ msgstr "" msgid "Serial and Batch Summary" msgstr "" -#: erpnext/stock/utils.py:419 +#: erpnext/stock/utils.py:423 msgid "Serial number {0} entered more than once" msgstr "الرقم التسلسلي {0} دخلت أكثر من مرة" @@ -44725,7 +44912,7 @@ msgstr "" #: erpnext/accounts/doctype/budget/budget.json #: erpnext/accounts/doctype/cashier_closing/cashier_closing.json #: erpnext/accounts/doctype/dunning/dunning.json -#: erpnext/accounts/doctype/journal_entry/journal_entry.js:620 +#: erpnext/accounts/doctype/journal_entry/journal_entry.js:624 #: erpnext/accounts/doctype/journal_entry/journal_entry.json #: erpnext/accounts/doctype/journal_entry_template/journal_entry_template.json #: erpnext/accounts/doctype/payment_entry/payment_entry.json @@ -44968,20 +45155,16 @@ msgstr "تاريخ بدء الخدمة" msgid "Service Stop Date" msgstr "تاريخ توقف الخدمة" -#: erpnext/accounts/deferred_revenue.py:44 -#: erpnext/public/js/controllers/transaction.js:1654 +#: erpnext/accounts/deferred_revenue.py:45 +#: erpnext/public/js/controllers/transaction.js:1662 msgid "Service Stop Date cannot be after Service End Date" msgstr "لا يمكن أن يكون تاريخ إيقاف الخدمة بعد تاريخ انتهاء الخدمة" -#: erpnext/accounts/deferred_revenue.py:41 -#: erpnext/public/js/controllers/transaction.js:1651 +#: erpnext/accounts/deferred_revenue.py:42 +#: erpnext/public/js/controllers/transaction.js:1659 msgid "Service Stop Date cannot be before Service Start Date" msgstr "لا يمكن أن يكون تاريخ إيقاف الخدمة قبل تاريخ بدء الخدمة" -#: erpnext/assets/doctype/asset_repair/asset_repair.py:118 -msgid "Service item not present in Purchase Invoice {0}" -msgstr "" - #. Label of the service_items (Table) field in DocType 'Asset Capitalization' #: erpnext/assets/doctype/asset_capitalization/asset_capitalization.json #: erpnext/setup/setup_wizard/operations/install_fixtures.py:52 @@ -45016,8 +45199,8 @@ msgstr "" msgid "Set Delivery Warehouse" msgstr "" -#: erpnext/manufacturing/doctype/job_card/job_card.js:391 -#: erpnext/manufacturing/doctype/job_card/job_card.js:460 +#: erpnext/manufacturing/doctype/job_card/job_card.js:403 +#: erpnext/manufacturing/doctype/job_card/job_card.js:472 msgid "Set Finished Good Quantity" msgstr "" @@ -45048,11 +45231,11 @@ msgstr "تعيين مجموعة من الحكمة الإغلاق الميزان msgid "Set Landed Cost Based on Purchase Invoice Rate" msgstr "" -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.js:1166 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.js:1167 msgid "Set Loyalty Program" msgstr "" -#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js:304 +#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js:305 msgid "Set New Release Date" msgstr "تعيين تاريخ الإصدار الجديد" @@ -45068,7 +45251,7 @@ msgstr "" msgid "Set Operating Cost Based On BOM Quantity" msgstr "" -#: erpnext/manufacturing/doctype/bom_creator/bom_creator.py:88 +#: erpnext/manufacturing/doctype/bom_creator/bom_creator.py:90 msgid "Set Parent Row No in Items Table" msgstr "" @@ -45077,7 +45260,7 @@ msgstr "" msgid "Set Posting Date" msgstr "حدد تاريخ النشر" -#: erpnext/manufacturing/doctype/bom/bom.js:957 +#: erpnext/manufacturing/doctype/bom/bom.js:974 msgid "Set Process Loss Item Quantity" msgstr "" @@ -45113,13 +45296,17 @@ msgstr "" #. Label of the set_warehouse (Link) field in DocType 'Sales Order' #. Label of the set_warehouse (Link) field in DocType 'Delivery Note' #. Label of the set_from_warehouse (Link) field in DocType 'Material Request' -#: erpnext/public/js/utils/sales_common.js:520 +#: erpnext/public/js/utils/sales_common.js:545 #: erpnext/selling/doctype/sales_order/sales_order.json #: erpnext/stock/doctype/delivery_note/delivery_note.json #: erpnext/stock/doctype/material_request/material_request.json msgid "Set Source Warehouse" msgstr "تعيين المخزن المصدر" +#: erpnext/selling/doctype/sales_order/sales_order.js:1594 +msgid "Set Supplier" +msgstr "" + #. Label of the set_target_warehouse (Link) field in DocType 'Sales Invoice' #. Label of the set_warehouse (Link) field in DocType 'Purchase Order' #. Label of the set_target_warehouse (Link) field in DocType 'Delivery Note' @@ -45127,7 +45314,7 @@ msgstr "تعيين المخزن المصدر" #. Label of the set_warehouse (Link) field in DocType 'Subcontracting Order' #: erpnext/accounts/doctype/sales_invoice/sales_invoice.json #: erpnext/buying/doctype/purchase_order/purchase_order.json -#: erpnext/public/js/utils/sales_common.js:517 +#: erpnext/public/js/utils/sales_common.js:542 #: erpnext/stock/doctype/delivery_note/delivery_note.json #: erpnext/stock/doctype/material_request/material_request.json #: erpnext/subcontracting/doctype/subcontracting_order/subcontracting_order.json @@ -45159,7 +45346,7 @@ msgstr "على النحو مغلق" msgid "Set as Completed" msgstr "تعيين كـ مكتمل" -#: erpnext/public/js/utils/sales_common.js:544 +#: erpnext/public/js/utils/sales_common.js:569 #: erpnext/selling/doctype/quotation/quotation.js:129 msgid "Set as Lost" msgstr "على النحو المفقودة" @@ -45182,11 +45369,11 @@ msgstr "على النحو المفتوحة" msgid "Set by Item Tax Template" msgstr "" -#: erpnext/setup/doctype/company/company.py:502 +#: erpnext/setup/doctype/company/company.py:538 msgid "Set default inventory account for perpetual inventory" msgstr "تعيين حساب المخزون الافتراضي للمخزون الدائم" -#: erpnext/setup/doctype/company/company.py:528 +#: erpnext/setup/doctype/company/company.py:564 msgid "Set default {0} account for non stock items" msgstr "" @@ -45196,7 +45383,7 @@ msgstr "" msgid "Set fieldname from which you want to fetch the data from the parent form." msgstr "" -#: erpnext/manufacturing/doctype/bom/bom.js:947 +#: erpnext/manufacturing/doctype/bom/bom.js:964 msgid "Set quantity of process loss item:" msgstr "" @@ -45212,7 +45399,7 @@ msgstr "تعيين معدل عنصر التجميع الفرعي استنادا msgid "Set targets Item Group-wise for this Sales Person." msgstr "تحديد أهداف المجموعة السلعة الحكيم لهذا الشخص المبيعات." -#: erpnext/manufacturing/doctype/work_order/work_order.js:1183 +#: erpnext/manufacturing/doctype/work_order/work_order.js:1178 msgid "Set the Planned Start Date (an Estimated Date at which you want the Production to begin)" msgstr "" @@ -45226,15 +45413,15 @@ msgstr "" msgid "Set this if the customer is a Public Administration company." msgstr "حدد هذا إذا كان العميل شركة إدارة عامة." -#: erpnext/assets/doctype/asset/asset.py:771 +#: erpnext/assets/doctype/asset/asset.py:819 msgid "Set {0} in asset category {1} for company {2}" msgstr "" -#: erpnext/assets/doctype/asset/asset.py:1104 +#: erpnext/assets/doctype/asset/asset.py:1152 msgid "Set {0} in asset category {1} or company {2}" msgstr "تعيين {0} في فئة الأصول {1} أو الشركة {2}" -#: erpnext/assets/doctype/asset/asset.py:1101 +#: erpnext/assets/doctype/asset/asset.py:1149 msgid "Set {0} in company {1}" msgstr "قم بتعيين {0} في الشركة {1}" @@ -45301,8 +45488,8 @@ msgstr "" msgid "Setting up company" msgstr "تأسيس شركة" -#: erpnext/manufacturing/doctype/bom/bom.py:1097 -#: erpnext/manufacturing/doctype/work_order/work_order.py:1446 +#: erpnext/manufacturing/doctype/bom/bom.py:1115 +#: erpnext/manufacturing/doctype/work_order/work_order.py:1450 msgid "Setting {0} is required" msgstr "" @@ -45411,7 +45598,7 @@ msgid "Shift Time (In Hours)" msgstr "" #. Name of a DocType -#: erpnext/stock/doctype/delivery_note/delivery_note.js:249 +#: erpnext/stock/doctype/delivery_note/delivery_note.js:250 #: erpnext/stock/doctype/shipment/shipment.json msgid "Shipment" msgstr "" @@ -45462,7 +45649,7 @@ msgstr "" msgid "Shipment details" msgstr "" -#: erpnext/stock/doctype/delivery_note/delivery_note.py:789 +#: erpnext/stock/doctype/delivery_note/delivery_note.py:793 msgid "Shipments" msgstr "شحنات" @@ -45497,7 +45684,7 @@ msgstr "الشحن العنوان الاسم" msgid "Shipping Address Template" msgstr "" -#: erpnext/controllers/accounts_controller.py:505 +#: erpnext/controllers/accounts_controller.py:575 msgid "Shipping Address does not belong to the {0}" msgstr "" @@ -45639,7 +45826,7 @@ msgid "Short-term Investments" msgstr "" #: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:175 -#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:295 +#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:296 msgid "Short-term Provisions" msgstr "" @@ -45705,6 +45892,7 @@ msgstr "إظهار السجلات الفاشلة" msgid "Show Future Payments" msgstr "إظهار المدفوعات المستقبلية" +#: erpnext/accounts/report/accounts_payable_summary/accounts_payable_summary.js:107 #: erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.js:125 msgid "Show GL Balance" msgstr "" @@ -45860,7 +46048,7 @@ msgstr "إظهار نقاط البيع فقط" msgid "Show only the Immediate Upcoming Term" msgstr "" -#: erpnext/stock/utils.py:579 +#: erpnext/stock/utils.py:585 msgid "Show pending entries" msgstr "" @@ -45957,11 +46145,11 @@ msgstr "" msgid "Simultaneous" msgstr "" -#: erpnext/stock/doctype/stock_entry/stock_entry.py:583 +#: erpnext/stock/doctype/stock_entry/stock_entry.py:651 msgid "Since there is a process loss of {0} units for the finished good {1}, you should reduce the quantity by {0} units for the finished good {1} in the Items Table." msgstr "" -#: erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py:96 +#: erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py:105 msgid "Since {0} are Serial No/Batch No items, you cannot enable 'Recreate Stock Ledgers' in Repost Item Valuation." msgstr "" @@ -45993,7 +46181,7 @@ msgstr "تخطي ملاحظة التسليم" #. Label of the skip_material_transfer (Check) field in DocType 'Work Order #. Operation' -#: erpnext/manufacturing/doctype/work_order/work_order.js:355 +#: erpnext/manufacturing/doctype/work_order/work_order.js:362 #: erpnext/manufacturing/doctype/work_order_operation/work_order_operation.json #: erpnext/manufacturing/doctype/workstation/workstation.js:454 msgid "Skip Material Transfer" @@ -46009,7 +46197,7 @@ msgstr "" msgid "Skip Material Transfer to WIP Warehouse" msgstr "تخطي نقل المواد إلى مستودع WIP" -#: erpnext/accounts/doctype/tax_withholding_category/tax_withholding_category.py:138 +#: erpnext/accounts/doctype/tax_withholding_category/tax_withholding_category.py:141 msgid "Skipping Tax Withholding Category {0} as there is no associated account set for Company {1} in it." msgstr "" @@ -46060,7 +46248,7 @@ msgstr "" msgid "Solvency Ratios" msgstr "" -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:300 +#: erpnext/controllers/accounts_controller.py:4259 msgid "Some required Company details are missing. You don't have permission to update them. Please contact your System Manager." msgstr "" @@ -46068,15 +46256,15 @@ msgstr "" msgid "Something went wrong please try again" msgstr "" -#: erpnext/accounts/doctype/pricing_rule/utils.py:752 +#: erpnext/accounts/doctype/pricing_rule/utils.py:755 msgid "Sorry, this coupon code is no longer valid" msgstr "عذرا ، رمز القسيمة هذا لم يعد صالحًا" -#: erpnext/accounts/doctype/pricing_rule/utils.py:750 +#: erpnext/accounts/doctype/pricing_rule/utils.py:753 msgid "Sorry, this coupon code's validity has expired" msgstr "عذرا ، لقد انتهت صلاحية رمز القسيمة" -#: erpnext/accounts/doctype/pricing_rule/utils.py:748 +#: erpnext/accounts/doctype/pricing_rule/utils.py:751 msgid "Sorry, this coupon code's validity has not started" msgstr "عذرًا ، لم تبدأ صلاحية رمز القسيمة" @@ -46143,7 +46331,7 @@ msgstr "نوع المصدر" #. Label of the s_warehouse (Link) field in DocType 'Stock Entry Detail' #: erpnext/accounts/doctype/pos_invoice/pos_invoice.json #: erpnext/accounts/doctype/sales_invoice/sales_invoice.json -#: erpnext/manufacturing/doctype/bom/bom.js:424 +#: erpnext/manufacturing/doctype/bom/bom.js:431 #: erpnext/manufacturing/doctype/bom_explosion_item/bom_explosion_item.json #: erpnext/manufacturing/doctype/bom_item/bom_item.json #: erpnext/manufacturing/doctype/bom_operation/bom_operation.json @@ -46153,10 +46341,10 @@ msgstr "نوع المصدر" #: erpnext/manufacturing/doctype/work_order_item/work_order_item.json #: erpnext/manufacturing/doctype/work_order_operation/work_order_operation.json #: erpnext/manufacturing/report/work_order_stock_report/work_order_stock_report.py:126 -#: erpnext/public/js/utils/sales_common.js:516 +#: erpnext/public/js/utils/sales_common.js:541 #: erpnext/stock/dashboard/item_dashboard.js:227 #: erpnext/stock/doctype/material_request_item/material_request_item.json -#: erpnext/stock/doctype/stock_entry/stock_entry.js:668 +#: erpnext/stock/doctype/stock_entry/stock_entry.js:681 #: erpnext/stock/doctype/stock_entry_detail/stock_entry_detail.json msgid "Source Warehouse" msgstr "مصدر مستودع" @@ -46172,11 +46360,11 @@ msgstr "عنوان مستودع المصدر" msgid "Source Warehouse Address Link" msgstr "" -#: erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py:1160 +#: erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py:1163 msgid "Source Warehouse is mandatory for the Item {0}." msgstr "" -#: erpnext/manufacturing/doctype/work_order/work_order.py:281 +#: erpnext/manufacturing/doctype/work_order/work_order.py:282 msgid "Source Warehouse {0} must be same as Customer Warehouse {1} in the Subcontracting Inward Order." msgstr "" @@ -46184,7 +46372,7 @@ msgstr "" msgid "Source and Target Location cannot be same" msgstr "لا يمكن أن يكون المصدر و الموقع الهدف نفسه" -#: erpnext/stock/doctype/stock_entry/stock_entry.py:701 +#: erpnext/stock/doctype/stock_entry/stock_entry.py:769 msgid "Source and target warehouse cannot be same for row {0}" msgstr "المصدر والمستودع المستهدف لا يمكن أن يكون نفس الصف {0}\\n
        \\nSource and target warehouse cannot be same for row {0}" @@ -46193,12 +46381,12 @@ msgid "Source and target warehouse must be different" msgstr "ويجب أن تكون مصدر ومستودع الهدف مختلفة" #: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:152 -#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:253 +#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:254 msgid "Source of Funds (Liabilities)" msgstr "(مصدر الأموال (الخصوم" -#: erpnext/stock/doctype/stock_entry/stock_entry.py:678 -#: erpnext/stock/doctype/stock_entry/stock_entry.py:695 +#: erpnext/stock/doctype/stock_entry/stock_entry.py:746 +#: erpnext/stock/doctype/stock_entry/stock_entry.py:763 msgid "Source warehouse is mandatory for row {0}" msgstr "مستودع المصدر إلزامي للصف {0}\\n
        \\nSource warehouse is mandatory for row {0}" @@ -46232,6 +46420,10 @@ msgstr "" msgid "Specify conditions to calculate shipping amount" msgstr "" +#: erpnext/accounts/doctype/budget/budget.py:217 +msgid "Spending for Account {0} ({1}) between {2} and {3} has already exceeded the new allocated budget. Spent: {4}, Budget: {5}" +msgstr "" + #: erpnext/assets/doctype/asset/asset.js:557 #: erpnext/stock/doctype/batch/batch.js:91 #: erpnext/stock/doctype/batch/batch.js:183 @@ -46267,11 +46459,11 @@ msgstr "تقسيم القضية" msgid "Split Qty" msgstr "" -#: erpnext/assets/doctype/asset/asset.py:1243 +#: erpnext/assets/doctype/asset/asset.py:1291 msgid "Split Quantity must be less than Asset Quantity" msgstr "" -#: erpnext/accounts/doctype/payment_entry/payment_entry.py:2518 +#: erpnext/accounts/doctype/payment_entry/payment_entry.py:2519 msgid "Splitting {0} {1} into {2} rows as per Payment Terms" msgstr "" @@ -46329,7 +46521,7 @@ msgstr "اسم المرحلة" msgid "Stale Days" msgstr "أيام قديمة" -#: erpnext/accounts/doctype/accounts_settings/accounts_settings.py:114 +#: erpnext/accounts/doctype/accounts_settings/accounts_settings.py:109 msgid "Stale Days should start from 1." msgstr "" @@ -46338,7 +46530,7 @@ msgstr "" msgid "Standard Buying" msgstr "شراء القياسية" -#: erpnext/manufacturing/report/bom_explorer/bom_explorer.py:61 +#: erpnext/manufacturing/report/bom_explorer/bom_explorer.py:73 msgid "Standard Description" msgstr "" @@ -46348,7 +46540,7 @@ msgstr "" #: erpnext/setup/setup_wizard/operations/defaults_setup.py:70 #: erpnext/setup/setup_wizard/operations/install_fixtures.py:484 -#: erpnext/stock/doctype/item/item.py:246 +#: erpnext/stock/doctype/item/item.py:248 msgid "Standard Selling" msgstr "البيع القياسية" @@ -46408,7 +46600,7 @@ msgstr "" msgid "Start Deletion" msgstr "" -#: erpnext/manufacturing/doctype/job_card/job_card.js:206 +#: erpnext/manufacturing/doctype/job_card/job_card.js:215 #: erpnext/manufacturing/doctype/workstation/workstation.js:124 msgid "Start Job" msgstr "" @@ -46417,7 +46609,7 @@ msgstr "" msgid "Start Merge" msgstr "" -#: erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.js:95 +#: erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.js:99 msgid "Start Reposting" msgstr "" @@ -46433,7 +46625,7 @@ msgstr "" #: erpnext/accounts/report/deferred_revenue_and_expense/deferred_revenue_and_expense.js:56 #: erpnext/accounts/report/financial_ratios/financial_ratios.js:17 #: erpnext/assets/report/fixed_asset_register/fixed_asset_register.js:81 -#: erpnext/public/js/financial_statements.js:332 +#: erpnext/public/js/financial_statements.js:343 msgid "Start Year" msgstr "بداية السنة" @@ -46464,8 +46656,8 @@ msgstr "يجب أن يكون تاريخ البدء أقل من تاريخ الا msgid "Started Time" msgstr "وقت البدء" -#: erpnext/utilities/bulk_transaction.py:24 -msgid "Started a background job to create {1} {0}" +#: erpnext/utilities/bulk_transaction.py:44 +msgid "Started a background job to create {1} {0}. {2}" msgstr "" #. Label of the date_dist_from_left_edge (Float) field in DocType 'Cheque Print @@ -46502,7 +46694,7 @@ msgstr "" msgid "Status Illustration" msgstr "" -#: erpnext/projects/doctype/project/project.py:710 +#: erpnext/projects/doctype/project/project.py:711 msgid "Status must be Cancelled or Completed" msgstr "يجب إلغاء الحالة أو إكمالها" @@ -46538,8 +46730,8 @@ msgstr "المخازن" #: erpnext/accounts/doctype/account/account.json #: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:96 #: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:158 -#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:1353 -#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:1379 +#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:1355 +#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:1381 #: erpnext/accounts/report/account_balance/account_balance.js:58 msgid "Stock Adjustment" msgstr "تسوية المخزون" @@ -46641,7 +46833,7 @@ msgstr "" msgid "Stock Details" msgstr "تفاصيل المخزون" -#: erpnext/stock/doctype/stock_entry/stock_entry.py:795 +#: erpnext/stock/doctype/stock_entry/stock_entry.py:863 msgid "Stock Entries already created for Work Order {0}: {1}" msgstr "" @@ -46696,7 +46888,7 @@ msgstr "" msgid "Stock Entry Type" msgstr "نوع إدخال الأسهم" -#: erpnext/stock/doctype/pick_list/pick_list.py:1402 +#: erpnext/stock/doctype/pick_list/pick_list.py:1410 msgid "Stock Entry has been already created against this Pick List" msgstr "تم إنشاء إدخال الأسهم بالفعل مقابل قائمة الاختيار هذه" @@ -46704,11 +46896,11 @@ msgstr "تم إنشاء إدخال الأسهم بالفعل مقابل قائم msgid "Stock Entry {0} created" msgstr "الأسهم الدخول {0} خلق" -#: erpnext/manufacturing/doctype/job_card/job_card.py:1343 +#: erpnext/manufacturing/doctype/job_card/job_card.py:1370 msgid "Stock Entry {0} has created" msgstr "" -#: erpnext/accounts/doctype/journal_entry/journal_entry.py:1369 +#: erpnext/accounts/doctype/journal_entry/journal_entry.py:1284 msgid "Stock Entry {0} is not submitted" msgstr "الحركة المخزنية {0} غير مسجلة" @@ -46760,7 +46952,7 @@ msgid "Stock Ledger Entry" msgstr "حركة سجل المخزن" #: erpnext/stock/report/incorrect_stock_value_report/incorrect_stock_value_report.py:98 -#: erpnext/stock/report/stock_and_account_value_comparison/stock_and_account_value_comparison.py:107 +#: erpnext/stock/report/stock_and_account_value_comparison/stock_and_account_value_comparison.py:110 msgid "Stock Ledger ID" msgstr "معرف دفتر الأستاذ" @@ -46774,13 +46966,19 @@ msgstr "" msgid "Stock Ledger Variance" msgstr "" +#. Description of the 'Repost Only Accounting Ledgers' (Check) field in DocType +#. 'Repost Item Valuation' +#: erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.json +msgid "Stock Ledgers won’t be reposted." +msgstr "" + #: erpnext/stock/doctype/batch/batch.js:79 -#: erpnext/stock/doctype/item/item.js:542 +#: erpnext/stock/doctype/item/item.js:561 msgid "Stock Levels" msgstr "مستوى المخزون" #: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:160 -#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:272 +#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:273 msgid "Stock Liabilities" msgstr "خصوم المخزون" @@ -46853,8 +47051,8 @@ msgstr "كمية المخزون المتوقعة" #. Label of the stock_qty (Float) field in DocType 'BOM Item' #. Label of the stock_qty (Float) field in DocType 'Delivery Schedule Item' #. Label of the stock_qty (Float) field in DocType 'Material Request Item' -#: erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py:259 -#: erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py:314 +#: erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py:251 +#: erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py:303 #: erpnext/manufacturing/doctype/bom_creator_item/bom_creator_item.json #: erpnext/manufacturing/doctype/bom_explosion_item/bom_explosion_item.json #: erpnext/manufacturing/doctype/bom_item/bom_item.json @@ -46873,7 +47071,7 @@ msgstr "كمية المخزون مقابل الرقم التسلسلي" #. Label of the stock_received_but_not_billed (Link) field in DocType 'Company' #: erpnext/accounts/doctype/account/account.json #: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:161 -#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:273 +#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:274 #: erpnext/accounts/report/account_balance/account_balance.js:59 #: erpnext/setup/doctype/company/company.json msgid "Stock Received But Not Billed" @@ -46884,7 +47082,7 @@ msgstr "المخزون المتلقي ولكن غير مفوتر" #. Option for the 'Purpose' (Select) field in DocType 'Stock Reconciliation' #. Label of a Link in the Stock Workspace #: erpnext/setup/workspace/home/home.json -#: erpnext/stock/doctype/item/item.py:614 +#: erpnext/stock/doctype/item/item.py:617 #: erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.json #: erpnext/stock/workspace/stock/stock.json msgid "Stock Reconciliation" @@ -46895,7 +47093,7 @@ msgstr "جرد المخزون" msgid "Stock Reconciliation Item" msgstr "جرد عناصر المخزون" -#: erpnext/stock/doctype/item/item.py:614 +#: erpnext/stock/doctype/item/item.py:617 msgid "Stock Reconciliations" msgstr "تسويات المخزون" @@ -46917,9 +47115,9 @@ msgstr "" #: erpnext/manufacturing/doctype/production_plan/production_plan.js:289 #: erpnext/manufacturing/doctype/production_plan/production_plan.js:297 #: erpnext/manufacturing/doctype/production_plan/production_plan.js:303 -#: erpnext/manufacturing/doctype/work_order/work_order.js:886 -#: erpnext/manufacturing/doctype/work_order/work_order.js:895 -#: erpnext/manufacturing/doctype/work_order/work_order.js:902 +#: erpnext/manufacturing/doctype/work_order/work_order.js:896 +#: erpnext/manufacturing/doctype/work_order/work_order.js:905 +#: erpnext/manufacturing/doctype/work_order/work_order.js:912 #: erpnext/manufacturing/doctype/work_order/work_order_dashboard.py:14 #: erpnext/public/js/stock_reservation.js:12 #: erpnext/selling/doctype/sales_order/sales_order.js:94 @@ -46932,13 +47130,13 @@ msgstr "" #: erpnext/stock/doctype/stock_entry/stock_entry_dashboard.py:12 #: erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py:719 #: erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py:674 -#: erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py:1233 -#: erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py:1640 -#: erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py:1653 -#: erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py:1667 -#: erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py:1681 -#: erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py:1695 -#: erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py:1712 +#: erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py:1236 +#: erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py:1643 +#: erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py:1656 +#: erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py:1670 +#: erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py:1684 +#: erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py:1698 +#: erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py:1715 #: erpnext/stock/doctype/stock_settings/stock_settings.json #: erpnext/stock/doctype/stock_settings/stock_settings.py:178 #: erpnext/stock/doctype/stock_settings/stock_settings.py:190 @@ -46951,14 +47149,14 @@ msgstr "" msgid "Stock Reservation" msgstr "" -#: erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py:1821 +#: erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py:1824 msgid "Stock Reservation Entries Cancelled" msgstr "" #: erpnext/controllers/subcontracting_inward_controller.py:995 -#: erpnext/manufacturing/doctype/production_plan/production_plan.py:2196 -#: erpnext/manufacturing/doctype/work_order/work_order.py:2028 -#: erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py:1773 +#: erpnext/manufacturing/doctype/production_plan/production_plan.py:2203 +#: erpnext/manufacturing/doctype/work_order/work_order.py:2064 +#: erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py:1776 msgid "Stock Reservation Entries Created" msgstr "" @@ -46985,7 +47183,7 @@ msgstr "" msgid "Stock Reservation Entry created against a Pick List cannot be updated. If you need to make changes, we recommend canceling the existing entry and creating a new one." msgstr "" -#: erpnext/stock/doctype/delivery_note/delivery_note.py:551 +#: erpnext/stock/doctype/delivery_note/delivery_note.py:555 msgid "Stock Reservation Warehouse Mismatch" msgstr "" @@ -47018,7 +47216,6 @@ msgstr "" #. Label of the auto_accounting_for_stock_settings (Section Break) field in #. DocType 'Company' -#. Label of a Link in the Settings Workspace #. Label of a shortcut in the Settings Workspace #. Name of a DocType #. Label of a Link in the Stock Workspace @@ -47098,8 +47295,8 @@ msgstr "" #: erpnext/accounts/doctype/pos_invoice_item/pos_invoice_item.json #: erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json #: erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json -#: erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py:261 -#: erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py:316 +#: erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py:253 +#: erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py:305 #: erpnext/assets/doctype/asset_capitalization_stock_item/asset_capitalization_stock_item.json #: erpnext/buying/doctype/purchase_order_item/purchase_order_item.json #: erpnext/buying/doctype/request_for_quotation_item/request_for_quotation_item.json @@ -47229,7 +47426,7 @@ msgstr "" #: erpnext/stock/doctype/bin/bin.json #: erpnext/stock/doctype/quick_stock_balance/quick_stock_balance.json #: erpnext/stock/report/incorrect_stock_value_report/incorrect_stock_value_report.py:134 -#: erpnext/stock/report/stock_and_account_value_comparison/stock_and_account_value_comparison.py:123 +#: erpnext/stock/report/stock_and_account_value_comparison/stock_and_account_value_comparison.py:126 msgid "Stock Value" msgstr "قيمة المخزون" @@ -47247,23 +47444,23 @@ msgstr "" msgid "Stock cannot be reserved in group warehouse {0}." msgstr "" -#: erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py:1585 +#: erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py:1588 msgid "Stock cannot be reserved in the group warehouse {0}." msgstr "" -#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:732 +#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:734 msgid "Stock cannot be updated against Purchase Receipt {0}" msgstr "لا يمكن تحديث المخزون مقابل إيصال الشراء {0}\\n
        \\nStock cannot be updated against Purchase Receipt {0}" -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1253 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1202 msgid "Stock cannot be updated against the following Delivery Notes: {0}" msgstr "" -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1322 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1271 msgid "Stock cannot be updated because the invoice contains a drop shipping item. Please disable 'Update Stock' or remove the drop shipping item." msgstr "" -#: erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py:1127 +#: erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py:1130 msgid "Stock has been unreserved for work order {0}." msgstr "" @@ -47271,11 +47468,11 @@ msgstr "" msgid "Stock not available for Item {0} in Warehouse {1}." msgstr "" -#: erpnext/selling/page/point_of_sale/pos_controller.js:855 +#: erpnext/selling/page/point_of_sale/pos_controller.js:859 msgid "Stock quantity not enough for Item Code: {0} under warehouse {1}. Available quantity {2} {3}." msgstr "" -#: erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py:252 +#: erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py:256 msgid "Stock transactions before {0} are frozen" msgstr "يتم تجميد المعاملات المخزنية قبل {0}" @@ -47291,7 +47488,7 @@ msgstr "" msgid "Stock will be reserved on submission of Purchase Receipt created against Material Request for Sales Order." msgstr "" -#: erpnext/stock/utils.py:570 +#: erpnext/stock/utils.py:576 msgid "Stock/Accounts can not be frozen as processing of backdated entries is going on. Please try again later." msgstr "" @@ -47306,14 +47503,14 @@ msgstr "" msgid "Stop Reason" msgstr "توقف السبب" -#: erpnext/manufacturing/doctype/work_order/work_order.py:1056 +#: erpnext/manufacturing/doctype/work_order/work_order.py:1060 msgid "Stopped Work Order cannot be cancelled, Unstop it first to cancel" msgstr "لا يمكن إلغاء طلب العمل المتوقف ، قم بإلغاء إيقافه أولاً للإلغاء" -#: erpnext/setup/doctype/company/company.py:339 +#: erpnext/setup/doctype/company/company.py:375 #: erpnext/setup/setup_wizard/operations/defaults_setup.py:33 #: erpnext/setup/setup_wizard/operations/install_fixtures.py:528 -#: erpnext/stock/doctype/item/item.py:283 +#: erpnext/stock/doctype/item/item.py:285 msgid "Stores" msgstr "مخازن" @@ -47337,7 +47534,7 @@ msgstr "المجمعات الفرعية" msgid "Sub Assemblies & Raw Materials" msgstr "" -#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:298 +#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:321 msgid "Sub Assembly Item" msgstr "" @@ -47353,7 +47550,7 @@ msgstr "" msgid "Sub Assembly Item Reference" msgstr "" -#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:403 +#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:430 msgid "Sub Assembly Item is mandatory" msgstr "" @@ -47371,7 +47568,7 @@ msgstr "" #. Label of the operation (Link) field in DocType 'Job Card Time Log' #. Name of a DocType -#: erpnext/manufacturing/doctype/job_card/job_card.js:336 +#: erpnext/manufacturing/doctype/job_card/job_card.js:348 #: erpnext/manufacturing/doctype/job_card_time_log/job_card_time_log.json #: erpnext/manufacturing/doctype/sub_operation/sub_operation.json msgid "Sub Operation" @@ -47430,8 +47627,10 @@ msgstr "" #. Name of a report #. Label of a Link in the Manufacturing Workspace +#. Label of a Link in the Subcontracting Workspace #: erpnext/buying/report/subcontract_order_summary/subcontract_order_summary.json #: erpnext/manufacturing/workspace/manufacturing/manufacturing.json +#: erpnext/subcontracting/workspace/subcontracting/subcontracting.json msgid "Subcontract Order Summary" msgstr "" @@ -47449,14 +47648,16 @@ msgstr "البند من الباطن" #. Label of a Link in the Buying Workspace #. Label of a Link in the Manufacturing Workspace #. Label of a Link in the Stock Workspace +#. Label of a Link in the Subcontracting Workspace #: erpnext/buying/report/subcontracted_item_to_be_received/subcontracted_item_to_be_received.json #: erpnext/buying/workspace/buying/buying.json #: erpnext/manufacturing/workspace/manufacturing/manufacturing.json #: erpnext/stock/workspace/stock/stock.json +#: erpnext/subcontracting/workspace/subcontracting/subcontracting.json msgid "Subcontracted Item To Be Received" msgstr "البند المتعاقد عليه من الباطن" -#: erpnext/stock/doctype/material_request/material_request.js:209 +#: erpnext/stock/doctype/material_request/material_request.js:210 msgid "Subcontracted Purchase Order" msgstr "" @@ -47472,10 +47673,12 @@ msgstr "" #. Label of a Link in the Buying Workspace #. Label of a Link in the Manufacturing Workspace #. Label of a Link in the Stock Workspace +#. Label of a Link in the Subcontracting Workspace #: erpnext/buying/report/subcontracted_raw_materials_to_be_transferred/subcontracted_raw_materials_to_be_transferred.json #: erpnext/buying/workspace/buying/buying.json #: erpnext/manufacturing/workspace/manufacturing/manufacturing.json #: erpnext/stock/workspace/stock/stock.json +#: erpnext/subcontracting/workspace/subcontracting/subcontracting.json msgid "Subcontracted Raw Materials To Be Transferred" msgstr "المواد الخام المتعاقد عليها من الباطن" @@ -47484,18 +47687,22 @@ msgstr "المواد الخام المتعاقد عليها من الباطن" #. 'Production Plan Sub Assembly Item' #. Label of a Card Break in the Manufacturing Workspace #. Option for the 'Purpose' (Select) field in DocType 'Material Request' +#. Name of a Workspace #: erpnext/manufacturing/doctype/job_card/job_card_dashboard.py:10 #: erpnext/manufacturing/doctype/material_request_plan_item/material_request_plan_item.json #: erpnext/manufacturing/doctype/production_plan_sub_assembly_item/production_plan_sub_assembly_item.json #: erpnext/manufacturing/workspace/manufacturing/manufacturing.json #: erpnext/stock/doctype/material_request/material_request.json +#: erpnext/subcontracting/workspace/subcontracting/subcontracting.json msgid "Subcontracting" msgstr "" #. Label of a Link in the Manufacturing Workspace #. Name of a DocType +#. Label of a shortcut in the Subcontracting Workspace #: erpnext/manufacturing/workspace/manufacturing/manufacturing.json #: erpnext/subcontracting/doctype/subcontracting_bom/subcontracting_bom.json +#: erpnext/subcontracting/workspace/subcontracting/subcontracting.json msgid "Subcontracting BOM" msgstr "" @@ -47510,10 +47717,12 @@ msgstr "" #. Option for the 'Purpose' (Select) field in DocType 'Stock Entry' #. Option for the 'Purpose' (Select) field in DocType 'Stock Entry Type' +#. Label of a shortcut in the Subcontracting Workspace #: erpnext/setup/setup_wizard/operations/install_fixtures.py:132 #: erpnext/stock/doctype/stock_entry/stock_entry.json #: erpnext/stock/doctype/stock_entry_type/stock_entry_type.json #: erpnext/subcontracting/doctype/subcontracting_inward_order/subcontracting_inward_order.js:158 +#: erpnext/subcontracting/workspace/subcontracting/subcontracting.json msgid "Subcontracting Delivery" msgstr "" @@ -47533,11 +47742,13 @@ msgstr "" #. Option for the 'From Voucher Type' (Select) field in DocType 'Stock #. Reservation Entry' #. Name of a DocType +#. Label of a shortcut in the Subcontracting Workspace #: erpnext/manufacturing/doctype/work_order/work_order.json -#: erpnext/selling/doctype/sales_order/sales_order.js:1001 +#: erpnext/selling/doctype/sales_order/sales_order.js:1005 #: erpnext/stock/doctype/stock_entry/stock_entry.json #: erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.json #: erpnext/subcontracting/doctype/subcontracting_inward_order/subcontracting_inward_order.json +#: erpnext/subcontracting/workspace/subcontracting/subcontracting.json msgid "Subcontracting Inward Order" msgstr "" @@ -47579,8 +47790,9 @@ msgstr "" #. Receipt Item' #. Label of the subcontracting_order (Link) field in DocType 'Subcontracting #. Receipt Supplied Item' -#: erpnext/buying/doctype/purchase_order/purchase_order.js:440 -#: erpnext/controllers/subcontracting_controller.py:1102 +#. Label of a shortcut in the Subcontracting Workspace +#: erpnext/buying/doctype/purchase_order/purchase_order.js:441 +#: erpnext/controllers/subcontracting_controller.py:1133 #: erpnext/manufacturing/workspace/manufacturing/manufacturing.json #: erpnext/stock/doctype/stock_entry/stock_entry.json #: erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.json @@ -47588,6 +47800,7 @@ msgstr "" #: erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.js:140 #: erpnext/subcontracting/doctype/subcontracting_receipt_item/subcontracting_receipt_item.json #: erpnext/subcontracting/doctype/subcontracting_receipt_supplied_item/subcontracting_receipt_supplied_item.json +#: erpnext/subcontracting/workspace/subcontracting/subcontracting.json msgid "Subcontracting Order" msgstr "" @@ -47616,7 +47829,7 @@ msgstr "" msgid "Subcontracting Order Supplied Item" msgstr "" -#: erpnext/buying/doctype/purchase_order/purchase_order.py:968 +#: erpnext/buying/doctype/purchase_order/purchase_order.py:967 msgid "Subcontracting Order {0} created." msgstr "" @@ -47635,6 +47848,7 @@ msgstr "" #. Option for the 'Reference Type' (Select) field in DocType 'Quality #. Inspection' #. Name of a DocType +#. Label of a shortcut in the Subcontracting Workspace #: erpnext/manufacturing/workspace/manufacturing/manufacturing.json #: erpnext/stock/doctype/landed_cost_item/landed_cost_item.json #: erpnext/stock/doctype/landed_cost_purchase_receipt/landed_cost_purchase_receipt.json @@ -47642,6 +47856,7 @@ msgstr "" #: erpnext/stock/doctype/quality_inspection/quality_inspection.json #: erpnext/subcontracting/doctype/subcontracting_order/subcontracting_order.js:530 #: erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.json +#: erpnext/subcontracting/workspace/subcontracting/subcontracting.json msgid "Subcontracting Receipt" msgstr "" @@ -47684,8 +47899,8 @@ msgstr "" msgid "Subdivision" msgstr "" -#: erpnext/buying/doctype/purchase_order/purchase_order.py:964 -#: erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py:987 +#: erpnext/buying/doctype/purchase_order/purchase_order.py:963 +#: erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py:1042 msgid "Submit Action Failed" msgstr "" @@ -47732,7 +47947,7 @@ msgstr "" #: erpnext/buying/doctype/supplier_quotation/supplier_quotation_dashboard.py:16 #: erpnext/selling/doctype/quotation/quotation_dashboard.py:12 #: erpnext/stock/doctype/delivery_note/delivery_note_dashboard.py:25 -#: erpnext/stock/doctype/purchase_receipt/purchase_receipt_dashboard.py:31 +#: erpnext/stock/doctype/purchase_receipt/purchase_receipt_dashboard.py:34 msgid "Subscription" msgstr "اشتراك" @@ -47861,7 +48076,7 @@ msgstr "تمت التسوية بنجاح\\n
        \\nSuccessfully Reconciled" msgid "Successfully Set Supplier" msgstr "بنجاح تعيين المورد" -#: erpnext/stock/doctype/item/item.py:338 +#: erpnext/stock/doctype/item/item.py:339 msgid "Successfully changed Stock UOM, please redefine conversion factors for new UOM." msgstr "" @@ -47881,11 +48096,11 @@ msgstr "" msgid "Successfully imported {0} records." msgstr "" -#: erpnext/buying/doctype/supplier/supplier.js:202 +#: erpnext/buying/doctype/supplier/supplier.js:212 msgid "Successfully linked to Customer" msgstr "" -#: erpnext/selling/doctype/customer/customer.js:252 +#: erpnext/selling/doctype/customer/customer.js:271 msgid "Successfully linked to Supplier" msgstr "" @@ -48001,7 +48216,7 @@ msgstr "الموردة الكمية" #: erpnext/accounts/doctype/tax_rule/tax_rule.json #: erpnext/accounts/report/billed_items_to_be_received/billed_items_to_be_received.py:60 #: erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.js:34 -#: erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py:191 +#: erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py:183 #: erpnext/accounts/report/purchase_register/purchase_register.js:21 #: erpnext/accounts/report/purchase_register/purchase_register.py:171 #: erpnext/accounts/report/received_items_to_be_billed/received_items_to_be_billed.py:29 @@ -48035,10 +48250,10 @@ msgstr "الموردة الكمية" #: erpnext/public/js/purchase_trends_filters.js:63 #: erpnext/regional/doctype/lower_deduction_certificate/lower_deduction_certificate.json #: erpnext/regional/report/irs_1099/irs_1099.py:77 -#: erpnext/selling/doctype/customer/customer.js:234 +#: erpnext/selling/doctype/customer/customer.js:253 #: erpnext/selling/doctype/party_specific_item/party_specific_item.json #: erpnext/selling/doctype/sales_order/sales_order.js:182 -#: erpnext/selling/doctype/sales_order/sales_order.js:1630 +#: erpnext/selling/doctype/sales_order/sales_order.js:1652 #: erpnext/selling/doctype/sales_order_item/sales_order_item.json #: erpnext/selling/doctype/sms_center/sms_center.json #: erpnext/setup/workspace/home/home.json @@ -48131,7 +48346,7 @@ msgstr "تفاصيل المورد" #: erpnext/accounts/report/accounts_payable_summary/accounts_payable_summary.js:91 #: erpnext/accounts/report/accounts_receivable/accounts_receivable.py:1257 #: erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.py:198 -#: erpnext/accounts/report/customer_ledger_summary/customer_ledger_summary.py:238 +#: erpnext/accounts/report/customer_ledger_summary/customer_ledger_summary.py:180 #: erpnext/accounts/report/purchase_register/purchase_register.js:27 #: erpnext/accounts/report/purchase_register/purchase_register.py:186 #: erpnext/accounts/report/supplier_ledger_summary/supplier_ledger_summary.js:55 @@ -48168,13 +48383,16 @@ msgstr "" msgid "Supplier Invoice" msgstr "" +#. Label of the supplier_invoice_date (Date) field in DocType 'Opening Invoice +#. Creation Tool Item' #. Label of the bill_date (Date) field in DocType 'Purchase Invoice' +#: erpnext/accounts/doctype/opening_invoice_creation_tool_item/opening_invoice_creation_tool_item.json #: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json -#: erpnext/accounts/report/tax_withholding_details/tax_withholding_details.py:224 +#: erpnext/accounts/report/tax_withholding_details/tax_withholding_details.py:238 msgid "Supplier Invoice Date" msgstr "المورد فاتورة التسجيل" -#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:1746 +#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:1748 msgid "Supplier Invoice Date cannot be greater than Posting Date" msgstr "تاريخ فاتورة المورد لا يمكن أن تكون أكبر من تاريخ الإنشاء
        Supplier Invoice Date cannot be greater than Posting Date" @@ -48184,12 +48402,12 @@ msgstr "تاريخ فاتورة المورد لا يمكن أن تكون أكب #: erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.html:58 #: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json #: erpnext/accounts/report/general_ledger/general_ledger.html:110 -#: erpnext/accounts/report/general_ledger/general_ledger.py:780 -#: erpnext/accounts/report/tax_withholding_details/tax_withholding_details.py:218 +#: erpnext/accounts/report/general_ledger/general_ledger.py:787 +#: erpnext/accounts/report/tax_withholding_details/tax_withholding_details.py:232 msgid "Supplier Invoice No" msgstr "رقم فاتورة المورد" -#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:1773 +#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:1775 msgid "Supplier Invoice No exists in Purchase Invoice {0}" msgstr "المورد فاتورة لا يوجد في شراء الفاتورة {0}" @@ -48231,7 +48449,7 @@ msgstr "ملخص دفتر الأستاذ" #: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json #: erpnext/accounts/report/accounts_receivable/accounts_receivable.py:1174 #: erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.py:156 -#: erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py:198 +#: erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py:190 #: erpnext/accounts/report/purchase_register/purchase_register.py:177 #: erpnext/accounts/report/received_items_to_be_billed/received_items_to_be_billed.py:35 #: erpnext/accounts/report/supplier_ledger_summary/supplier_ledger_summary.js:73 @@ -48309,18 +48527,18 @@ msgstr "" #. Name of a DocType #. Label of a Link in the Buying Workspace #. Label of the supplier_quotation (Link) field in DocType 'Quotation' -#: erpnext/buying/doctype/purchase_order/purchase_order.js:606 +#: erpnext/buying/doctype/purchase_order/purchase_order.js:607 #: erpnext/buying/doctype/purchase_order/purchase_order.json #: erpnext/buying/doctype/purchase_order_item/purchase_order_item.json #: erpnext/buying/doctype/request_for_quotation/request_for_quotation.js:49 #: erpnext/buying/doctype/supplier_quotation/supplier_quotation.json -#: erpnext/buying/doctype/supplier_quotation/supplier_quotation.py:232 +#: erpnext/buying/doctype/supplier_quotation/supplier_quotation.py:234 #: erpnext/buying/report/supplier_quotation_comparison/supplier_quotation_comparison.js:60 #: erpnext/buying/report/supplier_quotation_comparison/supplier_quotation_comparison.py:258 #: erpnext/buying/workspace/buying/buying.json #: erpnext/crm/doctype/opportunity/opportunity.js:81 #: erpnext/selling/doctype/quotation/quotation.json -#: erpnext/stock/doctype/material_request/material_request.js:193 +#: erpnext/stock/doctype/material_request/material_request.js:194 msgid "Supplier Quotation" msgstr "التسعيرة من المورد" @@ -48348,6 +48566,10 @@ msgstr "تم إنشاء عرض أسعار المورد {0}" msgid "Supplier Reference" msgstr "" +#: erpnext/selling/doctype/sales_order/sales_order.js:1676 +msgid "Supplier Required" +msgstr "" + #. Label of the supplier_score (Data) field in DocType 'Supplier Scorecard' #: erpnext/buying/doctype/supplier_scorecard/supplier_scorecard.json msgid "Supplier Score" @@ -48417,7 +48639,7 @@ msgstr "المورد نوع" #. Label of the supplier_warehouse (Link) field in DocType 'Purchase Receipt' #: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json #: erpnext/buying/doctype/purchase_order/purchase_order.json -#: erpnext/manufacturing/doctype/job_card/job_card.js:80 +#: erpnext/manufacturing/doctype/job_card/job_card.js:89 #: erpnext/stock/doctype/purchase_receipt/purchase_receipt.json msgid "Supplier Warehouse" msgstr "المورد مستودع" @@ -48430,6 +48652,10 @@ msgstr "المورد مستودع" msgid "Supplier delivers to Customer" msgstr "المورد يسلم للعميل" +#: erpnext/selling/doctype/sales_order/sales_order.js:1675 +msgid "Supplier is required for all selected Items" +msgstr "" + #. Description of the 'Supplier Numbers' (Table) field in DocType 'Customer' #: erpnext/selling/doctype/customer/customer.json msgid "Supplier numbers assigned by the customer" @@ -48440,7 +48666,7 @@ msgstr "" msgid "Supplier of Goods or Services." msgstr "" -#: erpnext/buying/doctype/supplier_quotation/supplier_quotation.py:185 +#: erpnext/buying/doctype/supplier_quotation/supplier_quotation.py:187 msgid "Supplier {0} not found in {1}" msgstr "المورد {0} غير موجود في {1}" @@ -48493,10 +48719,8 @@ msgstr "بوابة الدعم" msgid "Support Search Source" msgstr "دعم مصدر البحث" -#. Label of a Link in the Settings Workspace #. Name of a DocType #. Label of a Link in the Support Workspace -#: erpnext/setup/workspace/settings/settings.json #: erpnext/support/doctype/support_settings/support_settings.json #: erpnext/support/workspace/support/support.json msgid "Support Settings" @@ -48540,7 +48764,7 @@ msgstr "" msgid "Synchronize all accounts every hour" msgstr "مزامنة جميع الحسابات كل ساعة" -#: erpnext/accounts/doctype/account/account.py:659 +#: erpnext/accounts/doctype/account/account.py:661 msgid "System In Use" msgstr "" @@ -48570,7 +48794,7 @@ msgstr "" msgid "System will fetch all the entries if limit value is zero." msgstr "سيقوم النظام بجلب كل الإدخالات إذا كانت قيمة الحد صفرا." -#: erpnext/controllers/accounts_controller.py:2147 +#: erpnext/controllers/accounts_controller.py:2220 msgid "System will not check over billing since amount for Item {0} in {1} is zero" msgstr "" @@ -48580,16 +48804,16 @@ msgstr "" msgid "System will notify to increase or decrease quantity or amount " msgstr "سيُعلم النظام بزيادة أو تقليل الكمية أو الكمية" -#: erpnext/accounts/report/tax_withholding_details/tax_withholding_details.py:253 +#: erpnext/accounts/report/tax_withholding_details/tax_withholding_details.py:267 msgid "TCS Amount" msgstr "" -#: erpnext/accounts/report/tax_withholding_details/tax_withholding_details.py:235 +#: erpnext/accounts/report/tax_withholding_details/tax_withholding_details.py:249 #: erpnext/accounts/report/tds_computation_summary/tds_computation_summary.py:125 msgid "TCS Rate %" msgstr "" -#: erpnext/accounts/report/tax_withholding_details/tax_withholding_details.py:253 +#: erpnext/accounts/report/tax_withholding_details/tax_withholding_details.py:267 msgid "TDS Amount" msgstr "" @@ -48598,15 +48822,15 @@ msgstr "" msgid "TDS Computation Summary" msgstr "ملخص حساب TDS" -#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:1530 +#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:1532 msgid "TDS Deducted" msgstr "" -#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:286 +#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:287 msgid "TDS Payable" msgstr "" -#: erpnext/accounts/report/tax_withholding_details/tax_withholding_details.py:235 +#: erpnext/accounts/report/tax_withholding_details/tax_withholding_details.py:249 #: erpnext/accounts/report/tds_computation_summary/tds_computation_summary.py:125 msgid "TDS Rate %" msgstr "" @@ -48773,12 +48997,11 @@ msgstr "" #: erpnext/buying/doctype/purchase_order_item/purchase_order_item.json #: erpnext/manufacturing/doctype/job_card/job_card.json #: erpnext/manufacturing/doctype/production_plan_sub_assembly_item/production_plan_sub_assembly_item.json -#: erpnext/manufacturing/doctype/work_order/work_order.js:998 #: erpnext/manufacturing/doctype/work_order/work_order.json #: erpnext/stock/dashboard/item_dashboard.js:234 #: erpnext/stock/doctype/delivery_note_item/delivery_note_item.json #: erpnext/stock/doctype/material_request_item/material_request_item.json -#: erpnext/stock/doctype/stock_entry/stock_entry.js:674 +#: erpnext/stock/doctype/stock_entry/stock_entry.js:687 #: erpnext/stock/doctype/stock_entry_detail/stock_entry_detail.json msgid "Target Warehouse" msgstr "المخزن المستهدف" @@ -48794,7 +49017,7 @@ msgstr "عنوان المستودع المستهدف" msgid "Target Warehouse Address Link" msgstr "" -#: erpnext/manufacturing/doctype/work_order/work_order.py:236 +#: erpnext/manufacturing/doctype/work_order/work_order.py:237 msgid "Target Warehouse Reservation Error" msgstr "" @@ -48802,20 +49025,20 @@ msgstr "" msgid "Target Warehouse for Finished Good must be same as Finished Good Warehouse {1} in Work Order {2} linked to the Subcontracting Inward Order." msgstr "" -#: erpnext/manufacturing/doctype/work_order/work_order.py:741 +#: erpnext/manufacturing/doctype/work_order/work_order.py:742 msgid "Target Warehouse is required before Submit" msgstr "" -#: erpnext/controllers/selling_controller.py:840 +#: erpnext/controllers/selling_controller.py:865 msgid "Target Warehouse is set for some items but the customer is not an internal customer." msgstr "" -#: erpnext/manufacturing/doctype/work_order/work_order.py:297 +#: erpnext/manufacturing/doctype/work_order/work_order.py:298 msgid "Target Warehouse {0} must be same as Delivery Warehouse {1} in the Subcontracting Inward Order Item." msgstr "" -#: erpnext/stock/doctype/stock_entry/stock_entry.py:684 -#: erpnext/stock/doctype/stock_entry/stock_entry.py:691 +#: erpnext/stock/doctype/stock_entry/stock_entry.py:752 +#: erpnext/stock/doctype/stock_entry/stock_entry.py:759 msgid "Target warehouse is mandatory for row {0}" msgstr "المستودع المستهدف إلزامي للصف {0}\\n
        \\nTarget warehouse is mandatory for row {0}" @@ -48905,6 +49128,8 @@ msgstr "ضريبة" msgid "Tax Account" msgstr "حساب الضرائب" +#. Label of the amount (Currency) field in DocType 'Item Wise Tax Detail' +#: erpnext/accounts/doctype/item_wise_tax_detail/item_wise_tax_detail.json #: erpnext/accounts/report/tds_computation_summary/tds_computation_summary.py:137 msgid "Tax Amount" msgstr "" @@ -49008,7 +49233,7 @@ msgstr "تفكيك الضرائب" msgid "Tax Category" msgstr "الفئة الضريبية" -#: erpnext/controllers/buying_controller.py:245 +#: erpnext/controllers/buying_controller.py:258 msgid "Tax Category has been changed to \"Total\" because all the Items are non-stock items" msgstr "تم تغيير فئة الضرائب إلى "توتال" لأن جميع العناصر هي عناصر غير مخزون" @@ -49061,12 +49286,14 @@ msgstr "" #. Label of the tax_rate (Float) field in DocType 'Account' #. Label of the rate (Float) field in DocType 'Advance Taxes and Charges' #. Label of the tax_rate (Float) field in DocType 'Item Tax Template Detail' +#. Label of the rate (Float) field in DocType 'Item Wise Tax Detail' #. Label of the rate (Float) field in DocType 'Purchase Taxes and Charges' #. Label of the rate (Float) field in DocType 'Sales Taxes and Charges' #: erpnext/accounts/doctype/account/account.json -#: erpnext/accounts/doctype/account/account_tree.js:166 +#: erpnext/accounts/doctype/account/account_tree.js:174 #: erpnext/accounts/doctype/advance_taxes_and_charges/advance_taxes_and_charges.json #: erpnext/accounts/doctype/item_tax_template_detail/item_tax_template_detail.json +#: erpnext/accounts/doctype/item_wise_tax_detail/item_wise_tax_detail.json #: erpnext/accounts/doctype/pos_closing_entry/closing_voucher_details.html:66 #: erpnext/accounts/doctype/purchase_taxes_and_charges/purchase_taxes_and_charges.json #: erpnext/accounts/doctype/sales_taxes_and_charges/sales_taxes_and_charges.json @@ -49082,6 +49309,11 @@ msgstr "معدلات الضريبة" msgid "Tax Refunds provided to Tourists under the Tax Refunds for Tourists Scheme" msgstr "" +#. Label of the tax_row (Data) field in DocType 'Item Wise Tax Detail' +#: erpnext/accounts/doctype/item_wise_tax_detail/item_wise_tax_detail.json +msgid "Tax Row" +msgstr "" + #. Name of a DocType #. Label of a Link in the Accounting Workspace #: erpnext/accounts/doctype/tax_rule/tax_rule.json @@ -49122,7 +49354,7 @@ msgstr "نوع الضريبة" msgid "Tax Withheld Vouchers" msgstr "" -#: erpnext/accounts/report/tax_withholding_details/tax_withholding_details.py:347 +#: erpnext/accounts/report/tax_withholding_details/tax_withholding_details.py:361 msgid "Tax Withholding" msgstr "" @@ -49157,7 +49389,7 @@ msgstr "حساب حجب الضرائب" msgid "Tax Withholding Category" msgstr "فئة حجب الضرائب" -#: erpnext/accounts/doctype/tax_withholding_category/tax_withholding_category.py:149 +#: erpnext/accounts/doctype/tax_withholding_category/tax_withholding_category.py:152 msgid "Tax Withholding Category {} against Company {} for Customer {} should have Cumulative Threshold value." msgstr "" @@ -49213,10 +49445,13 @@ msgstr "" msgid "Tax will be withheld only for amount exceeding the cumulative threshold" msgstr "" +#. Label of the taxable_amount (Currency) field in DocType 'Item Wise Tax +#. Detail' #. Label of the taxable_amount (Currency) field in DocType 'Tax Withheld #. Vouchers' +#: erpnext/accounts/doctype/item_wise_tax_detail/item_wise_tax_detail.json #: erpnext/accounts/doctype/tax_withheld_vouchers/tax_withheld_vouchers.json -#: erpnext/controllers/taxes_and_totals.py:1148 +#: erpnext/controllers/taxes_and_totals.py:1221 msgid "Taxable Amount" msgstr "المبلغ الخاضع للضريبة" @@ -49356,7 +49591,7 @@ msgstr "خصم الضرائب والرسوم" msgid "Taxes and Charges Deducted (Company Currency)" msgstr "الضرائب والرسوم مقطوعة (عملة الشركة)" -#: erpnext/stock/doctype/item/item.py:351 +#: erpnext/stock/doctype/item/item.py:352 msgid "Taxes row #{0}: {1} cannot be smaller than {2}" msgstr "" @@ -49403,7 +49638,7 @@ msgstr "" msgid "Television" msgstr "" -#: erpnext/manufacturing/doctype/bom/bom.js:376 +#: erpnext/manufacturing/doctype/bom/bom.js:383 msgid "Template Item" msgstr "عنصر القالب" @@ -49629,11 +49864,11 @@ msgstr "قالب الشروط والأحكام" #: erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.js:97 #: erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.py:182 #: erpnext/accounts/report/customer_ledger_summary/customer_ledger_summary.js:68 -#: erpnext/accounts/report/customer_ledger_summary/customer_ledger_summary.py:221 +#: erpnext/accounts/report/customer_ledger_summary/customer_ledger_summary.py:171 #: erpnext/accounts/report/gross_profit/gross_profit.py:425 #: erpnext/accounts/report/inactive_sales_items/inactive_sales_items.js:8 #: erpnext/accounts/report/inactive_sales_items/inactive_sales_items.py:21 -#: erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py:262 +#: erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py:251 #: erpnext/accounts/report/sales_register/sales_register.py:209 #: erpnext/crm/doctype/lead/lead.json #: erpnext/crm/doctype/opportunity/opportunity.json @@ -49735,7 +49970,7 @@ msgstr "تم تعطيل الوصول إلى طلب عرض الأسعار من ا msgid "The BOM which will be replaced" msgstr "وBOM التي سيتم استبدالها" -#: erpnext/stock/serial_batch_bundle.py:1495 +#: erpnext/stock/serial_batch_bundle.py:1506 msgid "The Batch {0} has negative batch quantity {1}. To fix this, go to the batch and click on Recalculate Batch Qty. If the issue still persists, create an inward entry." msgstr "" @@ -49743,6 +49978,10 @@ msgstr "" msgid "The Campaign '{0}' already exists for the {1} '{2}'" msgstr "الحملة '{0}' موجودة بالفعل لـ {1} '{2}'" +#: erpnext/manufacturing/doctype/master_production_schedule/master_production_schedule.py:74 +msgid "The Company {0} of Sales Forecast {1} does not match with the Company {2} of Master Production Schedule {3}." +msgstr "" + #: erpnext/support/doctype/service_level_agreement/service_level_agreement.py:206 msgid "The Document Type {0} must have a Status field to configure Service Level Agreement" msgstr "" @@ -49759,7 +49998,7 @@ msgstr "" msgid "The Loyalty Program isn't valid for the selected company" msgstr "برنامج الولاء غير صالح للشركة المختارة" -#: erpnext/accounts/doctype/payment_request/payment_request.py:964 +#: erpnext/accounts/doctype/payment_request/payment_request.py:968 msgid "The Payment Request {0} is already paid, cannot process payment twice" msgstr "" @@ -49771,7 +50010,7 @@ msgstr "قد يكون مصطلح الدفع في الصف {0} مكررا." msgid "The Pick List having Stock Reservation Entries cannot be updated. If you need to make changes, we recommend canceling the existing Stock Reservation Entries before updating the Pick List." msgstr "" -#: erpnext/stock/doctype/stock_entry/stock_entry.py:2430 +#: erpnext/stock/doctype/stock_entry/stock_entry.py:2512 msgid "The Process Loss Qty has reset as per job cards Process Loss Qty" msgstr "" @@ -49783,11 +50022,11 @@ msgstr "" msgid "The Serial No at Row #{0}: {1} is not available in warehouse {2}." msgstr "" -#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:2285 +#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:2314 msgid "The Serial No {0} is reserved against the {1} {2} and cannot be used for any other transaction." msgstr "" -#: erpnext/stock/doctype/stock_entry/stock_entry.py:1595 +#: erpnext/stock/doctype/stock_entry/stock_entry.py:1665 msgid "The Serial and Batch Bundle {0} is not valid for this transaction. The 'Type of Transaction' should be 'Outward' instead of 'Inward' in Serial and Batch Bundle {0}" msgstr "" @@ -49795,7 +50034,7 @@ msgstr "" msgid "The Stock Entry of type 'Manufacture' is known as backflush. Raw materials being consumed to manufacture finished goods is known as backflushing.

        When creating Manufacture Entry, raw-material items are backflushed based on BOM of production item. If you want raw-material items to be backflushed based on Material Transfer entry made against that Work Order instead, then you can set it under this field." msgstr "يُعرف إدخال المخزون من نوع "التصنيع" باسم التدفق الرجعي. تُعرف المواد الخام التي يتم استهلاكها لتصنيع السلع التامة الصنع بالتدفق العكسي.

        عند إنشاء إدخال التصنيع ، يتم إجراء مسح تلقائي لعناصر المواد الخام استنادًا إلى قائمة مكونات الصنف الخاصة بصنف الإنتاج. إذا كنت تريد إعادة تسريح أصناف المواد الخام استنادًا إلى إدخال نقل المواد الذي تم إجراؤه مقابل طلب العمل هذا بدلاً من ذلك ، فيمكنك تعيينه ضمن هذا الحقل." -#: erpnext/stock/doctype/stock_entry/stock_entry.py:2091 +#: erpnext/stock/doctype/stock_entry/stock_entry.py:2165 msgid "The Work Order is mandatory for Disassembly Order" msgstr "" @@ -49805,7 +50044,7 @@ msgstr "" msgid "The account head under Liability or Equity, in which Profit/Loss will be booked" msgstr "رئيس الحساب تحت المسؤولية أو الأسهم، والتي سيتم حجز الربح / الخسارة" -#: erpnext/accounts/doctype/payment_request/payment_request.py:865 +#: erpnext/accounts/doctype/payment_request/payment_request.py:866 msgid "The allocated amount is greater than the outstanding amount of Payment Request {0}" msgstr "" @@ -49813,6 +50052,14 @@ msgstr "" msgid "The amount of {0} set in this payment request is different from the calculated amount of all payment plans: {1}. Make sure this is correct before submitting the document." msgstr "يختلف مبلغ {0} المحدد في طلب الدفع هذا عن المبلغ المحسوب لجميع خطط الدفع: {1}. تأكد من صحة ذلك قبل إرسال المستند." +#: erpnext/controllers/stock_controller.py:1258 +msgid "The batch {0} is already reserved in {1} {2}. So, cannot proceed with the {3} {4}, which is created against the {5} {6}." +msgstr "" + +#: erpnext/manufacturing/doctype/job_card/job_card.py:1199 +msgid "The completed quantity {0} of an operation {1} cannot be greater than the completed quantity {2} of a previous operation {3}." +msgstr "" + #: erpnext/accounts/doctype/dunning/dunning.py:87 msgid "The currency of invoice {} ({}) is different from the currency of this dunning ({})." msgstr "" @@ -49821,7 +50068,7 @@ msgstr "" msgid "The current POS opening entry is outdated. Please close it and create a new one." msgstr "" -#: erpnext/manufacturing/doctype/work_order/work_order.js:1131 +#: erpnext/manufacturing/doctype/work_order/work_order.js:1126 msgid "The default BOM for that item will be fetched by the system. You can also change the BOM." msgstr "" @@ -49846,7 +50093,7 @@ msgstr "لا يمكن ترك الحقل من المساهمين فارغا" msgid "The field To Shareholder cannot be blank" msgstr "لا يمكن ترك الحقل للمساهم فارغا" -#: erpnext/stock/doctype/delivery_note/delivery_note.py:401 +#: erpnext/stock/doctype/delivery_note/delivery_note.py:405 msgid "The field {0} in row {1} is not set" msgstr "" @@ -49858,11 +50105,15 @@ msgstr "لا يمكن ترك الحقول من المساهمين والمساه msgid "The folio numbers are not matching" msgstr "أرقام الورقة غير متطابقة" -#: erpnext/stock/doctype/putaway_rule/putaway_rule.py:293 +#: erpnext/stock/doctype/putaway_rule/putaway_rule.py:305 msgid "The following Items, having Putaway Rules, could not be accomodated:" msgstr "" -#: erpnext/assets/doctype/asset/depreciation.py:340 +#: erpnext/assets/doctype/asset_repair/asset_repair.py:138 +msgid "The following Purchase Invoices are not submitted:" +msgstr "" + +#: erpnext/assets/doctype/asset/depreciation.py:342 msgid "The following assets have failed to automatically post depreciation entries: {0}" msgstr "" @@ -49870,7 +50121,11 @@ msgstr "" msgid "The following batches are expired, please restock them:
        {0}" msgstr "" -#: erpnext/stock/doctype/item/item.py:839 +#: erpnext/controllers/accounts_controller.py:426 +msgid "The following cancelled repost entries exist for {0}:

        {1}

        Kindly delete these entries before continuing." +msgstr "" + +#: erpnext/stock/doctype/item/item.py:842 msgid "The following deleted attributes exist in Variants but not in the Template. You can either delete the Variants or keep the attribute(s) in template." msgstr "توجد السمات المحذوفة التالية في المتغيرات ولكن ليس في القالب. يمكنك إما حذف المتغيرات أو الاحتفاظ بالسمة (السمات) في القالب." @@ -49882,7 +50137,11 @@ msgstr "لا يزال الموظفون التالي ذكرهم يتبعون حا msgid "The following invalid Pricing Rules are deleted:" msgstr "" -#: erpnext/stock/doctype/material_request/material_request.py:884 +#: erpnext/assets/doctype/asset_repair/asset_repair.py:112 +msgid "The following rows are duplicates:" +msgstr "" + +#: erpnext/stock/doctype/material_request/material_request.py:891 msgid "The following {0} were created: {1}" msgstr "تم إنشاء {0} التالية: {1}" @@ -49891,19 +50150,19 @@ msgstr "تم إنشاء {0} التالية: {1}" msgid "The gross weight of the package. Usually net weight + packaging material weight. (for print)" msgstr "الوزن الكلي للحزمة. الوزن الصافي عادة + تغليف المواد الوزن. (للطباعة)" -#: erpnext/setup/doctype/holiday_list/holiday_list.py:117 +#: erpnext/setup/doctype/holiday_list/holiday_list.py:126 msgid "The holiday on {0} is not between From Date and To Date" msgstr "عطلة على {0} ليست بين من تاريخ وإلى تاريخ" -#: erpnext/controllers/buying_controller.py:1223 +#: erpnext/controllers/buying_controller.py:1236 msgid "The item {item} is not marked as {type_of} item. You can enable it as {type_of} item from its Item master." msgstr "" -#: erpnext/stock/doctype/item/item.py:616 +#: erpnext/stock/doctype/item/item.py:619 msgid "The items {0} and {1} are present in the following {2} :" msgstr "" -#: erpnext/controllers/buying_controller.py:1216 +#: erpnext/controllers/buying_controller.py:1229 msgid "The items {items} are not marked as {type_of} item. You can enable them as {type_of} item from their Item masters." msgstr "" @@ -49945,7 +50204,7 @@ msgstr "" msgid "The operation {0} can not be the sub operation" msgstr "" -#: erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.py:108 +#: erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.py:107 msgid "The original invoice should be consolidated before or along with the return invoice." msgstr "" @@ -49989,7 +50248,7 @@ msgstr "" msgid "The reserved stock will be released. Are you certain you wish to proceed?" msgstr "" -#: erpnext/accounts/doctype/account/account.py:216 +#: erpnext/accounts/doctype/account/account.py:218 msgid "The root account {0} must be a group" msgstr "يجب أن يكون حساب الجذر {0} مجموعة" @@ -49997,7 +50256,7 @@ msgstr "يجب أن يكون حساب الجذر {0} مجموعة" msgid "The selected BOMs are not for the same item" msgstr "قواائم المواد المحددة ليست لنفس البند" -#: erpnext/accounts/doctype/pos_invoice/pos_invoice.py:494 +#: erpnext/accounts/doctype/pos_invoice/pos_invoice.py:539 msgid "The selected change account {} doesn't belongs to Company {}." msgstr "حساب التغيير المحدد {} لا ينتمي إلى الشركة {}." @@ -50014,7 +50273,7 @@ msgstr "البائع والمشتري لا يمكن أن يكون هو نفسه" msgid "The serial and batch bundle {0} not linked to {1} {2}" msgstr "" -#: erpnext/stock/doctype/batch/batch.py:426 +#: erpnext/stock/doctype/batch/batch.py:427 msgid "The serial no {0} does not belong to item {1}" msgstr "الرقم التسلسلي {0} لا ينتمي إلى العنصر {1}" @@ -50030,7 +50289,7 @@ msgstr "الأسهم موجودة بالفعل" msgid "The shares don't exist with the {0}" msgstr "الأسهم غير موجودة مع {0}" -#: erpnext/stock/stock_ledger.py:779 +#: erpnext/stock/stock_ledger.py:810 msgid "The stock for the item {0} in the {1} warehouse was negative on the {2}. You should create a positive entry {3} before the date {4} and time {5} to post the correct valuation rate. For more details, please read the documentation." msgstr "" @@ -50048,28 +50307,28 @@ msgstr "" msgid "The system will create a Sales Invoice or a POS Invoice from the POS interface based on this setting. For high-volume transactions, it is recommended to use POS Invoice." msgstr "" -#: erpnext/accounts/doctype/journal_entry/journal_entry.py:178 -#: erpnext/accounts/doctype/journal_entry/journal_entry.py:185 +#: erpnext/accounts/doctype/journal_entry/journal_entry.py:179 +#: erpnext/accounts/doctype/journal_entry/journal_entry.py:186 msgid "The task has been enqueued as a background job." msgstr "" -#: erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py:1007 +#: erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py:1008 msgid "The task has been enqueued as a background job. In case there is any issue on processing in background, the system will add a comment about the error on this Stock Reconciliation and revert to the Draft stage" msgstr "وقد تم إرساء المهمة كعمل خلفية. في حالة وجود أي مشكلة في المعالجة في الخلفية ، سيقوم النظام بإضافة تعليق حول الخطأ في تسوية المخزون هذا والعودة إلى مرحلة المسودة" -#: erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py:1018 +#: erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py:1019 msgid "The task has been enqueued as a background job. In case there is any issue on processing in background, the system will add a comment about the error on this Stock Reconciliation and revert to the Submitted stage" msgstr "" -#: erpnext/stock/doctype/material_request/material_request.py:334 +#: erpnext/stock/doctype/material_request/material_request.py:338 msgid "The total Issue / Transfer quantity {0} in Material Request {1} cannot be greater than allowed requested quantity {2} for Item {3}" msgstr "" -#: erpnext/stock/doctype/material_request/material_request.py:341 +#: erpnext/stock/doctype/material_request/material_request.py:345 msgid "The total Issue / Transfer quantity {0} in Material Request {1} cannot be greater than requested quantity {2} for Item {3}" msgstr "" -#: erpnext/accounts/doctype/bank_statement_import/bank_statement_import.py:153 +#: erpnext/accounts/doctype/bank_statement_import/bank_statement_import.py:154 msgid "The uploaded file does not appear to be in valid MT940 format." msgstr "" @@ -50101,35 +50360,39 @@ msgstr "تختلف قيمة {0} بين العناصر {1} و {2}" msgid "The value {0} is already assigned to an existing Item {1}." msgstr "تم تعيين القيمة {0} بالفعل لعنصر موجود {1}." -#: erpnext/manufacturing/doctype/work_order/work_order.js:1159 +#: erpnext/manufacturing/doctype/work_order/work_order.js:1154 msgid "The warehouse where you store finished Items before they are shipped." msgstr "" -#: erpnext/manufacturing/doctype/work_order/work_order.js:1152 +#: erpnext/manufacturing/doctype/work_order/work_order.js:1147 msgid "The warehouse where you store your raw materials. Each required item can have a separate source warehouse. Group warehouse also can be selected as source warehouse. On submission of the Work Order, the raw materials will be reserved in these warehouses for production usage." msgstr "" -#: erpnext/manufacturing/doctype/work_order/work_order.js:1164 +#: erpnext/manufacturing/doctype/work_order/work_order.js:1159 msgid "The warehouse where your Items will be transferred when you begin production. Group Warehouse can also be selected as a Work in Progress warehouse." msgstr "" -#: erpnext/manufacturing/doctype/job_card/job_card.py:777 +#: erpnext/manufacturing/doctype/job_card/job_card.py:772 msgid "The {0} ({1}) must be equal to {2} ({3})" msgstr "يجب أن يكون {0} ({1}) مساويًا لـ {2} ({3})" -#: erpnext/public/js/controllers/transaction.js:3258 +#: erpnext/public/js/controllers/transaction.js:3283 msgid "The {0} contains Unit Price Items." msgstr "" -#: erpnext/stock/doctype/material_request/material_request.py:890 +#: erpnext/stock/doctype/item/item.py:423 +msgid "The {0} prefix '{1}' already exists. Please change the Serial No Series, otherwise you will get a Duplicate Entry error." +msgstr "" + +#: erpnext/stock/doctype/material_request/material_request.py:897 msgid "The {0} {1} created successfully" msgstr "" -#: erpnext/controllers/sales_and_purchase_return.py:43 +#: erpnext/controllers/sales_and_purchase_return.py:42 msgid "The {0} {1} does not match with the {0} {2} in the {3} {4}" msgstr "" -#: erpnext/manufacturing/doctype/job_card/job_card.py:880 +#: erpnext/manufacturing/doctype/job_card/job_card.py:875 msgid "The {0} {1} is used to calculate the valuation cost for the finished good {2}." msgstr "" @@ -50137,7 +50400,7 @@ msgstr "" msgid "Then Pricing Rules are filtered out based on Customer, Customer Group, Territory, Supplier, Supplier Type, Campaign, Sales Partner etc." msgstr "" -#: erpnext/assets/doctype/asset/asset.py:600 +#: erpnext/assets/doctype/asset/asset.py:648 msgid "There are active maintenance or repairs against the asset. You must complete all of them before cancelling the asset." msgstr "هناك صيانة نشطة أو إصلاحات ضد الأصل. يجب عليك إكمالها جميعًا قبل إلغاء الأصل." @@ -50145,11 +50408,11 @@ msgstr "هناك صيانة نشطة أو إصلاحات ضد الأصل. يجب msgid "There are inconsistencies between the rate, no of shares and the amount calculated" msgstr "هناك تناقضات بين المعدل، لا من الأسهم والمبلغ المحسوب" -#: erpnext/accounts/doctype/account/account.py:201 +#: erpnext/accounts/doctype/account/account.py:203 msgid "There are ledger entries against this account. Changing {0} to non-{1} in live system will cause incorrect output in 'Accounts {2}' report" msgstr "" -#: erpnext/utilities/bulk_transaction.py:46 +#: erpnext/utilities/bulk_transaction.py:67 msgid "There are no Failed transactions" msgstr "" @@ -50161,7 +50424,7 @@ msgstr "" msgid "There are no slots available on this date" msgstr "" -#: erpnext/stock/doctype/item/item.js:1046 +#: erpnext/stock/doctype/item/item.js:1065 msgid "There are two options to maintain valuation of stock. FIFO (first in - first out) and Moving Average. To understand this topic in detail please visit Item Valuation, FIFO and Moving Average." msgstr "" @@ -50189,11 +50452,11 @@ msgstr "" msgid "There is already an active Subcontracting BOM {0} for the Finished Good {1}." msgstr "" -#: erpnext/stock/doctype/batch/batch.py:434 +#: erpnext/stock/doctype/batch/batch.py:435 msgid "There is no batch found against the {0}: {1}" msgstr "لم يتم العثور على دفعة بالمقابلة مع {0}: {1}" -#: erpnext/stock/doctype/stock_entry/stock_entry.py:1532 +#: erpnext/stock/doctype/stock_entry/stock_entry.py:1602 msgid "There must be atleast 1 Finished Good in this Stock Entry" msgstr "" @@ -50214,7 +50477,7 @@ msgstr "" msgid "There was an issue connecting to Plaid's authentication server. Check browser console for more information" msgstr "" -#: erpnext/accounts/utils.py:1095 +#: erpnext/accounts/utils.py:1099 msgid "There were issues unlinking payment entry {0}." msgstr "" @@ -50236,22 +50499,14 @@ msgstr "هذا العنصر هو متغير {0} (قالب)." msgid "This Month's Summary" msgstr "ملخص هذا الشهر" -#: erpnext/buying/doctype/purchase_order/purchase_order.py:977 +#: erpnext/buying/doctype/purchase_order/purchase_order.py:976 msgid "This Purchase Order has been fully subcontracted." msgstr "" -#: erpnext/selling/doctype/sales_order/sales_order.py:2132 +#: erpnext/selling/doctype/sales_order/sales_order.py:2005 msgid "This Sales Order has been fully subcontracted." msgstr "" -#: erpnext/manufacturing/doctype/manufacturing_settings/manufacturing_settings.js:31 -msgid "This Warehouse will be auto-updated in the Target Warehouse field of Work Order." -msgstr "سيتم تحديث هذا المستودع تلقائيًا في حقل "المستودع الهدف" الخاص بأمر العمل." - -#: erpnext/manufacturing/doctype/manufacturing_settings/manufacturing_settings.js:24 -msgid "This Warehouse will be auto-updated in the Work In Progress Warehouse field of Work Orders." -msgstr "سيتم تحديث هذا المستودع تلقائيًا في حقل "مستودع العمل قيد التقدم" الخاص بأوامر العمل." - #: erpnext/setup/doctype/email_digest/email_digest.py:184 msgid "This Week's Summary" msgstr "ملخص هذا الأسبوع" @@ -50264,7 +50519,7 @@ msgstr "سيوقف هذا الإجراء الفوترة المستقبلية. ه msgid "This action will unlink this account from any external service integrating ERPNext with your bank accounts. It cannot be undone. Are you certain ?" msgstr "سيؤدي هذا الإجراء إلى إلغاء ربط هذا الحساب بأي خدمة خارجية تدمج ERPNext مع حساباتك المصرفية. لا يمكن التراجع. هل أنت متأكد؟" -#: erpnext/assets/doctype/asset/asset.py:366 +#: erpnext/assets/doctype/asset/asset.py:367 msgid "This asset category is marked as non-depreciable. Please disable depreciation calculation or choose a different category." msgstr "" @@ -50272,11 +50527,11 @@ msgstr "" msgid "This covers all scorecards tied to this Setup" msgstr "وهذا يغطي جميع بطاقات الأداء مرتبطة بهذا الإعداد" -#: erpnext/controllers/status_updater.py:447 +#: erpnext/controllers/status_updater.py:449 msgid "This document is over limit by {0} {1} for item {4}. Are you making another {3} against the same {2}?" msgstr "هذه الوثيقة هي على حد كتبها {0} {1} لمادة {4}. وجعل لكم آخر {3} ضد نفسه {2}؟" -#: erpnext/stock/doctype/delivery_note/delivery_note.js:490 +#: erpnext/stock/doctype/delivery_note/delivery_note.js:491 msgid "This field is used to set the 'Customer'." msgstr "" @@ -50286,11 +50541,11 @@ msgstr "" msgid "This filter will be applied to Journal Entry." msgstr "" -#: erpnext/accounts/doctype/pos_invoice/pos_invoice.py:820 +#: erpnext/accounts/doctype/pos_invoice/pos_invoice.py:865 msgid "This invoice has already been paid." msgstr "" -#: erpnext/manufacturing/doctype/bom/bom.js:240 +#: erpnext/manufacturing/doctype/bom/bom.js:241 msgid "This is a Template BOM and will be used to make the work order for {0} of the item {1}" msgstr "" @@ -50363,15 +50618,15 @@ msgstr "هذا يعتمد على المعاملات ضد هذا الشخص ال msgid "This is considered dangerous from accounting point of view." msgstr "" -#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:536 +#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:538 msgid "This is done to handle accounting for cases when Purchase Receipt is created after Purchase Invoice" msgstr "يتم إجراء ذلك للتعامل مع محاسبة الحالات التي يتم فيها إنشاء إيصال الشراء بعد فاتورة الشراء" -#: erpnext/manufacturing/doctype/work_order/work_order.js:1145 +#: erpnext/manufacturing/doctype/work_order/work_order.js:1140 msgid "This is enabled by default. If you want to plan materials for sub-assemblies of the Item you're manufacturing leave this enabled. If you plan and manufacture the sub-assemblies separately, you can disable this checkbox." msgstr "" -#: erpnext/stock/doctype/item/item.js:1034 +#: erpnext/stock/doctype/item/item.js:1053 msgid "This is for raw material Items that'll be used to create finished goods. If the Item is an additional service like 'washing' that'll be used in the BOM, keep this unchecked." msgstr "" @@ -50379,7 +50634,7 @@ msgstr "" msgid "This item filter has already been applied for the {0}" msgstr "" -#: erpnext/stock/doctype/delivery_note/delivery_note.js:503 +#: erpnext/stock/doctype/delivery_note/delivery_note.js:504 msgid "This option can be checked to edit the 'Posting Date' and 'Posting Time' fields." msgstr "" @@ -50391,11 +50646,11 @@ msgstr "" msgid "This schedule was created when Asset {0} was consumed through Asset Capitalization {1}." msgstr "" -#: erpnext/assets/doctype/asset_repair/asset_repair.py:392 +#: erpnext/assets/doctype/asset_repair/asset_repair.py:435 msgid "This schedule was created when Asset {0} was repaired through Asset Repair {1}." msgstr "" -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1476 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1425 msgid "This schedule was created when Asset {0} was restored due to Sales Invoice {1} cancellation." msgstr "" @@ -50403,23 +50658,23 @@ msgstr "" msgid "This schedule was created when Asset {0} was restored on Asset Capitalization {1}'s cancellation." msgstr "" -#: erpnext/assets/doctype/asset/depreciation.py:454 +#: erpnext/assets/doctype/asset/depreciation.py:456 msgid "This schedule was created when Asset {0} was restored." msgstr "" -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1472 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1421 msgid "This schedule was created when Asset {0} was returned through Sales Invoice {1}." msgstr "" -#: erpnext/assets/doctype/asset/depreciation.py:413 +#: erpnext/assets/doctype/asset/depreciation.py:415 msgid "This schedule was created when Asset {0} was scrapped." msgstr "" -#: erpnext/assets/doctype/asset/asset.py:1377 +#: erpnext/assets/doctype/asset/asset.py:1425 msgid "This schedule was created when Asset {0} was {1} into new Asset {2}." msgstr "" -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1448 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1397 msgid "This schedule was created when Asset {0} was {1} through Sales Invoice {2}." msgstr "" @@ -50437,7 +50692,7 @@ msgstr "" msgid "This section allows the user to set the Body and Closing text of the Dunning Letter for the Dunning Type based on language, which can be used in Print." msgstr "يسمح هذا القسم للمستخدم بتعيين النص الأساسي ونص الإغلاق لحرف المطالبة لنوع المطالبة بناءً على اللغة ، والتي يمكن استخدامها في الطباعة." -#: erpnext/stock/doctype/delivery_note/delivery_note.js:496 +#: erpnext/stock/doctype/delivery_note/delivery_note.js:497 msgid "This table is used to set details about the 'Item', 'Qty', 'Basic Rate', etc." msgstr "" @@ -50463,7 +50718,7 @@ msgstr "سيتم إلحاق هذا إلى بند رمز للمتغير. على msgid "This will restrict user access to other employee records" msgstr "سيؤدي هذا إلى تقييد وصول المستخدم لسجلات الموظفين الأخرى" -#: erpnext/controllers/selling_controller.py:841 +#: erpnext/controllers/selling_controller.py:866 msgid "This {} will be treated as material transfer." msgstr "" @@ -50568,7 +50823,7 @@ msgstr "الوقت بالدقائق" msgid "Time in mins." msgstr "" -#: erpnext/manufacturing/doctype/job_card/job_card.py:756 +#: erpnext/manufacturing/doctype/job_card/job_card.py:751 msgid "Time logs are required for {0} {1}" msgstr "سجلات الوقت مطلوبة لـ {0} {1}" @@ -50592,7 +50847,7 @@ msgstr "الموقت تجاوزت الساعات المعطاة." #. Name of a DocType #. Label of a Link in the Projects Workspace #. Label of a shortcut in the Projects Workspace -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.js:1047 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.js:1048 #: erpnext/projects/doctype/timesheet/timesheet.json #: erpnext/projects/report/daily_timesheet_summary/daily_timesheet_summary.py:26 #: erpnext/projects/report/timesheet_billing_summary/timesheet_billing_summary.py:59 @@ -50621,7 +50876,7 @@ msgstr "تفاصيل الجدول الزمني" msgid "Timesheet for tasks." msgstr "الجدول الزمني للمهام." -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:919 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:868 msgid "Timesheet {0} is already completed or cancelled" msgstr "الجدول الزمني {0} بالفعل منتهي أو ملغى" @@ -50668,8 +50923,8 @@ msgstr "على فاتورة" msgid "To Currency" msgstr "إلى العملات" -#: erpnext/controllers/accounts_controller.py:555 -#: erpnext/setup/doctype/holiday_list/holiday_list.py:112 +#: erpnext/controllers/accounts_controller.py:625 +#: erpnext/setup/doctype/holiday_list/holiday_list.py:121 msgid "To Date cannot be before From Date" msgstr "(الى تاريخ) لا يمكن ان يكون قبل (من تاريخ)" @@ -50683,7 +50938,7 @@ msgstr "لا يمكن أن يكون "إلى" قبل "من تار msgid "To Date cannot be less than From Date" msgstr "لا يمكن أن يكون تاريخ التاريخ أقل من تاريخ" -#: erpnext/crm/report/sales_pipeline_analytics/sales_pipeline_analytics.py:29 +#: erpnext/crm/report/sales_pipeline_analytics/sales_pipeline_analytics.py:30 msgid "To Date is mandatory" msgstr "" @@ -50740,6 +50995,8 @@ msgstr "" msgid "To Employee" msgstr "إلى الموظف" +#. Label of the to_fiscal_year (Link) field in DocType 'Budget' +#: erpnext/accounts/doctype/budget/budget.json #: erpnext/accounts/report/budget_variance_report/budget_variance_report.js:51 msgid "To Fiscal Year" msgstr "إلى السنة المالية" @@ -50857,7 +51114,7 @@ msgstr "للمساهم" msgid "To Time" msgstr "إلى وقت" -#: erpnext/projects/doctype/timesheet_detail/timesheet_detail.py:98 +#: erpnext/projects/doctype/timesheet_detail/timesheet_detail.py:108 msgid "To Time cannot be before from date" msgstr "" @@ -50881,7 +51138,7 @@ msgstr "لمستودع" msgid "To Warehouse (Optional)" msgstr "إلى مستودع (اختياري)" -#: erpnext/manufacturing/doctype/bom/bom.js:925 +#: erpnext/manufacturing/doctype/bom/bom.js:942 msgid "To add Operations tick the 'With Operations' checkbox." msgstr "" @@ -50889,11 +51146,11 @@ msgstr "" msgid "To add subcontracted Item's raw materials if include exploded items is disabled." msgstr "" -#: erpnext/controllers/status_updater.py:442 +#: erpnext/controllers/status_updater.py:444 msgid "To allow over billing, update \"Over Billing Allowance\" in Accounts Settings or the Item." msgstr "للسماح بزيادة الفواتير ، حدّث "Over Billing Allowance" في إعدادات الحسابات أو العنصر." -#: erpnext/controllers/status_updater.py:438 +#: erpnext/controllers/status_updater.py:440 msgid "To allow over receipt / delivery, update \"Over Receipt/Delivery Allowance\" in Stock Settings or the Item." msgstr "للسماح بوصول الاستلام / التسليم ، قم بتحديث "الإفراط في الاستلام / بدل التسليم" في إعدادات المخزون أو العنصر." @@ -50909,11 +51166,11 @@ msgstr "" msgid "To be Delivered to Customer" msgstr "" -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:611 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:560 msgid "To cancel a {} you need to cancel the POS Closing Entry {}." msgstr "" -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:624 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:573 msgid "To cancel this Sales Invoice you need to cancel the POS Closing Entry {}." msgstr "" @@ -50935,12 +51192,12 @@ msgstr "" msgid "To include sub-assembly costs and scrap items in Finished Goods on a work order without using a job card, when the 'Use Multi-Level BOM' option is enabled." msgstr "" -#: erpnext/accounts/doctype/payment_entry/payment_entry.py:2308 -#: erpnext/controllers/accounts_controller.py:3156 +#: erpnext/accounts/doctype/payment_entry/payment_entry.py:2309 +#: erpnext/controllers/accounts_controller.py:3229 msgid "To include tax in row {0} in Item rate, taxes in rows {1} must also be included" msgstr "ل تشمل الضريبة في الصف {0} في معدل الإغلاق ، {1} ويجب أيضا تضمين الضرائب في الصفوف" -#: erpnext/stock/doctype/item/item.py:638 +#: erpnext/stock/doctype/item/item.py:641 msgid "To merge, following properties must be same for both items" msgstr "لدمج ، يجب أن يكون نفس الخصائص التالية ل كلا البندين" @@ -50948,7 +51205,7 @@ msgstr "لدمج ، يجب أن يكون نفس الخصائص التالية ل msgid "To not apply Pricing Rule in a particular transaction, all applicable Pricing Rules should be disabled." msgstr "" -#: erpnext/accounts/doctype/account/account.py:550 +#: erpnext/accounts/doctype/account/account.py:552 msgid "To overrule this, enable '{0}' in company {1}" msgstr "لإلغاء هذا ، قم بتمكين "{0}" في الشركة {1}" @@ -50956,11 +51213,11 @@ msgstr "لإلغاء هذا ، قم بتمكين "{0}" في الشرك msgid "To still proceed with editing this Attribute Value, enable {0} in Item Variant Settings." msgstr "للاستمرار في تعديل قيمة السمة هذه ، قم بتمكين {0} في إعدادات متغير العنصر." -#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:626 +#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:628 msgid "To submit the invoice without purchase order please set {0} as {1} in {2}" msgstr "" -#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:647 +#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:649 msgid "To submit the invoice without purchase receipt please set {0} as {1} in {2}" msgstr "" @@ -51010,6 +51267,23 @@ msgstr "" msgid "Too many columns. Export the report and print it using a spreadsheet application." msgstr "" +#. Label of a Card Break in the Manufacturing Workspace +#. Label of the tools (Column Break) field in DocType 'Email Digest' +#. Label of a Card Break in the Stock Workspace +#: erpnext/buying/doctype/purchase_order/purchase_order.js:641 +#: erpnext/buying/doctype/purchase_order/purchase_order.js:717 +#: erpnext/buying/doctype/request_for_quotation/request_for_quotation.js:70 +#: erpnext/buying/doctype/request_for_quotation/request_for_quotation.js:157 +#: erpnext/buying/doctype/request_for_quotation/request_for_quotation.js:442 +#: erpnext/buying/doctype/request_for_quotation/request_for_quotation.js:451 +#: erpnext/buying/doctype/supplier_quotation/supplier_quotation.js:69 +#: erpnext/buying/report/supplier_quotation_comparison/supplier_quotation_comparison.js:123 +#: erpnext/manufacturing/workspace/manufacturing/manufacturing.json +#: erpnext/setup/doctype/email_digest/email_digest.json +#: erpnext/stock/workspace/stock/stock.json +msgid "Tools" +msgstr "" + #. Name of a UOM #: erpnext/setup/setup_wizard/data/uom_data.json msgid "Torr" @@ -51114,7 +51388,7 @@ msgstr "" #. Label of the total_amount (Currency) field in DocType 'Stock Entry' #: erpnext/accounts/doctype/invoice_discounting/invoice_discounting.json #: erpnext/accounts/doctype/journal_entry/journal_entry.json -#: erpnext/accounts/report/tax_withholding_details/tax_withholding_details.py:241 +#: erpnext/accounts/report/tax_withholding_details/tax_withholding_details.py:255 #: erpnext/accounts/report/tds_computation_summary/tds_computation_summary.py:131 #: erpnext/selling/page/sales_funnel/sales_funnel.py:167 #: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.json @@ -51223,7 +51497,7 @@ msgstr "مجموع العمولة" #. Label of the total_completed_qty (Float) field in DocType 'Job Card' #: erpnext/manufacturing/doctype/job_card/job_card.json -#: erpnext/manufacturing/doctype/job_card/job_card.py:773 +#: erpnext/manufacturing/doctype/job_card/job_card.py:768 #: erpnext/manufacturing/report/job_card_summary/job_card_summary.py:174 msgid "Total Completed Qty" msgstr "إجمالي الكمية المكتملة" @@ -51271,7 +51545,7 @@ msgstr "إجمالي مبلغ التكلفة (عبر الجداول الزمني msgid "Total Credit" msgstr "إجمالي الائتمان" -#: erpnext/accounts/doctype/journal_entry/journal_entry.py:325 +#: erpnext/accounts/doctype/journal_entry/journal_entry.py:326 msgid "Total Credit/ Debit Amount should be same as linked Journal Entry" msgstr "يجب أن يكون إجمالي مبلغ الائتمان / المدين هو نفسه المرتبطة بإدخال المجلة" @@ -51280,11 +51554,11 @@ msgstr "يجب أن يكون إجمالي مبلغ الائتمان / المدي msgid "Total Debit" msgstr "مجموع الخصم" -#: erpnext/accounts/doctype/journal_entry/journal_entry.py:990 +#: erpnext/accounts/doctype/journal_entry/journal_entry.py:905 msgid "Total Debit must be equal to Total Credit. The difference is {0}" msgstr "يجب أن يكون إجمالي الخصم يساوي إجمالي الائتمان ." -#: erpnext/stock/report/delivery_note_trends/delivery_note_trends.py:45 +#: erpnext/stock/report/delivery_note_trends/delivery_note_trends.py:51 msgid "Total Delivered Amount" msgstr "إجمالي المبلغ الذي تم تسليمه" @@ -51309,6 +51583,10 @@ msgstr "المصاريف الكلية" msgid "Total Expense This Year" msgstr "إجمالي النفقات هذا العام" +#: erpnext/accounts/doctype/budget/budget.py:576 +msgid "Total Expenses booked through" +msgstr "" + #. Label of the total_experience (Data) field in DocType 'Employee External #. Work History' #: erpnext/setup/doctype/employee_external_work_history/employee_external_work_history.json @@ -51464,7 +51742,7 @@ msgstr "اجمالي أمر البيع التقديري" msgid "Total Order Value" msgstr "مجموع قيمة الطلب" -#: erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py:694 +#: erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py:622 msgid "Total Other Charges" msgstr "" @@ -51505,7 +51783,7 @@ msgstr "إجمالي المبلغ المستحق" msgid "Total Paid Amount" msgstr "إجمالي المبلغ المدفوع" -#: erpnext/controllers/accounts_controller.py:2704 +#: erpnext/controllers/accounts_controller.py:2777 msgid "Total Payment Amount in Payment Schedule must be equal to Grand / Rounded Total" msgstr "يجب أن يكون إجمالي مبلغ الدفع في جدول الدفع مساويا للمجموع الكبير / المستدير" @@ -51517,7 +51795,7 @@ msgstr "لا يمكن أن يكون إجمالي مبلغ طلب الدفع أك msgid "Total Payments" msgstr "مجموع المدفوعات" -#: erpnext/selling/doctype/sales_order/sales_order.py:713 +#: erpnext/selling/doctype/sales_order/sales_order.py:712 msgid "Total Picked Quantity {0} is more than ordered qty {1}. You can set the Over Picking Allowance in Stock Settings." msgstr "" @@ -51640,7 +51918,7 @@ msgstr "إجمالي المستهدف" msgid "Total Tasks" msgstr "إجمالي المهام" -#: erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py:687 +#: erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py:615 #: erpnext/accounts/report/purchase_register/purchase_register.py:263 msgid "Total Tax" msgstr "مجموع الضرائب" @@ -51797,20 +52075,28 @@ msgstr "" msgid "Total Workstation Time (In Hours)" msgstr "" -#: erpnext/controllers/selling_controller.py:234 +#: erpnext/controllers/selling_controller.py:256 msgid "Total allocated percentage for sales team should be 100" msgstr "مجموع النسبة المئوية المخصصة ل فريق المبيعات يجب أن يكون 100" -#: erpnext/selling/doctype/customer/customer.py:161 +#: erpnext/selling/doctype/customer/customer.py:162 msgid "Total contribution percentage should be equal to 100" msgstr "يجب أن تكون نسبة المساهمة الإجمالية مساوية 100" +#: erpnext/accounts/doctype/budget/budget.py:363 +msgid "Total distributed amount {0} must be equal to Budget Amount {1}" +msgstr "" + +#: erpnext/accounts/doctype/budget/budget.py:370 +msgid "Total distribution percent must equal 100 (currently {0})" +msgstr "" + #: erpnext/projects/doctype/project/project_dashboard.html:2 msgid "Total hours: {0}" msgstr "" -#: erpnext/accounts/doctype/pos_invoice/pos_invoice.py:524 -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:595 +#: erpnext/accounts/doctype/pos_invoice/pos_invoice.py:569 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:544 msgid "Total payments amount can't be greater than {}" msgstr "لا يمكن أن يكون إجمالي المدفوعات أكبر من {}" @@ -51926,7 +52212,7 @@ msgstr "عملية العملات" msgid "Transaction Date" msgstr "تاريخ المعاملة" -#: erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py:503 +#: erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py:504 msgid "Transaction Deletion Document: {0} is running for this Company. {1}" msgstr "" @@ -51989,7 +52275,7 @@ msgstr "" #. Label of the transaction_type (Data) field in DocType 'Bank Transaction' #: erpnext/accounts/doctype/bank_transaction/bank_transaction.json #: erpnext/accounts/report/calculated_discount_mismatch/calculated_discount_mismatch.py:38 -#: erpnext/accounts/report/tax_withholding_details/tax_withholding_details.py:264 +#: erpnext/accounts/report/tax_withholding_details/tax_withholding_details.py:278 msgid "Transaction Type" msgstr "نوع المعاملة" @@ -52001,7 +52287,7 @@ msgstr "يجب أن تكون العملة المعاملة نفس العملة msgid "Transaction currency: {0} cannot be different from Bank Account({1}) currency: {2}" msgstr "" -#: erpnext/manufacturing/doctype/job_card/job_card.py:749 +#: erpnext/manufacturing/doctype/job_card/job_card.py:744 msgid "Transaction not allowed against stopped Work Order {0}" msgstr "المعاملة غير مسموح بها في مقابل أمر العمل المتوقف {0}" @@ -52030,7 +52316,7 @@ msgstr "المعاملات السنوية التاريخ" msgid "Transactions against the Company already exist! Chart of Accounts can only be imported for a Company with no transactions." msgstr "" -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1186 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1135 msgid "Transactions using Sales Invoice in POS are disabled." msgstr "" @@ -52041,7 +52327,7 @@ msgstr "" #. Option for the 'Asset Status' (Select) field in DocType 'Serial No' #: erpnext/accounts/doctype/share_transfer/share_transfer.json #: erpnext/assets/doctype/asset_movement/asset_movement.json -#: erpnext/buying/doctype/purchase_order/purchase_order.js:434 +#: erpnext/buying/doctype/purchase_order/purchase_order.js:435 #: erpnext/stock/doctype/item_reorder/item_reorder.json #: erpnext/stock/doctype/serial_no/serial_no.json #: erpnext/subcontracting/doctype/subcontracting_order/subcontracting_order.js:538 @@ -52097,7 +52383,7 @@ msgstr "" #. Option for the 'Status' (Select) field in DocType 'Material Request' #: erpnext/stock/doctype/material_request/material_request.json -#: erpnext/stock/doctype/material_request/material_request_list.js:41 +#: erpnext/stock/doctype/material_request/material_request_list.js:42 msgid "Transferred" msgstr "نقل" @@ -52129,7 +52415,7 @@ msgstr "" msgid "Transit" msgstr "" -#: erpnext/stock/doctype/stock_entry/stock_entry.js:474 +#: erpnext/stock/doctype/stock_entry/stock_entry.js:479 msgid "Transit Entry" msgstr "" @@ -52202,10 +52488,8 @@ msgid "Tree of Procedures" msgstr "شجرة الإجراءات" #. Name of a report -#. Label of a shortcut in the Accounting Workspace #. Label of a Link in the Financial Reports Workspace #: erpnext/accounts/report/trial_balance/trial_balance.json -#: erpnext/accounts/workspace/accounting/accounting.json #: erpnext/accounts/workspace/financial_reports/financial_reports.json msgid "Trial Balance" msgstr "ميزان المراجعة" @@ -52406,7 +52690,7 @@ msgstr "" #: erpnext/manufacturing/doctype/production_plan_sub_assembly_item/production_plan_sub_assembly_item.json #: erpnext/manufacturing/doctype/sales_forecast_item/sales_forecast_item.json #: erpnext/manufacturing/doctype/workstation/workstation.js:480 -#: erpnext/manufacturing/report/bom_explorer/bom_explorer.py:58 +#: erpnext/manufacturing/report/bom_explorer/bom_explorer.py:70 #: erpnext/manufacturing/report/bom_operations_time/bom_operations_time.py:110 #: erpnext/public/js/stock_analytics.js:94 erpnext/public/js/utils.js:742 #: erpnext/quality_management/doctype/quality_goal_objective/quality_goal_objective.json @@ -52414,7 +52698,7 @@ msgstr "" #: erpnext/selling/doctype/delivery_schedule_item/delivery_schedule_item.json #: erpnext/selling/doctype/product_bundle_item/product_bundle_item.json #: erpnext/selling/doctype/quotation_item/quotation_item.json -#: erpnext/selling/doctype/sales_order/sales_order.js:1623 +#: erpnext/selling/doctype/sales_order/sales_order.js:1645 #: erpnext/selling/doctype/sales_order_item/sales_order_item.json #: erpnext/selling/report/item_wise_sales_history/item_wise_sales_history.py:43 #: erpnext/selling/report/sales_analytics/sales_analytics.py:138 @@ -52435,7 +52719,7 @@ msgstr "" #: erpnext/stock/report/batch_wise_balance_history/batch_wise_balance_history.py:87 #: erpnext/stock/report/item_prices/item_prices.py:55 #: erpnext/stock/report/product_bundle_balance/product_bundle_balance.py:94 -#: erpnext/stock/report/stock_ageing/stock_ageing.py:176 +#: erpnext/stock/report/stock_ageing/stock_ageing.py:178 #: erpnext/stock/report/stock_analytics/stock_analytics.py:45 #: erpnext/stock/report/stock_projected_qty/stock_projected_qty.py:134 #: erpnext/stock/report/supplier_wise_sales_analytics/supplier_wise_sales_analytics.py:60 @@ -52489,7 +52773,7 @@ msgstr "تفاصيل تحويل وحدة القياس" msgid "UOM Conversion Factor" msgstr "عامل تحويل وحدة القياس" -#: erpnext/manufacturing/doctype/production_plan/production_plan.py:1424 +#: erpnext/manufacturing/doctype/production_plan/production_plan.py:1431 msgid "UOM Conversion factor ({0} -> {1}) not found for item: {2}" msgstr "معامل تحويل UOM ({0} -> {1}) غير موجود للعنصر: {2}" @@ -52502,7 +52786,7 @@ msgstr "معامل تحويل وحدة القياس مطلوب في الصف: {0 msgid "UOM Name" msgstr "اسم وحدة القايس" -#: erpnext/stock/doctype/stock_entry/stock_entry.py:3507 +#: erpnext/stock/doctype/stock_entry/stock_entry.py:3611 msgid "UOM conversion factor required for UOM: {0} in Item: {1}" msgstr "" @@ -52557,7 +52841,7 @@ msgstr "تعذر العثور على سعر الصرف من {0} إلى {1} لت msgid "Unable to find score starting at {0}. You need to have standing scores covering 0 to 100" msgstr "تعذر العثور على النتيجة بدءا من {0}. يجب أن يكون لديك درجات دائمة تغطي 0 إلى 100" -#: erpnext/manufacturing/doctype/work_order/work_order.py:1014 +#: erpnext/manufacturing/doctype/work_order/work_order.py:1018 msgid "Unable to find the time slot in the next {0} days for the operation {1}. Please increase the 'Capacity Planning For (Days)' in the {2}." msgstr "" @@ -52574,15 +52858,15 @@ msgstr "" msgid "Unallocated Amount" msgstr "المبلغ غير المخصصة" -#: erpnext/stock/doctype/putaway_rule/putaway_rule.py:311 +#: erpnext/stock/doctype/putaway_rule/putaway_rule.py:323 msgid "Unassigned Qty" msgstr "" -#: erpnext/accounts/doctype/budget/budget.py:360 +#: erpnext/accounts/doctype/budget/budget.py:649 msgid "Unbilled Orders" msgstr "" -#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js:100 +#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js:101 msgid "Unblock Invoice" msgstr "الافراج عن الفاتورة" @@ -52628,7 +52912,7 @@ msgstr "لم تتحقق" msgid "Unit" msgstr "" -#: erpnext/controllers/accounts_controller.py:3930 +#: erpnext/controllers/accounts_controller.py:4003 msgid "Unit Price" msgstr "" @@ -52643,7 +52927,7 @@ msgstr "وحدة القياس" msgid "Unit of Measure (UOM)" msgstr "وحدة القياس" -#: erpnext/stock/doctype/item/item.py:383 +#: erpnext/stock/doctype/item/item.py:384 msgid "Unit of Measure {0} has been entered more than once in Conversion Factor Table" msgstr "وحدة القياس {0} تم إدخال أكثر من مرة واحدة في معامل التحويل الجدول" @@ -52685,7 +52969,7 @@ msgstr "" #: erpnext/accounts/doctype/pos_invoice/pos_invoice.json #: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json #: erpnext/accounts/doctype/sales_invoice/sales_invoice.json -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:272 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:274 #: erpnext/accounts/doctype/subscription/subscription.json #: erpnext/accounts/doctype/subscription/subscription_list.js:12 msgid "Unpaid" @@ -52773,7 +53057,7 @@ msgstr "" msgid "Unreconciled Entries" msgstr "" -#: erpnext/manufacturing/doctype/work_order/work_order.js:893 +#: erpnext/manufacturing/doctype/work_order/work_order.js:903 #: erpnext/selling/doctype/sales_order/sales_order.js:107 #: erpnext/stock/doctype/pick_list/pick_list.js:156 #: erpnext/subcontracting/doctype/subcontracting_order/subcontracting_order.js:193 @@ -52814,11 +53098,11 @@ msgid "Unscheduled" msgstr "غير المجدولة" #: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:178 -#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:304 +#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:305 msgid "Unsecured Loans" msgstr "القروض غير المضمونة" -#: erpnext/accounts/doctype/payment_entry/payment_entry.js:1712 +#: erpnext/accounts/doctype/payment_entry/payment_entry.js:1711 msgid "Unset Matched Payment Request" msgstr "" @@ -52895,7 +53179,7 @@ msgstr "تحديث السيارات تكرار المرجع" #. Label of the update_bom_costs_automatically (Check) field in DocType #. 'Manufacturing Settings' -#: erpnext/manufacturing/doctype/manufacturing_settings/manufacturing_settings.js:35 +#: erpnext/manufacturing/doctype/manufacturing_settings/manufacturing_settings.js:23 #: erpnext/manufacturing/doctype/manufacturing_settings/manufacturing_settings.json msgid "Update BOM Cost Automatically" msgstr "تحديث بوم التكلفة تلقائيا" @@ -52950,7 +53234,7 @@ msgstr "تحديث تكلفة المواد المستهلكة في المشرو #. Option for the 'Update Type' (Select) field in DocType 'BOM Update Log' #. Label of the update_cost_section (Section Break) field in DocType 'BOM #. Update Tool' -#: erpnext/manufacturing/doctype/bom/bom.js:156 +#: erpnext/manufacturing/doctype/bom/bom.js:157 #: erpnext/manufacturing/doctype/bom_update_log/bom_update_log.json #: erpnext/manufacturing/doctype/bom_update_tool/bom_update_tool.json msgid "Update Cost" @@ -52975,10 +53259,10 @@ msgstr "تحديث المخزون الحالي" msgid "Update Existing Price List Rate" msgstr "" -#: erpnext/buying/doctype/purchase_order/purchase_order.js:365 +#: erpnext/buying/doctype/purchase_order/purchase_order.js:366 #: erpnext/public/js/utils.js:842 #: erpnext/selling/doctype/sales_order/sales_order.js:75 -#: erpnext/selling/doctype/sales_order/sales_order.js:936 +#: erpnext/selling/doctype/sales_order/sales_order.js:940 msgid "Update Items" msgstr "تحديث العناصر" @@ -52988,7 +53272,7 @@ msgstr "تحديث العناصر" #. Invoice' #: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json #: erpnext/accounts/doctype/sales_invoice/sales_invoice.json -#: erpnext/controllers/accounts_controller.py:190 +#: erpnext/controllers/accounts_controller.py:196 msgid "Update Outstanding for Self" msgstr "" @@ -53007,7 +53291,7 @@ msgstr "تحديث تنسيق الطباعة" msgid "Update Rate and Availability" msgstr "معدل التحديث والتوفر" -#: erpnext/buying/doctype/purchase_order/purchase_order.js:629 +#: erpnext/buying/doctype/purchase_order/purchase_order.js:630 msgid "Update Rate as per Last Purchase" msgstr "" @@ -53039,7 +53323,7 @@ msgstr "" msgid "Update latest price in all BOMs" msgstr "تحديث آخر الأسعار في جميع بومس" -#: erpnext/assets/doctype/asset/asset.py:406 +#: erpnext/assets/doctype/asset/asset.py:407 msgid "Update stock must be enabled for the purchase invoice {0}" msgstr "" @@ -53073,15 +53357,15 @@ msgstr "" msgid "Updating Costing and Billing fields against this Project..." msgstr "" -#: erpnext/stock/doctype/item/item.py:1382 +#: erpnext/stock/doctype/item/item.py:1385 msgid "Updating Variants..." msgstr "جارٍ تحديث المتغيرات ..." -#: erpnext/manufacturing/doctype/work_order/work_order.js:1107 +#: erpnext/manufacturing/doctype/work_order/work_order.js:1102 msgid "Updating Work Order status" msgstr "" -#: erpnext/public/js/print.js:129 +#: erpnext/public/js/print.js:140 msgid "Updating details." msgstr "" @@ -53198,7 +53482,7 @@ msgstr "" #. Label of the use_multi_level_bom (Check) field in DocType 'Work Order' #. Label of the use_multi_level_bom (Check) field in DocType 'Stock Entry' -#: erpnext/manufacturing/doctype/bom/bom.js:358 +#: erpnext/manufacturing/doctype/bom/bom.js:365 #: erpnext/manufacturing/doctype/work_order/work_order.json #: erpnext/stock/doctype/stock_entry/stock_entry.json msgid "Use Multi-Level BOM" @@ -53263,7 +53547,7 @@ msgstr "" msgid "Use Transaction Date Exchange Rate" msgstr "" -#: erpnext/projects/doctype/project/project.py:561 +#: erpnext/projects/doctype/project/project.py:562 msgid "Use a name that is different from previous project name" msgstr "استخدم اسمًا مختلفًا عن اسم المشروع السابق" @@ -53299,7 +53583,7 @@ msgstr "هوية المستخدم لم يتم تعيين موظف ل {0}" #. Label of the user_remark (Small Text) field in DocType 'Journal Entry' #. Label of the user_remark (Small Text) field in DocType 'Journal Entry #. Account' -#: erpnext/accounts/doctype/journal_entry/journal_entry.js:616 +#: erpnext/accounts/doctype/journal_entry/journal_entry.js:620 #: erpnext/accounts/doctype/journal_entry/journal_entry.json #: erpnext/accounts/doctype/journal_entry_account/journal_entry_account.json msgid "User Remark" @@ -53310,7 +53594,7 @@ msgstr "ملاحظة المستخدم" msgid "User Resolution Time" msgstr "وقت قرار المستخدم" -#: erpnext/accounts/doctype/pricing_rule/utils.py:591 +#: erpnext/accounts/doctype/pricing_rule/utils.py:594 msgid "User has not applied rule on the invoice {0}" msgstr "لم يطبق المستخدم قاعدة على الفاتورة {0}" @@ -53362,11 +53646,11 @@ msgstr "" msgid "Users with this role are allowed to over deliver/receive against orders above the allowance percentage" msgstr "" -#. Description of the 'Role Allowed to Set Frozen Accounts and Edit Frozen -#. Entries' (Link) field in DocType 'Accounts Settings' +#. Description of the 'Role to Notify on Depreciation Failure' (Link) field in +#. DocType 'Accounts Settings' #: erpnext/accounts/doctype/accounts_settings/accounts_settings.json -msgid "Users with this role are allowed to set frozen accounts and create / modify accounting entries against frozen accounts" -msgstr "يسمح للمستخدمين مع هذا الدور لضبط الحسابات المجمدة و إنشاء / تعديل القيود المحاسبية على حسابات مجمدة" +msgid "Users with this role will be notified if the asset depreciation gets failed" +msgstr "" #: erpnext/stock/doctype/stock_settings/stock_settings.js:38 msgid "Using negative stock disables FIFO/Moving average valuation when inventory is negative." @@ -53474,11 +53758,11 @@ msgstr "صالحة للبلدان" msgid "Valid from and valid upto fields are mandatory for the cumulative" msgstr "صالحة من وحقول تصل صالحة إلزامية للتراكمية" -#: erpnext/buying/doctype/supplier_quotation/supplier_quotation.py:167 +#: erpnext/buying/doctype/supplier_quotation/supplier_quotation.py:169 msgid "Valid till Date cannot be before Transaction Date" msgstr "صالح حتى التاريخ لا يمكن أن يكون قبل تاريخ المعاملة" -#: erpnext/selling/doctype/quotation/quotation.py:156 +#: erpnext/selling/doctype/quotation/quotation.py:158 msgid "Valid till date cannot be before transaction date" msgstr "صالحة حتى تاريخ لا يمكن أن يكون قبل تاريخ المعاملة" @@ -53496,6 +53780,12 @@ msgstr "التحقق من صحة القاعدة المطبقة" msgid "Validate Components and Quantities Per BOM" msgstr "" +#. Label of the validate_consumed_qty (Check) field in DocType 'Buying +#. Settings' +#: erpnext/buying/doctype/buying_settings/buying_settings.json +msgid "Validate Consumed Qty (as per BOM)" +msgstr "" + #. Label of the validate_material_transfer_warehouses (Check) field in DocType #. 'Stock Settings' #: erpnext/stock/doctype/stock_settings/stock_settings.json @@ -53541,7 +53831,7 @@ msgstr "الصلاحية والاستخدام" msgid "Validity in Days" msgstr "الصلاحية في أيام" -#: erpnext/selling/doctype/quotation/quotation.py:363 +#: erpnext/selling/doctype/quotation/quotation.py:365 msgid "Validity period of this quotation has ended." msgstr "انتهت فترة صلاحية هذا الاقتباس." @@ -53617,15 +53907,15 @@ msgstr "سعر التقييم" msgid "Valuation Rate (In / Out)" msgstr "" -#: erpnext/stock/stock_ledger.py:2012 +#: erpnext/stock/stock_ledger.py:2049 msgid "Valuation Rate Missing" msgstr "معدل التقييم مفقود" -#: erpnext/stock/stock_ledger.py:1990 +#: erpnext/stock/stock_ledger.py:2027 msgid "Valuation Rate for the Item {0}, is required to do accounting entries for {1} {2}." msgstr "معدل التقييم للعنصر {0} ، مطلوب لإجراء إدخالات محاسبية لـ {1} {2}." -#: erpnext/stock/doctype/item/item.py:267 +#: erpnext/stock/doctype/item/item.py:269 msgid "Valuation Rate is mandatory if Opening Stock entered" msgstr "معدل التقييم إلزامي إذا ادخلت قيمة مبدئية للمخزون\\n
        \\nValuation Rate is mandatory if Opening Stock entered" @@ -53639,7 +53929,7 @@ msgstr "معدل التقييم مطلوب للبند {0} في الصف {1}" msgid "Valuation and Total" msgstr "التقييم والمجموع" -#: erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py:984 +#: erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py:985 msgid "Valuation rate for customer provided items has been set to zero." msgstr "" @@ -53652,8 +53942,8 @@ msgstr "" msgid "Valuation rate for the item as per Sales Invoice (Only for Internal Transfers)" msgstr "" -#: erpnext/accounts/doctype/payment_entry/payment_entry.py:2332 -#: erpnext/controllers/accounts_controller.py:3180 +#: erpnext/accounts/doctype/payment_entry/payment_entry.py:2333 +#: erpnext/controllers/accounts_controller.py:3253 msgid "Valuation type charges can not be marked as Inclusive" msgstr "لا يمكن تحديد رسوم نوع التقييم على أنها شاملة" @@ -53665,7 +53955,7 @@ msgstr "لا يمكن وضع علامة على رسوم التقييم على ا msgid "Value (G - D)" msgstr "" -#: erpnext/stock/report/stock_ageing/stock_ageing.py:219 +#: erpnext/stock/report/stock_ageing/stock_ageing.py:221 msgid "Value ({0})" msgstr "" @@ -53781,7 +54071,7 @@ msgstr "التباين ({})" msgid "Variant" msgstr "مختلف" -#: erpnext/stock/doctype/item/item.py:854 +#: erpnext/stock/doctype/item/item.py:857 msgid "Variant Attribute Error" msgstr "خطأ في سمة المتغير" @@ -53791,7 +54081,7 @@ msgstr "خطأ في سمة المتغير" msgid "Variant Attributes" msgstr "سمات متفاوتة" -#: erpnext/manufacturing/doctype/bom/bom.js:197 +#: erpnext/manufacturing/doctype/bom/bom.js:198 msgid "Variant BOM" msgstr "المتغير BOM" @@ -53800,7 +54090,7 @@ msgstr "المتغير BOM" msgid "Variant Based On" msgstr "البديل القائم على" -#: erpnext/stock/doctype/item/item.py:882 +#: erpnext/stock/doctype/item/item.py:885 msgid "Variant Based On cannot be changed" msgstr "لا يمكن تغيير المتغير بناءً على" @@ -53813,12 +54103,12 @@ msgstr "تفاصيل تقرير التقرير" msgid "Variant Field" msgstr "الحقل البديل" -#: erpnext/manufacturing/doctype/bom/bom.js:312 -#: erpnext/manufacturing/doctype/bom/bom.js:391 +#: erpnext/manufacturing/doctype/bom/bom.js:319 +#: erpnext/manufacturing/doctype/bom/bom.js:398 msgid "Variant Item" msgstr "عنصر متغير" -#: erpnext/stock/doctype/item/item.py:852 +#: erpnext/stock/doctype/item/item.py:855 msgid "Variant Items" msgstr "العناصر المتغيرة" @@ -53829,7 +54119,7 @@ msgstr "العناصر المتغيرة" msgid "Variant Of" msgstr "البديل من" -#: erpnext/stock/doctype/item/item.js:726 +#: erpnext/stock/doctype/item/item.js:745 msgid "Variant creation has been queued." msgstr "وقد وضعت قائمة الانتظار في قائمة الانتظار." @@ -53957,7 +54247,6 @@ msgid "View Exchange Gain/Loss Journals" msgstr "" #: erpnext/assets/doctype/asset/asset.js:166 -#: erpnext/assets/doctype/asset_repair/asset_repair.js:77 msgid "View General Ledger" msgstr "" @@ -53965,7 +54254,7 @@ msgstr "" msgid "View Leads" msgstr "مشاهدة العملاء المحتملون" -#: erpnext/accounts/doctype/account/account_tree.js:270 +#: erpnext/accounts/doctype/account/account_tree.js:278 #: erpnext/stock/doctype/batch/batch.js:18 msgid "View Ledger" msgstr "عرض القيود" @@ -53974,7 +54263,7 @@ msgstr "عرض القيود" msgid "View Ledgers" msgstr "" -#: erpnext/manufacturing/doctype/master_production_schedule/master_production_schedule.js:55 +#: erpnext/manufacturing/doctype/master_production_schedule/master_production_schedule.js:65 msgid "View MRP" msgstr "" @@ -54105,7 +54394,7 @@ msgstr "" #: erpnext/accounts/report/general_and_payment_ledger_comparison/general_and_payment_ledger_comparison.js:42 #: erpnext/accounts/report/general_and_payment_ledger_comparison/general_and_payment_ledger_comparison.py:209 #: erpnext/accounts/report/general_ledger/general_ledger.js:49 -#: erpnext/accounts/report/general_ledger/general_ledger.py:735 +#: erpnext/accounts/report/general_ledger/general_ledger.py:742 #: erpnext/accounts/report/invalid_ledger_entries/invalid_ledger_entries.js:41 #: erpnext/accounts/report/invalid_ledger_entries/invalid_ledger_entries.py:33 #: erpnext/accounts/report/payment_ledger/payment_ledger.js:65 @@ -54127,7 +54416,7 @@ msgstr "" #: erpnext/stock/report/serial_and_batch_summary/serial_and_batch_summary.js:51 #: erpnext/stock/report/serial_and_batch_summary/serial_and_batch_summary.py:112 #: erpnext/stock/report/serial_no_ledger/serial_no_ledger.py:33 -#: erpnext/stock/report/stock_and_account_value_comparison/stock_and_account_value_comparison.py:117 +#: erpnext/stock/report/stock_and_account_value_comparison/stock_and_account_value_comparison.py:120 #: erpnext/stock/report/stock_ledger_invariant_check/stock_ledger_invariant_check.py:165 #: erpnext/stock/report/stock_ledger_variance/stock_ledger_variance.py:74 msgid "Voucher No" @@ -54145,7 +54434,7 @@ msgstr "" #. Label of the voucher_subtype (Small Text) field in DocType 'GL Entry' #: erpnext/accounts/doctype/gl_entry/gl_entry.json -#: erpnext/accounts/report/general_ledger/general_ledger.py:729 +#: erpnext/accounts/report/general_ledger/general_ledger.py:736 msgid "Voucher Subtype" msgstr "" @@ -54178,7 +54467,7 @@ msgstr "" #: erpnext/accounts/doctype/unreconcile_payment/unreconcile_payment.json #: erpnext/accounts/report/accounts_receivable/accounts_receivable.py:1194 #: erpnext/accounts/report/general_and_payment_ledger_comparison/general_and_payment_ledger_comparison.py:200 -#: erpnext/accounts/report/general_ledger/general_ledger.py:727 +#: erpnext/accounts/report/general_ledger/general_ledger.py:734 #: erpnext/accounts/report/invalid_ledger_entries/invalid_ledger_entries.py:31 #: erpnext/accounts/report/payment_ledger/payment_ledger.py:165 #: erpnext/accounts/report/purchase_register/purchase_register.py:158 @@ -54202,7 +54491,7 @@ msgstr "" #: erpnext/stock/report/serial_and_batch_summary/serial_and_batch_summary.py:107 #: erpnext/stock/report/serial_no_and_batch_traceability/serial_no_and_batch_traceability.py:482 #: erpnext/stock/report/serial_no_ledger/serial_no_ledger.py:27 -#: erpnext/stock/report/stock_and_account_value_comparison/stock_and_account_value_comparison.py:115 +#: erpnext/stock/report/stock_and_account_value_comparison/stock_and_account_value_comparison.py:118 #: erpnext/stock/report/stock_ledger/stock_ledger.py:321 #: erpnext/stock/report/stock_ledger_invariant_check/stock_ledger_invariant_check.py:159 #: erpnext/stock/report/stock_ledger_variance/stock_ledger_variance.py:68 @@ -54279,7 +54568,7 @@ msgstr "" msgid "Warehouse Capacity Summary" msgstr "" -#: erpnext/stock/doctype/putaway_rule/putaway_rule.py:78 +#: erpnext/stock/doctype/putaway_rule/putaway_rule.py:79 msgid "Warehouse Capacity for Item '{0}' must be greater than the existing stock level of {1} {2}." msgstr "" @@ -54356,7 +54645,7 @@ msgstr "" msgid "Warehouse and Reference" msgstr "مستودع والمراجع" -#: erpnext/stock/doctype/warehouse/warehouse.py:98 +#: erpnext/stock/doctype/warehouse/warehouse.py:100 msgid "Warehouse can not be deleted as stock ledger entry exists for this warehouse." msgstr "لا يمكن حذف مستودع كما دخول دفتر الأستاذ موجود لهذا المستودع.\\n
        \\nWarehouse can not be deleted as stock ledger entry exists for this warehouse." @@ -54364,16 +54653,16 @@ msgstr "لا يمكن حذف مستودع كما دخول دفتر الأستا msgid "Warehouse cannot be changed for Serial No." msgstr "المستودع لا يمكن ان يكون متغير لرقم تسلسلى.\\n
        \\nWarehouse cannot be changed for Serial No." -#: erpnext/controllers/sales_and_purchase_return.py:161 +#: erpnext/controllers/sales_and_purchase_return.py:160 msgid "Warehouse is mandatory" msgstr "المستودع إلزامي" -#: erpnext/stock/doctype/warehouse/warehouse.py:253 +#: erpnext/stock/doctype/warehouse/warehouse.py:259 msgid "Warehouse not found against the account {0}" msgstr "لم يتم العثور على المستودع مقابل الحساب {0}" -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1243 -#: erpnext/stock/doctype/delivery_note/delivery_note.py:428 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1192 +#: erpnext/stock/doctype/delivery_note/delivery_note.py:432 msgid "Warehouse required for stock Item {0}" msgstr "مستودع الأسهم المطلوبة لل تفاصيل {0}" @@ -54387,27 +54676,31 @@ msgstr "مستودع الحكيم البند الرصيد العمر والقي msgid "Warehouse wise Stock Value" msgstr "" -#: erpnext/stock/doctype/warehouse/warehouse.py:92 +#: erpnext/stock/doctype/warehouse/warehouse.py:94 msgid "Warehouse {0} can not be deleted as quantity exists for Item {1}" msgstr "مستودع {0} لا يمكن حذف كما توجد كمية القطعة ل {1}" -#: erpnext/stock/doctype/putaway_rule/putaway_rule.py:66 +#: erpnext/stock/doctype/putaway_rule/putaway_rule.py:67 msgid "Warehouse {0} does not belong to Company {1}." msgstr "" -#: erpnext/stock/utils.py:433 +#: erpnext/stock/utils.py:437 msgid "Warehouse {0} does not belong to company {1}" msgstr "مستودع {0} لا تنتمي إلى شركة {1}" -#: erpnext/manufacturing/doctype/work_order/work_order.py:233 +#: erpnext/stock/doctype/warehouse/warehouse.py:306 +msgid "Warehouse {0} does not exist" +msgstr "" + +#: erpnext/manufacturing/doctype/work_order/work_order.py:234 msgid "Warehouse {0} is not allowed for Sales Order {1}, it should be {2}" msgstr "" -#: erpnext/controllers/stock_controller.py:769 +#: erpnext/controllers/stock_controller.py:771 msgid "Warehouse {0} is not linked to any account, please mention the account in the warehouse record or set default inventory account in company {1}." msgstr "" -#: erpnext/stock/doctype/warehouse/warehouse.py:142 +#: erpnext/stock/doctype/warehouse/warehouse.py:144 msgid "Warehouse's Stock Value has already been booked in the following accounts:" msgstr "" @@ -54424,15 +54717,15 @@ msgstr "المستودع: {0} لا ينتمي إلى {1}" msgid "Warehouses" msgstr "المستودعات" -#: erpnext/stock/doctype/warehouse/warehouse.py:171 +#: erpnext/stock/doctype/warehouse/warehouse.py:173 msgid "Warehouses with child nodes cannot be converted to ledger" msgstr "المستودعات مع العقد التابعة لا يمكن أن يتم تحويلها إلى دفتر الاستاذ" -#: erpnext/stock/doctype/warehouse/warehouse.py:181 +#: erpnext/stock/doctype/warehouse/warehouse.py:183 msgid "Warehouses with existing transaction can not be converted to group." msgstr "لا يمكن تحويل المستودعات مع المعاملات الحالية إلى مجموعة.\\n
        \\nWarehouses with existing transaction can not be converted to group." -#: erpnext/stock/doctype/warehouse/warehouse.py:173 +#: erpnext/stock/doctype/warehouse/warehouse.py:175 msgid "Warehouses with existing transaction can not be converted to ledger." msgstr "المستودعات مع الصفقة الحالية لا يمكن أن يتم تحويلها إلى دفتر الأستاذ." @@ -54504,11 +54797,11 @@ msgstr "تحذير لأوامر الشراء الجديدة" msgid "Warn for new Request for Quotations" msgstr "تحذير لطلب جديد للاقتباسات" -#: erpnext/projects/doctype/timesheet_detail/timesheet_detail.py:124 +#: erpnext/projects/doctype/timesheet_detail/timesheet_detail.py:134 msgid "Warning - Row {0}: Billing Hours are more than Actual Hours" msgstr "" -#: erpnext/stock/stock_ledger.py:789 +#: erpnext/stock/stock_ledger.py:820 msgid "Warning on Negative Stock" msgstr "" @@ -54516,19 +54809,19 @@ msgstr "" msgid "Warning!" msgstr "" -#: erpnext/accounts/doctype/journal_entry/journal_entry.py:1375 +#: erpnext/accounts/doctype/journal_entry/journal_entry.py:1290 msgid "Warning: Another {0} # {1} exists against stock entry {2}" msgstr "تحذير: {0} أخر # {1} موجود في مدخل المخزن {2}\\n
        \\nWarning: Another {0} # {1} exists against stock entry {2}" -#: erpnext/stock/doctype/material_request/material_request.js:520 +#: erpnext/stock/doctype/material_request/material_request.js:542 msgid "Warning: Material Requested Qty is less than Minimum Order Qty" msgstr "تحذير : كمية المواد المطلوبة هي أقل من الحد الأدنى للطلب الكمية" -#: erpnext/manufacturing/doctype/work_order/work_order.py:1431 +#: erpnext/manufacturing/doctype/work_order/work_order.py:1435 msgid "Warning: Quantity exceeds maximum producible quantity based on quantity of raw materials received through the Subcontracting Inward Order {0}." msgstr "" -#: erpnext/selling/doctype/sales_order/sales_order.py:333 +#: erpnext/selling/doctype/sales_order/sales_order.py:335 msgid "Warning: Sales Order {0} already exists against Customer's Purchase Order {1}" msgstr "تحذير: أمر البيع {0} موجود مسبقاً لأمر الشراء الخاص بالعميل {1}\\n
        \\nWarning: Sales Order {0} already exists against Customer's Purchase Order {1}" @@ -54642,8 +54935,8 @@ msgstr "مجموعة الأصناف للموقع" msgid "Website Specifications" msgstr "موقع المواصفات" -#: erpnext/accounts/letterhead/company_letterhead.html:89 -#: erpnext/accounts/letterhead/company_letterhead_grey.html:105 +#: erpnext/accounts/letterhead/company_letterhead.html:91 +#: erpnext/accounts/letterhead/company_letterhead_grey.html:109 msgid "Website:" msgstr "الموقع:" @@ -54762,15 +55055,15 @@ msgstr "عجلات" msgid "When a parent warehouse is chosen, the system conducts Project Qty checks against the associated child warehouses" msgstr "" -#: erpnext/stock/doctype/item/item.js:1053 +#: erpnext/stock/doctype/item/item.js:1072 msgid "When creating an Item, entering a value for this field will automatically create an Item Price at the backend." msgstr "" -#: erpnext/accounts/doctype/account/account.py:378 +#: erpnext/accounts/doctype/account/account.py:380 msgid "While creating account for Child Company {0}, parent account {1} found as a ledger account." msgstr "أثناء إنشاء حساب الشركة الفرعية {0} ، تم العثور على الحساب الرئيسي {1} كحساب دفتر أستاذ." -#: erpnext/accounts/doctype/account/account.py:368 +#: erpnext/accounts/doctype/account/account.py:370 msgid "While creating account for Child Company {0}, parent account {1} not found. Please create the parent account in corresponding COA" msgstr "أثناء إنشاء حساب Child Company {0} ، لم يتم العثور على الحساب الرئيسي {1}. الرجاء إنشاء الحساب الرئيسي في شهادة توثيق البرامج المقابلة" @@ -54848,15 +55141,11 @@ msgstr "العمل المنجز" #: erpnext/assets/doctype/asset/asset_list.js:12 #: erpnext/manufacturing/doctype/job_card/job_card.json #: erpnext/manufacturing/doctype/job_card_operation/job_card_operation.json -#: erpnext/setup/doctype/company/company.py:340 +#: erpnext/setup/doctype/company/company.py:376 #: erpnext/support/doctype/warranty_claim/warranty_claim.json msgid "Work In Progress" msgstr "التقدم في العمل" -#: erpnext/manufacturing/doctype/manufacturing_settings/manufacturing_settings.js:23 -msgid "Work In Progress Warehouse" -msgstr "مستودع قيد الإنجاز" - #. Option for the 'Transfer Material Against' (Select) field in DocType 'BOM' #. Label of the work_order (Link) field in DocType 'Job Card' #. Name of a DocType @@ -54872,7 +55161,7 @@ msgstr "مستودع قيد الإنجاز" #. Entry' #. Option for the 'From Voucher Type' (Select) field in DocType 'Stock #. Reservation Entry' -#: erpnext/manufacturing/doctype/bom/bom.js:188 +#: erpnext/manufacturing/doctype/bom/bom.js:189 #: erpnext/manufacturing/doctype/bom/bom.json #: erpnext/manufacturing/doctype/job_card/job_card.json #: erpnext/manufacturing/doctype/work_order/work_order.json @@ -54886,10 +55175,10 @@ msgstr "مستودع قيد الإنجاز" #: erpnext/manufacturing/report/work_order_consumed_materials/work_order_consumed_materials.js:29 #: erpnext/manufacturing/report/work_order_stock_report/work_order_stock_report.py:104 #: erpnext/manufacturing/workspace/manufacturing/manufacturing.json -#: erpnext/selling/doctype/sales_order/sales_order.js:1046 -#: erpnext/stock/doctype/material_request/material_request.js:201 +#: erpnext/selling/doctype/sales_order/sales_order.js:1050 +#: erpnext/stock/doctype/material_request/material_request.js:202 #: erpnext/stock/doctype/material_request/material_request.json -#: erpnext/stock/doctype/material_request/material_request.py:891 +#: erpnext/stock/doctype/material_request/material_request.py:898 #: erpnext/stock/doctype/pick_list/pick_list.json #: erpnext/stock/doctype/serial_no/serial_no.json #: erpnext/stock/doctype/stock_entry/stock_entry.json @@ -54949,20 +55238,20 @@ msgstr "تقرير مخزون أمر العمل" msgid "Work Order Summary" msgstr "ملخص أمر العمل" -#: erpnext/stock/doctype/material_request/material_request.py:897 +#: erpnext/stock/doctype/material_request/material_request.py:904 msgid "Work Order cannot be created for following reason:
        {0}" msgstr "لا يمكن إنشاء أمر العمل للسبب التالي:
        {0}" -#: erpnext/manufacturing/doctype/work_order/work_order.py:1375 +#: erpnext/manufacturing/doctype/work_order/work_order.py:1379 msgid "Work Order cannot be raised against a Item Template" msgstr "لا يمكن رفع أمر العمل مقابل قالب العنصر" -#: erpnext/manufacturing/doctype/work_order/work_order.py:2345 -#: erpnext/manufacturing/doctype/work_order/work_order.py:2425 +#: erpnext/manufacturing/doctype/work_order/work_order.py:2386 +#: erpnext/manufacturing/doctype/work_order/work_order.py:2466 msgid "Work Order has been {0}" msgstr "تم عمل الطلب {0}" -#: erpnext/selling/doctype/sales_order/sales_order.js:1221 +#: erpnext/selling/doctype/sales_order/sales_order.js:1225 msgid "Work Order not created" msgstr "أمر العمل لم يتم إنشاؤه" @@ -54970,16 +55259,16 @@ msgstr "أمر العمل لم يتم إنشاؤه" msgid "Work Order {0} created" msgstr "" -#: erpnext/stock/doctype/stock_entry/stock_entry.py:745 +#: erpnext/stock/doctype/stock_entry/stock_entry.py:813 msgid "Work Order {0}: Job Card not found for the operation {1}" msgstr "أمر العمل {0}: لم يتم العثور على بطاقة المهمة للعملية {1}" #: erpnext/manufacturing/report/job_card_summary/job_card_summary.js:56 -#: erpnext/stock/doctype/material_request/material_request.py:885 +#: erpnext/stock/doctype/material_request/material_request.py:892 msgid "Work Orders" msgstr "طلبات العمل" -#: erpnext/selling/doctype/sales_order/sales_order.js:1306 +#: erpnext/selling/doctype/sales_order/sales_order.js:1310 msgid "Work Orders Created: {0}" msgstr "أوامر العمل التي تم إنشاؤها: {0}" @@ -55000,7 +55289,7 @@ msgstr "التقدم في العمل" msgid "Work-in-Progress Warehouse" msgstr "مستودع العمل قيد التنفيذ" -#: erpnext/manufacturing/doctype/work_order/work_order.py:739 +#: erpnext/manufacturing/doctype/work_order/work_order.py:740 msgid "Work-in-Progress Warehouse is required before Submit" msgstr "مستودع أعمال جارية مطلوب قبل التسجيل\\n
        \\nWork-in-Progress Warehouse is required before Submit" @@ -55045,7 +55334,7 @@ msgstr "ساعات العمل" #: erpnext/manufacturing/doctype/bom_operation/bom_operation.json #: erpnext/manufacturing/doctype/bom_website_operation/bom_website_operation.json #: erpnext/manufacturing/doctype/job_card/job_card.json -#: erpnext/manufacturing/doctype/work_order/work_order.js:319 +#: erpnext/manufacturing/doctype/work_order/work_order.js:326 #: erpnext/manufacturing/doctype/work_order_operation/work_order_operation.json #: erpnext/manufacturing/doctype/workstation/workstation.json #: erpnext/manufacturing/report/bom_operations_time/bom_operations_time.js:35 @@ -55137,7 +55426,7 @@ msgstr "" #: erpnext/accounts/doctype/pos_invoice/pos_invoice.json #: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json #: erpnext/accounts/doctype/sales_invoice/sales_invoice.json -#: erpnext/setup/doctype/company/company.py:617 +#: erpnext/setup/doctype/company/company.py:658 msgid "Write Off" msgstr "لا تصلح" @@ -55240,7 +55529,7 @@ msgstr "القيمة المكتوبة" msgid "Wrong Company" msgstr "" -#: erpnext/setup/doctype/company/company.js:226 +#: erpnext/setup/doctype/company/company.js:233 msgid "Wrong Password" msgstr "كلمة مرور خاطئة\\n
        \\nWrong Password" @@ -55287,19 +55576,19 @@ msgstr "تاريخ البدء أو تاريخ الانتهاء العام يتد msgid "You are importing data for the code list:" msgstr "" -#: erpnext/controllers/accounts_controller.py:3773 +#: erpnext/controllers/accounts_controller.py:3846 msgid "You are not allowed to update as per the conditions set in {} Workflow." msgstr "غير مسموح لك بالتحديث وفقًا للشروط المحددة في {} سير العمل." -#: erpnext/accounts/general_ledger.py:786 +#: erpnext/accounts/general_ledger.py:793 msgid "You are not authorized to add or update entries before {0}" msgstr "غير مصرح لك باضافه إدخالات أو تحديثها قبل {0}\\n
        \\nYou are not authorized to add or update entries before {0}" -#: erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py:334 +#: erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py:338 msgid "You are not authorized to make/edit Stock Transactions for Item {0} under warehouse {1} before this time." msgstr "" -#: erpnext/accounts/doctype/account/account.py:310 +#: erpnext/accounts/doctype/account/account.py:312 msgid "You are not authorized to set Frozen value" msgstr ".أنت غير مخول لتغيير القيم المجمدة" @@ -55307,7 +55596,7 @@ msgstr ".أنت غير مخول لتغيير القيم المجمدة" msgid "You are picking more than required quantity for the item {0}. Check if there is any other pick list created for the sales order {1}." msgstr "" -#: erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.py:112 +#: erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.py:111 msgid "You can add the original invoice {} manually to proceed." msgstr "" @@ -55319,11 +55608,11 @@ msgstr "يمكنك أيضا نسخ - لصق هذا الرابط في متصفح msgid "You can also set default CWIP account in Company {}" msgstr "يمكنك أيضًا تعيين حساب CWIP الافتراضي في الشركة {}" -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1041 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:990 msgid "You can change the parent account to a Balance Sheet account or select a different account." msgstr "يمكنك تغيير الحساب الرئيسي إلى حساب الميزانية العمومية أو تحديد حساب مختلف." -#: erpnext/accounts/doctype/journal_entry/journal_entry.py:766 +#: erpnext/accounts/doctype/journal_entry/journal_entry.py:681 msgid "You can not enter current voucher in 'Against Journal Entry' column" msgstr "لا يمكنك إدخال القسيمة الحالية في عمود 'قيد اليومية المقابل'.\\n
        \\nYou can not enter current voucher in 'Against Journal Entry' column" @@ -55332,7 +55621,7 @@ msgid "You can only have Plans with the same billing cycle in a Subscription" msgstr "يمكنك فقط الحصول على خطط مع دورة الفواتير نفسها في الاشتراك" #: erpnext/accounts/doctype/pos_invoice/pos_invoice.js:423 -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.js:909 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.js:910 msgid "You can only redeem max {0} points in this order." msgstr "لا يمكنك استرداد سوى {0} نقاط كحد أقصى بهذا الترتيب." @@ -55348,7 +55637,7 @@ msgstr "يمكنك استرداد ما يصل إلى {0}." msgid "You can set it as a machine name or operation type. For example, stiching machine 12" msgstr "" -#: erpnext/manufacturing/doctype/job_card/job_card.py:1184 +#: erpnext/manufacturing/doctype/job_card/job_card.py:1211 msgid "You can't make any changes to Job Card since Work Order is closed." msgstr "" @@ -55360,7 +55649,7 @@ msgstr "" msgid "You can't redeem Loyalty Points having more value than the Total Amount." msgstr "" -#: erpnext/manufacturing/doctype/bom/bom.js:681 +#: erpnext/manufacturing/doctype/bom/bom.js:698 msgid "You cannot change the rate if BOM is mentioned against any Item." msgstr "" @@ -55372,11 +55661,11 @@ msgstr "" msgid "You cannot create or cancel any accounting entries with in the closed Accounting Period {0}" msgstr "لا يمكنك إنشاء أو إلغاء أي قيود محاسبية في فترة المحاسبة المغلقة {0}" -#: erpnext/accounts/general_ledger.py:806 +#: erpnext/accounts/general_ledger.py:813 msgid "You cannot create/amend any accounting entries till this date." msgstr "" -#: erpnext/accounts/doctype/journal_entry/journal_entry.py:999 +#: erpnext/accounts/doctype/journal_entry/journal_entry.py:914 msgid "You cannot credit and debit same account at the same time" msgstr "لا يمكن إعطاء الحساب قيمة مدين وقيمة دائن في نفس الوقت" @@ -55388,7 +55677,7 @@ msgstr "لا يمكنك حذف مشروع من نوع 'خارجي'" msgid "You cannot edit root node." msgstr "لا يمكنك تحرير عقدة الجذر." -#: erpnext/accounts/doctype/accounts_settings/accounts_settings.py:153 +#: erpnext/accounts/doctype/accounts_settings/accounts_settings.py:144 msgid "You cannot enable both the settings '{0}' and '{1}'." msgstr "" @@ -55396,7 +55685,7 @@ msgstr "" msgid "You cannot redeem more than {0}." msgstr "لا يمكنك استرداد أكثر من {0}." -#: erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py:171 +#: erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py:183 msgid "You cannot repost item valuation before {}" msgstr "" @@ -55416,7 +55705,7 @@ msgstr "لا يمكنك تقديم الطلب بدون دفع." msgid "You cannot {0} this document because another Period Closing Entry {1} exists after {2}" msgstr "" -#: erpnext/controllers/accounts_controller.py:3749 +#: erpnext/controllers/accounts_controller.py:3822 msgid "You do not have permissions to {} items in a {}." msgstr "ليس لديك أذونات لـ {} من العناصر في {}." @@ -55428,7 +55717,7 @@ msgstr "ليس لديك ما يكفي من نقاط الولاء لاستردا msgid "You don't have enough points to redeem." msgstr "ليس لديك ما يكفي من النقاط لاستردادها." -#: erpnext/accounts/doctype/opening_invoice_creation_tool/opening_invoice_creation_tool.py:270 +#: erpnext/accounts/doctype/opening_invoice_creation_tool/opening_invoice_creation_tool.py:273 msgid "You had {} errors while creating opening invoices. Check {} for more details" msgstr "كان لديك {} من الأخطاء أثناء إنشاء الفواتير الافتتاحية. تحقق من {} لمزيد من التفاصيل" @@ -55436,7 +55725,7 @@ msgstr "كان لديك {} من الأخطاء أثناء إنشاء الفوا msgid "You have already selected items from {0} {1}" msgstr "لقد حددت العناصر من {0} {1}" -#: erpnext/projects/doctype/project/project.py:361 +#: erpnext/projects/doctype/project/project.py:363 msgid "You have been invited to collaborate on the project {0}." msgstr "" @@ -55452,7 +55741,7 @@ msgstr "" msgid "You have entered a duplicate Delivery Note on Row" msgstr "" -#: erpnext/stock/doctype/item/item.py:1058 +#: erpnext/stock/doctype/item/item.py:1061 msgid "You have to enable auto re-order in Stock Settings to maintain re-order levels." msgstr "يجب عليك تمكين الطلب التلقائي في إعدادات الأسهم للحفاظ على مستويات إعادة الطلب." @@ -55464,11 +55753,11 @@ msgstr "" msgid "You must select a customer before adding an item." msgstr "يجب عليك تحديد عميل قبل إضافة عنصر." -#: erpnext/accounts/doctype/pos_invoice/pos_invoice.py:268 +#: erpnext/accounts/doctype/pos_invoice/pos_invoice.py:278 msgid "You need to cancel POS Closing Entry {} to be able to cancel this document." msgstr "" -#: erpnext/controllers/accounts_controller.py:3131 +#: erpnext/controllers/accounts_controller.py:3204 msgid "You selected the account group {1} as {2} Account in row {0}. Please select a single account." msgstr "" @@ -55519,7 +55808,7 @@ msgstr "" msgid "Zero Rated" msgstr "" -#: erpnext/stock/doctype/stock_entry/stock_entry.py:461 +#: erpnext/stock/doctype/stock_entry/stock_entry.py:524 msgid "Zero quantity" msgstr "" @@ -55528,15 +55817,15 @@ msgstr "" msgid "Zip File" msgstr "ملف مضغوط" -#: erpnext/stock/reorder_item.py:374 +#: erpnext/stock/reorder_item.py:382 msgid "[Important] [ERPNext] Auto Reorder Errors" msgstr "[هام] [ERPNext] إعادة ترتيب الأخطاء تلقائيًا" -#: erpnext/controllers/status_updater.py:285 +#: erpnext/controllers/status_updater.py:287 msgid "`Allow Negative rates for Items`" msgstr "" -#: erpnext/stock/stock_ledger.py:2004 +#: erpnext/stock/stock_ledger.py:2041 msgid "after" msgstr "" @@ -55552,7 +55841,7 @@ msgstr "" msgid "as Title" msgstr "" -#: erpnext/manufacturing/doctype/bom/bom.js:949 +#: erpnext/manufacturing/doctype/bom/bom.js:966 msgid "as a percentage of finished item quantity" msgstr "" @@ -55568,12 +55857,12 @@ msgstr "مرتكز على" msgid "by {}" msgstr "" -#: erpnext/public/js/utils/sales_common.js:314 +#: erpnext/public/js/utils/sales_common.js:336 msgid "cannot be greater than 100" msgstr "" -#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:332 -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1129 +#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:334 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1078 msgid "dated {0}" msgstr "" @@ -55621,14 +55910,14 @@ msgstr "مثال:شحن اليوم التالي" msgid "exchangerate.host" msgstr "" -#: erpnext/crm/report/sales_pipeline_analytics/sales_pipeline_analytics.py:171 +#: erpnext/crm/report/sales_pipeline_analytics/sales_pipeline_analytics.py:184 msgid "fieldname" msgstr "" #. Option for the 'Service Provider' (Select) field in DocType 'Currency #. Exchange Settings' #: erpnext/accounts/doctype/currency_exchange_settings/currency_exchange_settings.json -msgid "frankfurter.app" +msgid "frankfurter.dev" msgstr "" #: erpnext/templates/form_grid/item_grid.html:66 @@ -55676,7 +55965,7 @@ msgstr "LFT" msgid "material_request_item" msgstr "" -#: erpnext/controllers/selling_controller.py:195 +#: erpnext/controllers/selling_controller.py:217 msgid "must be between 0 and 100" msgstr "" @@ -55722,7 +56011,7 @@ msgstr "" msgid "per hour" msgstr "كل ساعة" -#: erpnext/stock/stock_ledger.py:2005 +#: erpnext/stock/stock_ledger.py:2042 msgid "performing either one below:" msgstr "" @@ -55751,7 +56040,7 @@ msgstr "" msgid "received from" msgstr "مستلم من" -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1450 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1399 msgid "returned" msgstr "تم إرجاعه" @@ -55786,7 +56075,7 @@ msgstr "RGT" msgid "sandbox" msgstr "رمل" -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1450 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1399 msgid "sold" msgstr "تم البيع" @@ -55794,8 +56083,8 @@ msgstr "تم البيع" msgid "subscription is already cancelled." msgstr "" -#: erpnext/controllers/status_updater.py:450 -#: erpnext/controllers/status_updater.py:470 +#: erpnext/controllers/status_updater.py:452 +#: erpnext/controllers/status_updater.py:472 msgid "target_ref_field" msgstr "" @@ -55813,7 +56102,7 @@ msgstr "عنوان" msgid "to" msgstr "إلى" -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:3186 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:3086 msgid "to unallocate the amount of this Return Invoice before cancelling it." msgstr "" @@ -55840,7 +56129,7 @@ msgstr "" msgid "you must select Capital Work in Progress Account in accounts table" msgstr "يجب عليك تحديد حساب رأس المال قيد التقدم في جدول الحسابات" -#: erpnext/controllers/accounts_controller.py:1210 +#: erpnext/controllers/accounts_controller.py:1279 msgid "{0} '{1}' is disabled" msgstr "{0} '{1}' معطل" @@ -55848,7 +56137,7 @@ msgstr "{0} '{1}' معطل" msgid "{0} '{1}' not in Fiscal Year {2}" msgstr "{0} '{1}' ليس في السنة المالية {2}" -#: erpnext/manufacturing/doctype/work_order/work_order.py:631 +#: erpnext/manufacturing/doctype/work_order/work_order.py:632 msgid "{0} ({1}) cannot be greater than planned quantity ({2}) in Work Order {3}" msgstr "{0} ({1}) لا يمكن أن يكون أكبر من الكمية المخطط لها ({2}) في أمر العمل {3}" @@ -55856,7 +56145,7 @@ msgstr "{0} ({1}) لا يمكن أن يكون أكبر من الكمية الم msgid "{0} {1} has submitted Assets. Remove Item {2} from table to continue." msgstr "" -#: erpnext/controllers/accounts_controller.py:2291 +#: erpnext/controllers/accounts_controller.py:2364 msgid "{0} Account not found against Customer {1}." msgstr "" @@ -55864,15 +56153,15 @@ msgstr "" msgid "{0} Account: {1} ({2}) must be in either customer billing currency: {3} or Company default currency: {4}" msgstr "" -#: erpnext/accounts/doctype/budget/budget.py:276 +#: erpnext/accounts/doctype/budget/budget.py:547 msgid "{0} Budget for Account {1} against {2} {3} is {4}. It is already exceeded by {5}." msgstr "" -#: erpnext/accounts/doctype/budget/budget.py:279 +#: erpnext/accounts/doctype/budget/budget.py:550 msgid "{0} Budget for Account {1} against {2} {3} is {4}. It will be exceeded by {5}." msgstr "" -#: erpnext/accounts/doctype/pricing_rule/utils.py:767 +#: erpnext/accounts/doctype/pricing_rule/utils.py:770 msgid "{0} Coupon used are {1}. Allowed quantity is exhausted" msgstr "{0} القسيمة المستخدمة هي {1}. الكمية المسموح بها مستنفدة" @@ -55880,23 +56169,23 @@ msgstr "{0} القسيمة المستخدمة هي {1}. الكمية المسم msgid "{0} Digest" msgstr "{0} الملخص" -#: erpnext/accounts/utils.py:1437 +#: erpnext/accounts/utils.py:1444 msgid "{0} Number {1} is already used in {2} {3}" msgstr "{0} الرقم {1} مستخدم بالفعل في {2} {3}" -#: erpnext/manufacturing/doctype/bom/bom.py:1511 +#: erpnext/manufacturing/doctype/bom/bom.py:1548 msgid "{0} Operating Cost for operation {1}" msgstr "" -#: erpnext/manufacturing/doctype/work_order/work_order.js:518 +#: erpnext/manufacturing/doctype/work_order/work_order.js:528 msgid "{0} Operations: {1}" msgstr "{0} العمليات: {1}" -#: erpnext/stock/doctype/material_request/material_request.py:219 +#: erpnext/stock/doctype/material_request/material_request.py:220 msgid "{0} Request for {1}" msgstr "{0} طلب {1}" -#: erpnext/stock/doctype/item/item.py:322 +#: erpnext/stock/doctype/item/item.py:323 msgid "{0} Retain Sample is based on batch, please check Has Batch No to retain sample of item" msgstr "{0} يعتمد الاحتفاظ بالعينة على الدُفعة ، يُرجى تحديد "رقم الدُفعة" للاحتفاظ بعينة من العنصر" @@ -55912,23 +56201,23 @@ msgstr "" msgid "{0} account is not of type {1}" msgstr "" -#: erpnext/stock/doctype/purchase_receipt/purchase_receipt.py:499 +#: erpnext/stock/doctype/purchase_receipt/purchase_receipt.py:514 msgid "{0} account not found while submitting purchase receipt" msgstr "" -#: erpnext/accounts/doctype/journal_entry/journal_entry.py:1119 +#: erpnext/accounts/doctype/journal_entry/journal_entry.py:1034 msgid "{0} against Bill {1} dated {2}" msgstr "{0} مقابل الفاتورة {1} بتاريخ {2}" -#: erpnext/accounts/doctype/journal_entry/journal_entry.py:1128 +#: erpnext/accounts/doctype/journal_entry/journal_entry.py:1043 msgid "{0} against Purchase Order {1}" msgstr "{0} مقابل أمر الشراء {1}" -#: erpnext/accounts/doctype/journal_entry/journal_entry.py:1095 +#: erpnext/accounts/doctype/journal_entry/journal_entry.py:1010 msgid "{0} against Sales Invoice {1}" msgstr "{0} مقابل فاتورة المبيعات {1}" -#: erpnext/accounts/doctype/journal_entry/journal_entry.py:1102 +#: erpnext/accounts/doctype/journal_entry/journal_entry.py:1017 msgid "{0} against Sales Order {1}" msgstr "{0} مقابل طلب مبيعات {1}" @@ -55963,15 +56252,19 @@ msgstr "" #: erpnext/manufacturing/doctype/production_plan/production_plan.py:897 #: erpnext/manufacturing/doctype/production_plan/production_plan.py:1013 -#: erpnext/subcontracting/doctype/subcontracting_inward_order/subcontracting_inward_order.py:318 +#: erpnext/subcontracting/doctype/subcontracting_inward_order/subcontracting_inward_order.py:322 msgid "{0} created" msgstr "{0} تم انشاؤه" -#: erpnext/setup/doctype/company/company.py:247 +#: erpnext/utilities/bulk_transaction.py:31 +msgid "{0} creation for the following records will be skipped." +msgstr "" + +#: erpnext/setup/doctype/company/company.py:283 msgid "{0} currency must be same as company's default currency. Please select another account." msgstr "" -#: erpnext/buying/doctype/purchase_order/purchase_order.py:330 +#: erpnext/buying/doctype/purchase_order/purchase_order.py:332 msgid "{0} currently has a {1} Supplier Scorecard standing, and Purchase Orders to this supplier should be issued with caution." msgstr "{0} لديها حاليا {1} بطاقة أداء بطاقة الموردين، ويجب إصدار أوامر الشراء إلى هذا المورد بحذر." @@ -55983,12 +56276,16 @@ msgstr "{0} لديه حاليا {1} بطاقة أداء بطاقة المورد msgid "{0} does not belong to Company {1}" msgstr "{0} لا تنتمي إلى شركة {1}" +#: erpnext/controllers/accounts_controller.py:352 +msgid "{0} does not belong to the Company {1}." +msgstr "" + #: erpnext/accounts/doctype/item_tax_template/item_tax_template.py:67 msgid "{0} entered twice in Item Tax" msgstr "{0} ادخل مرتين في ضريبة البند" #: erpnext/setup/doctype/item_group/item_group.py:48 -#: erpnext/stock/doctype/item/item.py:435 +#: erpnext/stock/doctype/item/item.py:454 msgid "{0} entered twice {1} in Item Taxes" msgstr "" @@ -56001,6 +56298,10 @@ msgstr "{0} ل {1}" msgid "{0} has Payment Term based allocation enabled. Select a Payment Term for Row #{1} in Payment References section" msgstr "" +#: erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py:773 +msgid "{0} has been modified after you pulled it. Please pull it again." +msgstr "" + #: erpnext/setup/default_success_action.py:15 msgid "{0} has been submitted successfully" msgstr "{0} تم التقديم بنجاح" @@ -56009,7 +56310,7 @@ msgstr "{0} تم التقديم بنجاح" msgid "{0} hours" msgstr "" -#: erpnext/controllers/accounts_controller.py:2644 +#: erpnext/controllers/accounts_controller.py:2717 msgid "{0} in row {1}" msgstr "{0} في الحقل {1}" @@ -56019,7 +56320,7 @@ msgstr "" #: erpnext/accounts/doctype/pos_closing_entry/pos_closing_entry.py:100 #: erpnext/accounts/doctype/pos_closing_entry/pos_closing_entry.py:153 -#: erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.py:61 +#: erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.py:60 msgid "{0} is added multiple times on rows: {1}" msgstr "" @@ -56027,16 +56328,20 @@ msgstr "" msgid "{0} is already running for {1}" msgstr "" -#: erpnext/controllers/accounts_controller.py:166 +#: erpnext/controllers/accounts_controller.py:172 msgid "{0} is blocked so this transaction cannot proceed" msgstr "تم حظر {0} حتى لا تتم متابعة هذه المعاملة" -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1158 +#: erpnext/assets/doctype/asset/asset.py:438 +msgid "{0} is in Draft. Submit it before creating the Asset." +msgstr "" + +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1107 msgid "{0} is mandatory for Item {1}" msgstr "{0} إلزامي للصنف {1}\\n
        \\n{0} is mandatory for Item {1}" #: erpnext/accounts/doctype/payment_ledger_entry/payment_ledger_entry.py:99 -#: erpnext/accounts/general_ledger.py:830 +#: erpnext/accounts/general_ledger.py:837 msgid "{0} is mandatory for account {1}" msgstr "" @@ -56044,11 +56349,11 @@ msgstr "" msgid "{0} is mandatory. Maybe Currency Exchange record is not created for {1} to {2}" msgstr "{0} إلزامي. ربما لم يتم إنشاء سجل صرف العملات من {1} إلى {2}" -#: erpnext/controllers/accounts_controller.py:3088 +#: erpnext/controllers/accounts_controller.py:3161 msgid "{0} is mandatory. Maybe Currency Exchange record is not created for {1} to {2}." msgstr "{0} إلزامي. ربما لم يتم إنشاء سجل سعر صرف العملة ل{1} إلى {2}." -#: erpnext/selling/doctype/customer/customer.py:203 +#: erpnext/selling/doctype/customer/customer.py:204 msgid "{0} is not a company bank account" msgstr "{0} ليس حسابًا مصرفيًا للشركة" @@ -56056,7 +56361,7 @@ msgstr "{0} ليس حسابًا مصرفيًا للشركة" msgid "{0} is not a group node. Please select a group node as parent cost center" msgstr "{0} ليست عقدة مجموعة. يرجى تحديد عقدة المجموعة كمركز تكلفة الأصل" -#: erpnext/stock/doctype/stock_entry/stock_entry.py:512 +#: erpnext/stock/doctype/stock_entry/stock_entry.py:576 msgid "{0} is not a stock Item" msgstr "{0} ليس من نوع المخزون" @@ -56076,11 +56381,11 @@ msgstr "{0} غير ممكّن في {1}" msgid "{0} is not running. Cannot trigger events for this Document" msgstr "" -#: erpnext/stock/doctype/material_request/material_request.py:647 +#: erpnext/stock/doctype/material_request/material_request.py:651 msgid "{0} is not the default supplier for any items." msgstr "{0} ليس المورد الافتراضي لأية عناصر." -#: erpnext/accounts/doctype/payment_entry/payment_entry.py:3014 +#: erpnext/accounts/doctype/payment_entry/payment_entry.py:3015 msgid "{0} is on hold till {1}" msgstr "{0} معلق حتى {1}" @@ -56088,35 +56393,27 @@ msgstr "{0} معلق حتى {1}" msgid "{0} is open. Close the POS or cancel the existing POS Opening Entry to create a new POS Opening Entry." msgstr "" -#: erpnext/assets/doctype/asset_repair/asset_repair.py:95 -msgid "{0} is still in Draft. Please submit it before saving the Asset Repair." -msgstr "" - -#: erpnext/assets/doctype/asset/asset.py:435 -msgid "{0} is still in Draft. Please submit it before saving the Asset." -msgstr "" - -#: erpnext/manufacturing/doctype/work_order/work_order.js:473 +#: erpnext/manufacturing/doctype/work_order/work_order.js:483 msgid "{0} items in progress" msgstr "{0} العنصر قيد الأستخدام" -#: erpnext/manufacturing/doctype/work_order/work_order.js:484 +#: erpnext/manufacturing/doctype/work_order/work_order.js:494 msgid "{0} items lost during process." msgstr "" -#: erpnext/manufacturing/doctype/work_order/work_order.js:454 +#: erpnext/manufacturing/doctype/work_order/work_order.js:464 msgid "{0} items produced" msgstr "{0} عناصر منتجة" -#: erpnext/controllers/sales_and_purchase_return.py:219 +#: erpnext/controllers/sales_and_purchase_return.py:218 msgid "{0} must be negative in return document" msgstr "{0} يجب أن يكون سالبة في وثيقة الارجاع" -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:2337 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:2290 msgid "{0} not allowed to transact with {1}. Please change the Company or add the Company in the 'Allowed To Transact With'-Section in the Customer record." msgstr "" -#: erpnext/manufacturing/doctype/bom/bom.py:499 +#: erpnext/manufacturing/doctype/bom/bom.py:510 msgid "{0} not found for item {1}" msgstr "{0} لم يتم العثور على العنصر {1}" @@ -56128,7 +56425,7 @@ msgstr "{0} المعلمة غير صالحة" msgid "{0} payment entries can not be filtered by {1}" msgstr "{0} لا يمكن فلترة المدفوعات المدخلة {1}" -#: erpnext/controllers/stock_controller.py:1571 +#: erpnext/controllers/stock_controller.py:1680 msgid "{0} qty of Item {1} is being received into Warehouse {2} with capacity {3}." msgstr "" @@ -56136,28 +56433,28 @@ msgstr "" msgid "{0} units are reserved for Item {1} in Warehouse {2}, please un-reserve the same to {3} the Stock Reconciliation." msgstr "" -#: erpnext/stock/doctype/pick_list/pick_list.py:1006 +#: erpnext/stock/doctype/pick_list/pick_list.py:1013 msgid "{0} units of Item {1} is not available in any of the warehouses." msgstr "" -#: erpnext/stock/doctype/pick_list/pick_list.py:998 +#: erpnext/stock/doctype/pick_list/pick_list.py:1005 msgid "{0} units of Item {1} is picked in another Pick List." msgstr "" -#: erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py:142 -msgid "{0} units of {1} are required in {2} with the inventory dimension: {3} ({4}) on {5} {6} for {7} to complete the transaction." +#: erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py:145 +msgid "{0} units of {1} are required in {2} with the inventory dimension: {3} on {4} {5} for {6} to complete the transaction." msgstr "" -#: erpnext/stock/stock_ledger.py:1652 erpnext/stock/stock_ledger.py:2156 -#: erpnext/stock/stock_ledger.py:2170 +#: erpnext/stock/stock_ledger.py:1687 erpnext/stock/stock_ledger.py:2193 +#: erpnext/stock/stock_ledger.py:2207 msgid "{0} units of {1} needed in {2} on {3} {4} for {5} to complete this transaction." msgstr "{0} وحدات من {1} لازمة ل {2} في {3} {4} ل {5} لإكمال هذه المعاملة." -#: erpnext/stock/stock_ledger.py:2257 erpnext/stock/stock_ledger.py:2302 +#: erpnext/stock/stock_ledger.py:2294 erpnext/stock/stock_ledger.py:2339 msgid "{0} units of {1} needed in {2} on {3} {4} to complete this transaction." msgstr "" -#: erpnext/stock/stock_ledger.py:1646 +#: erpnext/stock/stock_ledger.py:1681 msgid "{0} units of {1} needed in {2} to complete this transaction." msgstr "{0} وحدات من {1} لازمة في {2} لإكمال هذه المعاملة." @@ -56165,11 +56462,11 @@ msgstr "{0} وحدات من {1} لازمة في {2} لإكمال هذه الم msgid "{0} until {1}" msgstr "" -#: erpnext/stock/utils.py:424 +#: erpnext/stock/utils.py:428 msgid "{0} valid serial nos for Item {1}" msgstr "{0} أرقام تسلسلية صالحة للبند {1}" -#: erpnext/stock/doctype/item/item.js:731 +#: erpnext/stock/doctype/item/item.js:750 msgid "{0} variants created." msgstr "تم إنشاء المتغيرات {0}." @@ -56185,7 +56482,7 @@ msgstr "" msgid "{0} will be set as the {1} in subsequently scanned items" msgstr "" -#: erpnext/manufacturing/doctype/job_card/job_card.py:889 +#: erpnext/manufacturing/doctype/job_card/job_card.py:884 msgid "{0} {1}" msgstr "" @@ -56207,7 +56504,7 @@ msgstr "{0} {1} إنشاء" #: erpnext/accounts/doctype/payment_entry/payment_entry.py:607 #: erpnext/accounts/doctype/payment_entry/payment_entry.py:660 -#: erpnext/accounts/doctype/payment_entry/payment_entry.py:2756 +#: erpnext/accounts/doctype/payment_entry/payment_entry.py:2757 msgid "{0} {1} does not exist" msgstr "{0} {1} غير موجود\\n
        \\n{0} {1} does not exist" @@ -56223,13 +56520,13 @@ msgstr "" msgid "{0} {1} has already been partly paid. Please use the 'Get Outstanding Invoice' or the 'Get Outstanding Orders' button to get the latest outstanding amounts." msgstr "" -#: erpnext/buying/doctype/purchase_order/purchase_order.py:470 -#: erpnext/selling/doctype/sales_order/sales_order.py:583 -#: erpnext/stock/doctype/material_request/material_request.py:246 +#: erpnext/buying/doctype/purchase_order/purchase_order.py:472 +#: erpnext/selling/doctype/sales_order/sales_order.py:585 +#: erpnext/stock/doctype/material_request/material_request.py:247 msgid "{0} {1} has been modified. Please refresh." msgstr "تم تعديل {0} {1}، يرجى تحديث الصفحة من المتصفح" -#: erpnext/stock/doctype/material_request/material_request.py:273 +#: erpnext/stock/doctype/material_request/material_request.py:274 msgid "{0} {1} has not been submitted so the action cannot be completed" msgstr "{0} {1} لم يتم إرسالها، ولذلك لا يمكن إكمال الإجراء" @@ -56245,20 +56542,20 @@ msgstr "" msgid "{0} {1} is associated with {2}, but Party Account is {3}" msgstr "{0} {1} مرتبط ب {2}، ولكن حساب الطرف هو {3}" -#: erpnext/controllers/selling_controller.py:504 -#: erpnext/controllers/subcontracting_controller.py:1102 +#: erpnext/controllers/selling_controller.py:526 +#: erpnext/controllers/subcontracting_controller.py:1133 msgid "{0} {1} is cancelled or closed" msgstr "{0} {1} تم إلغائه أو مغلق" -#: erpnext/stock/doctype/material_request/material_request.py:419 +#: erpnext/stock/doctype/material_request/material_request.py:423 msgid "{0} {1} is cancelled or stopped" msgstr "{0} {1} يتم إلغاؤه أو إيقافه\\n
        \\n{0} {1} is cancelled or stopped" -#: erpnext/stock/doctype/material_request/material_request.py:263 +#: erpnext/stock/doctype/material_request/material_request.py:264 msgid "{0} {1} is cancelled so the action cannot be completed" msgstr "{0} {1} تم إلغاؤه لذلك لا يمكن إكمال الإجراء" -#: erpnext/accounts/doctype/journal_entry/journal_entry.py:914 +#: erpnext/accounts/doctype/journal_entry/journal_entry.py:829 msgid "{0} {1} is closed" msgstr "{0} {1} مغلقة" @@ -56270,7 +56567,7 @@ msgstr "{0} {1} معطل" msgid "{0} {1} is frozen" msgstr "{0} {1} مجمد" -#: erpnext/accounts/doctype/journal_entry/journal_entry.py:911 +#: erpnext/accounts/doctype/journal_entry/journal_entry.py:826 msgid "{0} {1} is fully billed" msgstr "{0} {1} قدمت الفواتير بشكل كامل" @@ -56286,8 +56583,8 @@ msgstr "{0} {1} غير مرتبط {2} {3}" msgid "{0} {1} is not in any active Fiscal Year" msgstr "" -#: erpnext/accounts/doctype/journal_entry/journal_entry.py:908 -#: erpnext/accounts/doctype/journal_entry/journal_entry.py:947 +#: erpnext/accounts/doctype/journal_entry/journal_entry.py:823 +#: erpnext/accounts/doctype/journal_entry/journal_entry.py:862 msgid "{0} {1} is not submitted" msgstr "{0} {1} لم يتم تقديمه" @@ -56299,7 +56596,7 @@ msgstr "" msgid "{0} {1} must be submitted" msgstr "{0} {1} يجب أن يتم اعتماده\\n
        \\n{0} {1} must be submitted" -#: erpnext/accounts/doctype/repost_accounting_ledger/repost_accounting_ledger.py:269 +#: erpnext/accounts/doctype/repost_accounting_ledger/repost_accounting_ledger.py:272 msgid "{0} {1} not allowed to be reposted. Modify {2} to enable reposting." msgstr "" @@ -56334,7 +56631,7 @@ msgstr "{0} {1}: الحساب {2} غير فعال \\n
        \\n{0} {1}: Account {2} msgid "{0} {1}: Accounting Entry for {2} can only be made in currency: {3}" msgstr "{0} {1}: قيد محاسبي ل {2} يمكن ان يتم فقط بالعملة : {3}" -#: erpnext/controllers/stock_controller.py:901 +#: erpnext/controllers/stock_controller.py:903 msgid "{0} {1}: Cost Center is mandatory for Item {2}" msgstr "{0} {1}: مركز التكلفة إلزامي للبند {2}" @@ -56379,16 +56676,16 @@ msgstr "" msgid "{0}% of total invoice value will be given as discount." msgstr "" -#: erpnext/projects/doctype/task/task.py:129 +#: erpnext/projects/doctype/task/task.py:130 msgid "{0}'s {1} cannot be after {2}'s Expected End Date." msgstr "" -#: erpnext/manufacturing/doctype/job_card/job_card.py:1158 -#: erpnext/manufacturing/doctype/job_card/job_card.py:1166 +#: erpnext/manufacturing/doctype/job_card/job_card.py:1183 +#: erpnext/manufacturing/doctype/job_card/job_card.py:1191 msgid "{0}, complete the operation {1} before the operation {2}." msgstr "{0} ، أكمل العملية {1} قبل العملية {2}." -#: erpnext/controllers/accounts_controller.py:472 +#: erpnext/controllers/accounts_controller.py:542 msgid "{0}: {1} does not belong to the Company: {2}" msgstr "" @@ -56396,7 +56693,7 @@ msgstr "" msgid "{0}: {1} does not exists" msgstr "{0}: {1} غير موجود" -#: erpnext/setup/doctype/company/company.py:234 +#: erpnext/setup/doctype/company/company.py:270 msgid "{0}: {1} is a group account." msgstr "" @@ -56404,23 +56701,23 @@ msgstr "" msgid "{0}: {1} must be less than {2}" msgstr "{0}: {1} يجب أن يكون أقل من {2}" -#: erpnext/controllers/buying_controller.py:996 +#: erpnext/controllers/buying_controller.py:1009 msgid "{count} Assets created for {item_code}" msgstr "" -#: erpnext/controllers/buying_controller.py:894 +#: erpnext/controllers/buying_controller.py:907 msgid "{doctype} {name} is cancelled or closed." msgstr "{doctype} {name} تم إلغائه أو مغلق." -#: erpnext/controllers/buying_controller.py:615 +#: erpnext/controllers/buying_controller.py:628 msgid "{field_label} is mandatory for sub-contracted {doctype}." msgstr "" -#: erpnext/controllers/stock_controller.py:1976 +#: erpnext/controllers/stock_controller.py:2085 msgid "{item_name}'s Sample Size ({sample_size}) cannot be greater than the Accepted Quantity ({accepted_quantity})" msgstr "" -#: erpnext/controllers/buying_controller.py:719 +#: erpnext/controllers/buying_controller.py:732 msgid "{ref_doctype} {ref_name} is {status}." msgstr "" @@ -56482,11 +56779,11 @@ msgstr "" msgid "{} To Bill" msgstr "" -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:2103 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:2056 msgid "{} can't be cancelled since the Loyalty Points earned has been redeemed. First cancel the {} No {}" msgstr "لا يمكن إلغاء {} نظرًا لاسترداد نقاط الولاء المكتسبة. قم أولاً بإلغاء {} لا {}" -#: erpnext/controllers/buying_controller.py:273 +#: erpnext/controllers/buying_controller.py:286 msgid "{} has submitted assets linked to it. You need to cancel the assets to create purchase return." msgstr "قام {} بتقديم أصول مرتبطة به. تحتاج إلى إلغاء الأصول لإنشاء عائد شراء." diff --git a/erpnext/locale/bs.po b/erpnext/locale/bs.po index ab0ffb11175..ff42a90a3a1 100644 --- a/erpnext/locale/bs.po +++ b/erpnext/locale/bs.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: frappe\n" "Report-Msgid-Bugs-To: hello@frappe.io\n" -"POT-Creation-Date: 2025-11-16 09:35+0000\n" -"PO-Revision-Date: 2025-11-19 22:23\n" +"POT-Creation-Date: 2025-12-14 09:37+0000\n" +"PO-Revision-Date: 2025-12-15 01:41\n" "Last-Translator: hello@frappe.io\n" "Language-Team: Bosnian\n" "MIME-Version: 1.0\n" @@ -27,7 +27,7 @@ msgstr " " msgid " Address" msgstr " Adresa" -#: erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py:677 +#: erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py:605 msgid " Amount" msgstr "Iznos" @@ -35,6 +35,11 @@ msgstr "Iznos" msgid " BOM" msgstr " Sastavnica" +#. Label of the default_wip_warehouse (Link) field in DocType 'Company' +#: erpnext/setup/doctype/company/company.json +msgid " Default Work In Progress Warehouse " +msgstr " Standard Skladište Posla u Toku " + #. Label of the istable (Check) field in DocType 'Inventory Dimension' #: erpnext/stock/doctype/inventory_dimension/inventory_dimension.json msgid " Is Child Table" @@ -45,18 +50,23 @@ msgstr "Podređena tabela" msgid " Is Subcontracted" msgstr "Podizvođač" -#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:174 +#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:196 msgid " Item" msgstr " Artikal" -#: erpnext/accounts/report/customer_ledger_summary/customer_ledger_summary.py:147 -#: erpnext/accounts/report/tax_withholding_details/tax_withholding_details.py:192 +#: erpnext/accounts/report/customer_ledger_summary/customer_ledger_summary.py:153 +#: erpnext/accounts/report/tax_withholding_details/tax_withholding_details.py:206 #: erpnext/accounts/report/tds_computation_summary/tds_computation_summary.py:107 #: erpnext/selling/report/sales_analytics/sales_analytics.py:128 msgid " Name" msgstr " Naziv" -#: erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py:668 +#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:144 +#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:185 +msgid " Phantom Item" +msgstr " Fantomski Artikal" + +#: erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py:596 msgid " Rate" msgstr " Cijena" @@ -70,7 +80,7 @@ msgid " Skip Material Transfer" msgstr " Preskoči Prijenos Materijala" #: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:133 -#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:163 +#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:174 msgid " Sub Assembly" msgstr " Podsklop" @@ -78,15 +88,15 @@ msgstr " Podsklop" msgid " Summary" msgstr " Sažetak" -#: erpnext/stock/doctype/item/item.py:236 +#: erpnext/stock/doctype/item/item.py:238 msgid "\"Customer Provided Item\" cannot be Purchase Item also" msgstr "\"Artikal koji osigurava Klijent\" ne može biti Kupovni Artikal" -#: erpnext/stock/doctype/item/item.py:238 +#: erpnext/stock/doctype/item/item.py:240 msgid "\"Customer Provided Item\" cannot have Valuation Rate" msgstr "\"Artikal koju daje Klijent\" ne može imati Stopu Vrednovanja" -#: erpnext/stock/doctype/item/item.py:314 +#: erpnext/stock/doctype/item/item.py:315 msgid "\"Is Fixed Asset\" cannot be unchecked, as Asset record exists against the item" msgstr "Ne može se poništiti izbor opcije \"Fiksna Imovina\", jer postoji zapis imovine naspram artikla" @@ -141,7 +151,7 @@ msgstr "% Završeno" msgid "% Delivered" msgstr "% Dostavljeno" -#: erpnext/manufacturing/doctype/bom/bom.js:945 +#: erpnext/manufacturing/doctype/bom/bom.js:962 #, python-format msgid "% Finished Item Quantity" msgstr "% Količina Gotovih Proizvoda" @@ -156,8 +166,8 @@ msgstr "% Instalirano" msgid "% Occupied" msgstr "% Zauzeto" -#: erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py:285 -#: erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py:340 +#: erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py:277 +#: erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py:329 msgid "% Of Grand Total" msgstr "% Od Ukupnog Iznosa" @@ -246,11 +256,11 @@ msgstr "% materijala isporučenih prema ovoj Listi Odabira" msgid "% of materials delivered against this Sales Order" msgstr "% materijala dostavljenog naspram ovog Prodajnog Naloga" -#: erpnext/controllers/accounts_controller.py:2295 +#: erpnext/controllers/accounts_controller.py:2368 msgid "'Account' in the Accounting section of Customer {0}" msgstr "'Račun' u sekciji Knjigovodstvo Klijenta {0}" -#: erpnext/selling/doctype/sales_order/sales_order.py:346 +#: erpnext/selling/doctype/sales_order/sales_order.py:348 msgid "'Allow Multiple Sales Orders Against a Customer's Purchase Order'" msgstr "'Dozvoli višestruke Prodajne Naloge naspram Kupovnog Naloga Klijenta'" @@ -262,11 +272,11 @@ msgstr "'Na Osnovu' i 'Grupiraj Po' ne mogu biti isti" msgid "'Days Since Last Order' must be greater than or equal to zero" msgstr "'Dana od posljednje narudžbe' mora biti veći ili jednako nuli" -#: erpnext/controllers/accounts_controller.py:2300 +#: erpnext/controllers/accounts_controller.py:2373 msgid "'Default {0} Account' in Company {1}" -msgstr "'Standard {0} račun' u Kompaniji {1}" +msgstr "'Standard {0} račun' u {1}" -#: erpnext/accounts/doctype/journal_entry/journal_entry.py:1283 +#: erpnext/accounts/doctype/journal_entry/journal_entry.py:1198 msgid "'Entries' cannot be empty" msgstr "Polje 'Unosi' ne može biti prazno" @@ -280,7 +290,7 @@ msgstr "'Od datuma' je obavezan" msgid "'From Date' must be after 'To Date'" msgstr "'Od datuma' mora biti nakon 'Do datuma'" -#: erpnext/stock/doctype/item/item.py:397 +#: erpnext/stock/doctype/item/item.py:398 msgid "'Has Serial No' can not be 'Yes' for non-stock item" msgstr "'Ima Serijski Broj' ne može biti 'Da' za artikal koji nije na zalihama" @@ -292,8 +302,8 @@ msgstr "'Kontrola Obavezna prije Dostave' je onemogućena za artikal {0}, nema p msgid "'Inspection Required before Purchase' has disabled for the item {0}, no need to create the QI" msgstr "'Potrebna kontrola prije kupovine' je onemogućena za artikal {0}, nema potrebe za kreiranjem kvaliteta kontrole" -#: erpnext/stock/report/stock_ledger/stock_ledger.py:598 -#: erpnext/stock/report/stock_ledger/stock_ledger.py:631 +#: erpnext/stock/report/stock_ledger/stock_ledger.py:601 +#: erpnext/stock/report/stock_ledger/stock_ledger.py:634 msgid "'Opening'" msgstr "'Početno'" @@ -307,11 +317,11 @@ msgstr "'Do Datuma' je obavezno" msgid "'To Package No.' cannot be less than 'From Package No.'" msgstr "'Do Paketa Broj' ne može biti manje od 'Od Paketa Broj.'" -#: erpnext/controllers/sales_and_purchase_return.py:81 +#: erpnext/controllers/sales_and_purchase_return.py:80 msgid "'Update Stock' can not be checked because items are not delivered via {0}" msgstr "'Ažuriraj Zalihe' se ne može provjeriti jer se artikli ne isporučuju putem {0}" -#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:439 +#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:388 msgid "'Update Stock' cannot be checked for fixed asset sale" msgstr "'Ažuriraj Zalihe' ne može se provjeriti za prodaju osnovne Imovine" @@ -323,10 +333,10 @@ msgstr "Račun '{0}' već koristi {1}. Koristite drugi račun." msgid "'{0}' has been already added." msgstr "'{0}' je već dodan." -#: erpnext/setup/doctype/company/company.py:259 -#: erpnext/setup/doctype/company/company.py:270 +#: erpnext/setup/doctype/company/company.py:295 +#: erpnext/setup/doctype/company/company.py:306 msgid "'{0}' should be in company currency {1}." -msgstr "'{0}' bi trebao biti u valuti kompanije {1}." +msgstr "'{0}' bi trebao biti u valuti {1}." #: erpnext/stock/report/fifo_queue_vs_qty_after_transaction_comparison/fifo_queue_vs_qty_after_transaction_comparison.py:174 #: erpnext/stock/report/stock_ledger_invariant_check/stock_ledger_invariant_check.py:203 @@ -580,10 +590,18 @@ msgstr "90 - 120 dana" msgid "90 Above" msgstr "Iznad 90" +#: erpnext/assets/doctype/asset/asset.py:474 +msgid "Cannot create asset.

        You're trying to create {0} asset(s) from {2} {3}.
        However, only {1} item(s) were purchased and {4} asset(s) already exist against {5}." +msgstr "Nije moguće kreirati imovinu.

        Pokušavate kreirati {0} imovinu od {2} {3}.
        Međutim, kupljeno je samo {1} artikala i {4} imovina već postoji za {5}." + #: erpnext/crm/doctype/appointment_booking_settings/appointment_booking_settings.py:61 msgid "From Time cannot be later than To Time for {0}" msgstr "Od Vremena ne može biti kasnije od Do Vremena za {0}" +#: erpnext/accounts/doctype/pos_invoice/pos_invoice.py:432 +msgid "Row #{0}: Bundle {1} in warehouse {2} has insufficient packed items:
          {3}
        " +msgstr "Red #{0}: Paket {1} u skladištu {2} ima nedovoljno spakovanih artikala:
          {3}
        " + #. Content of the 'Help Text' (HTML) field in DocType 'Process Statement Of #. Accounts' #: erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.json @@ -753,25 +771,30 @@ msgstr "