Merge remote-tracking branch 'upstream/develop' into feat/so-po-advance-payment-status
diff --git a/README.md b/README.md
index 44bd729..710187a 100644
--- a/README.md
+++ b/README.md
@@ -73,8 +73,6 @@
 1. [Issue Guidelines](https://github.com/frappe/erpnext/wiki/Issue-Guidelines)
 1. [Report Security Vulnerabilities](https://erpnext.com/security)
 1. [Pull Request Requirements](https://github.com/frappe/erpnext/wiki/Contribution-Guidelines)
-1. [Translations](https://translate.erpnext.com)
-
 
 ## License
 
diff --git a/erpnext/__init__.py b/erpnext/__init__.py
index 3e418c4..5c58f84 100644
--- a/erpnext/__init__.py
+++ b/erpnext/__init__.py
@@ -3,7 +3,7 @@
 
 import frappe
 
-__version__ = "15.0.0-dev"
+__version__ = "16.0.0-dev"
 
 
 def get_default_company(user=None):
diff --git a/erpnext/accounts/doctype/account/account.py b/erpnext/accounts/doctype/account/account.py
index 02e6c20..82af85d 100644
--- a/erpnext/accounts/doctype/account/account.py
+++ b/erpnext/accounts/doctype/account/account.py
@@ -23,6 +23,65 @@
 
 
 class Account(NestedSet):
+	# 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_currency: DF.Link | None
+		account_name: DF.Data
+		account_number: DF.Data | None
+		account_type: DF.Literal[
+			"",
+			"Accumulated Depreciation",
+			"Asset Received But Not Billed",
+			"Bank",
+			"Cash",
+			"Chargeable",
+			"Capital Work in Progress",
+			"Cost of Goods Sold",
+			"Current Asset",
+			"Current Liability",
+			"Depreciation",
+			"Direct Expense",
+			"Direct Income",
+			"Equity",
+			"Expense Account",
+			"Expenses Included In Asset Valuation",
+			"Expenses Included In Valuation",
+			"Fixed Asset",
+			"Income Account",
+			"Indirect Expense",
+			"Indirect Income",
+			"Liability",
+			"Payable",
+			"Receivable",
+			"Round Off",
+			"Stock",
+			"Stock Adjustment",
+			"Stock Received But Not Billed",
+			"Service Received But Not Billed",
+			"Tax",
+			"Temporary",
+		]
+		balance_must_be: DF.Literal["", "Debit", "Credit"]
+		company: DF.Link
+		disabled: DF.Check
+		freeze_account: DF.Literal["No", "Yes"]
+		include_in_gross: DF.Check
+		is_group: DF.Check
+		lft: DF.Int
+		old_parent: DF.Data | None
+		parent_account: DF.Link
+		report_type: DF.Literal["", "Balance Sheet", "Profit and Loss"]
+		rgt: DF.Int
+		root_type: DF.Literal["", "Asset", "Liability", "Income", "Expense", "Equity"]
+		tax_rate: DF.Float
+	# end: auto-generated types
+
 	nsm_parent_field = "parent_account"
 
 	def on_update(self):
diff --git a/erpnext/accounts/doctype/account/chart_of_accounts/verified/hu_chart_of_accounts_for_microenterprises_with_account_number.json b/erpnext/accounts/doctype/account/chart_of_accounts/verified/hu_chart_of_accounts_for_microenterprises_with_account_number.json
index 2cd6c0f..4013bb0 100644
--- a/erpnext/accounts/doctype/account/chart_of_accounts/verified/hu_chart_of_accounts_for_microenterprises_with_account_number.json
+++ b/erpnext/accounts/doctype/account/chart_of_accounts/verified/hu_chart_of_accounts_for_microenterprises_with_account_number.json
@@ -1,4 +1,6 @@
 {
+  "country_code": "hu", 
+  "name": "Hungary - Chart of Accounts for Microenterprises", 
   "tree": {
     "SZ\u00c1MLAOSZT\u00c1LY BEFEKTETETT ESZK\u00d6Z\u00d6K": {
       "account_number": 1,
@@ -1651,4 +1653,4 @@
       }
     }
   }
-}
\ No newline at end of file
+}
diff --git a/erpnext/accounts/doctype/account_closing_balance/account_closing_balance.py b/erpnext/accounts/doctype/account_closing_balance/account_closing_balance.py
index d06bd83..65933ab 100644
--- a/erpnext/accounts/doctype/account_closing_balance/account_closing_balance.py
+++ b/erpnext/accounts/doctype/account_closing_balance/account_closing_balance.py
@@ -11,6 +11,29 @@
 
 
 class AccountClosingBalance(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: DF.Link | None
+		account_currency: DF.Link | None
+		closing_date: DF.Date | None
+		company: DF.Link | None
+		cost_center: DF.Link | None
+		credit: DF.Currency
+		credit_in_account_currency: DF.Currency
+		debit: DF.Currency
+		debit_in_account_currency: DF.Currency
+		finance_book: DF.Link | None
+		is_period_closing_voucher_entry: DF.Check
+		period_closing_voucher: DF.Link | None
+		project: DF.Link | None
+	# end: auto-generated types
+
 	pass
 
 
diff --git a/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.py b/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.py
index 8f76492..295cd98 100644
--- a/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.py
+++ b/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.py
@@ -13,6 +13,25 @@
 
 
 class AccountingDimension(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
+
+		from erpnext.accounts.doctype.accounting_dimension_detail.accounting_dimension_detail import (
+			AccountingDimensionDetail,
+		)
+
+		dimension_defaults: DF.Table[AccountingDimensionDetail]
+		disabled: DF.Check
+		document_type: DF.Link
+		fieldname: DF.Data | None
+		label: DF.Data | None
+	# end: auto-generated types
+
 	def before_insert(self):
 		self.set_fieldname_and_label()
 
diff --git a/erpnext/accounts/doctype/accounting_dimension_detail/accounting_dimension_detail.py b/erpnext/accounts/doctype/accounting_dimension_detail/accounting_dimension_detail.py
index 4b0cbb3..e797ac6 100644
--- a/erpnext/accounts/doctype/accounting_dimension_detail/accounting_dimension_detail.py
+++ b/erpnext/accounts/doctype/accounting_dimension_detail/accounting_dimension_detail.py
@@ -7,4 +7,24 @@
 
 
 class AccountingDimensionDetail(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
+
+		automatically_post_balancing_accounting_entry: DF.Check
+		company: DF.Link | None
+		default_dimension: DF.DynamicLink | None
+		mandatory_for_bs: DF.Check
+		mandatory_for_pl: DF.Check
+		offsetting_account: DF.Link | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		reference_document: DF.Link | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.py b/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.py
index de1b82c..01f6e60 100644
--- a/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.py
+++ b/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.py
@@ -8,6 +8,28 @@
 
 
 class AccountingDimensionFilter(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
+
+		from erpnext.accounts.doctype.allowed_dimension.allowed_dimension import AllowedDimension
+		from erpnext.accounts.doctype.applicable_on_account.applicable_on_account import (
+			ApplicableOnAccount,
+		)
+
+		accounting_dimension: DF.Literal
+		accounts: DF.Table[ApplicableOnAccount]
+		allow_or_restrict: DF.Literal["Allow", "Restrict"]
+		apply_restriction_on_values: DF.Check
+		company: DF.Link
+		dimensions: DF.Table[AllowedDimension]
+		disabled: DF.Check
+	# end: auto-generated types
+
 	def before_save(self):
 		# If restriction is not applied on values, then remove all the dimensions and set allow_or_restrict to Restrict
 		if not self.apply_restriction_on_values:
diff --git a/erpnext/accounts/doctype/accounting_period/accounting_period.py b/erpnext/accounts/doctype/accounting_period/accounting_period.py
index d5f37a6..b32a231 100644
--- a/erpnext/accounts/doctype/accounting_period/accounting_period.py
+++ b/erpnext/accounts/doctype/accounting_period/accounting_period.py
@@ -16,6 +16,23 @@
 
 
 class AccountingPeriod(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
+
+		from erpnext.accounts.doctype.closed_document.closed_document import ClosedDocument
+
+		closed_documents: DF.Table[ClosedDocument]
+		company: DF.Link
+		end_date: DF.Date
+		period_name: DF.Data
+		start_date: DF.Date
+	# end: auto-generated types
+
 	def validate(self):
 		self.validate_overlap()
 
diff --git a/erpnext/accounts/doctype/accounts_settings/accounts_settings.json b/erpnext/accounts/doctype/accounts_settings/accounts_settings.json
index 061bab3..fd052d0 100644
--- a/erpnext/accounts/doctype/accounts_settings/accounts_settings.json
+++ b/erpnext/accounts/doctype/accounts_settings/accounts_settings.json
@@ -66,7 +66,12 @@
   "show_balance_in_coa",
   "banking_tab",
   "enable_party_matching",
-  "enable_fuzzy_matching"
+  "enable_fuzzy_matching",
+  "reports_tab",
+  "remarks_section",
+  "general_ledger_remarks_length",
+  "column_break_lvjk",
+  "receivable_payable_remarks_length"
  ],
  "fields": [
   {
@@ -422,6 +427,34 @@
    "fieldname": "round_row_wise_tax",
    "fieldtype": "Check",
    "label": "Round Tax Amount Row-wise"
+  },
+  {
+   "fieldname": "reports_tab",
+   "fieldtype": "Tab Break",
+   "label": "Reports"
+  },
+  {
+   "default": "0",
+   "description": "Truncates 'Remarks' column to set character length",
+   "fieldname": "general_ledger_remarks_length",
+   "fieldtype": "Int",
+   "label": "General Ledger"
+  },
+  {
+   "default": "0",
+   "description": "Truncates 'Remarks' column to set character length",
+   "fieldname": "receivable_payable_remarks_length",
+   "fieldtype": "Int",
+   "label": "Accounts Receivable/Payable"
+  },
+  {
+   "fieldname": "column_break_lvjk",
+   "fieldtype": "Column Break"
+  },
+  {
+   "fieldname": "remarks_section",
+   "fieldtype": "Section Break",
+   "label": "Remarks Column Length"
   }
  ],
  "icon": "icon-cog",
@@ -429,7 +462,7 @@
  "index_web_pages_for_search": 1,
  "issingle": 1,
  "links": [],
- "modified": "2023-08-28 00:12:02.740633",
+ "modified": "2023-11-20 09:37:47.650347",
  "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 ac3d44b..07d1a65 100644
--- a/erpnext/accounts/doctype/accounts_settings/accounts_settings.py
+++ b/erpnext/accounts/doctype/accounts_settings/accounts_settings.py
@@ -14,6 +14,52 @@
 
 
 class AccountsSettings(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
+
+		acc_frozen_upto: DF.Date | None
+		add_taxes_from_item_tax_template: DF.Check
+		allow_multi_currency_invoices_against_single_party_account: DF.Check
+		allow_stale: DF.Check
+		auto_reconcile_payments: DF.Check
+		automatically_fetch_payment_terms: DF.Check
+		automatically_process_deferred_accounting_entry: DF.Check
+		book_asset_depreciation_entry_automatically: DF.Check
+		book_deferred_entries_based_on: DF.Literal["Days", "Months"]
+		book_deferred_entries_via_journal_entry: DF.Check
+		book_tax_discount_loss: DF.Check
+		check_supplier_invoice_uniqueness: DF.Check
+		credit_controller: DF.Link | None
+		delete_linked_ledger_entries: DF.Check
+		determine_address_tax_category_from: DF.Literal["Billing Address", "Shipping Address"]
+		enable_common_party_accounting: DF.Check
+		enable_fuzzy_matching: DF.Check
+		enable_party_matching: DF.Check
+		frozen_accounts_modifier: DF.Link | None
+		general_ledger_remarks_length: DF.Int
+		ignore_account_closing_balance: DF.Check
+		make_payment_via_journal_entry: DF.Check
+		merge_similar_account_heads: DF.Check
+		over_billing_allowance: DF.Currency
+		post_change_gl_entries: DF.Check
+		receivable_payable_remarks_length: DF.Int
+		role_allowed_to_over_bill: DF.Link | None
+		round_row_wise_tax: DF.Check
+		show_balance_in_coa: DF.Check
+		show_inclusive_tax_in_print: DF.Check
+		show_payment_schedule_in_print: DF.Check
+		show_taxes_as_table_in_print: DF.Check
+		stale_days: DF.Int
+		submit_journal_entries: DF.Check
+		unlink_advance_payment_on_cancelation_of_order: DF.Check
+		unlink_payment_on_cancellation_of_invoice: DF.Check
+	# end: auto-generated types
+
 	def validate(self):
 		old_doc = self.get_doc_before_save()
 		clear_cache = False
diff --git a/erpnext/accounts/doctype/advance_tax/advance_tax.py b/erpnext/accounts/doctype/advance_tax/advance_tax.py
index 2e784ef..59bdac7 100644
--- a/erpnext/accounts/doctype/advance_tax/advance_tax.py
+++ b/erpnext/accounts/doctype/advance_tax/advance_tax.py
@@ -6,4 +6,22 @@
 
 
 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.py b/erpnext/accounts/doctype/advance_taxes_and_charges/advance_taxes_and_charges.py
index 55c84fb..47e97ba 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
@@ -7,4 +7,33 @@
 
 
 class AdvanceTaxesandCharges(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
+		add_deduct_tax: DF.Literal["Add", "Deduct"]
+		allocated_amount: DF.Currency
+		base_tax_amount: DF.Currency
+		base_total: DF.Currency
+		charge_type: DF.Literal[
+			"", "Actual", "On Paid Amount", "On Previous Row Amount", "On Previous Row Total"
+		]
+		cost_center: DF.Link | None
+		currency: DF.Link | None
+		description: DF.SmallText
+		included_in_paid_amount: DF.Check
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		rate: DF.Float
+		row_id: DF.Data | None
+		tax_amount: DF.Currency
+		total: DF.Currency
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/allowed_dimension/allowed_dimension.py b/erpnext/accounts/doctype/allowed_dimension/allowed_dimension.py
index a3173a8..ddc3a16 100644
--- a/erpnext/accounts/doctype/allowed_dimension/allowed_dimension.py
+++ b/erpnext/accounts/doctype/allowed_dimension/allowed_dimension.py
@@ -7,4 +7,19 @@
 
 
 class AllowedDimension(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
+
+		accounting_dimension: DF.Link | None
+		dimension_value: DF.DynamicLink | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/allowed_to_transact_with/allowed_to_transact_with.py b/erpnext/accounts/doctype/allowed_to_transact_with/allowed_to_transact_with.py
index a532070..1665419 100644
--- a/erpnext/accounts/doctype/allowed_to_transact_with/allowed_to_transact_with.py
+++ b/erpnext/accounts/doctype/allowed_to_transact_with/allowed_to_transact_with.py
@@ -6,4 +6,18 @@
 
 
 class AllowedToTransactWith(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
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/applicable_on_account/applicable_on_account.py b/erpnext/accounts/doctype/applicable_on_account/applicable_on_account.py
index aae2166..c32f7df 100644
--- a/erpnext/accounts/doctype/applicable_on_account/applicable_on_account.py
+++ b/erpnext/accounts/doctype/applicable_on_account/applicable_on_account.py
@@ -7,4 +7,19 @@
 
 
 class ApplicableOnAccount(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
+
+		applicable_on_account: DF.Link
+		is_mandatory: DF.Check
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/bank/bank.py b/erpnext/accounts/doctype/bank/bank.py
index d44be9a..23bd30c 100644
--- a/erpnext/accounts/doctype/bank/bank.py
+++ b/erpnext/accounts/doctype/bank/bank.py
@@ -10,6 +10,25 @@
 
 
 class Bank(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
+
+		from erpnext.accounts.doctype.bank_transaction_mapping.bank_transaction_mapping import (
+			BankTransactionMapping,
+		)
+
+		bank_name: DF.Data
+		bank_transaction_mapping: DF.Table[BankTransactionMapping]
+		plaid_access_token: DF.Data | None
+		swift_number: DF.Data | None
+		website: DF.Data | None
+	# end: auto-generated types
+
 	def onload(self):
 		"""Load address and contacts in `__onload`"""
 		load_address_and_contact(self)
diff --git a/erpnext/accounts/doctype/bank_account/bank_account.py b/erpnext/accounts/doctype/bank_account/bank_account.py
index 363a277..4b99b19 100644
--- a/erpnext/accounts/doctype/bank_account/bank_account.py
+++ b/erpnext/accounts/doctype/bank_account/bank_account.py
@@ -12,6 +12,33 @@
 
 
 class BankAccount(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: DF.Link | None
+		account_name: DF.Data
+		account_subtype: DF.Link | None
+		account_type: DF.Link | None
+		bank: DF.Link
+		bank_account_no: DF.Data | None
+		branch_code: DF.Data | None
+		company: DF.Link | None
+		disabled: DF.Check
+		iban: DF.Data | None
+		integration_id: DF.Data | None
+		is_company_account: DF.Check
+		is_default: DF.Check
+		last_integration_date: DF.Date | None
+		mask: DF.Data | None
+		party: DF.DynamicLink | None
+		party_type: DF.Link | None
+	# end: auto-generated types
+
 	def onload(self):
 		"""Load address and contacts in `__onload`"""
 		load_address_and_contact(self)
diff --git a/erpnext/accounts/doctype/bank_account_subtype/bank_account_subtype.py b/erpnext/accounts/doctype/bank_account_subtype/bank_account_subtype.py
index 6355478..dbd71cc 100644
--- a/erpnext/accounts/doctype/bank_account_subtype/bank_account_subtype.py
+++ b/erpnext/accounts/doctype/bank_account_subtype/bank_account_subtype.py
@@ -6,4 +6,15 @@
 
 
 class BankAccountSubtype(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_subtype: DF.Data | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/bank_account_type/bank_account_type.py b/erpnext/accounts/doctype/bank_account_type/bank_account_type.py
index 177b711..79b7551 100644
--- a/erpnext/accounts/doctype/bank_account_type/bank_account_type.py
+++ b/erpnext/accounts/doctype/bank_account_type/bank_account_type.py
@@ -7,4 +7,15 @@
 
 
 class BankAccountType(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_type: DF.Data | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/bank_clearance/bank_clearance.py b/erpnext/accounts/doctype/bank_clearance/bank_clearance.py
index 8edd376..4b97619 100644
--- a/erpnext/accounts/doctype/bank_clearance/bank_clearance.py
+++ b/erpnext/accounts/doctype/bank_clearance/bank_clearance.py
@@ -13,6 +13,28 @@
 
 
 class BankClearance(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
+
+		from erpnext.accounts.doctype.bank_clearance_detail.bank_clearance_detail import (
+			BankClearanceDetail,
+		)
+
+		account: DF.Link
+		account_currency: DF.Link | None
+		bank_account: DF.Link | None
+		from_date: DF.Date
+		include_pos_transactions: DF.Check
+		include_reconciled_entries: DF.Check
+		payment_entries: DF.Table[BankClearanceDetail]
+		to_date: DF.Date
+	# end: auto-generated types
+
 	@frappe.whitelist()
 	def get_payment_entries(self):
 		if not (self.from_date and self.to_date):
diff --git a/erpnext/accounts/doctype/bank_clearance_detail/bank_clearance_detail.py b/erpnext/accounts/doctype/bank_clearance_detail/bank_clearance_detail.py
index 3d29fd7..5c1f5bf 100644
--- a/erpnext/accounts/doctype/bank_clearance_detail/bank_clearance_detail.py
+++ b/erpnext/accounts/doctype/bank_clearance_detail/bank_clearance_detail.py
@@ -6,4 +6,25 @@
 
 
 class BankClearanceDetail(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
+
+		against_account: DF.Data | None
+		amount: DF.Data | None
+		cheque_date: DF.Date | None
+		cheque_number: DF.Data | None
+		clearance_date: DF.Date | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		payment_document: DF.Link | None
+		payment_entry: DF.DynamicLink | None
+		posting_date: DF.Date | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/bank_guarantee/bank_guarantee.py b/erpnext/accounts/doctype/bank_guarantee/bank_guarantee.py
index 02eb599..0af2caf 100644
--- a/erpnext/accounts/doctype/bank_guarantee/bank_guarantee.py
+++ b/erpnext/accounts/doctype/bank_guarantee/bank_guarantee.py
@@ -8,6 +8,40 @@
 
 
 class BankGuarantee(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: DF.Link | None
+		amended_from: DF.Link | None
+		amount: DF.Currency
+		bank: DF.Link | None
+		bank_account: DF.Link | None
+		bank_account_no: DF.Data | None
+		bank_guarantee_number: DF.Data | None
+		bg_type: DF.Literal["", "Receiving", "Providing"]
+		branch_code: DF.Data | None
+		charges: DF.Currency
+		customer: DF.Link | None
+		end_date: DF.Date | None
+		fixed_deposit_number: DF.Data | None
+		iban: DF.Data | None
+		margin_money: DF.Currency
+		more_information: DF.TextEditor | None
+		name_of_beneficiary: DF.Data | None
+		project: DF.Link | None
+		reference_docname: DF.DynamicLink | None
+		reference_doctype: DF.Link | None
+		start_date: DF.Date
+		supplier: DF.Link | None
+		swift_number: DF.Data | None
+		validity: DF.Int
+	# end: auto-generated types
+
 	def validate(self):
 		if not (self.customer or self.supplier):
 			frappe.throw(_("Select the customer or supplier."))
diff --git a/erpnext/accounts/doctype/bank_reconciliation_tool/bank_reconciliation_tool.py b/erpnext/accounts/doctype/bank_reconciliation_tool/bank_reconciliation_tool.py
index 7e2f763..0779a09 100644
--- a/erpnext/accounts/doctype/bank_reconciliation_tool/bank_reconciliation_tool.py
+++ b/erpnext/accounts/doctype/bank_reconciliation_tool/bank_reconciliation_tool.py
@@ -22,6 +22,26 @@
 
 
 class BankReconciliationTool(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_currency: DF.Link | None
+		account_opening_balance: DF.Currency
+		bank_account: DF.Link | None
+		bank_statement_closing_balance: DF.Currency
+		bank_statement_from_date: DF.Date | None
+		bank_statement_to_date: DF.Date | None
+		company: DF.Link | None
+		filter_by_reference_date: DF.Check
+		from_reference_date: DF.Date | None
+		to_reference_date: DF.Date | None
+	# end: auto-generated types
+
 	pass
 
 
@@ -424,7 +444,9 @@
 	vouchers = json.loads(vouchers)
 	transaction = frappe.get_doc("Bank Transaction", bank_transaction_name)
 	transaction.add_payment_entries(vouchers)
-	return frappe.get_doc("Bank Transaction", bank_transaction_name)
+	transaction.save()
+
+	return transaction
 
 
 @frappe.whitelist()
diff --git a/erpnext/accounts/doctype/bank_statement_import/bank_statement_import.py b/erpnext/accounts/doctype/bank_statement_import/bank_statement_import.py
index 003a43c..1a4747c 100644
--- a/erpnext/accounts/doctype/bank_statement_import/bank_statement_import.py
+++ b/erpnext/accounts/doctype/bank_statement_import/bank_statement_import.py
@@ -20,6 +20,30 @@
 
 
 class BankStatementImport(DataImport):
+	# 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
+
+		bank: DF.Link | None
+		bank_account: DF.Link
+		company: DF.Link
+		google_sheets_url: DF.Data | None
+		import_file: DF.Attach | None
+		import_type: DF.Literal["", "Insert New Records", "Update Existing Records"]
+		mute_emails: DF.Check
+		reference_doctype: DF.Link
+		show_failed_logs: DF.Check
+		statement_import_log: DF.Code | None
+		status: DF.Literal["Pending", "Success", "Partial Success", "Error"]
+		submit_after_import: DF.Check
+		template_options: DF.Code | None
+		template_warnings: DF.Code | None
+	# end: auto-generated types
+
 	def __init__(self, *args, **kwargs):
 		super(BankStatementImport, self).__init__(*args, **kwargs)
 
diff --git a/erpnext/accounts/doctype/bank_transaction/bank_transaction.json b/erpnext/accounts/doctype/bank_transaction/bank_transaction.json
index b32022e..0328d51 100644
--- a/erpnext/accounts/doctype/bank_transaction/bank_transaction.json
+++ b/erpnext/accounts/doctype/bank_transaction/bank_transaction.json
@@ -13,6 +13,7 @@
   "status",
   "bank_account",
   "company",
+  "amended_from",
   "section_break_4",
   "deposit",
   "withdrawal",
@@ -25,10 +26,10 @@
   "transaction_id",
   "transaction_type",
   "section_break_14",
+  "column_break_oufv",
   "payment_entries",
   "section_break_18",
   "allocated_amount",
-  "amended_from",
   "column_break_17",
   "unallocated_amount",
   "party_section",
@@ -138,10 +139,12 @@
    "fieldtype": "Section Break"
   },
   {
+   "allow_on_submit": 1,
    "fieldname": "allocated_amount",
    "fieldtype": "Currency",
    "label": "Allocated Amount",
-   "options": "currency"
+   "options": "currency",
+   "read_only": 1
   },
   {
    "fieldname": "amended_from",
@@ -157,10 +160,12 @@
    "fieldtype": "Column Break"
   },
   {
+   "allow_on_submit": 1,
    "fieldname": "unallocated_amount",
    "fieldtype": "Currency",
    "label": "Unallocated Amount",
-   "options": "currency"
+   "options": "currency",
+   "read_only": 1
   },
   {
    "fieldname": "party_section",
@@ -225,11 +230,15 @@
    "fieldname": "bank_party_account_number",
    "fieldtype": "Data",
    "label": "Party Account No. (Bank Statement)"
+  },
+  {
+   "fieldname": "column_break_oufv",
+   "fieldtype": "Column Break"
   }
  ],
  "is_submittable": 1,
  "links": [],
- "modified": "2023-06-06 13:58:12.821411",
+ "modified": "2023-11-18 18:32:47.203694",
  "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 4649d23..629ed1c 100644
--- a/erpnext/accounts/doctype/bank_transaction/bank_transaction.py
+++ b/erpnext/accounts/doctype/bank_transaction/bank_transaction.py
@@ -2,78 +2,108 @@
 # For license information, please see license.txt
 
 import frappe
+from frappe import _
 from frappe.utils import flt
 
 from erpnext.controllers.status_updater import StatusUpdater
 
 
 class BankTransaction(StatusUpdater):
-	def after_insert(self):
-		self.unallocated_amount = abs(flt(self.withdrawal) - flt(self.deposit))
+	# begin: auto-generated types
+	# This code is auto-generated. Do not modify anything in this block.
 
-	def on_submit(self):
-		self.clear_linked_payment_entries()
+	from typing import TYPE_CHECKING
+
+	if TYPE_CHECKING:
+		from frappe.types import DF
+
+		from erpnext.accounts.doctype.bank_transaction_payments.bank_transaction_payments import (
+			BankTransactionPayments,
+		)
+
+		allocated_amount: DF.Currency
+		amended_from: DF.Link | None
+		bank_account: DF.Link | None
+		bank_party_account_number: DF.Data | None
+		bank_party_iban: DF.Data | None
+		bank_party_name: DF.Data | None
+		company: DF.Link | None
+		currency: DF.Link | None
+		date: DF.Date | None
+		deposit: DF.Currency
+		description: DF.SmallText | None
+		naming_series: DF.Literal["ACC-BTN-.YYYY.-"]
+		party: DF.DynamicLink | None
+		party_type: DF.Link | None
+		payment_entries: DF.Table[BankTransactionPayments]
+		reference_number: DF.Data | None
+		status: DF.Literal["", "Pending", "Settled", "Unreconciled", "Reconciled", "Cancelled"]
+		transaction_id: DF.Data | None
+		transaction_type: DF.Data | None
+		unallocated_amount: DF.Currency
+		withdrawal: DF.Currency
+	# end: auto-generated types
+
+	def before_validate(self):
+		self.update_allocated_amount()
+
+	def validate(self):
+		self.validate_duplicate_references()
+
+	def validate_duplicate_references(self):
+		"""Make sure the same voucher is not allocated twice within the same Bank Transaction"""
+		if not self.payment_entries:
+			return
+
+		pe = []
+		for row in self.payment_entries:
+			reference = (row.payment_document, row.payment_entry)
+			if reference in pe:
+				frappe.throw(
+					_("{0} {1} is allocated twice in this Bank Transaction").format(
+						row.payment_document, row.payment_entry
+					)
+				)
+			pe.append(reference)
+
+	def update_allocated_amount(self):
+		self.allocated_amount = (
+			sum(p.allocated_amount for p in self.payment_entries) if self.payment_entries else 0.0
+		)
+		self.unallocated_amount = abs(flt(self.withdrawal) - flt(self.deposit)) - self.allocated_amount
+
+	def before_submit(self):
+		self.allocate_payment_entries()
 		self.set_status()
 
 		if frappe.db.get_single_value("Accounts Settings", "enable_party_matching"):
 			self.auto_set_party()
 
-	_saving_flag = False
-
-	# nosemgrep: frappe-semgrep-rules.rules.frappe-modifying-but-not-comitting
-	def on_update_after_submit(self):
-		"Run on save(). Avoid recursion caused by multiple saves"
-		if not self._saving_flag:
-			self._saving_flag = True
-			self.clear_linked_payment_entries()
-			self.update_allocations()
-			self._saving_flag = False
+	def before_update_after_submit(self):
+		self.validate_duplicate_references()
+		self.allocate_payment_entries()
+		self.update_allocated_amount()
 
 	def on_cancel(self):
-		self.clear_linked_payment_entries(for_cancel=True)
-		self.set_status(update=True)
+		for payment_entry in self.payment_entries:
+			self.clear_linked_payment_entry(payment_entry, for_cancel=True)
 
-	def update_allocations(self):
-		"The doctype does not allow modifications after submission, so write to the db direct"
-		if self.payment_entries:
-			allocated_amount = sum(p.allocated_amount for p in self.payment_entries)
-		else:
-			allocated_amount = 0.0
-
-		amount = abs(flt(self.withdrawal) - flt(self.deposit))
-		self.db_set("allocated_amount", flt(allocated_amount))
-		self.db_set("unallocated_amount", amount - flt(allocated_amount))
-		self.reload()
 		self.set_status(update=True)
 
 	def add_payment_entries(self, vouchers):
 		"Add the vouchers with zero allocation. Save() will perform the allocations and clearance"
 		if 0.0 >= self.unallocated_amount:
-			frappe.throw(frappe._("Bank Transaction {0} is already fully reconciled").format(self.name))
+			frappe.throw(_("Bank Transaction {0} is already fully reconciled").format(self.name))
 
-		added = False
 		for voucher in vouchers:
-			# Can't add same voucher twice
-			found = False
-			for pe in self.payment_entries:
-				if (
-					pe.payment_document == voucher["payment_doctype"]
-					and pe.payment_entry == voucher["payment_name"]
-				):
-					found = True
-
-			if not found:
-				pe = {
+			self.append(
+				"payment_entries",
+				{
 					"payment_document": voucher["payment_doctype"],
 					"payment_entry": voucher["payment_name"],
 					"allocated_amount": 0.0,  # Temporary
-				}
-				child = self.append("payment_entries", pe)
-				added = True
-
-		# runs on_update_after_submit
-		if added:
-			self.save()
+				},
+			)
 
 	def allocate_payment_entries(self):
 		"""Refactored from bank reconciliation tool.
@@ -90,6 +120,7 @@
 		- clear means: set the latest transaction date as clearance date
 		"""
 		remaining_amount = self.unallocated_amount
+		to_remove = []
 		for payment_entry in self.payment_entries:
 			if payment_entry.allocated_amount == 0.0:
 				unallocated_amount, should_clear, latest_transaction = get_clearance_details(
@@ -99,49 +130,39 @@
 				if 0.0 == unallocated_amount:
 					if should_clear:
 						latest_transaction.clear_linked_payment_entry(payment_entry)
-					self.db_delete_payment_entry(payment_entry)
+					to_remove.append(payment_entry)
 
 				elif remaining_amount <= 0.0:
-					self.db_delete_payment_entry(payment_entry)
+					to_remove.append(payment_entry)
 
-				elif 0.0 < unallocated_amount and unallocated_amount <= remaining_amount:
-					payment_entry.db_set("allocated_amount", unallocated_amount)
+				elif 0.0 < unallocated_amount <= remaining_amount:
+					payment_entry.allocated_amount = unallocated_amount
 					remaining_amount -= unallocated_amount
 					if should_clear:
 						latest_transaction.clear_linked_payment_entry(payment_entry)
 
-				elif 0.0 < unallocated_amount and unallocated_amount > remaining_amount:
-					payment_entry.db_set("allocated_amount", remaining_amount)
+				elif 0.0 < unallocated_amount:
+					payment_entry.allocated_amount = remaining_amount
 					remaining_amount = 0.0
 
 				elif 0.0 > unallocated_amount:
-					self.db_delete_payment_entry(payment_entry)
-					frappe.throw(frappe._("Voucher {0} is over-allocated by {1}").format(unallocated_amount))
+					frappe.throw(_("Voucher {0} is over-allocated by {1}").format(unallocated_amount))
 
-		self.reload()
-
-	def db_delete_payment_entry(self, payment_entry):
-		frappe.db.delete("Bank Transaction Payments", {"name": payment_entry.name})
+		for payment_entry in to_remove:
+			self.remove(to_remove)
 
 	@frappe.whitelist()
 	def remove_payment_entries(self):
 		for payment_entry in self.payment_entries:
 			self.remove_payment_entry(payment_entry)
-		# runs on_update_after_submit
-		self.save()
+
+		self.save()  # runs before_update_after_submit
 
 	def remove_payment_entry(self, payment_entry):
 		"Clear payment entry and clearance"
 		self.clear_linked_payment_entry(payment_entry, for_cancel=True)
 		self.remove(payment_entry)
 
-	def clear_linked_payment_entries(self, for_cancel=False):
-		if for_cancel:
-			for payment_entry in self.payment_entries:
-				self.clear_linked_payment_entry(payment_entry, for_cancel)
-		else:
-			self.allocate_payment_entries()
-
 	def clear_linked_payment_entry(self, payment_entry, for_cancel=False):
 		clearance_date = None if for_cancel else self.date
 		set_voucher_clearance(
@@ -162,11 +183,10 @@
 			deposit=self.deposit,
 		).match()
 
-		if result:
-			party_type, party = result
-			frappe.db.set_value(
-				"Bank Transaction", self.name, field={"party_type": party_type, "party": party}
-			)
+		if not result:
+			return
+
+		self.party_type, self.party = result
 
 
 @frappe.whitelist()
@@ -198,9 +218,7 @@
 		if gle["gl_account"] == gl_bank_account:
 			if gle["amount"] <= 0.0:
 				frappe.throw(
-					frappe._("Voucher {0} value is broken: {1}").format(
-						payment_entry.payment_entry, gle["amount"]
-					)
+					_("Voucher {0} value is broken: {1}").format(payment_entry.payment_entry, gle["amount"])
 				)
 
 			unmatched_gles -= 1
@@ -221,7 +239,7 @@
 
 def get_related_bank_gl_entries(doctype, docname):
 	# nosemgrep: frappe-semgrep-rules.rules.frappe-using-db-sql
-	result = frappe.db.sql(
+	return frappe.db.sql(
 		"""
 		SELECT
 			ABS(gle.credit_in_account_currency - gle.debit_in_account_currency) AS amount,
@@ -239,7 +257,6 @@
 		dict(doctype=doctype, docname=docname),
 		as_dict=True,
 	)
-	return result
 
 
 def get_total_allocated_amount(doctype, docname):
@@ -365,6 +382,7 @@
 		if clearance_date:
 			vouchers = [{"payment_doctype": "Bank Transaction", "payment_name": self.name}]
 			bt.add_payment_entries(vouchers)
+			bt.save()
 		else:
 			for pe in bt.payment_entries:
 				if pe.payment_document == self.doctype and pe.payment_entry == self.name:
diff --git a/erpnext/accounts/doctype/bank_transaction_mapping/bank_transaction_mapping.py b/erpnext/accounts/doctype/bank_transaction_mapping/bank_transaction_mapping.py
index e19712c..44aaf38 100644
--- a/erpnext/accounts/doctype/bank_transaction_mapping/bank_transaction_mapping.py
+++ b/erpnext/accounts/doctype/bank_transaction_mapping/bank_transaction_mapping.py
@@ -6,4 +6,19 @@
 
 
 class BankTransactionMapping(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
+
+		bank_transaction_field: DF.Literal
+		file_field: DF.Data
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/bank_transaction_payments/bank_transaction_payments.py b/erpnext/accounts/doctype/bank_transaction_payments/bank_transaction_payments.py
index 0536aa2..e0c84a3 100644
--- a/erpnext/accounts/doctype/bank_transaction_payments/bank_transaction_payments.py
+++ b/erpnext/accounts/doctype/bank_transaction_payments/bank_transaction_payments.py
@@ -6,4 +6,21 @@
 
 
 class BankTransactionPayments(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
+
+		allocated_amount: DF.Currency
+		clearance_date: DF.Date | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		payment_document: DF.Link
+		payment_entry: DF.DynamicLink
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/budget/budget.py b/erpnext/accounts/doctype/budget/budget.py
index 63e7bc6..2cf9d97 100644
--- a/erpnext/accounts/doctype/budget/budget.py
+++ b/erpnext/accounts/doctype/budget/budget.py
@@ -22,6 +22,36 @@
 
 
 class Budget(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
+
+		from erpnext.accounts.doctype.budget_account.budget_account import BudgetAccount
+
+		accounts: DF.Table[BudgetAccount]
+		action_if_accumulated_monthly_budget_exceeded: DF.Literal["", "Stop", "Warn", "Ignore"]
+		action_if_accumulated_monthly_budget_exceeded_on_mr: DF.Literal["", "Stop", "Warn", "Ignore"]
+		action_if_accumulated_monthly_budget_exceeded_on_po: DF.Literal["", "Stop", "Warn", "Ignore"]
+		action_if_annual_budget_exceeded: DF.Literal["", "Stop", "Warn", "Ignore"]
+		action_if_annual_budget_exceeded_on_mr: DF.Literal["", "Stop", "Warn", "Ignore"]
+		action_if_annual_budget_exceeded_on_po: DF.Literal["", "Stop", "Warn", "Ignore"]
+		amended_from: DF.Link | None
+		applicable_on_booking_actual_expenses: DF.Check
+		applicable_on_material_request: DF.Check
+		applicable_on_purchase_order: DF.Check
+		budget_against: DF.Literal["", "Cost Center", "Project"]
+		company: DF.Link
+		cost_center: DF.Link | None
+		fiscal_year: DF.Link
+		monthly_distribution: DF.Link | None
+		naming_series: DF.Data | None
+		project: DF.Link | None
+	# end: auto-generated types
+
 	def validate(self):
 		if not self.get(frappe.scrub(self.budget_against)):
 			frappe.throw(_("{0} is mandatory").format(self.budget_against))
diff --git a/erpnext/accounts/doctype/budget_account/budget_account.py b/erpnext/accounts/doctype/budget_account/budget_account.py
index 65bc951..db2b9a3 100644
--- a/erpnext/accounts/doctype/budget_account/budget_account.py
+++ b/erpnext/accounts/doctype/budget_account/budget_account.py
@@ -6,4 +6,19 @@
 
 
 class BudgetAccount(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: DF.Link
+		budget_amount: DF.Currency
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/campaign_item/campaign_item.py b/erpnext/accounts/doctype/campaign_item/campaign_item.py
index d78fdf5..929ac33 100644
--- a/erpnext/accounts/doctype/campaign_item/campaign_item.py
+++ b/erpnext/accounts/doctype/campaign_item/campaign_item.py
@@ -6,4 +6,18 @@
 
 
 class CampaignItem(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
+
+		campaign: DF.Link | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/cashier_closing/cashier_closing.py b/erpnext/accounts/doctype/cashier_closing/cashier_closing.py
index 6013807..6ab94c5 100644
--- a/erpnext/accounts/doctype/cashier_closing/cashier_closing.py
+++ b/erpnext/accounts/doctype/cashier_closing/cashier_closing.py
@@ -9,6 +9,32 @@
 
 
 class CashierClosing(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
+
+		from erpnext.accounts.doctype.cashier_closing_payments.cashier_closing_payments import (
+			CashierClosingPayments,
+		)
+
+		amended_from: DF.Link | None
+		custody: DF.Float
+		date: DF.Date | None
+		expense: DF.Float
+		from_time: DF.Time
+		naming_series: DF.Literal["POS-CLO-"]
+		net_amount: DF.Float
+		outstanding_amount: DF.Float
+		payments: DF.Table[CashierClosingPayments]
+		returns: DF.Float
+		time: DF.Time
+		user: DF.Link
+	# end: auto-generated types
+
 	def validate(self):
 		self.validate_time()
 
diff --git a/erpnext/accounts/doctype/cashier_closing_payments/cashier_closing_payments.py b/erpnext/accounts/doctype/cashier_closing_payments/cashier_closing_payments.py
index 7617f9b..84ce232 100644
--- a/erpnext/accounts/doctype/cashier_closing_payments/cashier_closing_payments.py
+++ b/erpnext/accounts/doctype/cashier_closing_payments/cashier_closing_payments.py
@@ -6,4 +6,19 @@
 
 
 class CashierClosingPayments(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
+
+		amount: DF.Float
+		mode_of_payment: DF.Link
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/chart_of_accounts_importer/chart_of_accounts_importer.py b/erpnext/accounts/doctype/chart_of_accounts_importer/chart_of_accounts_importer.py
index 5a1c139..1c805cc 100644
--- a/erpnext/accounts/doctype/chart_of_accounts_importer/chart_of_accounts_importer.py
+++ b/erpnext/accounts/doctype/chart_of_accounts_importer/chart_of_accounts_importer.py
@@ -24,6 +24,18 @@
 
 
 class ChartofAccountsImporter(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
+		import_file: DF.Attach | None
+	# end: auto-generated types
+
 	def validate(self):
 		if self.import_file:
 			get_coa(
@@ -113,7 +125,7 @@
 			if as_dict:
 				data.append({frappe.scrub(header): row[index] for index, header in enumerate(headers)})
 			else:
-				if not row[1]:
+				if not row[1] and len(row) > 1:
 					row[1] = row[0]
 					row[3] = row[2]
 				data.append(row)
diff --git a/erpnext/accounts/doctype/cheque_print_template/cheque_print_template.py b/erpnext/accounts/doctype/cheque_print_template/cheque_print_template.py
index f8ac664..205bb29 100644
--- a/erpnext/accounts/doctype/cheque_print_template/cheque_print_template.py
+++ b/erpnext/accounts/doctype/cheque_print_template/cheque_print_template.py
@@ -8,6 +8,41 @@
 
 
 class ChequePrintTemplate(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
+
+		acc_no_dist_from_left_edge: DF.Float
+		acc_no_dist_from_top_edge: DF.Float
+		acc_pay_dist_from_left_edge: DF.Float
+		acc_pay_dist_from_top_edge: DF.Float
+		amt_in_figures_from_left_edge: DF.Float
+		amt_in_figures_from_top_edge: DF.Float
+		amt_in_word_width: DF.Float
+		amt_in_words_from_left_edge: DF.Float
+		amt_in_words_from_top_edge: DF.Float
+		amt_in_words_line_spacing: DF.Float
+		bank_name: DF.Data
+		cheque_height: DF.Float
+		cheque_size: DF.Literal["", "Regular", "A4"]
+		cheque_width: DF.Float
+		date_dist_from_left_edge: DF.Float
+		date_dist_from_top_edge: DF.Float
+		has_print_format: DF.Check
+		is_account_payable: DF.Check
+		message_to_show: DF.Data | None
+		payer_name_from_left_edge: DF.Float
+		payer_name_from_top_edge: DF.Float
+		scanned_cheque: DF.Attach | None
+		signatory_from_left_edge: DF.Float
+		signatory_from_top_edge: DF.Float
+		starting_position_from_top_edge: DF.Float
+	# end: auto-generated types
+
 	pass
 
 
diff --git a/erpnext/accounts/doctype/closed_document/closed_document.py b/erpnext/accounts/doctype/closed_document/closed_document.py
index 89d3d2e..2f8cd52 100644
--- a/erpnext/accounts/doctype/closed_document/closed_document.py
+++ b/erpnext/accounts/doctype/closed_document/closed_document.py
@@ -6,4 +6,19 @@
 
 
 class ClosedDocument(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
+
+		closed: DF.Check
+		document_type: DF.Link
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/cost_center/cost_center.py b/erpnext/accounts/doctype/cost_center/cost_center.py
index e8b34bb..f662eb1 100644
--- a/erpnext/accounts/doctype/cost_center/cost_center.py
+++ b/erpnext/accounts/doctype/cost_center/cost_center.py
@@ -10,6 +10,25 @@
 
 
 class CostCenter(NestedSet):
+	# 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
+		cost_center_name: DF.Data
+		cost_center_number: DF.Data | None
+		disabled: DF.Check
+		is_group: DF.Check
+		lft: DF.Int
+		old_parent: DF.Link | None
+		parent_cost_center: DF.Link
+		rgt: DF.Int
+	# end: auto-generated types
+
 	nsm_parent_field = "parent_cost_center"
 
 	def autoname(self):
diff --git a/erpnext/accounts/doctype/cost_center_allocation/cost_center_allocation.py b/erpnext/accounts/doctype/cost_center_allocation/cost_center_allocation.py
index 54ffe21..9ed5ddf 100644
--- a/erpnext/accounts/doctype/cost_center_allocation/cost_center_allocation.py
+++ b/erpnext/accounts/doctype/cost_center_allocation/cost_center_allocation.py
@@ -28,6 +28,25 @@
 
 
 class CostCenterAllocation(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
+
+		from erpnext.accounts.doctype.cost_center_allocation_percentage.cost_center_allocation_percentage import (
+			CostCenterAllocationPercentage,
+		)
+
+		allocation_percentages: DF.Table[CostCenterAllocationPercentage]
+		amended_from: DF.Link | None
+		company: DF.Link
+		main_cost_center: DF.Link
+		valid_from: DF.Date
+	# end: auto-generated types
+
 	def __init__(self, *args, **kwargs):
 		super(CostCenterAllocation, self).__init__(*args, **kwargs)
 		self._skip_from_date_validation = False
diff --git a/erpnext/accounts/doctype/cost_center_allocation_percentage/cost_center_allocation_percentage.py b/erpnext/accounts/doctype/cost_center_allocation_percentage/cost_center_allocation_percentage.py
index 7d20efb..7257907 100644
--- a/erpnext/accounts/doctype/cost_center_allocation_percentage/cost_center_allocation_percentage.py
+++ b/erpnext/accounts/doctype/cost_center_allocation_percentage/cost_center_allocation_percentage.py
@@ -6,4 +6,19 @@
 
 
 class CostCenterAllocationPercentage(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
+
+		cost_center: DF.Link
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		percentage: DF.Percent
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/coupon_code/coupon_code.py b/erpnext/accounts/doctype/coupon_code/coupon_code.py
index 6a0cdf9..540011d 100644
--- a/erpnext/accounts/doctype/coupon_code/coupon_code.py
+++ b/erpnext/accounts/doctype/coupon_code/coupon_code.py
@@ -9,6 +9,27 @@
 
 
 class CouponCode(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
+
+		amended_from: DF.Link | None
+		coupon_code: DF.Data | None
+		coupon_name: DF.Data
+		coupon_type: DF.Literal["Promotional", "Gift Card"]
+		customer: DF.Link | None
+		description: DF.TextEditor | None
+		maximum_use: DF.Int
+		pricing_rule: DF.Link
+		used: DF.Int
+		valid_from: DF.Date | None
+		valid_upto: DF.Date | None
+	# end: auto-generated types
+
 	def autoname(self):
 		self.coupon_name = strip(self.coupon_name)
 		self.name = self.coupon_name
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 117d5ff..3393d41 100644
--- a/erpnext/accounts/doctype/currency_exchange_settings/currency_exchange_settings.py
+++ b/erpnext/accounts/doctype/currency_exchange_settings/currency_exchange_settings.py
@@ -9,6 +9,30 @@
 
 
 class CurrencyExchangeSettings(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
+
+		from erpnext.accounts.doctype.currency_exchange_settings_details.currency_exchange_settings_details import (
+			CurrencyExchangeSettingsDetails,
+		)
+		from erpnext.accounts.doctype.currency_exchange_settings_result.currency_exchange_settings_result import (
+			CurrencyExchangeSettingsResult,
+		)
+
+		access_key: DF.Data | None
+		api_endpoint: DF.Data
+		disabled: DF.Check
+		req_params: DF.Table[CurrencyExchangeSettingsDetails]
+		result_key: DF.Table[CurrencyExchangeSettingsResult]
+		service_provider: DF.Literal["frankfurter.app", "exchangerate.host", "Custom"]
+		url: DF.Data | None
+	# end: auto-generated types
+
 	def validate(self):
 		self.set_parameters_and_result()
 		if frappe.flags.in_test or frappe.flags.in_install or frappe.flags.in_setup_wizard:
diff --git a/erpnext/accounts/doctype/currency_exchange_settings_details/currency_exchange_settings_details.py b/erpnext/accounts/doctype/currency_exchange_settings_details/currency_exchange_settings_details.py
index a6ad763..bba0d5d 100644
--- a/erpnext/accounts/doctype/currency_exchange_settings_details/currency_exchange_settings_details.py
+++ b/erpnext/accounts/doctype/currency_exchange_settings_details/currency_exchange_settings_details.py
@@ -6,4 +6,19 @@
 
 
 class CurrencyExchangeSettingsDetails(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
+
+		key: DF.Data
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		value: DF.Data
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/currency_exchange_settings_result/currency_exchange_settings_result.py b/erpnext/accounts/doctype/currency_exchange_settings_result/currency_exchange_settings_result.py
index 1774128..75fb1df 100644
--- a/erpnext/accounts/doctype/currency_exchange_settings_result/currency_exchange_settings_result.py
+++ b/erpnext/accounts/doctype/currency_exchange_settings_result/currency_exchange_settings_result.py
@@ -6,4 +6,18 @@
 
 
 class CurrencyExchangeSettingsResult(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
+
+		key: DF.Data
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/customer_group_item/customer_group_item.py b/erpnext/accounts/doctype/customer_group_item/customer_group_item.py
index 100bfd5..db76f5b 100644
--- a/erpnext/accounts/doctype/customer_group_item/customer_group_item.py
+++ b/erpnext/accounts/doctype/customer_group_item/customer_group_item.py
@@ -6,4 +6,18 @@
 
 
 class CustomerGroupItem(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
+
+		customer_group: DF.Link | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/customer_item/customer_item.py b/erpnext/accounts/doctype/customer_item/customer_item.py
index da3533f..67473d4 100644
--- a/erpnext/accounts/doctype/customer_item/customer_item.py
+++ b/erpnext/accounts/doctype/customer_item/customer_item.py
@@ -6,4 +6,18 @@
 
 
 class CustomerItem(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
+
+		customer: DF.Link | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/discounted_invoice/discounted_invoice.py b/erpnext/accounts/doctype/discounted_invoice/discounted_invoice.py
index 9b8932c..25bef70 100644
--- a/erpnext/accounts/doctype/discounted_invoice/discounted_invoice.py
+++ b/erpnext/accounts/doctype/discounted_invoice/discounted_invoice.py
@@ -7,4 +7,22 @@
 
 
 class DiscountedInvoice(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
+
+		customer: DF.Link | None
+		debit_to: DF.Link | None
+		outstanding_amount: DF.Currency
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		posting_date: DF.Date | None
+		sales_invoice: DF.Link
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/dunning/dunning.py b/erpnext/accounts/doctype/dunning/dunning.py
index 9d0d36b..c61c332 100644
--- a/erpnext/accounts/doctype/dunning/dunning.py
+++ b/erpnext/accounts/doctype/dunning/dunning.py
@@ -22,6 +22,52 @@
 
 
 class Dunning(AccountsController):
+	# 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
+
+		from erpnext.accounts.doctype.overdue_payment.overdue_payment import OverduePayment
+
+		address_display: DF.SmallText | None
+		amended_from: DF.Link | None
+		base_dunning_amount: DF.Currency
+		body_text: DF.TextEditor | None
+		closing_text: DF.TextEditor | None
+		company: DF.Link
+		company_address: DF.Link | None
+		company_address_display: DF.SmallText | None
+		contact_display: DF.SmallText | None
+		contact_email: DF.Data | None
+		contact_mobile: DF.SmallText | None
+		contact_person: DF.Link | None
+		conversion_rate: DF.Float
+		cost_center: DF.Link | None
+		currency: DF.Link | None
+		customer: DF.Link
+		customer_address: DF.Link | None
+		customer_name: DF.Data | None
+		dunning_amount: DF.Currency
+		dunning_fee: DF.Currency
+		dunning_type: DF.Link | None
+		grand_total: DF.Currency
+		income_account: DF.Link | None
+		language: DF.Link | None
+		letter_head: DF.Link | None
+		naming_series: DF.Literal["DUNN-.MM.-.YY.-"]
+		overdue_payments: DF.Table[OverduePayment]
+		posting_date: DF.Date
+		posting_time: DF.Time | None
+		rate_of_interest: DF.Float
+		spacer: DF.Data | None
+		status: DF.Literal["Draft", "Resolved", "Unresolved", "Cancelled"]
+		total_interest: DF.Currency
+		total_outstanding: DF.Currency
+	# end: auto-generated types
+
 	def validate(self):
 		self.validate_same_currency()
 		self.validate_overdue_payments()
diff --git a/erpnext/accounts/doctype/dunning_letter_text/dunning_letter_text.py b/erpnext/accounts/doctype/dunning_letter_text/dunning_letter_text.py
index 9f3cf7f..a126ff7 100644
--- a/erpnext/accounts/doctype/dunning_letter_text/dunning_letter_text.py
+++ b/erpnext/accounts/doctype/dunning_letter_text/dunning_letter_text.py
@@ -7,4 +7,21 @@
 
 
 class DunningLetterText(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
+
+		body_text: DF.TextEditor | None
+		closing_text: DF.TextEditor | None
+		is_default_language: DF.Check
+		language: DF.Link | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/dunning_type/dunning_type.py b/erpnext/accounts/doctype/dunning_type/dunning_type.py
index 226e159..77f2e00 100644
--- a/erpnext/accounts/doctype/dunning_type/dunning_type.py
+++ b/erpnext/accounts/doctype/dunning_type/dunning_type.py
@@ -7,6 +7,26 @@
 
 
 class DunningType(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
+
+		from erpnext.accounts.doctype.dunning_letter_text.dunning_letter_text import DunningLetterText
+
+		company: DF.Link
+		cost_center: DF.Link | None
+		dunning_fee: DF.Currency
+		dunning_letter_text: DF.Table[DunningLetterText]
+		dunning_type: DF.Data
+		income_account: DF.Link | None
+		is_default: DF.Check
+		rate_of_interest: DF.Float
+	# end: auto-generated types
+
 	def autoname(self):
 		company_abbr = frappe.get_value("Company", self.company, "abbr")
 		self.name = f"{self.dunning_type} - {company_abbr}"
diff --git a/erpnext/accounts/doctype/exchange_rate_revaluation/exchange_rate_revaluation.py b/erpnext/accounts/doctype/exchange_rate_revaluation/exchange_rate_revaluation.py
index 3b5698b..e9cbb33 100644
--- a/erpnext/accounts/doctype/exchange_rate_revaluation/exchange_rate_revaluation.py
+++ b/erpnext/accounts/doctype/exchange_rate_revaluation/exchange_rate_revaluation.py
@@ -17,6 +17,28 @@
 
 
 class ExchangeRateRevaluation(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
+
+		from erpnext.accounts.doctype.exchange_rate_revaluation_account.exchange_rate_revaluation_account import (
+			ExchangeRateRevaluationAccount,
+		)
+
+		accounts: DF.Table[ExchangeRateRevaluationAccount]
+		amended_from: DF.Link | None
+		company: DF.Link
+		gain_loss_booked: DF.Currency
+		gain_loss_unbooked: DF.Currency
+		posting_date: DF.Date
+		rounding_loss_allowance: DF.Float
+		total_gain_loss: DF.Currency
+	# end: auto-generated types
+
 	def validate(self):
 		self.validate_rounding_loss_allowance()
 		self.set_total_gain_loss()
@@ -192,7 +214,7 @@
 				# round off balance based on currency precision
 				# and consider debit-credit difference allowance
 				currency_precision = get_currency_precision()
-				rounding_loss_allowance = float(rounding_loss_allowance) or 0.05
+				rounding_loss_allowance = float(rounding_loss_allowance)
 				for acc in account_details:
 					acc.balance_in_account_currency = flt(acc.balance_in_account_currency, currency_precision)
 					if abs(acc.balance_in_account_currency) <= rounding_loss_allowance:
diff --git a/erpnext/accounts/doctype/exchange_rate_revaluation_account/exchange_rate_revaluation_account.py b/erpnext/accounts/doctype/exchange_rate_revaluation_account/exchange_rate_revaluation_account.py
index 96a92bb..4efdfdd 100644
--- a/erpnext/accounts/doctype/exchange_rate_revaluation_account/exchange_rate_revaluation_account.py
+++ b/erpnext/accounts/doctype/exchange_rate_revaluation_account/exchange_rate_revaluation_account.py
@@ -6,4 +6,29 @@
 
 
 class ExchangeRateRevaluationAccount(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: DF.Link
+		account_currency: DF.Link | None
+		balance_in_account_currency: DF.Currency
+		balance_in_base_currency: DF.Currency
+		current_exchange_rate: DF.Float
+		gain_loss: DF.Currency
+		new_balance_in_account_currency: DF.Currency
+		new_balance_in_base_currency: DF.Currency
+		new_exchange_rate: DF.Float
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		party: DF.DynamicLink | None
+		party_type: DF.Link | None
+		zero_balance: DF.Check
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/finance_book/finance_book.py b/erpnext/accounts/doctype/finance_book/finance_book.py
index 78b321b..a8f7a40 100644
--- a/erpnext/accounts/doctype/finance_book/finance_book.py
+++ b/erpnext/accounts/doctype/finance_book/finance_book.py
@@ -6,4 +6,15 @@
 
 
 class FinanceBook(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
+
+		finance_book_name: DF.Data | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/fiscal_year/fiscal_year.py b/erpnext/accounts/doctype/fiscal_year/fiscal_year.py
index 0dfe569..85f3ffd 100644
--- a/erpnext/accounts/doctype/fiscal_year/fiscal_year.py
+++ b/erpnext/accounts/doctype/fiscal_year/fiscal_year.py
@@ -10,6 +10,25 @@
 
 
 class FiscalYear(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
+
+		from erpnext.accounts.doctype.fiscal_year_company.fiscal_year_company import FiscalYearCompany
+
+		auto_created: DF.Check
+		companies: DF.Table[FiscalYearCompany]
+		disabled: DF.Check
+		is_short_year: DF.Check
+		year: DF.Data
+		year_end_date: DF.Date
+		year_start_date: DF.Date
+	# end: auto-generated types
+
 	def validate(self):
 		self.validate_dates()
 		self.validate_overlap()
diff --git a/erpnext/accounts/doctype/fiscal_year_company/fiscal_year_company.py b/erpnext/accounts/doctype/fiscal_year_company/fiscal_year_company.py
index d5db78d..9447120 100644
--- a/erpnext/accounts/doctype/fiscal_year_company/fiscal_year_company.py
+++ b/erpnext/accounts/doctype/fiscal_year_company/fiscal_year_company.py
@@ -6,4 +6,18 @@
 
 
 class FiscalYearCompany(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
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/gl_entry/gl_entry.py b/erpnext/accounts/doctype/gl_entry/gl_entry.py
index 7af40c4..f7dd29a 100644
--- a/erpnext/accounts/doctype/gl_entry/gl_entry.py
+++ b/erpnext/accounts/doctype/gl_entry/gl_entry.py
@@ -28,6 +28,47 @@
 
 
 class GLEntry(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: DF.Link | None
+		account_currency: DF.Link | None
+		against: DF.Text | None
+		against_voucher: DF.DynamicLink | None
+		against_voucher_type: DF.Link | None
+		company: DF.Link | None
+		cost_center: DF.Link | None
+		credit: DF.Currency
+		credit_in_account_currency: DF.Currency
+		credit_in_transaction_currency: DF.Currency
+		debit: DF.Currency
+		debit_in_account_currency: DF.Currency
+		debit_in_transaction_currency: DF.Currency
+		due_date: DF.Date | None
+		finance_book: DF.Link | None
+		fiscal_year: DF.Link | None
+		is_advance: DF.Literal["No", "Yes"]
+		is_cancelled: DF.Check
+		is_opening: DF.Literal["No", "Yes"]
+		party: DF.DynamicLink | None
+		party_type: DF.Link | None
+		posting_date: DF.Date | None
+		project: DF.Link | None
+		remarks: DF.Text | None
+		to_rename: DF.Check
+		transaction_currency: DF.Link | None
+		transaction_date: DF.Date | None
+		transaction_exchange_rate: DF.Float
+		voucher_detail_no: DF.Data | None
+		voucher_no: DF.DynamicLink | None
+		voucher_type: DF.Link | None
+	# end: auto-generated types
+
 	def autoname(self):
 		"""
 		Temporarily name doc for fast insertion
diff --git a/erpnext/accounts/doctype/invoice_discounting/invoice_discounting.py b/erpnext/accounts/doctype/invoice_discounting/invoice_discounting.py
index 5bd4585..76f4dad 100644
--- a/erpnext/accounts/doctype/invoice_discounting/invoice_discounting.py
+++ b/erpnext/accounts/doctype/invoice_discounting/invoice_discounting.py
@@ -17,6 +17,34 @@
 
 
 class InvoiceDiscounting(AccountsController):
+	# 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
+
+		from erpnext.accounts.doctype.discounted_invoice.discounted_invoice import DiscountedInvoice
+
+		accounts_receivable_credit: DF.Link
+		accounts_receivable_discounted: DF.Link
+		accounts_receivable_unpaid: DF.Link
+		amended_from: DF.Link | None
+		bank_account: DF.Link
+		bank_charges: DF.Currency
+		bank_charges_account: DF.Link
+		company: DF.Link
+		invoices: DF.Table[DiscountedInvoice]
+		loan_end_date: DF.Date | None
+		loan_period: DF.Int
+		loan_start_date: DF.Date | None
+		posting_date: DF.Date
+		short_term_loan: DF.Link
+		status: DF.Literal["Draft", "Sanctioned", "Disbursed", "Settled", "Cancelled"]
+		total_amount: DF.Currency
+	# end: auto-generated types
+
 	def validate(self):
 		self.validate_mandatory()
 		self.validate_invoices()
diff --git a/erpnext/accounts/doctype/item_tax_template/item_tax_template.py b/erpnext/accounts/doctype/item_tax_template/item_tax_template.py
index 7e2fca8..8d3cdc8 100644
--- a/erpnext/accounts/doctype/item_tax_template/item_tax_template.py
+++ b/erpnext/accounts/doctype/item_tax_template/item_tax_template.py
@@ -8,6 +8,24 @@
 
 
 class ItemTaxTemplate(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
+
+		from erpnext.accounts.doctype.item_tax_template_detail.item_tax_template_detail import (
+			ItemTaxTemplateDetail,
+		)
+
+		company: DF.Link
+		disabled: DF.Check
+		taxes: DF.Table[ItemTaxTemplateDetail]
+		title: DF.Data
+	# end: auto-generated types
+
 	def validate(self):
 		self.validate_tax_accounts()
 
diff --git a/erpnext/accounts/doctype/item_tax_template_detail/item_tax_template_detail.py b/erpnext/accounts/doctype/item_tax_template_detail/item_tax_template_detail.py
index 221081e..810235e 100644
--- a/erpnext/accounts/doctype/item_tax_template_detail/item_tax_template_detail.py
+++ b/erpnext/accounts/doctype/item_tax_template_detail/item_tax_template_detail.py
@@ -6,4 +6,19 @@
 
 
 class ItemTaxTemplateDetail(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
+
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		tax_rate: DF.Float
+		tax_type: DF.Link
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.js b/erpnext/accounts/doctype/journal_entry/journal_entry.js
index 22b6880..9684a0d 100644
--- a/erpnext/accounts/doctype/journal_entry/journal_entry.js
+++ b/erpnext/accounts/doctype/journal_entry/journal_entry.js
@@ -51,7 +51,7 @@
 				}, __('Make'));
 		}
 
-		erpnext.accounts.unreconcile_payments.add_unreconcile_btn(frm);
+		erpnext.accounts.unreconcile_payment.add_unreconcile_btn(frm);
 	},
 	before_save: function(frm) {
 		if ((frm.doc.docstatus == 0) && (!frm.doc.is_system_generated)) {
diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.json b/erpnext/accounts/doctype/journal_entry/journal_entry.json
index 2eb54a5..906760e 100644
--- a/erpnext/accounts/doctype/journal_entry/journal_entry.json
+++ b/erpnext/accounts/doctype/journal_entry/journal_entry.json
@@ -548,8 +548,16 @@
  "icon": "fa fa-file-text",
  "idx": 176,
  "is_submittable": 1,
- "links": [],
- "modified": "2023-08-10 14:32:22.366895",
+ "links": [
+  {
+   "is_child_table": 1,
+   "link_doctype": "Bank Transaction Payments",
+   "link_fieldname": "payment_entry",
+   "parent_doctype": "Bank Transaction",
+   "table_fieldname": "payment_entries"
+  }
+ ],
+ "modified": "2023-11-23 12:11:04.128015",
  "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 85ef6f7..e4f1645 100644
--- a/erpnext/accounts/doctype/journal_entry/journal_entry.py
+++ b/erpnext/accounts/doctype/journal_entry/journal_entry.py
@@ -35,6 +35,78 @@
 
 
 class JournalEntry(AccountsController):
+	# 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
+
+		from erpnext.accounts.doctype.journal_entry_account.journal_entry_account import (
+			JournalEntryAccount,
+		)
+
+		accounts: DF.Table[JournalEntryAccount]
+		amended_from: DF.Link | None
+		apply_tds: DF.Check
+		auto_repeat: DF.Link | None
+		bill_date: DF.Date | None
+		bill_no: DF.Data | None
+		cheque_date: DF.Date | None
+		cheque_no: DF.Data | None
+		clearance_date: DF.Date | None
+		company: DF.Link
+		difference: DF.Currency
+		due_date: DF.Date | None
+		finance_book: DF.Link | None
+		from_template: DF.Link | None
+		inter_company_journal_entry_reference: DF.Link | None
+		is_opening: DF.Literal["No", "Yes"]
+		is_system_generated: DF.Check
+		letter_head: DF.Link | None
+		mode_of_payment: DF.Link | None
+		multi_currency: DF.Check
+		naming_series: DF.Literal["ACC-JV-.YYYY.-"]
+		paid_loan: DF.Data | None
+		pay_to_recd_from: DF.Data | None
+		payment_order: DF.Link | None
+		posting_date: DF.Date
+		process_deferred_accounting: DF.Link | None
+		remark: DF.SmallText | None
+		reversal_of: DF.Link | None
+		select_print_heading: DF.Link | None
+		stock_entry: DF.Link | None
+		tax_withholding_category: DF.Link | None
+		title: DF.Data | None
+		total_amount: DF.Currency
+		total_amount_currency: DF.Link | None
+		total_amount_in_words: DF.Data | None
+		total_credit: DF.Currency
+		total_debit: DF.Currency
+		user_remark: DF.SmallText | None
+		voucher_type: DF.Literal[
+			"Journal Entry",
+			"Inter Company Journal Entry",
+			"Bank Entry",
+			"Cash Entry",
+			"Credit Card Entry",
+			"Debit Note",
+			"Credit Note",
+			"Contra Entry",
+			"Excise Entry",
+			"Write Off Entry",
+			"Opening Entry",
+			"Depreciation Entry",
+			"Exchange Rate Revaluation",
+			"Exchange Gain Or Loss",
+			"Deferred Revenue",
+			"Deferred Expense",
+		]
+		write_off_amount: DF.Currency
+		write_off_based_on: DF.Literal["Accounts Receivable", "Accounts Payable"]
+	# end: auto-generated types
+
 	def __init__(self, *args, **kwargs):
 		super(JournalEntry, self).__init__(*args, **kwargs)
 
@@ -508,7 +580,7 @@
 							).format(d.reference_name, d.account)
 						)
 				else:
-					dr_or_cr = "debit" if d.credit > 0 else "credit"
+					dr_or_cr = "debit" if flt(d.credit) > 0 else "credit"
 					valid = False
 					for jvd in against_entries:
 						if flt(jvd[dr_or_cr]) > 0:
@@ -868,7 +940,7 @@
 					party_account_currency = d.account_currency
 
 			elif frappe.get_cached_value("Account", d.account, "account_type") in ["Bank", "Cash"]:
-				bank_amount += d.debit_in_account_currency or d.credit_in_account_currency
+				bank_amount += flt(d.debit_in_account_currency) or flt(d.credit_in_account_currency)
 				bank_account_currency = d.account_currency
 
 		if party_type and pay_to_recd_from:
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 3ba8cea..3132fe9 100644
--- a/erpnext/accounts/doctype/journal_entry_account/journal_entry_account.json
+++ b/erpnext/accounts/doctype/journal_entry_account/journal_entry_account.json
@@ -203,7 +203,8 @@
    "fieldtype": "Select",
    "label": "Reference Type",
    "no_copy": 1,
-   "options": "\nSales Invoice\nPurchase Invoice\nJournal Entry\nSales Order\nPurchase Order\nExpense Claim\nAsset\nLoan\nPayroll Entry\nEmployee Advance\nExchange Rate Revaluation\nInvoice Discounting\nFees\nFull and Final Statement\nPayment Entry"
+   "options": "\nSales Invoice\nPurchase Invoice\nJournal Entry\nSales Order\nPurchase Order\nExpense Claim\nAsset\nLoan\nPayroll Entry\nEmployee Advance\nExchange Rate Revaluation\nInvoice Discounting\nFees\nFull and Final Statement\nPayment Entry",
+   "search_index": 1
   },
   {
    "fieldname": "reference_name",
@@ -211,7 +212,8 @@
    "in_list_view": 1,
    "label": "Reference Name",
    "no_copy": 1,
-   "options": "reference_type"
+   "options": "reference_type",
+   "search_index": 1
   },
   {
    "depends_on": "eval:doc.reference_type&&!in_list(doc.reference_type, ['Expense Claim', 'Asset', 'Employee Loan', 'Employee Advance'])",
@@ -278,13 +280,14 @@
    "fieldtype": "Data",
    "hidden": 1,
    "label": "Reference Detail No",
-   "no_copy": 1
+   "no_copy": 1,
+   "search_index": 1
   }
  ],
  "idx": 1,
  "istable": 1,
  "links": [],
- "modified": "2023-06-16 14:11:13.507807",
+ "modified": "2023-11-23 11:44:25.841187",
  "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 534b589..00c9dcb 100644
--- a/erpnext/accounts/doctype/journal_entry_account/journal_entry_account.py
+++ b/erpnext/accounts/doctype/journal_entry_account/journal_entry_account.py
@@ -6,4 +6,56 @@
 
 
 class JournalEntryAccount(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: DF.Link
+		account_currency: DF.Link | None
+		account_type: DF.Data | None
+		against_account: DF.Text | None
+		balance: DF.Currency
+		bank_account: DF.Link | None
+		cost_center: DF.Link | None
+		credit: DF.Currency
+		credit_in_account_currency: DF.Currency
+		debit: DF.Currency
+		debit_in_account_currency: DF.Currency
+		exchange_rate: DF.Float
+		is_advance: DF.Literal["No", "Yes"]
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		party: DF.DynamicLink | None
+		party_balance: DF.Currency
+		party_type: DF.Link | None
+		project: DF.Link | None
+		reference_detail_no: DF.Data | None
+		reference_due_date: DF.Date | None
+		reference_name: DF.DynamicLink | None
+		reference_type: DF.Literal[
+			"",
+			"Sales Invoice",
+			"Purchase Invoice",
+			"Journal Entry",
+			"Sales Order",
+			"Purchase Order",
+			"Expense Claim",
+			"Asset",
+			"Loan",
+			"Payroll Entry",
+			"Employee Advance",
+			"Exchange Rate Revaluation",
+			"Invoice Discounting",
+			"Fees",
+			"Full and Final Statement",
+			"Payment Entry",
+		]
+		user_remark: DF.SmallText | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/journal_entry_template/journal_entry_template.py b/erpnext/accounts/doctype/journal_entry_template/journal_entry_template.py
index b8ef354..f87efc5 100644
--- a/erpnext/accounts/doctype/journal_entry_template/journal_entry_template.py
+++ b/erpnext/accounts/doctype/journal_entry_template/journal_entry_template.py
@@ -7,6 +7,41 @@
 
 
 class JournalEntryTemplate(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
+
+		from erpnext.accounts.doctype.journal_entry_template_account.journal_entry_template_account import (
+			JournalEntryTemplateAccount,
+		)
+
+		accounts: DF.Table[JournalEntryTemplateAccount]
+		company: DF.Link
+		is_opening: DF.Literal["No", "Yes"]
+		multi_currency: DF.Check
+		naming_series: DF.Literal
+		template_title: DF.Data
+		voucher_type: DF.Literal[
+			"Journal Entry",
+			"Inter Company Journal Entry",
+			"Bank Entry",
+			"Cash Entry",
+			"Credit Card Entry",
+			"Debit Note",
+			"Credit Note",
+			"Contra Entry",
+			"Excise Entry",
+			"Write Off Entry",
+			"Opening Entry",
+			"Depreciation Entry",
+			"Exchange Rate Revaluation",
+		]
+	# end: auto-generated types
+
 	pass
 
 
diff --git a/erpnext/accounts/doctype/journal_entry_template_account/journal_entry_template_account.py b/erpnext/accounts/doctype/journal_entry_template_account/journal_entry_template_account.py
index f84fddd..2426f57 100644
--- a/erpnext/accounts/doctype/journal_entry_template_account/journal_entry_template_account.py
+++ b/erpnext/accounts/doctype/journal_entry_template_account/journal_entry_template_account.py
@@ -7,4 +7,18 @@
 
 
 class JournalEntryTemplateAccount(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: DF.Link
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/ledger_merge/ledger_merge.py b/erpnext/accounts/doctype/ledger_merge/ledger_merge.py
index 362d273..4999339 100644
--- a/erpnext/accounts/doctype/ledger_merge/ledger_merge.py
+++ b/erpnext/accounts/doctype/ledger_merge/ledger_merge.py
@@ -10,6 +10,27 @@
 
 
 class LedgerMerge(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
+
+		from erpnext.accounts.doctype.ledger_merge_accounts.ledger_merge_accounts import (
+			LedgerMergeAccounts,
+		)
+
+		account: DF.Link
+		account_name: DF.Data
+		company: DF.Link
+		is_group: DF.Check
+		merge_accounts: DF.Table[LedgerMergeAccounts]
+		root_type: DF.Literal["", "Asset", "Liability", "Income", "Expense", "Equity"]
+		status: DF.Literal["Pending", "Success", "Partial Success", "Error"]
+	# end: auto-generated types
+
 	def start_merge(self):
 		from frappe.utils.background_jobs import enqueue
 		from frappe.utils.scheduler import is_scheduler_inactive
diff --git a/erpnext/accounts/doctype/ledger_merge_accounts/ledger_merge_accounts.py b/erpnext/accounts/doctype/ledger_merge_accounts/ledger_merge_accounts.py
index 30dfd65..e40e7d6 100644
--- a/erpnext/accounts/doctype/ledger_merge_accounts/ledger_merge_accounts.py
+++ b/erpnext/accounts/doctype/ledger_merge_accounts/ledger_merge_accounts.py
@@ -6,4 +6,20 @@
 
 
 class LedgerMergeAccounts(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: DF.Link
+		account_name: DF.Data
+		merged: DF.Check
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/loyalty_point_entry/loyalty_point_entry.py b/erpnext/accounts/doctype/loyalty_point_entry/loyalty_point_entry.py
index dcb43fb..eb8a066 100644
--- a/erpnext/accounts/doctype/loyalty_point_entry/loyalty_point_entry.py
+++ b/erpnext/accounts/doctype/loyalty_point_entry/loyalty_point_entry.py
@@ -10,6 +10,27 @@
 
 
 class LoyaltyPointEntry(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
+		customer: DF.Link | None
+		expiry_date: DF.Date | None
+		invoice: DF.DynamicLink | None
+		invoice_type: DF.Link | None
+		loyalty_points: DF.Int
+		loyalty_program: DF.Link | None
+		loyalty_program_tier: DF.Data | None
+		posting_date: DF.Date | None
+		purchase_amount: DF.Currency
+		redeem_against: DF.Link | None
+	# end: auto-generated types
+
 	pass
 
 
diff --git a/erpnext/accounts/doctype/loyalty_point_entry_redemption/loyalty_point_entry_redemption.py b/erpnext/accounts/doctype/loyalty_point_entry_redemption/loyalty_point_entry_redemption.py
index bc8f5c7..1463b10 100644
--- a/erpnext/accounts/doctype/loyalty_point_entry_redemption/loyalty_point_entry_redemption.py
+++ b/erpnext/accounts/doctype/loyalty_point_entry_redemption/loyalty_point_entry_redemption.py
@@ -6,4 +6,20 @@
 
 
 class LoyaltyPointEntryRedemption(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
+
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		redeemed_points: DF.Int
+		redemption_date: DF.Date | None
+		sales_invoice: DF.Data | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/loyalty_program/loyalty_program.py b/erpnext/accounts/doctype/loyalty_program/loyalty_program.py
index 4f58579..463b3cd 100644
--- a/erpnext/accounts/doctype/loyalty_program/loyalty_program.py
+++ b/erpnext/accounts/doctype/loyalty_program/loyalty_program.py
@@ -9,6 +9,33 @@
 
 
 class LoyaltyProgram(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
+
+		from erpnext.accounts.doctype.loyalty_program_collection.loyalty_program_collection import (
+			LoyaltyProgramCollection,
+		)
+
+		auto_opt_in: DF.Check
+		collection_rules: DF.Table[LoyaltyProgramCollection]
+		company: DF.Link | None
+		conversion_factor: DF.Float
+		cost_center: DF.Link | None
+		customer_group: DF.Link | None
+		customer_territory: DF.Link | None
+		expense_account: DF.Link | None
+		expiry_duration: DF.Int
+		from_date: DF.Date
+		loyalty_program_name: DF.Data
+		loyalty_program_type: DF.Literal["Single Tier Program", "Multiple Tier Program"]
+		to_date: DF.Date | None
+	# end: auto-generated types
+
 	pass
 
 
diff --git a/erpnext/accounts/doctype/loyalty_program_collection/loyalty_program_collection.py b/erpnext/accounts/doctype/loyalty_program_collection/loyalty_program_collection.py
index c462d5f..b6cecb8 100644
--- a/erpnext/accounts/doctype/loyalty_program_collection/loyalty_program_collection.py
+++ b/erpnext/accounts/doctype/loyalty_program_collection/loyalty_program_collection.py
@@ -6,4 +6,20 @@
 
 
 class LoyaltyProgramCollection(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
+
+		collection_factor: DF.Currency
+		min_spent: DF.Currency
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		tier_name: DF.Data
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/mode_of_payment/mode_of_payment.py b/erpnext/accounts/doctype/mode_of_payment/mode_of_payment.py
index 7d6ef3c..6fc9eba 100644
--- a/erpnext/accounts/doctype/mode_of_payment/mode_of_payment.py
+++ b/erpnext/accounts/doctype/mode_of_payment/mode_of_payment.py
@@ -8,6 +8,24 @@
 
 
 class ModeofPayment(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
+
+		from erpnext.accounts.doctype.mode_of_payment_account.mode_of_payment_account import (
+			ModeofPaymentAccount,
+		)
+
+		accounts: DF.Table[ModeofPaymentAccount]
+		enabled: DF.Check
+		mode_of_payment: DF.Data
+		type: DF.Literal["Cash", "Bank", "General", "Phone"]
+	# end: auto-generated types
+
 	def validate(self):
 		self.validate_accounts()
 		self.validate_repeating_companies()
diff --git a/erpnext/accounts/doctype/mode_of_payment_account/mode_of_payment_account.py b/erpnext/accounts/doctype/mode_of_payment_account/mode_of_payment_account.py
index 3d3bba6..e20d6fb 100644
--- a/erpnext/accounts/doctype/mode_of_payment_account/mode_of_payment_account.py
+++ b/erpnext/accounts/doctype/mode_of_payment_account/mode_of_payment_account.py
@@ -6,4 +6,19 @@
 
 
 class ModeofPaymentAccount(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
+		default_account: DF.Link | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/monthly_distribution/monthly_distribution.py b/erpnext/accounts/doctype/monthly_distribution/monthly_distribution.py
index 1d19708..7270576 100644
--- a/erpnext/accounts/doctype/monthly_distribution/monthly_distribution.py
+++ b/erpnext/accounts/doctype/monthly_distribution/monthly_distribution.py
@@ -9,6 +9,23 @@
 
 
 class MonthlyDistribution(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
+
+		from erpnext.accounts.doctype.monthly_distribution_percentage.monthly_distribution_percentage import (
+			MonthlyDistributionPercentage,
+		)
+
+		distribution_id: DF.Data
+		fiscal_year: DF.Link | None
+		percentages: DF.Table[MonthlyDistributionPercentage]
+	# end: auto-generated types
+
 	@frappe.whitelist()
 	def get_months(self):
 		month_list = [
diff --git a/erpnext/accounts/doctype/monthly_distribution_percentage/monthly_distribution_percentage.py b/erpnext/accounts/doctype/monthly_distribution_percentage/monthly_distribution_percentage.py
index 274e2b6..d12f79f 100644
--- a/erpnext/accounts/doctype/monthly_distribution_percentage/monthly_distribution_percentage.py
+++ b/erpnext/accounts/doctype/monthly_distribution_percentage/monthly_distribution_percentage.py
@@ -6,4 +6,19 @@
 
 
 class MonthlyDistributionPercentage(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
+
+		month: DF.Data
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		percentage_allocation: DF.Float
+	# end: auto-generated types
+
 	pass
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 680afb1..f5f8f8a 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
@@ -14,6 +14,25 @@
 
 
 class OpeningInvoiceCreationTool(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
+
+		from erpnext.accounts.doctype.opening_invoice_creation_tool_item.opening_invoice_creation_tool_item import (
+			OpeningInvoiceCreationToolItem,
+		)
+
+		company: DF.Link
+		cost_center: DF.Link | None
+		create_missing_party: DF.Check
+		invoice_type: DF.Literal["Sales", "Purchase"]
+		invoices: DF.Table[OpeningInvoiceCreationToolItem]
+	# end: auto-generated types
+
 	def onload(self):
 		"""Load the Opening Invoice summary"""
 		summary, max_count = self.get_opening_invoice_summary()
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 6c0ca4a..bc48300 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
@@ -6,4 +6,27 @@
 
 
 class OpeningInvoiceCreationToolItem(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
+
+		cost_center: DF.Link | None
+		due_date: DF.Date | None
+		invoice_number: DF.Data | None
+		item_name: DF.Data | None
+		outstanding_amount: DF.Currency
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		party: DF.DynamicLink
+		party_type: DF.Link | None
+		posting_date: DF.Date | None
+		qty: DF.Data | None
+		temporary_opening_account: DF.Link | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/overdue_payment/overdue_payment.py b/erpnext/accounts/doctype/overdue_payment/overdue_payment.py
index 6a543ad..95e4255 100644
--- a/erpnext/accounts/doctype/overdue_payment/overdue_payment.py
+++ b/erpnext/accounts/doctype/overdue_payment/overdue_payment.py
@@ -6,4 +6,31 @@
 
 
 class OverduePayment(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
+
+		description: DF.SmallText | None
+		discounted_amount: DF.Currency
+		due_date: DF.Date | None
+		dunning_level: DF.Int
+		interest: DF.Currency
+		invoice_portion: DF.Percent
+		mode_of_payment: DF.Link | None
+		outstanding: DF.Currency
+		overdue_days: DF.Data | None
+		paid_amount: DF.Currency
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		payment_amount: DF.Currency
+		payment_schedule: DF.Data | None
+		payment_term: DF.Link | None
+		sales_invoice: DF.Link
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/party_account/party_account.py b/erpnext/accounts/doctype/party_account/party_account.py
index cd270b1..4b79595 100644
--- a/erpnext/accounts/doctype/party_account/party_account.py
+++ b/erpnext/accounts/doctype/party_account/party_account.py
@@ -6,4 +6,20 @@
 
 
 class PartyAccount(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: DF.Link | None
+		advance_account: DF.Link | None
+		company: DF.Link
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/party_link/party_link.py b/erpnext/accounts/doctype/party_link/party_link.py
index 312cfd2..d60acce 100644
--- a/erpnext/accounts/doctype/party_link/party_link.py
+++ b/erpnext/accounts/doctype/party_link/party_link.py
@@ -7,6 +7,20 @@
 
 
 class PartyLink(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
+
+		primary_party: DF.DynamicLink | None
+		primary_role: DF.Link
+		secondary_party: DF.DynamicLink | None
+		secondary_role: DF.Link | None
+	# end: auto-generated types
+
 	def validate(self):
 		if self.primary_role not in ["Customer", "Supplier"]:
 			frappe.throw(
diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.js b/erpnext/accounts/doctype/payment_entry/payment_entry.js
index b3ae627..2611240 100644
--- a/erpnext/accounts/doctype/payment_entry/payment_entry.js
+++ b/erpnext/accounts/doctype/payment_entry/payment_entry.js
@@ -9,7 +9,7 @@
 
 frappe.ui.form.on('Payment Entry', {
 	onload: function(frm) {
-		frm.ignore_doctypes_on_cancel_all = ['Sales Invoice', 'Purchase Invoice', 'Journal Entry', 'Repost Payment Ledger','Repost Accounting Ledger', 'Unreconcile Payments', 'Unreconcile Payment Entries'];
+		frm.ignore_doctypes_on_cancel_all = ['Sales Invoice', 'Purchase Invoice', 'Journal Entry', 'Repost Payment Ledger','Repost Accounting Ledger', 'Unreconcile Payment', 'Unreconcile Payment Entries'];
 
 		if(frm.doc.__islocal) {
 			if (!frm.doc.paid_from) frm.set_value("paid_from_account_currency", null);
@@ -160,7 +160,7 @@
 			}, __('Actions'));
 
 		}
-		erpnext.accounts.unreconcile_payments.add_unreconcile_btn(frm);
+		erpnext.accounts.unreconcile_payment.add_unreconcile_btn(frm);
 	},
 
 	validate_company: (frm) => {
@@ -853,6 +853,7 @@
 
 			var allocated_positive_outstanding =  paid_amount + allocated_negative_outstanding;
 		} else if (in_list(["Customer", "Supplier"], frm.doc.party_type)) {
+			total_negative_outstanding = flt(total_negative_outstanding, precision("outstanding_amount"))
 			if(paid_amount > total_negative_outstanding) {
 				if(total_negative_outstanding == 0) {
 					frappe.msgprint(
diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.json b/erpnext/accounts/doctype/payment_entry/payment_entry.json
index 4d50a35..aa18156 100644
--- a/erpnext/accounts/doctype/payment_entry/payment_entry.json
+++ b/erpnext/accounts/doctype/payment_entry/payment_entry.json
@@ -750,8 +750,16 @@
  ],
  "index_web_pages_for_search": 1,
  "is_submittable": 1,
- "links": [],
- "modified": "2023-11-08 21:51:03.482709",
+ "links": [
+  {
+   "is_child_table": 1,
+   "link_doctype": "Bank Transaction Payments",
+   "link_fieldname": "payment_entry",
+   "parent_doctype": "Bank Transaction",
+   "table_fieldname": "payment_entries"
+  }
+ ],
+ "modified": "2023-11-23 12:07:20.887885",
  "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 fc22f53..1282ab6 100644
--- a/erpnext/accounts/doctype/payment_entry/payment_entry.py
+++ b/erpnext/accounts/doctype/payment_entry/payment_entry.py
@@ -9,6 +9,8 @@
 from frappe import ValidationError, _, qb, scrub, throw
 from frappe.utils import cint, comma_or, flt, getdate, nowdate
 from frappe.utils.data import comma_and, fmt_money
+from pypika import Case
+from pypika.functions import Coalesce, Sum
 
 import erpnext
 from erpnext.accounts.doctype.bank_account.bank_account import (
@@ -104,9 +106,17 @@
 		self.set_status()
 
 	def set_liability_account(self):
-		if not self.book_advance_payments_in_separate_party_account:
+		# Auto setting liability account should only be done during 'draft' status
+		if self.docstatus > 0:
 			return
 
+		if not frappe.db.get_value(
+			"Company", self.company, "book_advance_payments_in_separate_party_account"
+		):
+			return
+
+		# Important to set this flag for the gl building logic to work properly
+		self.book_advance_payments_in_separate_party_account = True
 		account_type = frappe.get_value(
 			"Account", {"name": self.party_account, "company": self.company}, "account_type"
 		)
@@ -116,11 +126,13 @@
 		):
 			return
 
-		if self.unallocated_amount == 0:
-			for d in self.references:
-				if d.reference_doctype in ["Sales Order", "Purchase Order"]:
-					break
-			else:
+		if self.references:
+			allowed_types = frozenset(["Sales Order", "Purchase Order"])
+			reference_types = set([x.reference_doctype for x in self.references])
+
+			# If there are referencers other than `allowed_types`, treat this as a normal payment entry
+			if reference_types - allowed_types:
+				self.book_advance_payments_in_separate_party_account = False
 				return
 
 		liability_account = get_party_account(
@@ -148,7 +160,7 @@
 			"Repost Payment Ledger Items",
 			"Repost Accounting Ledger",
 			"Repost Accounting Ledger Items",
-			"Unreconcile Payments",
+			"Unreconcile Payment",
 			"Unreconcile Payment Entries",
 		)
 		super(PaymentEntry, self).on_cancel()
@@ -1022,6 +1034,7 @@
 		self.add_bank_gl_entries(gl_entries)
 		self.add_deductions_gl_entries(gl_entries)
 		self.add_tax_gl_entries(gl_entries)
+		add_regional_gl_entries(gl_entries, self)
 		return gl_entries
 
 	def make_gl_entries(self, cancel=0, adv_adj=0):
@@ -1055,112 +1068,104 @@
 			)
 
 			dr_or_cr = "credit" if self.payment_type == "Receive" else "debit"
-
-			for d in self.get("references"):
-				cost_center = self.cost_center
-				if d.reference_doctype == "Sales Invoice" and not cost_center:
-					cost_center = frappe.db.get_value(d.reference_doctype, d.reference_name, "cost_center")
-
+			if self.book_advance_payments_in_separate_party_account:
 				gle = party_gl_dict.copy()
 
-				allocated_amount_in_company_currency = self.calculate_base_allocated_amount_for_reference(d)
-
-				if self.book_advance_payments_in_separate_party_account:
-					against_voucher_type = "Payment Entry"
-					against_voucher = self.name
+				if self.payment_type == "Receive":
+					amount = self.base_paid_amount
 				else:
-					against_voucher_type = d.reference_doctype
-					against_voucher = d.reference_name
+					amount = self.base_received_amount
 
-				reverse_dr_or_cr, standalone_note = 0, 0
-				if d.reference_doctype in ["Sales Invoice", "Purchase Invoice"]:
-					is_return, return_against = frappe.db.get_value(
-						d.reference_doctype, d.reference_name, ["is_return", "return_against"]
-					)
-					payable_party_types = get_party_types_from_account_type("Payable")
-					receivable_party_types = get_party_types_from_account_type("Receivable")
-					if is_return and self.party_type in receivable_party_types and (self.payment_type == "Pay"):
-						reverse_dr_or_cr = 1
-					elif (
-						is_return and self.party_type in payable_party_types and (self.payment_type == "Receive")
-					):
-						reverse_dr_or_cr = 1
-
-					if is_return and not return_against and not reverse_dr_or_cr:
-						dr_or_cr = "debit" if dr_or_cr == "credit" else "credit"
-
-				gle.update(
-					{
-						dr_or_cr: abs(allocated_amount_in_company_currency),
-						dr_or_cr + "_in_account_currency": abs(d.allocated_amount),
-						"against_voucher_type": against_voucher_type,
-						"against_voucher": against_voucher,
-						"cost_center": cost_center,
-					}
-				)
-				gl_entries.append(gle)
-
-			if self.unallocated_amount:
 				exchange_rate = self.get_exchange_rate()
-				base_unallocated_amount = self.unallocated_amount * exchange_rate
-
-				gle = party_gl_dict.copy()
+				amount_in_account_currency = amount * exchange_rate
 				gle.update(
 					{
-						dr_or_cr + "_in_account_currency": self.unallocated_amount,
-						dr_or_cr: base_unallocated_amount,
+						dr_or_cr: amount,
+						dr_or_cr + "_in_account_currency": amount_in_account_currency,
+						"against_voucher_type": "Payment Entry",
+						"against_voucher": self.name,
+						"cost_center": self.cost_center,
 					}
 				)
-
 				gl_entries.append(gle)
+			else:
+				for d in self.get("references"):
+					# re-defining dr_or_cr for every reference in order to avoid the last value affecting calculation of reverse
+					dr_or_cr = "credit" if self.payment_type == "Receive" else "debit"
+					cost_center = self.cost_center
+					if d.reference_doctype == "Sales Invoice" and not cost_center:
+						cost_center = frappe.db.get_value(d.reference_doctype, d.reference_name, "cost_center")
 
-	def make_advance_gl_entries(self, against_voucher_type=None, against_voucher=None, cancel=0):
-		if self.book_advance_payments_in_separate_party_account:
-			gl_entries = []
-			for d in self.get("references"):
-				if d.reference_doctype in ("Sales Invoice", "Purchase Invoice", "Journal Entry"):
-					if not (against_voucher_type and against_voucher) or (
-						d.reference_doctype == against_voucher_type and d.reference_name == against_voucher
-					):
-						self.make_invoice_liability_entry(gl_entries, d)
+					gle = party_gl_dict.copy()
 
-			if cancel:
-				for entry in gl_entries:
-					frappe.db.set_value(
-						"GL Entry",
+					allocated_amount_in_company_currency = self.calculate_base_allocated_amount_for_reference(d)
+					reverse_dr_or_cr = 0
+
+					if d.reference_doctype in ["Sales Invoice", "Purchase Invoice"]:
+						is_return = frappe.db.get_value(d.reference_doctype, d.reference_name, "is_return")
+						payable_party_types = get_party_types_from_account_type("Payable")
+						receivable_party_types = get_party_types_from_account_type("Receivable")
+						if is_return and self.party_type in receivable_party_types and (self.payment_type == "Pay"):
+							reverse_dr_or_cr = 1
+						elif (
+							is_return and self.party_type in payable_party_types and (self.payment_type == "Receive")
+						):
+							reverse_dr_or_cr = 1
+
+						if is_return and not reverse_dr_or_cr:
+							dr_or_cr = "debit" if dr_or_cr == "credit" else "credit"
+
+					gle.update(
 						{
-							"voucher_no": self.name,
-							"voucher_type": self.doctype,
-							"voucher_detail_no": entry.voucher_detail_no,
-							"against_voucher_type": entry.against_voucher_type,
-							"against_voucher": entry.against_voucher,
-						},
-						"is_cancelled",
-						1,
+							dr_or_cr: abs(allocated_amount_in_company_currency),
+							dr_or_cr + "_in_account_currency": abs(d.allocated_amount),
+							"against_voucher_type": d.reference_doctype,
+							"against_voucher": d.reference_name,
+							"cost_center": cost_center,
+						}
+					)
+					gl_entries.append(gle)
+
+				if self.unallocated_amount:
+					dr_or_cr = "credit" if self.payment_type == "Receive" else "debit"
+					exchange_rate = self.get_exchange_rate()
+					base_unallocated_amount = self.unallocated_amount * exchange_rate
+
+					gle = party_gl_dict.copy()
+					gle.update(
+						{
+							dr_or_cr + "_in_account_currency": self.unallocated_amount,
+							dr_or_cr: base_unallocated_amount,
+						}
 					)
 
-				make_reverse_gl_entries(gl_entries=gl_entries, partial_cancel=True)
-				return
+					gl_entries.append(gle)
 
-			# same reference added to payment entry
-			for gl_entry in gl_entries.copy():
-				if frappe.db.exists(
-					"GL Entry",
-					{
-						"account": gl_entry.account,
-						"voucher_type": gl_entry.voucher_type,
-						"voucher_no": gl_entry.voucher_no,
-						"voucher_detail_no": gl_entry.voucher_detail_no,
-						"debit": gl_entry.debit,
-						"credit": gl_entry.credit,
-						"is_cancelled": 0,
-					},
-				):
-					gl_entries.remove(gl_entry)
+	def make_advance_gl_entries(
+		self, entry: object | dict = None, cancel: bool = 0, update_outstanding: str = "Yes"
+	):
+		gl_entries = []
+		self.add_advance_gl_entries(gl_entries, entry)
 
-			make_gl_entries(gl_entries)
+		if cancel:
+			make_reverse_gl_entries(gl_entries, partial_cancel=True)
+		else:
+			make_gl_entries(gl_entries, update_outstanding=update_outstanding)
 
-	def make_invoice_liability_entry(self, gl_entries, invoice):
+	def add_advance_gl_entries(self, gl_entries: list, entry: object | dict | None):
+		"""
+		If 'entry' is passed, GL enties only for that reference is added.
+		"""
+		if self.book_advance_payments_in_separate_party_account:
+			references = [x for x in self.get("references")]
+			if entry:
+				references = [x for x in self.get("references") if x.name == entry.name]
+
+			for ref in references:
+				if ref.reference_doctype in ("Sales Invoice", "Purchase Invoice", "Journal Entry"):
+					self.add_advance_gl_for_reference(gl_entries, ref)
+
+	def add_advance_gl_for_reference(self, gl_entries, invoice):
 		args_dict = {
 			"party_type": self.party_type,
 			"party": self.party,
@@ -1698,12 +1703,13 @@
 				if not split_rows:
 					continue
 
-				frappe.msgprint(
-					_("Splitting {0} {1} into {2} rows as per Payment Terms").format(
-						_(entry.voucher_type), frappe.bold(entry.voucher_no), len(split_rows)
-					),
-					alert=True,
-				)
+				if len(split_rows) > 1:
+					frappe.msgprint(
+						_("Splitting {0} {1} into {2} rows as per Payment Terms").format(
+							_(entry.voucher_type), frappe.bold(entry.voucher_no), len(split_rows)
+						),
+						alert=True,
+					)
 				outstanding_invoices_after_split += split_rows
 				continue
 
@@ -1986,18 +1992,24 @@
 
 
 def get_outstanding_on_journal_entry(name):
-	res = frappe.db.sql(
-		"SELECT "
-		'CASE WHEN party_type IN ("Customer") '
-		"THEN ifnull(sum(debit_in_account_currency - credit_in_account_currency), 0) "
-		"ELSE ifnull(sum(credit_in_account_currency - debit_in_account_currency), 0) "
-		"END as outstanding_amount "
-		"FROM `tabGL Entry` WHERE (voucher_no=%s OR against_voucher=%s) "
-		"AND party_type IS NOT NULL "
-		'AND party_type != ""',
-		(name, name),
-		as_dict=1,
-	)
+	gl = frappe.qb.DocType("GL Entry")
+	res = (
+		frappe.qb.from_(gl)
+		.select(
+			Case()
+			.when(
+				gl.party_type == "Customer",
+				Coalesce(Sum(gl.debit_in_account_currency - gl.credit_in_account_currency), 0),
+			)
+			.else_(Coalesce(Sum(gl.credit_in_account_currency - gl.debit_in_account_currency), 0))
+			.as_("outstanding_amount")
+		)
+		.where(
+			(Coalesce(gl.party_type, "") != "")
+			& (gl.is_cancelled == 0)
+			& ((gl.voucher_no == name) | (gl.against_voucher == name))
+		)
+	).run(as_dict=True)
 
 	outstanding_amount = res[0].get("outstanding_amount", 0) if res else 0
 
@@ -2622,3 +2634,8 @@
 	)
 
 	return doclist
+
+
+@erpnext.allow_regional
+def add_regional_gl_entries(gl_entries, doc):
+	return
diff --git a/erpnext/accounts/doctype/payment_entry/test_payment_entry.py b/erpnext/accounts/doctype/payment_entry/test_payment_entry.py
index 603f24a..8a03dd7 100644
--- a/erpnext/accounts/doctype/payment_entry/test_payment_entry.py
+++ b/erpnext/accounts/doctype/payment_entry/test_payment_entry.py
@@ -8,6 +8,7 @@
 from frappe.tests.utils import FrappeTestCase, change_settings
 from frappe.utils import add_days, flt, nowdate
 
+from erpnext.accounts.doctype.account.test_account import create_account
 from erpnext.accounts.doctype.payment_entry.payment_entry import (
 	InvalidPaymentEntry,
 	get_outstanding_reference_documents,
@@ -1290,6 +1291,9 @@
 		self.assertEqual(references[2].payment_term, "Tax Receivable")
 
 	def test_receive_payment_from_payable_party_type(self):
+		"""
+		Checks GL entries generated while receiving payments from a Payable Party Type.
+		"""
 		pe = create_payment_entry(
 			party_type="Supplier",
 			party="_Test Supplier",
@@ -1301,11 +1305,196 @@
 		)
 		self.voucher_no = pe.name
 		self.expected_gle = [
-			{"account": "_Test Cash - _TC", "debit": 1000.0, "credit": 0.0},
 			{"account": "Creditors - _TC", "debit": 0.0, "credit": 1000.0},
+			{"account": "_Test Cash - _TC", "debit": 1000.0, "credit": 0.0},
 		]
 		self.check_gl_entries()
 
+	def test_payment_against_partial_return_invoice(self):
+		"""
+		Checks GL entries generated for partial return invoice payments.
+		"""
+		si = create_sales_invoice(qty=10, rate=10, customer="_Test Customer")
+		credit_note = create_sales_invoice(
+			qty=-4, rate=10, customer="_Test Customer", is_return=1, return_against=si.name
+		)
+		pe = create_payment_entry(
+			party_type="Customer",
+			party="_Test Customer",
+			payment_type="Receive",
+			paid_from="Debtors - _TC",
+			paid_to="_Test Cash - _TC",
+		)
+		pe.set(
+			"references",
+			[
+				{
+					"reference_doctype": "Sales Invoice",
+					"reference_name": si.name,
+					"due_date": si.get("due_date"),
+					"total_amount": si.grand_total,
+					"outstanding_amount": si.outstanding_amount,
+					"allocated_amount": si.outstanding_amount,
+				},
+				{
+					"reference_doctype": "Sales Invoice",
+					"reference_name": credit_note.name,
+					"due_date": credit_note.get("due_date"),
+					"total_amount": credit_note.grand_total,
+					"outstanding_amount": credit_note.outstanding_amount,
+					"allocated_amount": credit_note.outstanding_amount,
+				},
+			],
+		)
+		pe.save()
+		pe.submit()
+		self.assertEqual(pe.total_allocated_amount, 60)
+		self.assertEqual(pe.unallocated_amount, 940)
+		self.voucher_no = pe.name
+		self.expected_gle = [
+			{"account": "Debtors - _TC", "debit": 40.0, "credit": 0.0},
+			{"account": "Debtors - _TC", "debit": 0.0, "credit": 940.0},
+			{"account": "Debtors - _TC", "debit": 0.0, "credit": 100.0},
+			{"account": "_Test Cash - _TC", "debit": 1000.0, "credit": 0.0},
+		]
+		self.check_gl_entries()
+
+	def test_ledger_entries_for_advance_as_liability(self):
+		from erpnext.accounts.doctype.account.test_account import create_account
+
+		company = "_Test Company"
+
+		advance_account = create_account(
+			parent_account="Current Assets - _TC",
+			account_name="Advances Received",
+			company=company,
+			account_type="Receivable",
+		)
+
+		frappe.db.set_value(
+			"Company",
+			company,
+			{
+				"book_advance_payments_in_separate_party_account": 1,
+				"default_advance_received_account": advance_account,
+			},
+		)
+		# Advance Payment
+		pe = create_payment_entry(
+			party_type="Customer",
+			party="_Test Customer",
+			payment_type="Receive",
+			paid_from="Debtors - _TC",
+			paid_to="_Test Cash - _TC",
+		)
+		pe.save()  # use save() to trigger set_liability_account()
+		pe.submit()
+
+		# Normal Invoice
+		si = create_sales_invoice(qty=10, rate=100, customer="_Test Customer")
+
+		pre_reconciliation_gle = [
+			{"account": advance_account, "debit": 0.0, "credit": 1000.0},
+			{"account": "_Test Cash - _TC", "debit": 1000.0, "credit": 0.0},
+		]
+		pre_reconciliation_ple = [
+			{
+				"account": advance_account,
+				"voucher_no": pe.name,
+				"against_voucher_no": pe.name,
+				"amount": -1000.0,
+			}
+		]
+
+		self.voucher_no = pe.name
+		self.expected_gle = pre_reconciliation_gle
+		self.expected_ple = pre_reconciliation_ple
+		self.check_gl_entries()
+		self.check_pl_entries()
+
+		# Partially reconcile advance against invoice
+		pr = frappe.get_doc("Payment Reconciliation")
+		pr.company = company
+		pr.party_type = "Customer"
+		pr.party = "_Test Customer"
+		pr.receivable_payable_account = si.debit_to
+		pr.default_advance_account = advance_account
+		pr.payment_name = pe.name
+		pr.invoice_name = si.name
+		pr.get_unreconciled_entries()
+
+		self.assertEqual(len(pr.invoices), 1)
+		self.assertEqual(len(pr.payments), 1)
+
+		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.allocation[0].allocated_amount = 400
+		pr.reconcile()
+
+		# assert General and Payment Ledger entries post partial reconciliation
+		self.expected_gle = [
+			{"account": si.debit_to, "debit": 0.0, "credit": 400.0},
+			{"account": advance_account, "debit": 400.0, "credit": 0.0},
+			{"account": advance_account, "debit": 0.0, "credit": 1000.0},
+			{"account": "_Test Cash - _TC", "debit": 1000.0, "credit": 0.0},
+		]
+		self.expected_ple = [
+			{
+				"account": advance_account,
+				"voucher_no": pe.name,
+				"against_voucher_no": pe.name,
+				"amount": -1000.0,
+			},
+			{
+				"account": si.debit_to,
+				"voucher_no": pe.name,
+				"against_voucher_no": si.name,
+				"amount": -400.0,
+			},
+			{
+				"account": advance_account,
+				"voucher_no": pe.name,
+				"against_voucher_no": pe.name,
+				"amount": 400.0,
+			},
+		]
+		self.check_gl_entries()
+		self.check_pl_entries()
+
+		# Unreconcile
+		unrecon = (
+			frappe.get_doc(
+				{
+					"doctype": "Unreconcile Payment",
+					"company": company,
+					"voucher_type": pe.doctype,
+					"voucher_no": pe.name,
+					"allocations": [{"reference_doctype": si.doctype, "reference_name": si.name}],
+				}
+			)
+			.save()
+			.submit()
+		)
+
+		self.voucher_no = pe.name
+		self.expected_gle = pre_reconciliation_gle
+		self.expected_ple = pre_reconciliation_ple
+		self.check_gl_entries()
+		self.check_pl_entries()
+
+	def check_pl_entries(self):
+		ple = frappe.qb.DocType("Payment Ledger Entry")
+		pl_entries = (
+			frappe.qb.from_(ple)
+			.select(ple.account, ple.voucher_no, ple.against_voucher_no, ple.amount)
+			.where((ple.voucher_no == self.voucher_no) & (ple.delinked == 0))
+			.orderby(ple.creation)
+		).run(as_dict=True)
+		for row in range(len(self.expected_ple)):
+			for field in ["account", "voucher_no", "against_voucher_no", "amount"]:
+				self.assertEqual(self.expected_ple[row][field], pl_entries[row][field])
+
 	def check_gl_entries(self):
 		gle = frappe.qb.DocType("GL Entry")
 		gl_entries = (
@@ -1316,7 +1505,7 @@
 				gle.credit,
 			)
 			.where((gle.voucher_no == self.voucher_no) & (gle.is_cancelled == 0))
-			.orderby(gle.account)
+			.orderby(gle.account, gle.debit, gle.credit, order=frappe.qb.desc)
 		).run(as_dict=True)
 		for row in range(len(self.expected_gle)):
 			for field in ["account", "debit", "credit"]:
diff --git a/erpnext/accounts/doctype/payment_entry_deduction/payment_entry_deduction.py b/erpnext/accounts/doctype/payment_entry_deduction/payment_entry_deduction.py
index b71dbb9..fc67c52 100644
--- a/erpnext/accounts/doctype/payment_entry_deduction/payment_entry_deduction.py
+++ b/erpnext/accounts/doctype/payment_entry_deduction/payment_entry_deduction.py
@@ -6,4 +6,21 @@
 
 
 class PaymentEntryDeduction(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: DF.Link
+		amount: DF.Currency
+		cost_center: DF.Link
+		description: DF.SmallText | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/payment_entry_reference/payment_entry_reference.py b/erpnext/accounts/doctype/payment_entry_reference/payment_entry_reference.py
index fc1cad9..13707e5 100644
--- a/erpnext/accounts/doctype/payment_entry_reference/payment_entry_reference.py
+++ b/erpnext/accounts/doctype/payment_entry_reference/payment_entry_reference.py
@@ -6,4 +6,28 @@
 
 
 class PaymentEntryReference(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: DF.Link | None
+		allocated_amount: DF.Float
+		bill_no: DF.Data | None
+		due_date: DF.Date | None
+		exchange_gain_loss: DF.Currency
+		exchange_rate: DF.Float
+		outstanding_amount: DF.Float
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		payment_term: DF.Link | None
+		reference_doctype: DF.Link
+		reference_name: DF.DynamicLink
+		total_amount: DF.Float
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/payment_gateway_account/payment_gateway_account.py b/erpnext/accounts/doctype/payment_gateway_account/payment_gateway_account.py
index 791de25..f1bf363 100644
--- a/erpnext/accounts/doctype/payment_gateway_account/payment_gateway_account.py
+++ b/erpnext/accounts/doctype/payment_gateway_account/payment_gateway_account.py
@@ -7,6 +7,22 @@
 
 
 class PaymentGatewayAccount(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
+
+		currency: DF.ReadOnly | None
+		is_default: DF.Check
+		message: DF.SmallText | None
+		payment_account: DF.Link
+		payment_channel: DF.Literal["", "Email", "Phone"]
+		payment_gateway: DF.Link
+	# end: auto-generated types
+
 	def autoname(self):
 		self.name = self.payment_gateway + " - " + self.currency
 
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 58691ab..e8dfda2 100644
--- a/erpnext/accounts/doctype/payment_ledger_entry/payment_ledger_entry.py
+++ b/erpnext/accounts/doctype/payment_ledger_entry/payment_ledger_entry.py
@@ -21,6 +21,35 @@
 
 
 class PaymentLedgerEntry(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: DF.Link | None
+		account_currency: DF.Link | None
+		account_type: DF.Literal["Receivable", "Payable"]
+		against_voucher_no: DF.DynamicLink | None
+		against_voucher_type: DF.Link | None
+		amount: DF.Currency
+		amount_in_account_currency: DF.Currency
+		company: DF.Link | None
+		cost_center: DF.Link | None
+		delinked: DF.Check
+		due_date: DF.Date | None
+		finance_book: DF.Link | None
+		party: DF.DynamicLink | None
+		party_type: DF.Link | None
+		posting_date: DF.Date | None
+		remarks: DF.Text | None
+		voucher_detail_no: DF.Data | None
+		voucher_no: DF.DynamicLink | None
+		voucher_type: DF.Link | None
+	# end: auto-generated types
+
 	def validate_account(self):
 		valid_account = frappe.db.get_list(
 			"Account",
diff --git a/erpnext/accounts/doctype/payment_order/payment_order.py b/erpnext/accounts/doctype/payment_order/payment_order.py
index ff9615d..0ed26e4 100644
--- a/erpnext/accounts/doctype/payment_order/payment_order.py
+++ b/erpnext/accounts/doctype/payment_order/payment_order.py
@@ -11,6 +11,30 @@
 
 
 class PaymentOrder(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
+
+		from erpnext.accounts.doctype.payment_order_reference.payment_order_reference import (
+			PaymentOrderReference,
+		)
+
+		account: DF.Data | None
+		amended_from: DF.Link | None
+		company: DF.Link
+		company_bank: DF.Link | None
+		company_bank_account: DF.Link
+		naming_series: DF.Literal["PMO-"]
+		party: DF.Link | None
+		payment_order_type: DF.Literal["", "Payment Request", "Payment Entry"]
+		posting_date: DF.Date | None
+		references: DF.Table[PaymentOrderReference]
+	# end: auto-generated types
+
 	def on_submit(self):
 		self.update_payment_status()
 
diff --git a/erpnext/accounts/doctype/payment_order_reference/payment_order_reference.py b/erpnext/accounts/doctype/payment_order_reference/payment_order_reference.py
index 94704fc..26c2ce2 100644
--- a/erpnext/accounts/doctype/payment_order_reference/payment_order_reference.py
+++ b/erpnext/accounts/doctype/payment_order_reference/payment_order_reference.py
@@ -6,4 +6,26 @@
 
 
 class PaymentOrderReference(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: DF.Link | None
+		amount: DF.Currency
+		bank_account: DF.Link
+		mode_of_payment: DF.Link | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		payment_reference: DF.Data | None
+		payment_request: DF.Link | None
+		reference_doctype: DF.Link
+		reference_name: DF.DynamicLink
+		supplier: DF.Link | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.json b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.json
index b88791d..ccb9e64 100644
--- a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.json
+++ b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.json
@@ -212,9 +212,10 @@
  ],
  "hide_toolbar": 1,
  "icon": "icon-resize-horizontal",
+ "is_virtual": 1,
  "issingle": 1,
  "links": [],
- "modified": "2023-08-15 05:35:50.109290",
+ "modified": "2023-11-17 17:33:55.701726",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Payment Reconciliation",
@@ -239,6 +240,5 @@
  ],
  "sort_field": "modified",
  "sort_order": "DESC",
- "states": [],
- "track_changes": 1
+ "states": []
 }
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py
index 43167be..fbc4d24 100644
--- a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py
+++ b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py
@@ -23,12 +23,106 @@
 
 
 class PaymentReconciliation(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
+
+		from erpnext.accounts.doctype.payment_reconciliation_allocation.payment_reconciliation_allocation import (
+			PaymentReconciliationAllocation,
+		)
+		from erpnext.accounts.doctype.payment_reconciliation_invoice.payment_reconciliation_invoice import (
+			PaymentReconciliationInvoice,
+		)
+		from erpnext.accounts.doctype.payment_reconciliation_payment.payment_reconciliation_payment import (
+			PaymentReconciliationPayment,
+		)
+
+		allocation: DF.Table[PaymentReconciliationAllocation]
+		bank_cash_account: DF.Link | None
+		company: DF.Link
+		cost_center: DF.Link | None
+		default_advance_account: DF.Link | None
+		from_invoice_date: DF.Date | None
+		from_payment_date: DF.Date | None
+		invoice_limit: DF.Int
+		invoice_name: DF.Data | None
+		invoices: DF.Table[PaymentReconciliationInvoice]
+		maximum_invoice_amount: DF.Currency
+		maximum_payment_amount: DF.Currency
+		minimum_invoice_amount: DF.Currency
+		minimum_payment_amount: DF.Currency
+		party: DF.DynamicLink
+		party_type: DF.Link
+		payment_limit: DF.Int
+		payment_name: DF.Data | None
+		payments: DF.Table[PaymentReconciliationPayment]
+		receivable_payable_account: DF.Link
+		to_invoice_date: DF.Date | None
+		to_payment_date: DF.Date | None
+	# end: auto-generated types
+
 	def __init__(self, *args, **kwargs):
 		super(PaymentReconciliation, self).__init__(*args, **kwargs)
 		self.common_filter_conditions = []
 		self.accounting_dimension_filter_conditions = []
 		self.ple_posting_date_filter = []
 
+	def load_from_db(self):
+		# 'modified' attribute is required for `run_doc_method` to work properly.
+		doc_dict = frappe._dict(
+			{
+				"modified": None,
+				"company": None,
+				"party": None,
+				"party_type": None,
+				"receivable_payable_account": None,
+				"default_advance_account": None,
+				"from_invoice_date": None,
+				"to_invoice_date": None,
+				"invoice_limit": 50,
+				"from_payment_date": None,
+				"to_payment_date": None,
+				"payment_limit": 50,
+				"minimum_invoice_amount": None,
+				"minimum_payment_amount": None,
+				"maximum_invoice_amount": None,
+				"maximum_payment_amount": None,
+				"bank_cash_account": None,
+				"cost_center": None,
+				"payment_name": None,
+				"invoice_name": None,
+			}
+		)
+		super(Document, self).__init__(doc_dict)
+
+	def save(self):
+		return
+
+	@staticmethod
+	def get_list(args):
+		pass
+
+	@staticmethod
+	def get_count(args):
+		pass
+
+	@staticmethod
+	def get_stats(args):
+		pass
+
+	def db_insert(self, *args, **kwargs):
+		pass
+
+	def db_update(self, *args, **kwargs):
+		pass
+
+	def delete(self):
+		pass
+
 	@frappe.whitelist()
 	def get_unreconciled_entries(self):
 		self.get_nonreconciled_payment_entries()
diff --git a/erpnext/accounts/doctype/payment_reconciliation/test_payment_reconciliation.py b/erpnext/accounts/doctype/payment_reconciliation/test_payment_reconciliation.py
index 71bc498..d7a73f0 100644
--- a/erpnext/accounts/doctype/payment_reconciliation/test_payment_reconciliation.py
+++ b/erpnext/accounts/doctype/payment_reconciliation/test_payment_reconciliation.py
@@ -1137,6 +1137,40 @@
 		self.assertEqual(pay.unallocated_amount, 1000)
 		self.assertEqual(pay.difference_amount, 0)
 
+	def test_rounding_of_unallocated_amount(self):
+		self.supplier = "_Test Supplier USD"
+		pi = self.create_purchase_invoice(qty=1, rate=10, do_not_submit=True)
+		pi.supplier = self.supplier
+		pi.currency = "USD"
+		pi.conversion_rate = 80
+		pi.credit_to = self.creditors_usd
+		pi.save().submit()
+
+		pe = get_payment_entry(pi.doctype, pi.name)
+		pe.target_exchange_rate = 78.726500000
+		pe.received_amount = 26.75
+		pe.paid_amount = 2105.93
+		pe.references = []
+		pe.save().submit()
+
+		# unallocated_amount will have some rounding loss - 26.749950
+		self.assertNotEqual(pe.unallocated_amount, 26.75)
+
+		pr = frappe.get_doc("Payment Reconciliation")
+		pr.company = self.company
+		pr.party_type = "Supplier"
+		pr.party = self.supplier
+		pr.receivable_payable_account = self.creditors_usd
+		pr.from_invoice_date = pr.to_invoice_date = pr.from_payment_date = pr.to_payment_date = nowdate()
+		pr.get_unreconciled_entries()
+
+		invoices = [invoice.as_dict() for invoice in pr.invoices]
+		payments = [payment.as_dict() for payment in pr.payments]
+		pr.allocate_entries(frappe._dict({"invoices": invoices, "payments": payments}))
+
+		# Should not raise frappe.exceptions.ValidationError: Payment Entry has been modified after you pulled it. Please pull it again.
+		pr.reconcile()
+
 
 def make_customer(customer_name, currency=None):
 	if not frappe.db.exists("Customer", customer_name):
diff --git a/erpnext/accounts/doctype/payment_reconciliation_allocation/payment_reconciliation_allocation.json b/erpnext/accounts/doctype/payment_reconciliation_allocation/payment_reconciliation_allocation.json
index 5b8556e..491c678 100644
--- a/erpnext/accounts/doctype/payment_reconciliation_allocation/payment_reconciliation_allocation.json
+++ b/erpnext/accounts/doctype/payment_reconciliation_allocation/payment_reconciliation_allocation.json
@@ -159,9 +159,10 @@
    "label": "Difference Posting Date"
   }
  ],
+ "is_virtual": 1,
  "istable": 1,
  "links": [],
- "modified": "2023-10-23 10:44:56.066303",
+ "modified": "2023-11-17 17:33:38.612615",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Payment Reconciliation Allocation",
diff --git a/erpnext/accounts/doctype/payment_reconciliation_allocation/payment_reconciliation_allocation.py b/erpnext/accounts/doctype/payment_reconciliation_allocation/payment_reconciliation_allocation.py
index 9db8e62..a4141af 100644
--- a/erpnext/accounts/doctype/payment_reconciliation_allocation/payment_reconciliation_allocation.py
+++ b/erpnext/accounts/doctype/payment_reconciliation_allocation/payment_reconciliation_allocation.py
@@ -6,4 +6,32 @@
 
 
 class PaymentReconciliationAllocation(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
+
+		allocated_amount: DF.Currency
+		amount: DF.Currency
+		cost_center: DF.Link | None
+		currency: DF.Link | None
+		difference_account: DF.Link | None
+		difference_amount: DF.Currency
+		exchange_rate: DF.Float
+		gain_loss_posting_date: DF.Date | None
+		invoice_number: DF.DynamicLink
+		invoice_type: DF.Link
+		is_advance: DF.Data | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		reference_name: DF.DynamicLink
+		reference_row: DF.Data | None
+		reference_type: DF.Link
+		unreconciled_amount: DF.Currency
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/payment_reconciliation_invoice/payment_reconciliation_invoice.json b/erpnext/accounts/doctype/payment_reconciliation_invoice/payment_reconciliation_invoice.json
index c4dbd7e..7c9d49e 100644
--- a/erpnext/accounts/doctype/payment_reconciliation_invoice/payment_reconciliation_invoice.json
+++ b/erpnext/accounts/doctype/payment_reconciliation_invoice/payment_reconciliation_invoice.json
@@ -71,9 +71,10 @@
    "label": "Exchange Rate"
   }
  ],
+ "is_virtual": 1,
  "istable": 1,
  "links": [],
- "modified": "2022-11-08 18:18:02.502149",
+ "modified": "2023-11-17 17:33:45.455166",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Payment Reconciliation Invoice",
diff --git a/erpnext/accounts/doctype/payment_reconciliation_invoice/payment_reconciliation_invoice.py b/erpnext/accounts/doctype/payment_reconciliation_invoice/payment_reconciliation_invoice.py
index 7665b75..1e9f6ce 100644
--- a/erpnext/accounts/doctype/payment_reconciliation_invoice/payment_reconciliation_invoice.py
+++ b/erpnext/accounts/doctype/payment_reconciliation_invoice/payment_reconciliation_invoice.py
@@ -6,4 +6,24 @@
 
 
 class PaymentReconciliationInvoice(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
+
+		amount: DF.Currency
+		currency: DF.Link | None
+		exchange_rate: DF.Float
+		invoice_date: DF.Date | None
+		invoice_number: DF.DynamicLink | None
+		invoice_type: DF.Literal["Sales Invoice", "Purchase Invoice", "Journal Entry"]
+		outstanding_amount: DF.Currency
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/payment_reconciliation_payment/payment_reconciliation_payment.json b/erpnext/accounts/doctype/payment_reconciliation_payment/payment_reconciliation_payment.json
index 17f3900..d199236 100644
--- a/erpnext/accounts/doctype/payment_reconciliation_payment/payment_reconciliation_payment.json
+++ b/erpnext/accounts/doctype/payment_reconciliation_payment/payment_reconciliation_payment.json
@@ -107,9 +107,10 @@
    "options": "Cost Center"
   }
  ],
+ "is_virtual": 1,
  "istable": 1,
  "links": [],
- "modified": "2023-09-03 07:43:29.965353",
+ "modified": "2023-11-17 17:33:34.818530",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Payment Reconciliation Payment",
diff --git a/erpnext/accounts/doctype/payment_reconciliation_payment/payment_reconciliation_payment.py b/erpnext/accounts/doctype/payment_reconciliation_payment/payment_reconciliation_payment.py
index c0e3fd6..aa956fe 100644
--- a/erpnext/accounts/doctype/payment_reconciliation_payment/payment_reconciliation_payment.py
+++ b/erpnext/accounts/doctype/payment_reconciliation_payment/payment_reconciliation_payment.py
@@ -6,4 +6,28 @@
 
 
 class PaymentReconciliationPayment(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
+
+		amount: DF.Currency
+		cost_center: DF.Link | None
+		currency: DF.Link | None
+		difference_amount: DF.Currency
+		exchange_rate: DF.Float
+		is_advance: DF.Data | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		posting_date: DF.Date | None
+		reference_name: DF.DynamicLink | None
+		reference_row: DF.Data | None
+		reference_type: DF.Link | None
+		remark: DF.SmallText | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/payment_request/payment_request.py b/erpnext/accounts/doctype/payment_request/payment_request.py
index 5f7fa72..be7dff6 100644
--- a/erpnext/accounts/doctype/payment_request/payment_request.py
+++ b/erpnext/accounts/doctype/payment_request/payment_request.py
@@ -27,6 +27,65 @@
 
 
 class PaymentRequest(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
+
+		from erpnext.accounts.doctype.subscription_plan_detail.subscription_plan_detail import (
+			SubscriptionPlanDetail,
+		)
+
+		account: DF.ReadOnly | None
+		amended_from: DF.Link | None
+		bank: DF.Link | None
+		bank_account: DF.Link | None
+		bank_account_no: DF.ReadOnly | None
+		branch_code: DF.ReadOnly | None
+		cost_center: DF.Link | None
+		currency: DF.Link | None
+		email_to: DF.Data | None
+		grand_total: DF.Currency
+		iban: DF.ReadOnly | None
+		is_a_subscription: DF.Check
+		make_sales_invoice: DF.Check
+		message: DF.Text | None
+		mode_of_payment: DF.Link | None
+		mute_email: DF.Check
+		naming_series: DF.Literal["ACC-PRQ-.YYYY.-"]
+		party: DF.DynamicLink | None
+		party_type: DF.Link | None
+		payment_account: DF.ReadOnly | None
+		payment_channel: DF.Literal["", "Email", "Phone"]
+		payment_gateway: DF.ReadOnly | None
+		payment_gateway_account: DF.Link | None
+		payment_order: DF.Link | None
+		payment_request_type: DF.Literal["Outward", "Inward"]
+		payment_url: DF.Data | None
+		print_format: DF.Literal
+		project: DF.Link | None
+		reference_doctype: DF.Link | None
+		reference_name: DF.DynamicLink | None
+		status: DF.Literal[
+			"",
+			"Draft",
+			"Requested",
+			"Initiated",
+			"Partially Paid",
+			"Payment Ordered",
+			"Paid",
+			"Failed",
+			"Cancelled",
+		]
+		subject: DF.Data | None
+		subscription_plans: DF.Table[SubscriptionPlanDetail]
+		swift_number: DF.ReadOnly | None
+		transaction_date: DF.Date | None
+	# end: auto-generated types
+
 	def validate(self):
 		if self.get("__islocal"):
 			self.status = "Draft"
diff --git a/erpnext/accounts/doctype/payment_schedule/payment_schedule.py b/erpnext/accounts/doctype/payment_schedule/payment_schedule.py
index 33e261f..8a292fd 100644
--- a/erpnext/accounts/doctype/payment_schedule/payment_schedule.py
+++ b/erpnext/accounts/doctype/payment_schedule/payment_schedule.py
@@ -6,4 +6,30 @@
 
 
 class PaymentSchedule(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
+
+		base_payment_amount: DF.Currency
+		description: DF.SmallText | None
+		discount: DF.Float
+		discount_date: DF.Date | None
+		discount_type: DF.Literal["Percentage", "Amount"]
+		discounted_amount: DF.Currency
+		due_date: DF.Date
+		invoice_portion: DF.Percent
+		mode_of_payment: DF.Link | None
+		outstanding: DF.Currency
+		paid_amount: DF.Currency
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		payment_amount: DF.Currency
+		payment_term: DF.Link | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/payment_term/payment_term.py b/erpnext/accounts/doctype/payment_term/payment_term.py
index 956c2b1..5f9171e 100644
--- a/erpnext/accounts/doctype/payment_term/payment_term.py
+++ b/erpnext/accounts/doctype/payment_term/payment_term.py
@@ -6,4 +6,33 @@
 
 
 class PaymentTerm(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
+
+		credit_days: DF.Int
+		credit_months: DF.Int
+		description: DF.SmallText | None
+		discount: DF.Float
+		discount_type: DF.Literal["Percentage", "Amount"]
+		discount_validity: DF.Int
+		discount_validity_based_on: DF.Literal[
+			"Day(s) after invoice date",
+			"Day(s) after the end of the invoice month",
+			"Month(s) after the end of the invoice month",
+		]
+		due_date_based_on: DF.Literal[
+			"Day(s) after invoice date",
+			"Day(s) after the end of the invoice month",
+			"Month(s) after the end of the invoice month",
+		]
+		invoice_portion: DF.Float
+		mode_of_payment: DF.Link | None
+		payment_term_name: DF.Data | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/payment_terms_template/payment_terms_template.py b/erpnext/accounts/doctype/payment_terms_template/payment_terms_template.py
index 7b04a68..8f028f9 100644
--- a/erpnext/accounts/doctype/payment_terms_template/payment_terms_template.py
+++ b/erpnext/accounts/doctype/payment_terms_template/payment_terms_template.py
@@ -9,6 +9,23 @@
 
 
 class PaymentTermsTemplate(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
+
+		from erpnext.accounts.doctype.payment_terms_template_detail.payment_terms_template_detail import (
+			PaymentTermsTemplateDetail,
+		)
+
+		allocate_payment_based_on_payment_terms: DF.Check
+		template_name: DF.Data | None
+		terms: DF.Table[PaymentTermsTemplateDetail]
+	# end: auto-generated types
+
 	def validate(self):
 		self.validate_invoice_portion()
 		self.validate_terms()
diff --git a/erpnext/accounts/doctype/payment_terms_template_detail/payment_terms_template_detail.py b/erpnext/accounts/doctype/payment_terms_template_detail/payment_terms_template_detail.py
index 710988b..0edcd42 100644
--- a/erpnext/accounts/doctype/payment_terms_template_detail/payment_terms_template_detail.py
+++ b/erpnext/accounts/doctype/payment_terms_template_detail/payment_terms_template_detail.py
@@ -6,4 +6,36 @@
 
 
 class PaymentTermsTemplateDetail(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
+
+		credit_days: DF.Int
+		credit_months: DF.Int
+		description: DF.SmallText | None
+		discount: DF.Float
+		discount_type: DF.Literal["Percentage", "Amount"]
+		discount_validity: DF.Int
+		discount_validity_based_on: DF.Literal[
+			"Day(s) after invoice date",
+			"Day(s) after the end of the invoice month",
+			"Month(s) after the end of the invoice month",
+		]
+		due_date_based_on: DF.Literal[
+			"Day(s) after invoice date",
+			"Day(s) after the end of the invoice month",
+			"Month(s) after the end of the invoice month",
+		]
+		invoice_portion: DF.Float
+		mode_of_payment: DF.Link | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		payment_term: DF.Link | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py b/erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py
index 674db6c..2a84d97 100644
--- a/erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py
+++ b/erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py
@@ -15,6 +15,26 @@
 
 
 class PeriodClosingVoucher(AccountsController):
+	# 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
+
+		amended_from: DF.Link | None
+		closing_account_head: DF.Link
+		company: DF.Link
+		error_message: DF.Text | None
+		fiscal_year: DF.Link
+		gle_processing_status: DF.Literal["In Progress", "Completed", "Failed"]
+		posting_date: DF.Date
+		remarks: DF.SmallText
+		transaction_date: DF.Date | None
+		year_start_date: DF.Date | None
+	# end: auto-generated types
+
 	def validate(self):
 		self.validate_account_head()
 		self.validate_posting_date()
diff --git a/erpnext/accounts/doctype/pos_closing_entry/pos_closing_entry.py b/erpnext/accounts/doctype/pos_closing_entry/pos_closing_entry.py
index 115b415..0f3a5bb 100644
--- a/erpnext/accounts/doctype/pos_closing_entry/pos_closing_entry.py
+++ b/erpnext/accounts/doctype/pos_closing_entry/pos_closing_entry.py
@@ -14,6 +14,43 @@
 
 
 class POSClosingEntry(StatusUpdater):
+	# 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
+
+		from erpnext.accounts.doctype.pos_closing_entry_detail.pos_closing_entry_detail import (
+			POSClosingEntryDetail,
+		)
+		from erpnext.accounts.doctype.pos_closing_entry_taxes.pos_closing_entry_taxes import (
+			POSClosingEntryTaxes,
+		)
+		from erpnext.accounts.doctype.pos_invoice_reference.pos_invoice_reference import (
+			POSInvoiceReference,
+		)
+
+		amended_from: DF.Link | None
+		company: DF.Link
+		error_message: DF.SmallText | None
+		grand_total: DF.Currency
+		net_total: DF.Currency
+		payment_reconciliation: DF.Table[POSClosingEntryDetail]
+		period_end_date: DF.Datetime
+		period_start_date: DF.Datetime
+		pos_opening_entry: DF.Link
+		pos_profile: DF.Link
+		pos_transactions: DF.Table[POSInvoiceReference]
+		posting_date: DF.Date
+		posting_time: DF.Time
+		status: DF.Literal["Draft", "Submitted", "Queued", "Failed", "Cancelled"]
+		taxes: DF.Table[POSClosingEntryTaxes]
+		total_quantity: DF.Float
+		user: DF.Link
+	# end: auto-generated types
+
 	def validate(self):
 		self.posting_date = self.posting_date or frappe.utils.nowdate()
 		self.posting_time = self.posting_time or frappe.utils.nowtime()
diff --git a/erpnext/accounts/doctype/pos_closing_entry_detail/pos_closing_entry_detail.py b/erpnext/accounts/doctype/pos_closing_entry_detail/pos_closing_entry_detail.py
index 2e34e44..97e5670 100644
--- a/erpnext/accounts/doctype/pos_closing_entry_detail/pos_closing_entry_detail.py
+++ b/erpnext/accounts/doctype/pos_closing_entry_detail/pos_closing_entry_detail.py
@@ -6,4 +6,22 @@
 
 
 class POSClosingEntryDetail(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
+
+		closing_amount: DF.Currency
+		difference: DF.Currency
+		expected_amount: DF.Currency
+		mode_of_payment: DF.Link
+		opening_amount: DF.Currency
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/pos_closing_entry_taxes/pos_closing_entry_taxes.py b/erpnext/accounts/doctype/pos_closing_entry_taxes/pos_closing_entry_taxes.py
index cfedeb3..ce354a7 100644
--- a/erpnext/accounts/doctype/pos_closing_entry_taxes/pos_closing_entry_taxes.py
+++ b/erpnext/accounts/doctype/pos_closing_entry_taxes/pos_closing_entry_taxes.py
@@ -6,4 +6,20 @@
 
 
 class POSClosingEntryTaxes(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
+		amount: DF.Currency
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		rate: DF.Percent
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/pos_customer_group/pos_customer_group.py b/erpnext/accounts/doctype/pos_customer_group/pos_customer_group.py
index 5e532ae..a1a184e 100644
--- a/erpnext/accounts/doctype/pos_customer_group/pos_customer_group.py
+++ b/erpnext/accounts/doctype/pos_customer_group/pos_customer_group.py
@@ -6,4 +6,18 @@
 
 
 class POSCustomerGroup(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
+
+		customer_group: DF.Link
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/pos_field/pos_field.py b/erpnext/accounts/doctype/pos_field/pos_field.py
index 4ef8827..68441c6 100644
--- a/erpnext/accounts/doctype/pos_field/pos_field.py
+++ b/erpnext/accounts/doctype/pos_field/pos_field.py
@@ -7,4 +7,24 @@
 
 
 class POSField(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
+
+		default_value: DF.Data | None
+		fieldname: DF.Literal
+		fieldtype: DF.Data | None
+		label: DF.Data | None
+		options: DF.Text | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		read_only: DF.Check
+		reqd: DF.Check
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/pos_invoice/pos_invoice.json b/erpnext/accounts/doctype/pos_invoice/pos_invoice.json
index f604707..955b66a 100644
--- a/erpnext/accounts/doctype/pos_invoice/pos_invoice.json
+++ b/erpnext/accounts/doctype/pos_invoice/pos_invoice.json
@@ -18,6 +18,7 @@
   "is_pos",
   "is_return",
   "update_billed_amount_in_sales_order",
+  "update_billed_amount_in_delivery_note",
   "column_break1",
   "company",
   "posting_date",
@@ -1550,12 +1551,19 @@
    "fieldtype": "Currency",
    "label": "Amount Eligible for Commission",
    "read_only": 1
+  },
+  {
+   "default": "1",
+   "depends_on": "eval: doc.is_return && doc.return_against",
+   "fieldname": "update_billed_amount_in_delivery_note",
+   "fieldtype": "Check",
+   "label": "Update Billed Amount in Delivery Note"
   }
  ],
  "icon": "fa fa-file-text",
  "is_submittable": 1,
  "links": [],
- "modified": "2023-06-03 16:23:41.083409",
+ "modified": "2023-11-20 12:27:12.848149",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "POS Invoice",
diff --git a/erpnext/accounts/doctype/pos_invoice/pos_invoice.py b/erpnext/accounts/doctype/pos_invoice/pos_invoice.py
index e36e97b..bfb51da 100644
--- a/erpnext/accounts/doctype/pos_invoice/pos_invoice.py
+++ b/erpnext/accounts/doctype/pos_invoice/pos_invoice.py
@@ -20,6 +20,169 @@
 
 
 class POSInvoice(SalesInvoice):
+	# 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
+
+		from erpnext.accounts.doctype.payment_schedule.payment_schedule import PaymentSchedule
+		from erpnext.accounts.doctype.pos_invoice_item.pos_invoice_item import POSInvoiceItem
+		from erpnext.accounts.doctype.pricing_rule_detail.pricing_rule_detail import PricingRuleDetail
+		from erpnext.accounts.doctype.sales_invoice_advance.sales_invoice_advance import (
+			SalesInvoiceAdvance,
+		)
+		from erpnext.accounts.doctype.sales_invoice_payment.sales_invoice_payment import (
+			SalesInvoicePayment,
+		)
+		from erpnext.accounts.doctype.sales_invoice_timesheet.sales_invoice_timesheet import (
+			SalesInvoiceTimesheet,
+		)
+		from erpnext.accounts.doctype.sales_taxes_and_charges.sales_taxes_and_charges import (
+			SalesTaxesandCharges,
+		)
+		from erpnext.selling.doctype.sales_team.sales_team import SalesTeam
+		from erpnext.stock.doctype.packed_item.packed_item import PackedItem
+
+		account_for_change_amount: DF.Link | None
+		additional_discount_percentage: DF.Float
+		address_display: DF.SmallText | None
+		advances: DF.Table[SalesInvoiceAdvance]
+		against_income_account: DF.SmallText | None
+		allocate_advances_automatically: DF.Check
+		amended_from: DF.Link | None
+		amount_eligible_for_commission: DF.Currency
+		apply_discount_on: DF.Literal["", "Grand Total", "Net Total"]
+		auto_repeat: DF.Link | None
+		base_change_amount: DF.Currency
+		base_discount_amount: DF.Currency
+		base_grand_total: DF.Currency
+		base_in_words: DF.Data | None
+		base_net_total: DF.Currency
+		base_paid_amount: DF.Currency
+		base_rounded_total: DF.Currency
+		base_rounding_adjustment: DF.Currency
+		base_total: DF.Currency
+		base_total_taxes_and_charges: DF.Currency
+		base_write_off_amount: DF.Currency
+		campaign: DF.Link | None
+		cash_bank_account: DF.Link | None
+		change_amount: DF.Currency
+		commission_rate: DF.Float
+		company: DF.Link
+		company_address: DF.Link | None
+		company_address_display: DF.SmallText | None
+		consolidated_invoice: DF.Link | None
+		contact_display: DF.SmallText | None
+		contact_email: DF.Data | None
+		contact_mobile: DF.Data | None
+		contact_person: DF.Link | None
+		conversion_rate: DF.Float
+		cost_center: DF.Link | None
+		coupon_code: DF.Link | None
+		currency: DF.Link
+		customer: DF.Link | None
+		customer_address: DF.Link | None
+		customer_group: DF.Link | None
+		customer_name: DF.Data | None
+		debit_to: DF.Link
+		discount_amount: DF.Currency
+		due_date: DF.Date | None
+		from_date: DF.Date | None
+		grand_total: DF.Currency
+		group_same_items: DF.Check
+		ignore_pricing_rule: DF.Check
+		in_words: DF.Data | None
+		inter_company_invoice_reference: DF.Link | None
+		is_discounted: DF.Check
+		is_opening: DF.Literal["No", "Yes"]
+		is_pos: DF.Check
+		is_return: DF.Check
+		items: DF.Table[POSInvoiceItem]
+		language: DF.Data | None
+		letter_head: DF.Link | None
+		loyalty_amount: DF.Currency
+		loyalty_points: DF.Int
+		loyalty_program: DF.Link | None
+		loyalty_redemption_account: DF.Link | None
+		loyalty_redemption_cost_center: DF.Link | None
+		naming_series: DF.Literal["ACC-PSINV-.YYYY.-"]
+		net_total: DF.Currency
+		other_charges_calculation: DF.LongText | None
+		outstanding_amount: DF.Currency
+		packed_items: DF.Table[PackedItem]
+		paid_amount: DF.Currency
+		party_account_currency: DF.Link | None
+		payment_schedule: DF.Table[PaymentSchedule]
+		payment_terms_template: DF.Link | None
+		payments: DF.Table[SalesInvoicePayment]
+		plc_conversion_rate: DF.Float
+		po_date: DF.Date | None
+		po_no: DF.Data | None
+		pos_profile: DF.Link | None
+		posting_date: DF.Date
+		posting_time: DF.Time | None
+		price_list_currency: DF.Link
+		pricing_rules: DF.Table[PricingRuleDetail]
+		project: DF.Link | None
+		redeem_loyalty_points: DF.Check
+		remarks: DF.SmallText | None
+		return_against: DF.Link | None
+		rounded_total: DF.Currency
+		rounding_adjustment: DF.Currency
+		sales_partner: DF.Link | None
+		sales_team: DF.Table[SalesTeam]
+		scan_barcode: DF.Data | None
+		select_print_heading: DF.Link | None
+		selling_price_list: DF.Link
+		set_posting_time: DF.Check
+		set_warehouse: DF.Link | None
+		shipping_address: DF.SmallText | None
+		shipping_address_name: DF.Link | None
+		shipping_rule: DF.Link | None
+		source: DF.Link | None
+		status: DF.Literal[
+			"",
+			"Draft",
+			"Return",
+			"Credit Note Issued",
+			"Consolidated",
+			"Submitted",
+			"Paid",
+			"Unpaid",
+			"Unpaid and Discounted",
+			"Overdue and Discounted",
+			"Overdue",
+			"Cancelled",
+		]
+		tax_category: DF.Link | None
+		tax_id: DF.Data | None
+		taxes: DF.Table[SalesTaxesandCharges]
+		taxes_and_charges: DF.Link | None
+		tc_name: DF.Link | None
+		terms: DF.TextEditor | None
+		territory: DF.Link | None
+		timesheets: DF.Table[SalesInvoiceTimesheet]
+		title: DF.Data | None
+		to_date: DF.Date | None
+		total: DF.Currency
+		total_advance: DF.Currency
+		total_billing_amount: DF.Currency
+		total_commission: DF.Currency
+		total_net_weight: DF.Float
+		total_qty: DF.Float
+		total_taxes_and_charges: DF.Currency
+		update_billed_amount_in_delivery_note: DF.Check
+		update_billed_amount_in_sales_order: DF.Check
+		update_stock: DF.Check
+		write_off_account: DF.Link | None
+		write_off_amount: DF.Currency
+		write_off_cost_center: DF.Link | None
+		write_off_outstanding_amount_automatically: DF.Check
+	# end: auto-generated types
+
 	def __init__(self, *args, **kwargs):
 		super(POSInvoice, self).__init__(*args, **kwargs)
 
@@ -556,7 +719,7 @@
 		return bin_qty - pos_sales_qty, is_stock_item
 	else:
 		is_stock_item = True
-		if frappe.db.exists("Product Bundle", item_code):
+		if frappe.db.exists("Product Bundle", {"name": item_code, "disabled": 0}):
 			return get_bundle_availability(item_code, warehouse), is_stock_item
 		else:
 			is_stock_item = False
diff --git a/erpnext/accounts/doctype/pos_invoice_item/pos_invoice_item.json b/erpnext/accounts/doctype/pos_invoice_item/pos_invoice_item.json
index cb0ed3d..5a281aa 100644
--- a/erpnext/accounts/doctype/pos_invoice_item/pos_invoice_item.json
+++ b/erpnext/accounts/doctype/pos_invoice_item/pos_invoice_item.json
@@ -186,6 +186,7 @@
    "label": "Image"
   },
   {
+   "fetch_from": "item_code.image",
    "fieldname": "image",
    "fieldtype": "Attach",
    "hidden": 1,
@@ -833,7 +834,7 @@
  ],
  "istable": 1,
  "links": [],
- "modified": "2023-03-12 13:36:40.160468",
+ "modified": "2023-11-14 18:33:22.585715",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "POS Invoice Item",
diff --git a/erpnext/accounts/doctype/pos_invoice_item/pos_invoice_item.py b/erpnext/accounts/doctype/pos_invoice_item/pos_invoice_item.py
index 7e3ae82..e2a62f1 100644
--- a/erpnext/accounts/doctype/pos_invoice_item/pos_invoice_item.py
+++ b/erpnext/accounts/doctype/pos_invoice_item/pos_invoice_item.py
@@ -7,4 +7,84 @@
 
 
 class POSInvoiceItem(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
+
+		actual_batch_qty: DF.Float
+		actual_qty: DF.Float
+		allow_zero_valuation_rate: DF.Check
+		amount: DF.Currency
+		asset: DF.Link | None
+		barcode: DF.Data | None
+		base_amount: DF.Currency
+		base_net_amount: DF.Currency
+		base_net_rate: DF.Currency
+		base_price_list_rate: DF.Currency
+		base_rate: DF.Currency
+		base_rate_with_margin: DF.Currency
+		batch_no: DF.Link | None
+		brand: DF.Data | None
+		conversion_factor: DF.Float
+		cost_center: DF.Link
+		customer_item_code: DF.Data | None
+		deferred_revenue_account: DF.Link | None
+		delivered_by_supplier: DF.Check
+		delivered_qty: DF.Float
+		delivery_note: DF.Link | None
+		description: DF.TextEditor
+		discount_amount: DF.Currency
+		discount_percentage: DF.Percent
+		dn_detail: DF.Data | None
+		enable_deferred_revenue: DF.Check
+		expense_account: DF.Link | None
+		finance_book: DF.Link | None
+		grant_commission: DF.Check
+		has_item_scanned: DF.Check
+		image: DF.Attach | None
+		income_account: DF.Link
+		is_fixed_asset: DF.Check
+		is_free_item: DF.Check
+		item_code: DF.Link | None
+		item_group: DF.Link | None
+		item_name: DF.Data
+		item_tax_rate: DF.SmallText | None
+		item_tax_template: DF.Link | None
+		margin_rate_or_amount: DF.Float
+		margin_type: DF.Literal["", "Percentage", "Amount"]
+		net_amount: DF.Currency
+		net_rate: DF.Currency
+		page_break: DF.Check
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		pos_invoice_item: DF.Data | None
+		price_list_rate: DF.Currency
+		pricing_rules: DF.SmallText | None
+		project: DF.Link | None
+		qty: DF.Float
+		quality_inspection: DF.Link | None
+		rate: DF.Currency
+		rate_with_margin: DF.Currency
+		sales_order: DF.Link | None
+		serial_and_batch_bundle: DF.Link | None
+		serial_no: DF.SmallText | None
+		service_end_date: DF.Date | None
+		service_start_date: DF.Date | None
+		service_stop_date: DF.Date | None
+		so_detail: DF.Data | None
+		stock_qty: DF.Float
+		stock_uom: DF.Link | None
+		target_warehouse: DF.Link | None
+		total_weight: DF.Float
+		uom: DF.Link
+		warehouse: DF.Link | None
+		weight_per_unit: DF.Float
+		weight_uom: DF.Link | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.py b/erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.py
index c161dac..cd858ca 100644
--- a/erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.py
+++ b/erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.py
@@ -16,6 +16,30 @@
 
 
 class POSInvoiceMergeLog(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
+
+		from erpnext.accounts.doctype.pos_invoice_reference.pos_invoice_reference import (
+			POSInvoiceReference,
+		)
+
+		amended_from: DF.Link | None
+		consolidated_credit_note: DF.Link | None
+		consolidated_invoice: DF.Link | None
+		customer: DF.Link
+		customer_group: DF.Link | None
+		merge_invoices_based_on: DF.Literal["Customer", "Customer Group"]
+		pos_closing_entry: DF.Link | None
+		pos_invoices: DF.Table[POSInvoiceReference]
+		posting_date: DF.Date
+		posting_time: DF.Time
+	# end: auto-generated types
+
 	def validate(self):
 		self.validate_customer()
 		self.validate_pos_invoice_status()
diff --git a/erpnext/accounts/doctype/pos_invoice_reference/pos_invoice_reference.py b/erpnext/accounts/doctype/pos_invoice_reference/pos_invoice_reference.py
index c1c36f8..6e7710a 100644
--- a/erpnext/accounts/doctype/pos_invoice_reference/pos_invoice_reference.py
+++ b/erpnext/accounts/doctype/pos_invoice_reference/pos_invoice_reference.py
@@ -7,4 +7,23 @@
 
 
 class POSInvoiceReference(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
+
+		customer: DF.Link
+		grand_total: DF.Currency
+		is_return: DF.Check
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		pos_invoice: DF.Link
+		posting_date: DF.Date
+		return_against: DF.Link | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/pos_item_group/pos_item_group.py b/erpnext/accounts/doctype/pos_item_group/pos_item_group.py
index 75fa080..650b0be 100644
--- a/erpnext/accounts/doctype/pos_item_group/pos_item_group.py
+++ b/erpnext/accounts/doctype/pos_item_group/pos_item_group.py
@@ -6,4 +6,18 @@
 
 
 class POSItemGroup(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
+
+		item_group: DF.Link
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/pos_opening_entry/pos_opening_entry.py b/erpnext/accounts/doctype/pos_opening_entry/pos_opening_entry.py
index 3cd1426..10b07c2 100644
--- a/erpnext/accounts/doctype/pos_opening_entry/pos_opening_entry.py
+++ b/erpnext/accounts/doctype/pos_opening_entry/pos_opening_entry.py
@@ -10,6 +10,31 @@
 
 
 class POSOpeningEntry(StatusUpdater):
+	# 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
+
+		from erpnext.accounts.doctype.pos_opening_entry_detail.pos_opening_entry_detail import (
+			POSOpeningEntryDetail,
+		)
+
+		amended_from: DF.Link | None
+		balance_details: DF.Table[POSOpeningEntryDetail]
+		company: DF.Link
+		period_end_date: DF.Date | None
+		period_start_date: DF.Datetime
+		pos_closing_entry: DF.Data | None
+		pos_profile: DF.Link
+		posting_date: DF.Date
+		set_posting_date: DF.Check
+		status: DF.Literal["Draft", "Open", "Closed", "Cancelled"]
+		user: DF.Link
+	# end: auto-generated types
+
 	def validate(self):
 		self.validate_pos_profile_and_cashier()
 		self.validate_payment_method_account()
diff --git a/erpnext/accounts/doctype/pos_opening_entry_detail/pos_opening_entry_detail.py b/erpnext/accounts/doctype/pos_opening_entry_detail/pos_opening_entry_detail.py
index 9108b90..e66769c 100644
--- a/erpnext/accounts/doctype/pos_opening_entry_detail/pos_opening_entry_detail.py
+++ b/erpnext/accounts/doctype/pos_opening_entry_detail/pos_opening_entry_detail.py
@@ -7,4 +7,19 @@
 
 
 class POSOpeningEntryDetail(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
+
+		mode_of_payment: DF.Link
+		opening_amount: DF.Currency
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/pos_payment_method/pos_payment_method.py b/erpnext/accounts/doctype/pos_payment_method/pos_payment_method.py
index 589047d..42d0409 100644
--- a/erpnext/accounts/doctype/pos_payment_method/pos_payment_method.py
+++ b/erpnext/accounts/doctype/pos_payment_method/pos_payment_method.py
@@ -7,4 +7,20 @@
 
 
 class POSPaymentMethod(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
+
+		allow_in_returns: DF.Check
+		default: DF.Check
+		mode_of_payment: DF.Link
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/pos_profile/pos_profile.py b/erpnext/accounts/doctype/pos_profile/pos_profile.py
index 58be2d3..30f3e0c 100644
--- a/erpnext/accounts/doctype/pos_profile/pos_profile.py
+++ b/erpnext/accounts/doctype/pos_profile/pos_profile.py
@@ -9,6 +9,57 @@
 
 
 class POSProfile(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
+
+		from erpnext.accounts.doctype.pos_customer_group.pos_customer_group import POSCustomerGroup
+		from erpnext.accounts.doctype.pos_item_group.pos_item_group import POSItemGroup
+		from erpnext.accounts.doctype.pos_payment_method.pos_payment_method import POSPaymentMethod
+		from erpnext.accounts.doctype.pos_profile_user.pos_profile_user import POSProfileUser
+
+		account_for_change_amount: DF.Link | None
+		allow_discount_change: DF.Check
+		allow_rate_change: DF.Check
+		applicable_for_users: DF.Table[POSProfileUser]
+		apply_discount_on: DF.Literal["Grand Total", "Net Total"]
+		auto_add_item_to_cart: DF.Check
+		campaign: DF.Link | None
+		company: DF.Link
+		company_address: DF.Link | None
+		cost_center: DF.Link | None
+		country: DF.ReadOnly | None
+		currency: DF.Link
+		customer: DF.Link | None
+		customer_groups: DF.Table[POSCustomerGroup]
+		disable_rounded_total: DF.Check
+		disabled: DF.Check
+		expense_account: DF.Link | None
+		hide_images: DF.Check
+		hide_unavailable_items: DF.Check
+		ignore_pricing_rule: DF.Check
+		income_account: DF.Link | None
+		item_groups: DF.Table[POSItemGroup]
+		letter_head: DF.Link | None
+		payments: DF.Table[POSPaymentMethod]
+		print_format: DF.Link | None
+		select_print_heading: DF.Link | None
+		selling_price_list: DF.Link | None
+		tax_category: DF.Link | None
+		taxes_and_charges: DF.Link | None
+		tc_name: DF.Link | None
+		update_stock: DF.Check
+		validate_stock_on_save: DF.Check
+		warehouse: DF.Link
+		write_off_account: DF.Link
+		write_off_cost_center: DF.Link
+		write_off_limit: DF.Currency
+	# end: auto-generated types
+
 	def validate(self):
 		self.validate_default_profile()
 		self.validate_all_link_fields()
diff --git a/erpnext/accounts/doctype/pos_profile_user/pos_profile_user.py b/erpnext/accounts/doctype/pos_profile_user/pos_profile_user.py
index c92d563..d4de263 100644
--- a/erpnext/accounts/doctype/pos_profile_user/pos_profile_user.py
+++ b/erpnext/accounts/doctype/pos_profile_user/pos_profile_user.py
@@ -6,4 +6,19 @@
 
 
 class POSProfileUser(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
+
+		default: DF.Check
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		user: DF.Link | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/pos_search_fields/pos_search_fields.py b/erpnext/accounts/doctype/pos_search_fields/pos_search_fields.py
index fd55dc8..181f9ef 100644
--- a/erpnext/accounts/doctype/pos_search_fields/pos_search_fields.py
+++ b/erpnext/accounts/doctype/pos_search_fields/pos_search_fields.py
@@ -7,4 +7,19 @@
 
 
 class POSSearchFields(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
+
+		field: DF.Literal
+		fieldname: DF.Data | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/pos_settings/pos_settings.py b/erpnext/accounts/doctype/pos_settings/pos_settings.py
index 2adecc0..1e298a6 100644
--- a/erpnext/accounts/doctype/pos_settings/pos_settings.py
+++ b/erpnext/accounts/doctype/pos_settings/pos_settings.py
@@ -6,5 +6,20 @@
 
 
 class POSSettings(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
+
+		from erpnext.accounts.doctype.pos_field.pos_field import POSField
+		from erpnext.accounts.doctype.pos_search_fields.pos_search_fields import POSSearchFields
+
+		invoice_fields: DF.Table[POSField]
+		pos_search_fields: DF.Table[POSSearchFields]
+	# end: auto-generated types
+
 	def validate(self):
 		pass
diff --git a/erpnext/accounts/doctype/pricing_rule/pricing_rule.py b/erpnext/accounts/doctype/pricing_rule/pricing_rule.py
index 0b7ea24..b41cf53 100644
--- a/erpnext/accounts/doctype/pricing_rule/pricing_rule.py
+++ b/erpnext/accounts/doctype/pricing_rule/pricing_rule.py
@@ -18,6 +18,115 @@
 
 
 class PricingRule(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
+
+		from erpnext.accounts.doctype.pricing_rule_brand.pricing_rule_brand import PricingRuleBrand
+		from erpnext.accounts.doctype.pricing_rule_item_code.pricing_rule_item_code import (
+			PricingRuleItemCode,
+		)
+		from erpnext.accounts.doctype.pricing_rule_item_group.pricing_rule_item_group import (
+			PricingRuleItemGroup,
+		)
+
+		applicable_for: DF.Literal[
+			"",
+			"Customer",
+			"Customer Group",
+			"Territory",
+			"Sales Partner",
+			"Campaign",
+			"Supplier",
+			"Supplier Group",
+		]
+		apply_discount_on: DF.Literal["Grand Total", "Net Total"]
+		apply_discount_on_rate: DF.Check
+		apply_multiple_pricing_rules: DF.Check
+		apply_on: DF.Literal["", "Item Code", "Item Group", "Brand", "Transaction"]
+		apply_recursion_over: DF.Float
+		apply_rule_on_other: DF.Literal["", "Item Code", "Item Group", "Brand"]
+		brands: DF.Table[PricingRuleBrand]
+		buying: DF.Check
+		campaign: DF.Link | None
+		company: DF.Link | None
+		condition: DF.Code | None
+		coupon_code_based: DF.Check
+		currency: DF.Link
+		customer: DF.Link | None
+		customer_group: DF.Link | None
+		disable: DF.Check
+		discount_amount: DF.Currency
+		discount_percentage: DF.Float
+		for_price_list: DF.Link | None
+		free_item: DF.Link | None
+		free_item_rate: DF.Currency
+		free_item_uom: DF.Link | None
+		free_qty: DF.Float
+		is_cumulative: DF.Check
+		is_recursive: DF.Check
+		item_groups: DF.Table[PricingRuleItemGroup]
+		items: DF.Table[PricingRuleItemCode]
+		margin_rate_or_amount: DF.Float
+		margin_type: DF.Literal["", "Percentage", "Amount"]
+		max_amt: DF.Currency
+		max_qty: DF.Float
+		min_amt: DF.Currency
+		min_qty: DF.Float
+		mixed_conditions: DF.Check
+		naming_series: DF.Literal["PRLE-.####"]
+		other_brand: DF.Link | None
+		other_item_code: DF.Link | None
+		other_item_group: DF.Link | None
+		price_or_product_discount: DF.Literal["Price", "Product"]
+		priority: DF.Literal[
+			"",
+			"1",
+			"2",
+			"3",
+			"4",
+			"5",
+			"6",
+			"7",
+			"8",
+			"9",
+			"10",
+			"11",
+			"12",
+			"13",
+			"14",
+			"15",
+			"16",
+			"17",
+			"18",
+			"19",
+			"20",
+		]
+		promotional_scheme: DF.Link | None
+		promotional_scheme_id: DF.Data | None
+		rate: DF.Currency
+		rate_or_discount: DF.Literal["", "Rate", "Discount Percentage", "Discount Amount"]
+		recurse_for: DF.Float
+		round_free_qty: DF.Check
+		rule_description: DF.SmallText | None
+		sales_partner: DF.Link | None
+		same_item: DF.Check
+		selling: DF.Check
+		supplier: DF.Link | None
+		supplier_group: DF.Link | None
+		territory: DF.Link | None
+		threshold_percentage: DF.Percent
+		title: DF.Data
+		valid_from: DF.Date | None
+		valid_upto: DF.Date | None
+		validate_applied_rule: DF.Check
+		warehouse: DF.Link | None
+	# end: auto-generated types
+
 	def validate(self):
 		self.validate_mandatory()
 		self.validate_duplicate_apply_on()
diff --git a/erpnext/accounts/doctype/pricing_rule_brand/pricing_rule_brand.py b/erpnext/accounts/doctype/pricing_rule_brand/pricing_rule_brand.py
index fdd5be0..ffd74c2 100644
--- a/erpnext/accounts/doctype/pricing_rule_brand/pricing_rule_brand.py
+++ b/erpnext/accounts/doctype/pricing_rule_brand/pricing_rule_brand.py
@@ -6,4 +6,19 @@
 
 
 class PricingRuleBrand(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
+
+		brand: DF.Link | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		uom: DF.Link | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/pricing_rule_detail/pricing_rule_detail.py b/erpnext/accounts/doctype/pricing_rule_detail/pricing_rule_detail.py
index f48b569..18be93d 100644
--- a/erpnext/accounts/doctype/pricing_rule_detail/pricing_rule_detail.py
+++ b/erpnext/accounts/doctype/pricing_rule_detail/pricing_rule_detail.py
@@ -6,4 +6,23 @@
 
 
 class PricingRuleDetail(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
+
+		child_docname: DF.Data | None
+		item_code: DF.Data | None
+		margin_type: DF.Data | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		pricing_rule: DF.Link | None
+		rate_or_discount: DF.Data | None
+		rule_applied: DF.Check
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/pricing_rule_item_code/pricing_rule_item_code.py b/erpnext/accounts/doctype/pricing_rule_item_code/pricing_rule_item_code.py
index f8a2c0e..ae9570a 100644
--- a/erpnext/accounts/doctype/pricing_rule_item_code/pricing_rule_item_code.py
+++ b/erpnext/accounts/doctype/pricing_rule_item_code/pricing_rule_item_code.py
@@ -6,4 +6,19 @@
 
 
 class PricingRuleItemCode(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
+
+		item_code: DF.Link | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		uom: DF.Link | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/pricing_rule_item_group/pricing_rule_item_group.py b/erpnext/accounts/doctype/pricing_rule_item_group/pricing_rule_item_group.py
index 940350a..fed0c29 100644
--- a/erpnext/accounts/doctype/pricing_rule_item_group/pricing_rule_item_group.py
+++ b/erpnext/accounts/doctype/pricing_rule_item_group/pricing_rule_item_group.py
@@ -6,4 +6,19 @@
 
 
 class PricingRuleItemGroup(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
+
+		item_group: DF.Link | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		uom: DF.Link | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/process_deferred_accounting/process_deferred_accounting.py b/erpnext/accounts/doctype/process_deferred_accounting/process_deferred_accounting.py
index 1f88849..6a13c1f 100644
--- a/erpnext/accounts/doctype/process_deferred_accounting/process_deferred_accounting.py
+++ b/erpnext/accounts/doctype/process_deferred_accounting/process_deferred_accounting.py
@@ -15,6 +15,23 @@
 
 
 class ProcessDeferredAccounting(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: DF.Link | None
+		amended_from: DF.Link | None
+		company: DF.Link
+		end_date: DF.Date
+		posting_date: DF.Date
+		start_date: DF.Date
+		type: DF.Literal["", "Income", "Expense"]
+	# end: auto-generated types
+
 	def validate(self):
 		if self.end_date < self.start_date:
 			frappe.throw(_("End date cannot be before start date"))
diff --git a/erpnext/accounts/doctype/process_payment_reconciliation/process_payment_reconciliation.py b/erpnext/accounts/doctype/process_payment_reconciliation/process_payment_reconciliation.py
index eb8c16e..67a7f90 100644
--- a/erpnext/accounts/doctype/process_payment_reconciliation/process_payment_reconciliation.py
+++ b/erpnext/accounts/doctype/process_payment_reconciliation/process_payment_reconciliation.py
@@ -9,6 +9,31 @@
 
 
 class ProcessPaymentReconciliation(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
+
+		amended_from: DF.Link | None
+		bank_cash_account: DF.Link | None
+		company: DF.Link
+		cost_center: DF.Link | None
+		error_log: DF.LongText | None
+		from_invoice_date: DF.Date | None
+		from_payment_date: DF.Date | None
+		party: DF.DynamicLink
+		party_type: DF.Link
+		receivable_payable_account: DF.Link
+		status: DF.Literal[
+			"", "Queued", "Running", "Paused", "Completed", "Partially Reconciled", "Failed", "Cancelled"
+		]
+		to_invoice_date: DF.Date | None
+		to_payment_date: DF.Date | None
+	# end: auto-generated types
+
 	def validate(self):
 		self.validate_receivable_payable_account()
 		self.validate_bank_cash_account()
diff --git a/erpnext/accounts/doctype/process_payment_reconciliation_log/process_payment_reconciliation_log.py b/erpnext/accounts/doctype/process_payment_reconciliation_log/process_payment_reconciliation_log.py
index 85d70a4..153fffc 100644
--- a/erpnext/accounts/doctype/process_payment_reconciliation_log/process_payment_reconciliation_log.py
+++ b/erpnext/accounts/doctype/process_payment_reconciliation_log/process_payment_reconciliation_log.py
@@ -6,4 +6,28 @@
 
 
 class ProcessPaymentReconciliationLog(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
+
+		from erpnext.accounts.doctype.process_payment_reconciliation_log_allocations.process_payment_reconciliation_log_allocations import (
+			ProcessPaymentReconciliationLogAllocations,
+		)
+
+		allocated: DF.Check
+		allocations: DF.Table[ProcessPaymentReconciliationLogAllocations]
+		error_log: DF.LongText | None
+		process_pr: DF.Link
+		reconciled: DF.Check
+		reconciled_entries: DF.Int
+		status: DF.Literal[
+			"Running", "Paused", "Reconciled", "Partially Reconciled", "Failed", "Cancelled"
+		]
+		total_allocations: DF.Int
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/process_payment_reconciliation_log_allocations/process_payment_reconciliation_log_allocations.py b/erpnext/accounts/doctype/process_payment_reconciliation_log_allocations/process_payment_reconciliation_log_allocations.py
index c3e4329..da02e1a 100644
--- a/erpnext/accounts/doctype/process_payment_reconciliation_log_allocations/process_payment_reconciliation_log_allocations.py
+++ b/erpnext/accounts/doctype/process_payment_reconciliation_log_allocations/process_payment_reconciliation_log_allocations.py
@@ -6,4 +6,31 @@
 
 
 class ProcessPaymentReconciliationLogAllocations(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
+
+		allocated_amount: DF.Currency
+		amount: DF.Currency
+		currency: DF.Link | None
+		difference_account: DF.Link | None
+		difference_amount: DF.Currency
+		exchange_rate: DF.Float
+		invoice_number: DF.DynamicLink
+		invoice_type: DF.Link
+		is_advance: DF.Data | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		reconciled: DF.Check
+		reference_name: DF.DynamicLink
+		reference_row: DF.Data | None
+		reference_type: DF.Link
+		unreconciled_amount: DF.Currency
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.py b/erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.py
index 6c959ba..9ad2548 100644
--- a/erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.py
+++ b/erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.py
@@ -23,6 +23,60 @@
 
 
 class ProcessStatementOfAccounts(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
+
+		from erpnext.accounts.doctype.process_statement_of_accounts_customer.process_statement_of_accounts_customer import (
+			ProcessStatementOfAccountsCustomer,
+		)
+		from erpnext.accounts.doctype.psoa_cost_center.psoa_cost_center import PSOACostCenter
+		from erpnext.accounts.doctype.psoa_project.psoa_project import PSOAProject
+
+		account: DF.Link | None
+		ageing_based_on: DF.Literal["Due Date", "Posting Date"]
+		based_on_payment_terms: DF.Check
+		body: DF.TextEditor | None
+		cc_to: DF.Link | None
+		collection_name: DF.DynamicLink | None
+		company: DF.Link
+		cost_center: DF.TableMultiSelect[PSOACostCenter]
+		currency: DF.Link | None
+		customer_collection: DF.Literal[
+			"", "Customer Group", "Territory", "Sales Partner", "Sales Person"
+		]
+		customers: DF.Table[ProcessStatementOfAccountsCustomer]
+		enable_auto_email: DF.Check
+		filter_duration: DF.Int
+		finance_book: DF.Link | None
+		frequency: DF.Literal["Weekly", "Monthly", "Quarterly"]
+		from_date: DF.Date | None
+		group_by: DF.Literal["", "Group by Voucher", "Group by Voucher (Consolidated)"]
+		include_ageing: DF.Check
+		include_break: DF.Check
+		letter_head: DF.Link | None
+		orientation: DF.Literal["Landscape", "Portrait"]
+		payment_terms_template: DF.Link | None
+		pdf_name: DF.Data | None
+		posting_date: DF.Date | None
+		primary_mandatory: DF.Check
+		project: DF.TableMultiSelect[PSOAProject]
+		report: DF.Literal["General Ledger", "Accounts Receivable"]
+		sales_partner: DF.Link | None
+		sales_person: DF.Link | None
+		sender: DF.Link | None
+		show_net_values_in_party_account: DF.Check
+		start_date: DF.Date | None
+		subject: DF.Data | None
+		terms_and_conditions: DF.Link | None
+		territory: DF.Link | None
+		to_date: DF.Date | None
+	# end: auto-generated types
+
 	def validate(self):
 		if not self.subject:
 			self.subject = "Statement Of Accounts for {{ customer.customer_name }}"
diff --git a/erpnext/accounts/doctype/process_statement_of_accounts_customer/process_statement_of_accounts_customer.py b/erpnext/accounts/doctype/process_statement_of_accounts_customer/process_statement_of_accounts_customer.py
index 94fcb78..cac2877 100644
--- a/erpnext/accounts/doctype/process_statement_of_accounts_customer/process_statement_of_accounts_customer.py
+++ b/erpnext/accounts/doctype/process_statement_of_accounts_customer/process_statement_of_accounts_customer.py
@@ -7,4 +7,21 @@
 
 
 class ProcessStatementOfAccountsCustomer(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
+
+		billing_email: DF.Data | None
+		customer: DF.Link
+		customer_name: DF.Data | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		primary_email: DF.ReadOnly | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/process_subscription/process_subscription.py b/erpnext/accounts/doctype/process_subscription/process_subscription.py
index 99269d6..b271e7c 100644
--- a/erpnext/accounts/doctype/process_subscription/process_subscription.py
+++ b/erpnext/accounts/doctype/process_subscription/process_subscription.py
@@ -12,16 +12,28 @@
 
 
 class ProcessSubscription(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
+
+		amended_from: DF.Link | None
+		posting_date: DF.Date
+		subscription: DF.Link | None
+	# end: auto-generated types
+
 	def on_submit(self):
 		process_all(subscription=self.subscription, posting_date=self.posting_date)
 
 
 def create_subscription_process(
-	subscription: str | None, posting_date: Union[str, datetime.date] | None
+	subscription: str | None = None, posting_date: Union[str, datetime.date] | None = None
 ):
 	"""Create a new Process Subscription document"""
 	doc = frappe.new_doc("Process Subscription")
 	doc.subscription = subscription
 	doc.posting_date = getdate(posting_date)
-	doc.insert(ignore_permissions=True)
 	doc.submit()
diff --git a/erpnext/accounts/doctype/promotional_scheme/promotional_scheme.py b/erpnext/accounts/doctype/promotional_scheme/promotional_scheme.py
index 4d28d10..0bb8d3a 100644
--- a/erpnext/accounts/doctype/promotional_scheme/promotional_scheme.py
+++ b/erpnext/accounts/doctype/promotional_scheme/promotional_scheme.py
@@ -69,6 +69,73 @@
 
 
 class PromotionalScheme(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
+
+		from erpnext.accounts.doctype.campaign_item.campaign_item import CampaignItem
+		from erpnext.accounts.doctype.customer_group_item.customer_group_item import CustomerGroupItem
+		from erpnext.accounts.doctype.customer_item.customer_item import CustomerItem
+		from erpnext.accounts.doctype.pricing_rule_brand.pricing_rule_brand import PricingRuleBrand
+		from erpnext.accounts.doctype.pricing_rule_item_code.pricing_rule_item_code import (
+			PricingRuleItemCode,
+		)
+		from erpnext.accounts.doctype.pricing_rule_item_group.pricing_rule_item_group import (
+			PricingRuleItemGroup,
+		)
+		from erpnext.accounts.doctype.promotional_scheme_price_discount.promotional_scheme_price_discount import (
+			PromotionalSchemePriceDiscount,
+		)
+		from erpnext.accounts.doctype.promotional_scheme_product_discount.promotional_scheme_product_discount import (
+			PromotionalSchemeProductDiscount,
+		)
+		from erpnext.accounts.doctype.sales_partner_item.sales_partner_item import SalesPartnerItem
+		from erpnext.accounts.doctype.supplier_group_item.supplier_group_item import SupplierGroupItem
+		from erpnext.accounts.doctype.supplier_item.supplier_item import SupplierItem
+		from erpnext.accounts.doctype.territory_item.territory_item import TerritoryItem
+
+		applicable_for: DF.Literal[
+			"",
+			"Customer",
+			"Customer Group",
+			"Territory",
+			"Sales Partner",
+			"Campaign",
+			"Supplier",
+			"Supplier Group",
+		]
+		apply_on: DF.Literal["", "Item Code", "Item Group", "Brand", "Transaction"]
+		apply_rule_on_other: DF.Literal["", "Item Code", "Item Group", "Brand"]
+		brands: DF.Table[PricingRuleBrand]
+		buying: DF.Check
+		campaign: DF.TableMultiSelect[CampaignItem]
+		company: DF.Link
+		currency: DF.Link | None
+		customer: DF.TableMultiSelect[CustomerItem]
+		customer_group: DF.TableMultiSelect[CustomerGroupItem]
+		disable: DF.Check
+		is_cumulative: DF.Check
+		item_groups: DF.Table[PricingRuleItemGroup]
+		items: DF.Table[PricingRuleItemCode]
+		mixed_conditions: DF.Check
+		other_brand: DF.Link | None
+		other_item_code: DF.Link | None
+		other_item_group: DF.Link | None
+		price_discount_slabs: DF.Table[PromotionalSchemePriceDiscount]
+		product_discount_slabs: DF.Table[PromotionalSchemeProductDiscount]
+		sales_partner: DF.TableMultiSelect[SalesPartnerItem]
+		selling: DF.Check
+		supplier: DF.TableMultiSelect[SupplierItem]
+		supplier_group: DF.TableMultiSelect[SupplierGroupItem]
+		territory: DF.TableMultiSelect[TerritoryItem]
+		valid_from: DF.Date | None
+		valid_upto: DF.Date | None
+	# end: auto-generated types
+
 	def validate(self):
 		if not self.selling and not self.buying:
 			frappe.throw(_("Either 'Selling' or 'Buying' must be selected"), title=_("Mandatory"))
diff --git a/erpnext/accounts/doctype/promotional_scheme_price_discount/promotional_scheme_price_discount.py b/erpnext/accounts/doctype/promotional_scheme_price_discount/promotional_scheme_price_discount.py
index a0e2200..545c17d 100644
--- a/erpnext/accounts/doctype/promotional_scheme_price_discount/promotional_scheme_price_discount.py
+++ b/erpnext/accounts/doctype/promotional_scheme_price_discount/promotional_scheme_price_discount.py
@@ -6,4 +6,55 @@
 
 
 class PromotionalSchemePriceDiscount(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
+
+		apply_discount_on_rate: DF.Check
+		apply_multiple_pricing_rules: DF.Check
+		disable: DF.Check
+		discount_amount: DF.Currency
+		discount_percentage: DF.Float
+		max_amount: DF.Currency
+		max_qty: DF.Float
+		min_amount: DF.Currency
+		min_qty: DF.Float
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		priority: DF.Literal[
+			"",
+			"1",
+			"2",
+			"3",
+			"4",
+			"5",
+			"6",
+			"7",
+			"8",
+			"9",
+			"10",
+			"11",
+			"12",
+			"13",
+			"14",
+			"15",
+			"16",
+			"17",
+			"18",
+			"19",
+			"20",
+		]
+		rate: DF.Currency
+		rate_or_discount: DF.Literal["", "Rate", "Discount Percentage", "Discount Amount"]
+		rule_description: DF.SmallText
+		threshold_percentage: DF.Percent
+		validate_applied_rule: DF.Check
+		warehouse: DF.Link | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/promotional_scheme_product_discount/promotional_scheme_product_discount.py b/erpnext/accounts/doctype/promotional_scheme_product_discount/promotional_scheme_product_discount.py
index c9f6f86..7dd5fea 100644
--- a/erpnext/accounts/doctype/promotional_scheme_product_discount/promotional_scheme_product_discount.py
+++ b/erpnext/accounts/doctype/promotional_scheme_product_discount/promotional_scheme_product_discount.py
@@ -6,4 +6,55 @@
 
 
 class PromotionalSchemeProductDiscount(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
+
+		apply_multiple_pricing_rules: DF.Check
+		disable: DF.Check
+		free_item: DF.Link | None
+		free_item_rate: DF.Currency
+		free_item_uom: DF.Link | None
+		free_qty: DF.Float
+		is_recursive: DF.Check
+		max_amount: DF.Currency
+		max_qty: DF.Float
+		min_amount: DF.Currency
+		min_qty: DF.Float
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		priority: DF.Literal[
+			"",
+			"1",
+			"2",
+			"3",
+			"4",
+			"5",
+			"6",
+			"7",
+			"8",
+			"9",
+			"10",
+			"11",
+			"12",
+			"13",
+			"14",
+			"15",
+			"16",
+			"17",
+			"18",
+			"19",
+			"20",
+		]
+		rule_description: DF.SmallText
+		same_item: DF.Check
+		threshold_percentage: DF.Percent
+		warehouse: DF.Link | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/psoa_cost_center/psoa_cost_center.py b/erpnext/accounts/doctype/psoa_cost_center/psoa_cost_center.py
index 877998a..683cd78 100644
--- a/erpnext/accounts/doctype/psoa_cost_center/psoa_cost_center.py
+++ b/erpnext/accounts/doctype/psoa_cost_center/psoa_cost_center.py
@@ -7,4 +7,18 @@
 
 
 class PSOACostCenter(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
+
+		cost_center_name: DF.Link | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/psoa_project/psoa_project.py b/erpnext/accounts/doctype/psoa_project/psoa_project.py
index de22bb7..c2d8076 100644
--- a/erpnext/accounts/doctype/psoa_project/psoa_project.py
+++ b/erpnext/accounts/doctype/psoa_project/psoa_project.py
@@ -7,4 +7,18 @@
 
 
 class PSOAProject(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
+
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		project_name: DF.Link | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js
index 2eaa337..4b0df12 100644
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js
@@ -180,7 +180,7 @@
 		}
 
 		this.frm.set_df_property("tax_withholding_category", "hidden", doc.apply_tds ? 0 : 1);
-		erpnext.accounts.unreconcile_payments.add_unreconcile_btn(me.frm);
+		erpnext.accounts.unreconcile_payment.add_unreconcile_btn(me.frm);
 	}
 
 	unblock_invoice() {
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json
index 09bffff..f85fc87 100644
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json
@@ -189,6 +189,7 @@
   "additional_info_section",
   "is_internal_supplier",
   "represents_company",
+  "supplier_group",
   "column_break_147",
   "inter_company_invoice_reference",
   "is_old_subcontracting_flow",
@@ -1598,13 +1599,20 @@
    "fieldtype": "Check",
    "label": "Use Transaction Date Exchange Rate",
    "read_only": 1
+  },
+  {
+   "fetch_from": "supplier.supplier_group",
+   "fieldname": "supplier_group",
+   "fieldtype": "Link",
+   "label": "Supplier Group",
+   "options": "Supplier Group"
   }
  ],
  "icon": "fa fa-file-text",
  "idx": 204,
  "is_submittable": 1,
  "links": [],
- "modified": "2023-11-03 15:47:30.319200",
+ "modified": "2023-11-29 15:35:44.697496",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Purchase Invoice",
@@ -1667,4 +1675,4 @@
  "timeline_field": "supplier",
  "title_field": "title",
  "track_changes": 1
-}
+}
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
index e1f0f19..262732c 100644
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
@@ -13,6 +13,7 @@
 from erpnext.accounts.doctype.gl_entry.gl_entry import update_outstanding_amt
 from erpnext.accounts.doctype.repost_accounting_ledger.repost_accounting_ledger import (
 	validate_docs_for_deferred_accounting,
+	validate_docs_for_voucher_types,
 )
 from erpnext.accounts.doctype.sales_invoice.sales_invoice import (
 	check_if_return_invoice_linked_with_payment_entry,
@@ -53,6 +54,174 @@
 
 
 class PurchaseInvoice(BuyingController):
+	# 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
+
+		from erpnext.accounts.doctype.advance_tax.advance_tax import AdvanceTax
+		from erpnext.accounts.doctype.payment_schedule.payment_schedule import PaymentSchedule
+		from erpnext.accounts.doctype.pricing_rule_detail.pricing_rule_detail import PricingRuleDetail
+		from erpnext.accounts.doctype.purchase_invoice_advance.purchase_invoice_advance import (
+			PurchaseInvoiceAdvance,
+		)
+		from erpnext.accounts.doctype.purchase_invoice_item.purchase_invoice_item import (
+			PurchaseInvoiceItem,
+		)
+		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.buying.doctype.purchase_receipt_item_supplied.purchase_receipt_item_supplied import (
+			PurchaseReceiptItemSupplied,
+		)
+
+		additional_discount_percentage: DF.Float
+		address_display: DF.SmallText | None
+		advance_tax: DF.Table[AdvanceTax]
+		advances: DF.Table[PurchaseInvoiceAdvance]
+		against_expense_account: DF.SmallText | None
+		allocate_advances_automatically: DF.Check
+		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
+		base_in_words: DF.Data | None
+		base_net_total: DF.Currency
+		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
+		base_total_taxes_and_charges: DF.Currency
+		base_write_off_amount: DF.Currency
+		bill_date: DF.Date | None
+		bill_no: DF.Data | None
+		billing_address: DF.Link | None
+		billing_address_display: DF.SmallText | None
+		buying_price_list: DF.Link | None
+		cash_bank_account: DF.Link | None
+		clearance_date: DF.Date | None
+		company: DF.Link | None
+		contact_display: DF.SmallText | None
+		contact_email: DF.SmallText | None
+		contact_mobile: DF.SmallText | None
+		contact_person: DF.Link | None
+		conversion_rate: DF.Float
+		cost_center: DF.Link | None
+		credit_to: DF.Link
+		currency: DF.Link | None
+		disable_rounded_total: DF.Check
+		discount_amount: DF.Currency
+		due_date: DF.Date | None
+		from_date: DF.Date | None
+		grand_total: DF.Currency
+		group_same_items: DF.Check
+		hold_comment: DF.SmallText | None
+		ignore_default_payment_terms_template: DF.Check
+		ignore_pricing_rule: DF.Check
+		in_words: DF.Data | None
+		incoterm: DF.Link | None
+		inter_company_invoice_reference: DF.Link | None
+		is_internal_supplier: DF.Check
+		is_old_subcontracting_flow: DF.Check
+		is_opening: DF.Literal["No", "Yes"]
+		is_paid: DF.Check
+		is_return: DF.Check
+		is_subcontracted: DF.Check
+		items: DF.Table[PurchaseInvoiceItem]
+		language: DF.Data | None
+		letter_head: DF.Link | None
+		mode_of_payment: DF.Link | None
+		named_place: DF.Data | None
+		naming_series: DF.Literal["ACC-PINV-.YYYY.-", "ACC-PINV-RET-.YYYY.-"]
+		net_total: DF.Currency
+		on_hold: DF.Check
+		only_include_allocated_payments: DF.Check
+		other_charges_calculation: DF.LongText | None
+		outstanding_amount: DF.Currency
+		paid_amount: DF.Currency
+		party_account_currency: DF.Link | None
+		payment_schedule: DF.Table[PaymentSchedule]
+		payment_terms_template: DF.Link | None
+		per_received: DF.Percent
+		plc_conversion_rate: DF.Float
+		posting_date: DF.Date
+		posting_time: DF.Time | None
+		price_list_currency: DF.Link | None
+		pricing_rules: DF.Table[PricingRuleDetail]
+		project: DF.Link | None
+		rejected_warehouse: DF.Link | None
+		release_date: DF.Date | None
+		remarks: DF.SmallText | None
+		repost_required: DF.Check
+		represents_company: DF.Link | None
+		return_against: DF.Link | None
+		rounded_total: DF.Currency
+		rounding_adjustment: DF.Currency
+		scan_barcode: DF.Data | None
+		select_print_heading: DF.Link | None
+		set_from_warehouse: DF.Link | None
+		set_posting_time: DF.Check
+		set_warehouse: DF.Link | None
+		shipping_address: DF.Link | None
+		shipping_address_display: DF.SmallText | None
+		shipping_rule: DF.Link | None
+		status: DF.Literal[
+			"",
+			"Draft",
+			"Return",
+			"Debit Note Issued",
+			"Submitted",
+			"Paid",
+			"Partly Paid",
+			"Unpaid",
+			"Overdue",
+			"Cancelled",
+			"Internal Transfer",
+		]
+		subscription: DF.Link | None
+		supplied_items: DF.Table[PurchaseReceiptItemSupplied]
+		supplier: DF.Link
+		supplier_address: DF.Link | None
+		supplier_name: DF.Data | None
+		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
+		taxes: DF.Table[PurchaseTaxesandCharges]
+		taxes_and_charges: DF.Link | None
+		taxes_and_charges_added: DF.Currency
+		taxes_and_charges_deducted: DF.Currency
+		tc_name: DF.Link | None
+		terms: DF.TextEditor | None
+		title: DF.Data | None
+		to_date: DF.Date | None
+		total: DF.Currency
+		total_advance: DF.Currency
+		total_net_weight: DF.Float
+		total_qty: DF.Float
+		total_taxes_and_charges: DF.Currency
+		unrealized_profit_loss_account: DF.Link | None
+		update_stock: DF.Check
+		use_company_roundoff_cost_center: DF.Check
+		use_transaction_date_exchange_rate: DF.Check
+		write_off_account: DF.Link | None
+		write_off_amount: DF.Currency
+		write_off_cost_center: DF.Link | None
+	# end: auto-generated types
+
 	def __init__(self, *args, **kwargs):
 		super(PurchaseInvoice, self).__init__(*args, **kwargs)
 		self.status_updater = [
@@ -491,6 +660,7 @@
 	def validate_for_repost(self):
 		self.validate_write_off_account()
 		self.validate_expense_account()
+		validate_docs_for_voucher_types(["Purchase Invoice"])
 		validate_docs_for_deferred_accounting([], [self.name])
 
 	def on_submit(self):
@@ -525,7 +695,11 @@
 		if self.update_stock == 1:
 			self.repost_future_sle_and_gle()
 
-		self.update_project()
+		if (
+			frappe.db.get_single_value("Buying Settings", "project_update_frequency") == "Each Transaction"
+		):
+			self.update_project()
+
 		update_linked_doc(self.doctype, self.name, self.inter_company_invoice_reference)
 		self.update_advance_tax_references()
 
@@ -1260,7 +1434,10 @@
 		if self.update_stock == 1:
 			self.repost_future_sle_and_gle()
 
-		self.update_project()
+		if (
+			frappe.db.get_single_value("Buying Settings", "project_update_frequency") == "Each Transaction"
+		):
+			self.update_project()
 		self.db_set("status", "Cancelled")
 
 		unlink_inter_company_doc(self.doctype, self.name, self.inter_company_invoice_reference)
@@ -1279,13 +1456,21 @@
 		self.update_advance_tax_references(cancel=1)
 
 	def update_project(self):
-		project_list = []
+		projects = frappe._dict()
 		for d in self.items:
-			if d.project and d.project not in project_list:
-				project = frappe.get_doc("Project", d.project)
-				project.update_purchase_costing()
-				project.db_update()
-				project_list.append(d.project)
+			if d.project:
+				if self.docstatus == 1:
+					projects[d.project] = projects.get(d.project, 0) + d.base_net_amount
+				elif self.docstatus == 2:
+					projects[d.project] = projects.get(d.project, 0) - d.base_net_amount
+
+		pj = frappe.qb.DocType("Project")
+		for proj, value in projects.items():
+			res = (
+				frappe.qb.from_(pj).select(pj.total_purchase_cost).where(pj.name == proj).for_update().run()
+			)
+			current_purchase_cost = res and res[0][0] or 0
+			frappe.db.set_value("Project", proj, "total_purchase_cost", current_purchase_cost + value)
 
 	def validate_supplier_invoice(self):
 		if self.bill_date:
@@ -1674,6 +1859,4 @@
 		target_doc,
 	)
 
-	doc.set_onload("ignore_price_list", True)
-
 	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 171cc0c..e43ea6e 100644
--- a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py
+++ b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py
@@ -1747,6 +1747,7 @@
 			paid_to="Creditors - _TC",
 			paid_amount=500,
 		)
+		pe.save()  # save trigger is needed for set_liability_account() to be executed
 		pe.submit()
 
 		pi = make_purchase_invoice(
@@ -1769,10 +1770,10 @@
 
 		# Check GL Entry against payment doctype
 		expected_gle = [
-			["Advances Paid - _TC", 0.0, 500, nowdate()],
+			["Advances Paid - _TC", 500.0, 0.0, nowdate()],
+			["Advances Paid - _TC", 0.0, 500.0, nowdate()],
 			["Cash - _TC", 0.0, 500, nowdate()],
 			["Creditors - _TC", 500, 0.0, nowdate()],
-			["Creditors - _TC", 500, 0.0, nowdate()],
 		]
 
 		check_gl_entries(self, pe.name, expected_gle, nowdate(), voucher_type="Payment Entry")
diff --git a/erpnext/accounts/doctype/purchase_invoice_advance/purchase_invoice_advance.py b/erpnext/accounts/doctype/purchase_invoice_advance/purchase_invoice_advance.py
index 44e1f6d..bbd3009 100644
--- a/erpnext/accounts/doctype/purchase_invoice_advance/purchase_invoice_advance.py
+++ b/erpnext/accounts/doctype/purchase_invoice_advance/purchase_invoice_advance.py
@@ -6,4 +6,25 @@
 
 
 class PurchaseInvoiceAdvance(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
+
+		advance_amount: DF.Currency
+		allocated_amount: DF.Currency
+		exchange_gain_loss: DF.Currency
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		ref_exchange_rate: DF.Float
+		reference_name: DF.DynamicLink | None
+		reference_row: DF.Data | None
+		reference_type: DF.Link | None
+		remarks: DF.Text | None
+	# end: auto-generated types
+
 	pass
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 424e942..7cad3ae 100644
--- a/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json
+++ b/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json
@@ -158,6 +158,7 @@
    "width": "300px"
   },
   {
+   "fetch_from": "item_code.image",
    "fieldname": "image",
    "fieldtype": "Attach",
    "hidden": 1,
@@ -287,6 +288,7 @@
    "oldfieldname": "import_rate",
    "oldfieldtype": "Currency",
    "options": "currency",
+   "read_only_depends_on": "eval: (!parent.is_return && doc.purchase_receipt && doc.pr_detail)",
    "reqd": 1
   },
   {
@@ -497,6 +499,7 @@
    "fieldtype": "Column Break"
   },
   {
+   "allow_on_submit": 1,
    "fieldname": "project",
    "fieldtype": "Link",
    "label": "Project",
@@ -504,6 +507,7 @@
    "print_hide": 1
   },
   {
+   "allow_on_submit": 1,
    "default": ":Company",
    "depends_on": "eval:!doc.is_fixed_asset",
    "fieldname": "cost_center",
@@ -915,7 +919,7 @@
  "idx": 1,
  "istable": 1,
  "links": [],
- "modified": "2023-10-03 21:01:01.824892",
+ "modified": "2023-11-30 16:26:05.629780",
  "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 0e3c723..e48d223 100644
--- a/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.py
+++ b/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.py
@@ -6,4 +6,93 @@
 
 
 class PurchaseInvoiceItem(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
+
+		allow_zero_valuation_rate: DF.Check
+		amount: DF.Currency
+		apply_tds: DF.Check
+		asset_category: DF.Link | None
+		asset_location: DF.Link | None
+		base_amount: DF.Currency
+		base_net_amount: DF.Currency
+		base_net_rate: DF.Currency
+		base_price_list_rate: DF.Currency
+		base_rate: DF.Currency
+		base_rate_with_margin: DF.Currency
+		batch_no: DF.Link | None
+		bom: DF.Link | None
+		brand: DF.Link | None
+		conversion_factor: DF.Float
+		cost_center: DF.Link | None
+		deferred_expense_account: DF.Link | None
+		description: DF.TextEditor | None
+		discount_amount: DF.Currency
+		discount_percentage: DF.Percent
+		enable_deferred_expense: DF.Check
+		expense_account: DF.Link | None
+		from_warehouse: DF.Link | None
+		image: DF.Attach | None
+		include_exploded_items: DF.Check
+		is_fixed_asset: DF.Check
+		is_free_item: DF.Check
+		item_code: DF.Link | None
+		item_group: DF.Link | None
+		item_name: DF.Data
+		item_tax_amount: DF.Currency
+		item_tax_rate: DF.Code | None
+		item_tax_template: DF.Link | None
+		landed_cost_voucher_amount: DF.Currency
+		manufacturer: DF.Link | None
+		manufacturer_part_no: DF.Data | None
+		margin_rate_or_amount: DF.Float
+		margin_type: DF.Literal["", "Percentage", "Amount"]
+		net_amount: DF.Currency
+		net_rate: DF.Currency
+		page_break: DF.Check
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		po_detail: DF.Data | None
+		pr_detail: DF.Data | None
+		price_list_rate: DF.Currency
+		pricing_rules: DF.SmallText | None
+		product_bundle: DF.Link | None
+		project: DF.Link | None
+		purchase_invoice_item: DF.Data | None
+		purchase_order: DF.Link | None
+		purchase_receipt: DF.Link | None
+		qty: DF.Float
+		quality_inspection: DF.Link | None
+		rate: DF.Currency
+		rate_with_margin: DF.Currency
+		received_qty: DF.Float
+		rejected_qty: DF.Float
+		rejected_serial_and_batch_bundle: DF.Link | None
+		rejected_serial_no: DF.Text | None
+		rejected_warehouse: DF.Link | None
+		rm_supp_cost: DF.Currency
+		sales_invoice_item: DF.Data | None
+		serial_and_batch_bundle: DF.Link | None
+		serial_no: DF.Text | None
+		service_end_date: DF.Date | None
+		service_start_date: DF.Date | None
+		service_stop_date: DF.Date | None
+		stock_qty: DF.Float
+		stock_uom: DF.Link | None
+		stock_uom_rate: DF.Currency
+		total_weight: DF.Float
+		uom: DF.Link
+		valuation_rate: DF.Currency
+		warehouse: DF.Link | None
+		weight_per_unit: DF.Float
+		weight_uom: DF.Link | None
+		wip_composite_asset: DF.Link | None
+	# end: auto-generated types
+
 	pass
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 262e7eb..d6c0292 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
@@ -6,4 +6,42 @@
 
 
 class PurchaseTaxesandCharges(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_currency: DF.Link | None
+		account_head: DF.Link
+		add_deduct_tax: DF.Literal["Add", "Deduct"]
+		base_tax_amount: DF.Currency
+		base_tax_amount_after_discount_amount: DF.Currency
+		base_total: DF.Currency
+		category: DF.Literal["Valuation and Total", "Valuation", "Total"]
+		charge_type: DF.Literal[
+			"",
+			"Actual",
+			"On Net Total",
+			"On Previous Row Amount",
+			"On Previous Row Total",
+			"On Item Quantity",
+		]
+		cost_center: DF.Link | None
+		description: DF.SmallText
+		included_in_paid_amount: DF.Check
+		included_in_print_rate: DF.Check
+		item_wise_tax_detail: DF.Code | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		rate: DF.Float
+		row_id: DF.Data | None
+		tax_amount: DF.Currency
+		tax_amount_after_discount_amount: DF.Currency
+		total: DF.Currency
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/purchase_taxes_and_charges_template/purchase_taxes_and_charges_template.py b/erpnext/accounts/doctype/purchase_taxes_and_charges_template/purchase_taxes_and_charges_template.py
index 70d29bf..16c30c5 100644
--- a/erpnext/accounts/doctype/purchase_taxes_and_charges_template/purchase_taxes_and_charges_template.py
+++ b/erpnext/accounts/doctype/purchase_taxes_and_charges_template/purchase_taxes_and_charges_template.py
@@ -11,6 +11,26 @@
 
 
 class PurchaseTaxesandChargesTemplate(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
+
+		from erpnext.accounts.doctype.purchase_taxes_and_charges.purchase_taxes_and_charges import (
+			PurchaseTaxesandCharges,
+		)
+
+		company: DF.Link
+		disabled: DF.Check
+		is_default: DF.Check
+		tax_category: DF.Link | None
+		taxes: DF.Table[PurchaseTaxesandCharges]
+		title: DF.Data
+	# end: auto-generated types
+
 	def validate(self):
 		valdiate_taxes_and_charges_template(self)
 
diff --git a/erpnext/accounts/doctype/repost_accounting_ledger/repost_accounting_ledger.py b/erpnext/accounts/doctype/repost_accounting_ledger/repost_accounting_ledger.py
index 69cfe9f..8c23c67 100644
--- a/erpnext/accounts/doctype/repost_accounting_ledger/repost_accounting_ledger.py
+++ b/erpnext/accounts/doctype/repost_accounting_ledger/repost_accounting_ledger.py
@@ -8,14 +8,27 @@
 
 
 class RepostAccountingLedger(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
+
+		from erpnext.accounts.doctype.repost_accounting_ledger_items.repost_accounting_ledger_items import (
+			RepostAccountingLedgerItems,
+		)
+
+		amended_from: DF.Link | None
+		company: DF.Link | None
+		delete_cancelled_entries: DF.Check
+		vouchers: DF.Table[RepostAccountingLedgerItems]
+	# end: auto-generated types
+
 	def __init__(self, *args, **kwargs):
 		super(RepostAccountingLedger, self).__init__(*args, **kwargs)
-		self._allowed_types = [
-			x.document_type
-			for x in frappe.db.get_all(
-				"Repost Allowed Types", filters={"allowed": True}, fields=["distinct(document_type)"]
-			)
-		]
+		self._allowed_types = get_allowed_types_from_settings()
 
 	def validate(self):
 		self.validate_vouchers()
@@ -56,15 +69,7 @@
 
 	def validate_vouchers(self):
 		if self.vouchers:
-			# Validate voucher types
-			voucher_types = set([x.voucher_type for x in self.vouchers])
-			if disallowed_types := voucher_types.difference(self._allowed_types):
-				frappe.throw(
-					_("{0} types are not allowed. Only {1} are.").format(
-						frappe.bold(comma_and(list(disallowed_types))),
-						frappe.bold(comma_and(list(self._allowed_types))),
-					)
-				)
+			validate_docs_for_voucher_types([x.voucher_type for x in self.vouchers])
 
 	def get_existing_ledger_entries(self):
 		vouchers = [x.voucher_no for x in self.vouchers]
@@ -168,6 +173,15 @@
 				frappe.db.commit()
 
 
+def get_allowed_types_from_settings():
+	return [
+		x.document_type
+		for x in frappe.db.get_all(
+			"Repost Allowed Types", filters={"allowed": True}, fields=["distinct(document_type)"]
+		)
+	]
+
+
 def validate_docs_for_deferred_accounting(sales_docs, purchase_docs):
 	docs_with_deferred_revenue = frappe.db.get_all(
 		"Sales Invoice Item",
@@ -191,6 +205,25 @@
 		)
 
 
+def validate_docs_for_voucher_types(doc_voucher_types):
+	allowed_types = get_allowed_types_from_settings()
+	# Validate voucher types
+	voucher_types = set(doc_voucher_types)
+	if disallowed_types := voucher_types.difference(allowed_types):
+		message = "are" if len(disallowed_types) > 1 else "is"
+		frappe.throw(
+			_("{0} {1} not allowed to be reposted. Modify {2} to enable reposting.").format(
+				frappe.bold(comma_and(list(disallowed_types))),
+				message,
+				frappe.bold(
+					frappe.utils.get_link_to_form(
+						"Repost Accounting Ledger Settings", "Repost Accounting Ledger Settings"
+					)
+				),
+			)
+		)
+
+
 @frappe.whitelist()
 @frappe.validate_and_sanitize_search_inputs
 def get_repost_allowed_types(doctype, txt, searchfield, start, page_len, filters):
diff --git a/erpnext/accounts/doctype/repost_accounting_ledger_items/repost_accounting_ledger_items.py b/erpnext/accounts/doctype/repost_accounting_ledger_items/repost_accounting_ledger_items.py
index 9221f44..6e02e3a 100644
--- a/erpnext/accounts/doctype/repost_accounting_ledger_items/repost_accounting_ledger_items.py
+++ b/erpnext/accounts/doctype/repost_accounting_ledger_items/repost_accounting_ledger_items.py
@@ -6,4 +6,19 @@
 
 
 class RepostAccountingLedgerItems(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
+
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		voucher_no: DF.DynamicLink | None
+		voucher_type: DF.Link | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/repost_accounting_ledger_settings/repost_accounting_ledger_settings.py b/erpnext/accounts/doctype/repost_accounting_ledger_settings/repost_accounting_ledger_settings.py
index 2b8230d..14a070d 100644
--- a/erpnext/accounts/doctype/repost_accounting_ledger_settings/repost_accounting_ledger_settings.py
+++ b/erpnext/accounts/doctype/repost_accounting_ledger_settings/repost_accounting_ledger_settings.py
@@ -6,4 +6,17 @@
 
 
 class RepostAccountingLedgerSettings(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
+
+		from erpnext.accounts.doctype.repost_allowed_types.repost_allowed_types import RepostAllowedTypes
+
+		allowed_types: DF.Table[RepostAllowedTypes]
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/repost_allowed_types/repost_allowed_types.py b/erpnext/accounts/doctype/repost_allowed_types/repost_allowed_types.py
index 0e4883b..8226a91 100644
--- a/erpnext/accounts/doctype/repost_allowed_types/repost_allowed_types.py
+++ b/erpnext/accounts/doctype/repost_allowed_types/repost_allowed_types.py
@@ -6,4 +6,19 @@
 
 
 class RepostAllowedTypes(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
+
+		allowed: DF.Check
+		document_type: DF.Link | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/repost_payment_ledger/repost_payment_ledger.py b/erpnext/accounts/doctype/repost_payment_ledger/repost_payment_ledger.py
index 209cad4..38bc1a6 100644
--- a/erpnext/accounts/doctype/repost_payment_ledger/repost_payment_ledger.py
+++ b/erpnext/accounts/doctype/repost_payment_ledger/repost_payment_ledger.py
@@ -52,6 +52,28 @@
 
 
 class RepostPaymentLedger(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
+
+		from erpnext.accounts.doctype.repost_payment_ledger_items.repost_payment_ledger_items import (
+			RepostPaymentLedgerItems,
+		)
+
+		add_manually: DF.Check
+		amended_from: DF.Link | None
+		company: DF.Link
+		posting_date: DF.Date
+		repost_error_log: DF.LongText | None
+		repost_status: DF.Literal["", "Queued", "Failed", "Completed"]
+		repost_vouchers: DF.Table[RepostPaymentLedgerItems]
+		voucher_type: DF.Link | None
+	# end: auto-generated types
+
 	def __init__(self, *args, **kwargs):
 		super(RepostPaymentLedger, self).__init__(*args, **kwargs)
 		self.vouchers = []
diff --git a/erpnext/accounts/doctype/repost_payment_ledger_items/repost_payment_ledger_items.py b/erpnext/accounts/doctype/repost_payment_ledger_items/repost_payment_ledger_items.py
index fb19e84..5f93518 100644
--- a/erpnext/accounts/doctype/repost_payment_ledger_items/repost_payment_ledger_items.py
+++ b/erpnext/accounts/doctype/repost_payment_ledger_items/repost_payment_ledger_items.py
@@ -6,4 +6,19 @@
 
 
 class RepostPaymentLedgerItems(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
+
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		voucher_no: DF.DynamicLink | None
+		voucher_type: DF.Link | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
index b1a7b10..6763e44 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
@@ -37,7 +37,7 @@
 		super.onload();
 
 		this.frm.ignore_doctypes_on_cancel_all = ['POS Invoice', 'Timesheet', 'POS Invoice Merge Log',
-							  'POS Closing Entry', 'Journal Entry', 'Payment Entry', "Repost Payment Ledger", "Repost Accounting Ledger", "Unreconcile Payments", "Unreconcile Payment Entries"];
+							  'POS Closing Entry', 'Journal Entry', 'Payment Entry', "Repost Payment Ledger", "Repost Accounting Ledger", "Unreconcile Payment", "Unreconcile Payment Entries"];
 
 		if(!this.frm.doc.__islocal && !this.frm.doc.customer && this.frm.doc.debit_to) {
 			// show debit_to in print format
@@ -184,7 +184,7 @@
 			}
 		}
 
-		erpnext.accounts.unreconcile_payments.add_unreconcile_btn(me.frm);
+		erpnext.accounts.unreconcile_payment.add_unreconcile_btn(me.frm);
 	}
 
 	make_maintenance_schedule() {
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json
index cd725b9..f209487 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json
@@ -1615,7 +1615,8 @@
    "hide_seconds": 1,
    "label": "Inter Company Invoice Reference",
    "options": "Purchase Invoice",
-   "read_only": 1
+   "read_only": 1,
+   "search_index": 1
   },
   {
    "fieldname": "customer_group",
@@ -2156,7 +2157,7 @@
    "label": "Use Company default Cost Center for Round off"
   },
   {
-   "default": "0",
+   "default": "1",
    "depends_on": "eval: doc.is_return",
    "fieldname": "update_billed_amount_in_delivery_note",
    "fieldtype": "Check",
@@ -2173,7 +2174,7 @@
    "link_fieldname": "consolidated_invoice"
   }
  ],
- "modified": "2023-11-03 14:39:38.012346",
+ "modified": "2023-11-23 16:56:29.679499",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Sales Invoice",
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
index fa95ccd..96a557b 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
@@ -17,6 +17,7 @@
 )
 from erpnext.accounts.doctype.repost_accounting_ledger.repost_accounting_ledger import (
 	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,
@@ -44,6 +45,189 @@
 
 
 class SalesInvoice(SellingController):
+	# 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
+
+		from erpnext.accounts.doctype.payment_schedule.payment_schedule import PaymentSchedule
+		from erpnext.accounts.doctype.pricing_rule_detail.pricing_rule_detail import PricingRuleDetail
+		from erpnext.accounts.doctype.sales_invoice_advance.sales_invoice_advance import (
+			SalesInvoiceAdvance,
+		)
+		from erpnext.accounts.doctype.sales_invoice_item.sales_invoice_item import SalesInvoiceItem
+		from erpnext.accounts.doctype.sales_invoice_payment.sales_invoice_payment import (
+			SalesInvoicePayment,
+		)
+		from erpnext.accounts.doctype.sales_invoice_timesheet.sales_invoice_timesheet import (
+			SalesInvoiceTimesheet,
+		)
+		from erpnext.accounts.doctype.sales_taxes_and_charges.sales_taxes_and_charges import (
+			SalesTaxesandCharges,
+		)
+		from erpnext.selling.doctype.sales_team.sales_team import SalesTeam
+		from erpnext.stock.doctype.packed_item.packed_item import PackedItem
+
+		account_for_change_amount: DF.Link | None
+		additional_discount_account: DF.Link | None
+		additional_discount_percentage: DF.Float
+		address_display: DF.SmallText | None
+		advances: DF.Table[SalesInvoiceAdvance]
+		against_income_account: DF.SmallText | None
+		allocate_advances_automatically: DF.Check
+		amended_from: DF.Link | None
+		amount_eligible_for_commission: DF.Currency
+		apply_discount_on: DF.Literal["", "Grand Total", "Net Total"]
+		auto_repeat: DF.Link | None
+		base_change_amount: DF.Currency
+		base_discount_amount: DF.Currency
+		base_grand_total: DF.Currency
+		base_in_words: DF.SmallText | None
+		base_net_total: DF.Currency
+		base_paid_amount: DF.Currency
+		base_rounded_total: DF.Currency
+		base_rounding_adjustment: DF.Currency
+		base_total: DF.Currency
+		base_total_taxes_and_charges: DF.Currency
+		base_write_off_amount: DF.Currency
+		campaign: DF.Link | None
+		cash_bank_account: DF.Link | None
+		change_amount: DF.Currency
+		commission_rate: DF.Float
+		company: DF.Link
+		company_address: DF.Link | None
+		company_address_display: DF.SmallText | None
+		company_tax_id: DF.Data | None
+		contact_display: DF.SmallText | None
+		contact_email: DF.Data | None
+		contact_mobile: DF.SmallText | None
+		contact_person: DF.Link | None
+		conversion_rate: DF.Float
+		cost_center: DF.Link | None
+		currency: DF.Link
+		customer: DF.Link | None
+		customer_address: DF.Link | None
+		customer_group: DF.Link | None
+		customer_name: DF.SmallText | None
+		debit_to: DF.Link
+		disable_rounded_total: DF.Check
+		discount_amount: DF.Currency
+		dispatch_address: DF.SmallText | None
+		dispatch_address_name: DF.Link | None
+		due_date: DF.Date | None
+		from_date: DF.Date | None
+		grand_total: DF.Currency
+		group_same_items: DF.Check
+		ignore_default_payment_terms_template: DF.Check
+		ignore_pricing_rule: DF.Check
+		in_words: DF.SmallText | None
+		incoterm: DF.Link | None
+		inter_company_invoice_reference: DF.Link | None
+		is_cash_or_non_trade_discount: DF.Check
+		is_consolidated: DF.Check
+		is_debit_note: DF.Check
+		is_discounted: DF.Check
+		is_internal_customer: DF.Check
+		is_opening: DF.Literal["No", "Yes"]
+		is_pos: DF.Check
+		is_return: DF.Check
+		items: DF.Table[SalesInvoiceItem]
+		language: DF.Data | None
+		letter_head: DF.Link | None
+		loyalty_amount: DF.Currency
+		loyalty_points: DF.Int
+		loyalty_program: DF.Link | None
+		loyalty_redemption_account: DF.Link | None
+		loyalty_redemption_cost_center: DF.Link | None
+		named_place: DF.Data | None
+		naming_series: DF.Literal["ACC-SINV-.YYYY.-", "ACC-SINV-RET-.YYYY.-"]
+		net_total: DF.Currency
+		only_include_allocated_payments: DF.Check
+		other_charges_calculation: DF.LongText | None
+		outstanding_amount: DF.Currency
+		packed_items: DF.Table[PackedItem]
+		paid_amount: DF.Currency
+		party_account_currency: DF.Link | None
+		payment_schedule: DF.Table[PaymentSchedule]
+		payment_terms_template: DF.Link | None
+		payments: DF.Table[SalesInvoicePayment]
+		plc_conversion_rate: DF.Float
+		po_date: DF.Date | None
+		po_no: DF.Data | None
+		pos_profile: DF.Link | None
+		posting_date: DF.Date
+		posting_time: DF.Time | None
+		price_list_currency: DF.Link
+		pricing_rules: DF.Table[PricingRuleDetail]
+		project: DF.Link | None
+		redeem_loyalty_points: DF.Check
+		remarks: DF.SmallText | None
+		repost_required: DF.Check
+		represents_company: DF.Link | None
+		return_against: DF.Link | None
+		rounded_total: DF.Currency
+		rounding_adjustment: DF.Currency
+		sales_partner: DF.Link | None
+		sales_team: DF.Table[SalesTeam]
+		scan_barcode: DF.Data | None
+		select_print_heading: DF.Link | None
+		selling_price_list: DF.Link
+		set_posting_time: DF.Check
+		set_target_warehouse: DF.Link | None
+		set_warehouse: DF.Link | None
+		shipping_address: DF.SmallText | None
+		shipping_address_name: DF.Link | None
+		shipping_rule: DF.Link | None
+		source: DF.Link | None
+		status: DF.Literal[
+			"",
+			"Draft",
+			"Return",
+			"Credit Note Issued",
+			"Submitted",
+			"Paid",
+			"Partly Paid",
+			"Unpaid",
+			"Unpaid and Discounted",
+			"Partly Paid and Discounted",
+			"Overdue and Discounted",
+			"Overdue",
+			"Cancelled",
+			"Internal Transfer",
+		]
+		subscription: DF.Link | None
+		tax_category: DF.Link | None
+		tax_id: DF.Data | None
+		taxes: DF.Table[SalesTaxesandCharges]
+		taxes_and_charges: DF.Link | None
+		tc_name: DF.Link | None
+		terms: DF.TextEditor | None
+		territory: DF.Link | None
+		timesheets: DF.Table[SalesInvoiceTimesheet]
+		title: DF.Data | None
+		to_date: DF.Date | None
+		total: DF.Currency
+		total_advance: DF.Currency
+		total_billing_amount: DF.Currency
+		total_billing_hours: DF.Float
+		total_commission: DF.Currency
+		total_net_weight: DF.Float
+		total_qty: DF.Float
+		total_taxes_and_charges: DF.Currency
+		unrealized_profit_loss_account: DF.Link | None
+		update_billed_amount_in_delivery_note: DF.Check
+		update_billed_amount_in_sales_order: DF.Check
+		update_stock: DF.Check
+		use_company_roundoff_cost_center: DF.Check
+		write_off_account: DF.Link | None
+		write_off_amount: DF.Currency
+		write_off_cost_center: DF.Link | None
+		write_off_outstanding_amount_automatically: DF.Check
+	# end: auto-generated types
+
 	def __init__(self, *args, **kwargs):
 		super(SalesInvoice, self).__init__(*args, **kwargs)
 		self.status_updater = [
@@ -172,6 +356,7 @@
 		self.validate_write_off_account()
 		self.validate_account_for_change_amount()
 		self.validate_income_account()
+		validate_docs_for_voucher_types(["Sales Invoice"])
 		validate_docs_for_deferred_accounting([self.name], [])
 
 	def validate_fixed_asset(self):
@@ -395,7 +580,7 @@
 			"Repost Payment Ledger Items",
 			"Repost Accounting Ledger",
 			"Repost Accounting Ledger Items",
-			"Unreconcile Payments",
+			"Unreconcile Payment",
 			"Unreconcile Payment Entries",
 			"Payment Ledger Entry",
 			"Serial and Batch Bundle",
@@ -1910,7 +2095,6 @@
 		set_missing_values,
 	)
 
-	doclist.set_onload("ignore_price_list", True)
 	return doclist
 
 
diff --git a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
index 5a41336..e9b71dd 100644
--- a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
@@ -789,6 +789,28 @@
 		w = self.make()
 		self.assertEqual(w.outstanding_amount, w.base_rounded_total)
 
+	def test_rounded_total_with_cash_discount(self):
+		si = frappe.copy_doc(test_records[2])
+
+		item = copy.deepcopy(si.get("items")[0])
+		item.update(
+			{
+				"qty": 1,
+				"rate": 14960.66,
+			}
+		)
+
+		si.set("items", [item])
+		si.set("taxes", [])
+		si.apply_discount_on = "Grand Total"
+		si.is_cash_or_non_trade_discount = 1
+		si.discount_amount = 1
+		si.insert()
+
+		self.assertEqual(si.grand_total, 14959.66)
+		self.assertEqual(si.rounded_total, 14960)
+		self.assertEqual(si.rounding_adjustment, 0.34)
+
 	def test_payment(self):
 		w = self.make()
 
@@ -2607,6 +2629,7 @@
 					"voucher_type": "Sales Invoice",
 					"voucher_no": si.name,
 					"allow_zero_valuation": d.get("allow_zero_valuation"),
+					"voucher_detail_no": d.name,
 				},
 				raise_error_if_no_rate=False,
 			)
@@ -3349,21 +3372,21 @@
 	def test_advance_entries_as_liability(self):
 		from erpnext.accounts.doctype.payment_entry.test_payment_entry import create_payment_entry
 
-		account = create_account(
+		advance_account = create_account(
 			parent_account="Current Liabilities - _TC",
 			account_name="Advances Received",
 			company="_Test Company",
 			account_type="Receivable",
 		)
 
-		set_advance_flag(company="_Test Company", flag=1, default_account=account)
+		set_advance_flag(company="_Test Company", flag=1, default_account=advance_account)
 
 		pe = create_payment_entry(
 			company="_Test Company",
 			payment_type="Receive",
 			party_type="Customer",
 			party="_Test Customer",
-			paid_from="Debtors - _TC",
+			paid_from=advance_account,
 			paid_to="Cash - _TC",
 			paid_amount=1000,
 		)
@@ -3389,9 +3412,9 @@
 
 		# Check GL Entry against payment doctype
 		expected_gle = [
+			["Advances Received - _TC", 0.0, 1000.0, nowdate()],
 			["Advances Received - _TC", 500, 0.0, nowdate()],
 			["Cash - _TC", 1000, 0.0, nowdate()],
-			["Debtors - _TC", 0.0, 1000, nowdate()],
 			["Debtors - _TC", 0.0, 500, nowdate()],
 		]
 
@@ -3428,6 +3451,93 @@
 		si.items[0].rate = 10
 		si.save()
 
+	def test_partial_allocation_on_advance_as_liability(self):
+		from erpnext.accounts.doctype.payment_entry.test_payment_entry import create_payment_entry
+
+		company = "_Test Company"
+		customer = "_Test Customer"
+		debtors_acc = "Debtors - _TC"
+		advance_account = create_account(
+			parent_account="Current Liabilities - _TC",
+			account_name="Advances Received",
+			company="_Test Company",
+			account_type="Receivable",
+		)
+
+		set_advance_flag(company="_Test Company", flag=1, default_account=advance_account)
+
+		pe = create_payment_entry(
+			company=company,
+			payment_type="Receive",
+			party_type="Customer",
+			party=customer,
+			paid_from=advance_account,
+			paid_to="Cash - _TC",
+			paid_amount=1000,
+		)
+		pe.submit()
+
+		si = create_sales_invoice(
+			company=company,
+			customer=customer,
+			do_not_save=True,
+			do_not_submit=True,
+			rate=1000,
+			price_list_rate=1000,
+		)
+		si.base_grand_total = 1000
+		si.grand_total = 1000
+		si.set_advances()
+		for advance in si.advances:
+			advance.allocated_amount = 200 if advance.reference_name == pe.name else 0
+		si.save()
+		si.submit()
+
+		self.assertEqual(si.advances[0].allocated_amount, 200)
+
+		# Check GL Entry against partial from advance
+		expected_gle = [
+			[advance_account, 0.0, 1000.0, nowdate()],
+			[advance_account, 200.0, 0.0, nowdate()],
+			["Cash - _TC", 1000.0, 0.0, nowdate()],
+			[debtors_acc, 0.0, 200.0, nowdate()],
+		]
+		check_gl_entries(self, pe.name, expected_gle, nowdate(), voucher_type="Payment Entry")
+		si.reload()
+		self.assertEqual(si.outstanding_amount, 800.0)
+
+		pr = frappe.get_doc("Payment Reconciliation")
+		pr.company = company
+		pr.party_type = "Customer"
+		pr.party = customer
+		pr.receivable_payable_account = debtors_acc
+		pr.default_advance_account = advance_account
+		pr.get_unreconciled_entries()
+
+		# allocate some more of the same advance
+		# self.assertEqual(len(pr.invoices), 1)
+		# self.assertEqual(len(pr.payments), 1)
+		invoices = [x.as_dict() for x in pr.invoices if x.get("invoice_number") == si.name]
+		payments = [x.as_dict() for x in pr.payments if x.get("reference_name") == pe.name]
+		pr.allocate_entries(frappe._dict({"invoices": invoices, "payments": payments}))
+		pr.allocation[0].allocated_amount = 300
+		pr.reconcile()
+
+		si.reload()
+		self.assertEqual(si.outstanding_amount, 500.0)
+
+		# Check GL Entry against multi partial allocations from advance
+		expected_gle = [
+			[advance_account, 0.0, 1000.0, nowdate()],
+			[advance_account, 200.0, 0.0, nowdate()],
+			[advance_account, 300.0, 0.0, nowdate()],
+			["Cash - _TC", 1000.0, 0.0, nowdate()],
+			[debtors_acc, 0.0, 200.0, nowdate()],
+			[debtors_acc, 0.0, 300.0, nowdate()],
+		]
+		check_gl_entries(self, pe.name, expected_gle, nowdate(), voucher_type="Payment Entry")
+		set_advance_flag(company="_Test Company", flag=0, default_account="")
+
 
 def set_advance_flag(company, flag, default_account):
 	frappe.db.set_value(
diff --git a/erpnext/accounts/doctype/sales_invoice_advance/sales_invoice_advance.py b/erpnext/accounts/doctype/sales_invoice_advance/sales_invoice_advance.py
index 6d4bd46..5eeedb2 100644
--- a/erpnext/accounts/doctype/sales_invoice_advance/sales_invoice_advance.py
+++ b/erpnext/accounts/doctype/sales_invoice_advance/sales_invoice_advance.py
@@ -6,4 +6,25 @@
 
 
 class SalesInvoiceAdvance(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
+
+		advance_amount: DF.Currency
+		allocated_amount: DF.Currency
+		exchange_gain_loss: DF.Currency
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		ref_exchange_rate: DF.Float
+		reference_name: DF.DynamicLink | None
+		reference_row: DF.Data | None
+		reference_type: DF.Link | None
+		remarks: DF.Text | None
+	# end: auto-generated types
+
 	pass
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 5d2764b..a403b14 100644
--- a/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json
+++ b/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json
@@ -167,6 +167,7 @@
    "print_hide": 1
   },
   {
+   "fetch_from": "item_code.image",
    "fieldname": "image",
    "fieldtype": "Attach",
    "hidden": 1,
@@ -901,7 +902,7 @@
  "idx": 1,
  "istable": 1,
  "links": [],
- "modified": "2023-07-26 12:53:22.404057",
+ "modified": "2023-11-14 18:34:10.479329",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Sales Invoice Item",
@@ -911,4 +912,4 @@
  "sort_field": "modified",
  "sort_order": "DESC",
  "states": []
-}
+}
\ No newline at end of file
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 ebeaf8b..80f6774 100644
--- a/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.py
+++ b/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.py
@@ -6,4 +6,89 @@
 
 
 class SalesInvoiceItem(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
+
+		actual_batch_qty: DF.Float
+		actual_qty: DF.Float
+		allow_zero_valuation_rate: DF.Check
+		amount: DF.Currency
+		asset: DF.Link | None
+		barcode: DF.Data | None
+		base_amount: DF.Currency
+		base_net_amount: DF.Currency
+		base_net_rate: DF.Currency
+		base_price_list_rate: DF.Currency
+		base_rate: DF.Currency
+		base_rate_with_margin: DF.Currency
+		batch_no: DF.Link | None
+		brand: DF.Data | None
+		conversion_factor: DF.Float
+		cost_center: DF.Link
+		customer_item_code: DF.Data | None
+		deferred_revenue_account: DF.Link | None
+		delivered_by_supplier: DF.Check
+		delivered_qty: DF.Float
+		delivery_note: DF.Link | None
+		description: DF.TextEditor | None
+		discount_account: DF.Link | None
+		discount_amount: DF.Currency
+		discount_percentage: DF.Percent
+		dn_detail: DF.Data | None
+		enable_deferred_revenue: DF.Check
+		expense_account: DF.Link | None
+		finance_book: DF.Link | None
+		grant_commission: DF.Check
+		has_item_scanned: DF.Check
+		image: DF.Attach | None
+		income_account: DF.Link
+		incoming_rate: DF.Currency
+		is_fixed_asset: DF.Check
+		is_free_item: DF.Check
+		item_code: DF.Link | None
+		item_group: DF.Link | None
+		item_name: DF.Data
+		item_tax_rate: DF.SmallText | None
+		item_tax_template: DF.Link | None
+		margin_rate_or_amount: DF.Float
+		margin_type: DF.Literal["", "Percentage", "Amount"]
+		net_amount: DF.Currency
+		net_rate: DF.Currency
+		page_break: DF.Check
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		price_list_rate: DF.Currency
+		pricing_rules: DF.SmallText | None
+		project: DF.Link | None
+		purchase_order: DF.Link | None
+		purchase_order_item: DF.Data | None
+		qty: DF.Float
+		quality_inspection: DF.Link | None
+		rate: DF.Currency
+		rate_with_margin: DF.Currency
+		sales_invoice_item: DF.Data | None
+		sales_order: DF.Link | None
+		serial_and_batch_bundle: DF.Link | None
+		serial_no: DF.SmallText | None
+		service_end_date: DF.Date | None
+		service_start_date: DF.Date | None
+		service_stop_date: DF.Date | None
+		so_detail: DF.Data | None
+		stock_qty: DF.Float
+		stock_uom: DF.Link | None
+		stock_uom_rate: DF.Currency
+		target_warehouse: DF.Link | None
+		total_weight: DF.Float
+		uom: DF.Link
+		warehouse: DF.Link | None
+		weight_per_unit: DF.Float
+		weight_uom: DF.Link | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/sales_invoice_payment/sales_invoice_payment.py b/erpnext/accounts/doctype/sales_invoice_payment/sales_invoice_payment.py
index d9b1dbe..57d0142 100644
--- a/erpnext/accounts/doctype/sales_invoice_payment/sales_invoice_payment.py
+++ b/erpnext/accounts/doctype/sales_invoice_payment/sales_invoice_payment.py
@@ -6,4 +6,24 @@
 
 
 class SalesInvoicePayment(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: DF.Link | None
+		amount: DF.Currency
+		base_amount: DF.Currency
+		clearance_date: DF.Date | None
+		default: DF.Check
+		mode_of_payment: DF.Link
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		type: DF.ReadOnly | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/sales_invoice_timesheet/sales_invoice_timesheet.py b/erpnext/accounts/doctype/sales_invoice_timesheet/sales_invoice_timesheet.py
index e50b1c2..108241d 100644
--- a/erpnext/accounts/doctype/sales_invoice_timesheet/sales_invoice_timesheet.py
+++ b/erpnext/accounts/doctype/sales_invoice_timesheet/sales_invoice_timesheet.py
@@ -6,4 +6,26 @@
 
 
 class SalesInvoiceTimesheet(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
+
+		activity_type: DF.Link | None
+		billing_amount: DF.Currency
+		billing_hours: DF.Float
+		description: DF.SmallText | None
+		from_time: DF.Datetime | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		project_name: DF.Data | None
+		time_sheet: DF.Link | None
+		timesheet_detail: DF.Data | None
+		to_time: DF.Datetime | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/sales_partner_item/sales_partner_item.py b/erpnext/accounts/doctype/sales_partner_item/sales_partner_item.py
index 97489d1..c6715dc 100644
--- a/erpnext/accounts/doctype/sales_partner_item/sales_partner_item.py
+++ b/erpnext/accounts/doctype/sales_partner_item/sales_partner_item.py
@@ -6,4 +6,18 @@
 
 
 class SalesPartnerItem(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
+
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		sales_partner: DF.Link | None
+	# end: auto-generated types
+
 	pass
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 d412c1b..7936178 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
@@ -6,4 +6,41 @@
 
 
 class SalesTaxesandCharges(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_currency: DF.Link | None
+		account_head: DF.Link
+		base_tax_amount: DF.Currency
+		base_tax_amount_after_discount_amount: DF.Currency
+		base_total: DF.Currency
+		charge_type: DF.Literal[
+			"",
+			"Actual",
+			"On Net Total",
+			"On Previous Row Amount",
+			"On Previous Row Total",
+			"On Item Quantity",
+		]
+		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
+		item_wise_tax_detail: DF.Code | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		rate: DF.Float
+		row_id: DF.Data | None
+		tax_amount: DF.Currency
+		tax_amount_after_discount_amount: DF.Currency
+		total: DF.Currency
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/sales_taxes_and_charges_template/sales_taxes_and_charges_template.py b/erpnext/accounts/doctype/sales_taxes_and_charges_template/sales_taxes_and_charges_template.py
index a3a5d62..ce3eda9 100644
--- a/erpnext/accounts/doctype/sales_taxes_and_charges_template/sales_taxes_and_charges_template.py
+++ b/erpnext/accounts/doctype/sales_taxes_and_charges_template/sales_taxes_and_charges_template.py
@@ -16,6 +16,26 @@
 
 
 class SalesTaxesandChargesTemplate(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
+
+		from erpnext.accounts.doctype.sales_taxes_and_charges.sales_taxes_and_charges import (
+			SalesTaxesandCharges,
+		)
+
+		company: DF.Link
+		disabled: DF.Check
+		is_default: DF.Check
+		tax_category: DF.Link | None
+		taxes: DF.Table[SalesTaxesandCharges]
+		title: DF.Data
+	# end: auto-generated types
+
 	def validate(self):
 		valdiate_taxes_and_charges_template(self)
 
diff --git a/erpnext/accounts/doctype/share_balance/share_balance.py b/erpnext/accounts/doctype/share_balance/share_balance.py
index 4c9ec43..7a77ce9 100644
--- a/erpnext/accounts/doctype/share_balance/share_balance.py
+++ b/erpnext/accounts/doctype/share_balance/share_balance.py
@@ -6,4 +6,25 @@
 
 
 class ShareBalance(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
+
+		amount: DF.Int
+		current_state: DF.Literal["", "Issued", "Purchased"]
+		from_no: DF.Int
+		is_company: DF.Check
+		no_of_shares: DF.Int
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		rate: DF.Int
+		share_type: DF.Link
+		to_no: DF.Int
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/share_transfer/share_transfer.py b/erpnext/accounts/doctype/share_transfer/share_transfer.py
index 4f49843..6a3ff7c 100644
--- a/erpnext/accounts/doctype/share_transfer/share_transfer.py
+++ b/erpnext/accounts/doctype/share_transfer/share_transfer.py
@@ -15,6 +15,33 @@
 
 
 class ShareTransfer(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
+
+		amended_from: DF.Link | None
+		amount: DF.Currency
+		asset_account: DF.Link | None
+		company: DF.Link
+		date: DF.Date
+		equity_or_liability_account: DF.Link
+		from_folio_no: DF.Data | None
+		from_no: DF.Int
+		from_shareholder: DF.Link | None
+		no_of_shares: DF.Int
+		rate: DF.Currency
+		remarks: DF.LongText | None
+		share_type: DF.Link
+		to_folio_no: DF.Data | None
+		to_no: DF.Int
+		to_shareholder: DF.Link | None
+		transfer_type: DF.Literal["", "Issue", "Purchase", "Transfer"]
+	# end: auto-generated types
+
 	def on_submit(self):
 		if self.transfer_type == "Issue":
 			shareholder = self.get_company_shareholder()
diff --git a/erpnext/accounts/doctype/share_type/share_type.py b/erpnext/accounts/doctype/share_type/share_type.py
index 80365aa..df8cbaf 100644
--- a/erpnext/accounts/doctype/share_type/share_type.py
+++ b/erpnext/accounts/doctype/share_type/share_type.py
@@ -6,4 +6,16 @@
 
 
 class ShareType(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
+
+		description: DF.LongText | None
+		title: DF.Data
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/shareholder/shareholder.py b/erpnext/accounts/doctype/shareholder/shareholder.py
index b0e2493..6542f93 100644
--- a/erpnext/accounts/doctype/shareholder/shareholder.py
+++ b/erpnext/accounts/doctype/shareholder/shareholder.py
@@ -10,6 +10,25 @@
 
 
 class Shareholder(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
+
+		from erpnext.accounts.doctype.share_balance.share_balance import ShareBalance
+
+		company: DF.Link
+		contact_list: DF.Code | None
+		folio_no: DF.Data | None
+		is_company: DF.Check
+		naming_series: DF.Literal["ACC-SH-.YYYY.-"]
+		share_balance: DF.Table[ShareBalance]
+		title: DF.Data
+	# end: auto-generated types
+
 	def onload(self):
 		"""Load address and contacts in `__onload`"""
 		load_address_and_contact(self)
diff --git a/erpnext/accounts/doctype/shipping_rule/shipping_rule.py b/erpnext/accounts/doctype/shipping_rule/shipping_rule.py
index 1d79503..52a60ac 100644
--- a/erpnext/accounts/doctype/shipping_rule/shipping_rule.py
+++ b/erpnext/accounts/doctype/shipping_rule/shipping_rule.py
@@ -25,6 +25,33 @@
 
 
 class ShippingRule(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
+
+		from erpnext.accounts.doctype.shipping_rule_condition.shipping_rule_condition import (
+			ShippingRuleCondition,
+		)
+		from erpnext.accounts.doctype.shipping_rule_country.shipping_rule_country import (
+			ShippingRuleCountry,
+		)
+
+		account: DF.Link
+		calculate_based_on: DF.Literal["Fixed", "Net Total", "Net Weight"]
+		company: DF.Link
+		conditions: DF.Table[ShippingRuleCondition]
+		cost_center: DF.Link
+		countries: DF.Table[ShippingRuleCountry]
+		disabled: DF.Check
+		label: DF.Data
+		shipping_amount: DF.Currency
+		shipping_rule_type: DF.Literal["Selling", "Buying"]
+	# end: auto-generated types
+
 	def validate(self):
 		self.validate_from_to_values()
 		self.sort_shipping_rule_conditions()
diff --git a/erpnext/accounts/doctype/shipping_rule_condition/shipping_rule_condition.py b/erpnext/accounts/doctype/shipping_rule_condition/shipping_rule_condition.py
index 07f98de..4370477 100644
--- a/erpnext/accounts/doctype/shipping_rule_condition/shipping_rule_condition.py
+++ b/erpnext/accounts/doctype/shipping_rule_condition/shipping_rule_condition.py
@@ -8,4 +8,20 @@
 
 
 class ShippingRuleCondition(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
+
+		from_value: DF.Float
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		shipping_amount: DF.Currency
+		to_value: DF.Float
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/shipping_rule_country/shipping_rule_country.py b/erpnext/accounts/doctype/shipping_rule_country/shipping_rule_country.py
index 90123c1..ff06e8f 100644
--- a/erpnext/accounts/doctype/shipping_rule_country/shipping_rule_country.py
+++ b/erpnext/accounts/doctype/shipping_rule_country/shipping_rule_country.py
@@ -6,4 +6,18 @@
 
 
 class ShippingRuleCountry(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
+
+		country: DF.Link
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/south_africa_vat_account/south_africa_vat_account.py b/erpnext/accounts/doctype/south_africa_vat_account/south_africa_vat_account.py
index d9a3bcc..516038a 100644
--- a/erpnext/accounts/doctype/south_africa_vat_account/south_africa_vat_account.py
+++ b/erpnext/accounts/doctype/south_africa_vat_account/south_africa_vat_account.py
@@ -6,4 +6,18 @@
 
 
 class SouthAfricaVATAccount(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: DF.Link | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/subscription/subscription.py b/erpnext/accounts/doctype/subscription/subscription.py
index 3cf7d28..6cc2d1e 100644
--- a/erpnext/accounts/doctype/subscription/subscription.py
+++ b/erpnext/accounts/doctype/subscription/subscription.py
@@ -40,6 +40,51 @@
 
 
 class Subscription(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
+
+		from erpnext.accounts.doctype.subscription_plan_detail.subscription_plan_detail import (
+			SubscriptionPlanDetail,
+		)
+
+		additional_discount_amount: DF.Currency
+		additional_discount_percentage: DF.Percent
+		apply_additional_discount: DF.Literal["", "Grand Total", "Net Total"]
+		cancel_at_period_end: DF.Check
+		cancelation_date: DF.Date | None
+		company: DF.Link | None
+		cost_center: DF.Link | None
+		current_invoice_end: DF.Date | None
+		current_invoice_start: DF.Date | None
+		days_until_due: DF.Int
+		end_date: DF.Date | None
+		follow_calendar_months: DF.Check
+		generate_invoice_at: DF.Literal[
+			"End of the current subscription period",
+			"Beginning of the current subscription period",
+			"Days before the current subscription period",
+		]
+		generate_new_invoices_past_due_date: DF.Check
+		number_of_days: DF.Int
+		party: DF.DynamicLink
+		party_type: DF.Link
+		plans: DF.Table[SubscriptionPlanDetail]
+		purchase_tax_template: DF.Link | None
+		sales_tax_template: DF.Link | None
+		start_date: DF.Date | None
+		status: DF.Literal[
+			"", "Trialling", "Active", "Past Due Date", "Cancelled", "Unpaid", "Completed"
+		]
+		submit_invoice: DF.Check
+		trial_period_end: DF.Date | None
+		trial_period_start: DF.Date | None
+	# end: auto-generated types
+
 	def before_insert(self):
 		# update start just before the subscription doc is created
 		self.update_subscription_period(self.start_date)
@@ -676,7 +721,7 @@
 
 
 def process_all(
-	subscription: str | None, posting_date: Optional["DateTimeLikeObject"] = None
+	subscription: str | None = None, posting_date: Optional["DateTimeLikeObject"] = None
 ) -> None:
 	"""
 	Task to updates the status of all `Subscription` apart from those that are cancelled
diff --git a/erpnext/accounts/doctype/subscription_invoice/subscription_invoice.py b/erpnext/accounts/doctype/subscription_invoice/subscription_invoice.py
index 41f7f9f..ecef5e7 100644
--- a/erpnext/accounts/doctype/subscription_invoice/subscription_invoice.py
+++ b/erpnext/accounts/doctype/subscription_invoice/subscription_invoice.py
@@ -6,4 +6,19 @@
 
 
 class SubscriptionInvoice(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
+
+		document_type: DF.Link | None
+		invoice: DF.DynamicLink | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/subscription_plan/subscription_plan.py b/erpnext/accounts/doctype/subscription_plan/subscription_plan.py
index f6e5c56..118d254 100644
--- a/erpnext/accounts/doctype/subscription_plan/subscription_plan.py
+++ b/erpnext/accounts/doctype/subscription_plan/subscription_plan.py
@@ -12,6 +12,27 @@
 
 
 class SubscriptionPlan(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
+
+		billing_interval: DF.Literal["Day", "Week", "Month", "Year"]
+		billing_interval_count: DF.Int
+		cost: DF.Currency
+		cost_center: DF.Link | None
+		currency: DF.Link | None
+		item: DF.Link
+		payment_gateway: DF.Link | None
+		plan_name: DF.Data
+		price_determination: DF.Literal["", "Fixed Rate", "Based On Price List", "Monthly Rate"]
+		price_list: DF.Link | None
+		product_price_id: DF.Data | None
+	# end: auto-generated types
+
 	def validate(self):
 		self.validate_interval_count()
 
diff --git a/erpnext/accounts/doctype/subscription_plan_detail/subscription_plan_detail.py b/erpnext/accounts/doctype/subscription_plan_detail/subscription_plan_detail.py
index d22a73f..91f3319 100644
--- a/erpnext/accounts/doctype/subscription_plan_detail/subscription_plan_detail.py
+++ b/erpnext/accounts/doctype/subscription_plan_detail/subscription_plan_detail.py
@@ -6,4 +6,19 @@
 
 
 class SubscriptionPlanDetail(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
+
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		plan: DF.Link
+		qty: DF.Int
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/subscription_settings/subscription_settings.py b/erpnext/accounts/doctype/subscription_settings/subscription_settings.py
index 12580db..abc698e 100644
--- a/erpnext/accounts/doctype/subscription_settings/subscription_settings.py
+++ b/erpnext/accounts/doctype/subscription_settings/subscription_settings.py
@@ -6,4 +6,17 @@
 
 
 class SubscriptionSettings(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
+
+		cancel_after_grace: DF.Check
+		grace_period: DF.Int
+		prorate: DF.Check
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/supplier_group_item/supplier_group_item.py b/erpnext/accounts/doctype/supplier_group_item/supplier_group_item.py
index 61c16fe..bcad816 100644
--- a/erpnext/accounts/doctype/supplier_group_item/supplier_group_item.py
+++ b/erpnext/accounts/doctype/supplier_group_item/supplier_group_item.py
@@ -6,4 +6,18 @@
 
 
 class SupplierGroupItem(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
+
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		supplier_group: DF.Link | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/supplier_item/supplier_item.py b/erpnext/accounts/doctype/supplier_item/supplier_item.py
index 2105b1d..c90a53a 100644
--- a/erpnext/accounts/doctype/supplier_item/supplier_item.py
+++ b/erpnext/accounts/doctype/supplier_item/supplier_item.py
@@ -6,4 +6,18 @@
 
 
 class SupplierItem(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
+
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		supplier: DF.Link | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/tax_category/tax_category.py b/erpnext/accounts/doctype/tax_category/tax_category.py
index 18cf72a..bfb1f16 100644
--- a/erpnext/accounts/doctype/tax_category/tax_category.py
+++ b/erpnext/accounts/doctype/tax_category/tax_category.py
@@ -6,4 +6,16 @@
 
 
 class TaxCategory(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
+
+		disabled: DF.Check
+		title: DF.Data
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/tax_rule/tax_rule.py b/erpnext/accounts/doctype/tax_rule/tax_rule.py
index ac0dd51..9ff530b 100644
--- a/erpnext/accounts/doctype/tax_rule/tax_rule.py
+++ b/erpnext/accounts/doctype/tax_rule/tax_rule.py
@@ -27,6 +27,41 @@
 
 
 class TaxRule(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
+
+		billing_city: DF.Data | None
+		billing_country: DF.Link | None
+		billing_county: DF.Data | None
+		billing_state: DF.Data | None
+		billing_zipcode: DF.Data | None
+		company: DF.Link | None
+		customer: DF.Link | None
+		customer_group: DF.Link | None
+		from_date: DF.Date | None
+		item: DF.Link | None
+		item_group: DF.Link | None
+		priority: DF.Int
+		purchase_tax_template: DF.Link | None
+		sales_tax_template: DF.Link | None
+		shipping_city: DF.Data | None
+		shipping_country: DF.Link | None
+		shipping_county: DF.Data | None
+		shipping_state: DF.Data | None
+		shipping_zipcode: DF.Data | None
+		supplier: DF.Link | None
+		supplier_group: DF.Link | None
+		tax_category: DF.Link | None
+		tax_type: DF.Literal["Sales", "Purchase"]
+		to_date: DF.Date | None
+		use_for_shopping_cart: DF.Check
+	# end: auto-generated types
+
 	def __setup__(self):
 		self.flags.ignore_these_exceptions_in_test = [ConflictingTaxRule]
 
diff --git a/erpnext/accounts/doctype/tax_withheld_vouchers/tax_withheld_vouchers.py b/erpnext/accounts/doctype/tax_withheld_vouchers/tax_withheld_vouchers.py
index ea54c54..bc2003e 100644
--- a/erpnext/accounts/doctype/tax_withheld_vouchers/tax_withheld_vouchers.py
+++ b/erpnext/accounts/doctype/tax_withheld_vouchers/tax_withheld_vouchers.py
@@ -6,4 +6,20 @@
 
 
 class TaxWithheldVouchers(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
+
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		taxable_amount: DF.Currency
+		voucher_name: DF.DynamicLink | None
+		voucher_type: DF.Link | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/tax_withholding_account/tax_withholding_account.py b/erpnext/accounts/doctype/tax_withholding_account/tax_withholding_account.py
index c8d9d45..f22ecba 100644
--- a/erpnext/accounts/doctype/tax_withholding_account/tax_withholding_account.py
+++ b/erpnext/accounts/doctype/tax_withholding_account/tax_withholding_account.py
@@ -6,4 +6,19 @@
 
 
 class TaxWithholdingAccount(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: DF.Link
+		company: DF.Link
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+	# end: auto-generated types
+
 	pass
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 de2f9e7..c39a9db 100644
--- a/erpnext/accounts/doctype/tax_withholding_category/tax_withholding_category.py
+++ b/erpnext/accounts/doctype/tax_withholding_category/tax_withholding_category.py
@@ -11,6 +11,27 @@
 
 
 class TaxWithholdingCategory(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
+
+		from erpnext.accounts.doctype.tax_withholding_account.tax_withholding_account import (
+			TaxWithholdingAccount,
+		)
+		from erpnext.accounts.doctype.tax_withholding_rate.tax_withholding_rate import TaxWithholdingRate
+
+		accounts: DF.Table[TaxWithholdingAccount]
+		category_name: DF.Data | None
+		consider_party_ledger_amount: DF.Check
+		rates: DF.Table[TaxWithholdingRate]
+		round_off_tax_amount: DF.Check
+		tax_on_excess_amount: DF.Check
+	# end: auto-generated types
+
 	def validate(self):
 		self.validate_dates()
 		self.validate_accounts()
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 16cbccc..35d4e63 100644
--- a/erpnext/accounts/doctype/tax_withholding_rate/tax_withholding_rate.py
+++ b/erpnext/accounts/doctype/tax_withholding_rate/tax_withholding_rate.py
@@ -6,4 +6,22 @@
 
 
 class TaxWithholdingRate(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
+
+		cumulative_threshold: DF.Float
+		from_date: DF.Date
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		single_threshold: DF.Float
+		tax_withholding_rate: DF.Float
+		to_date: DF.Date
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/territory_item/territory_item.py b/erpnext/accounts/doctype/territory_item/territory_item.py
index bcc02be..cadcbcf 100644
--- a/erpnext/accounts/doctype/territory_item/territory_item.py
+++ b/erpnext/accounts/doctype/territory_item/territory_item.py
@@ -6,4 +6,18 @@
 
 
 class TerritoryItem(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
+
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		territory: DF.Link | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/unreconcile_payments/__init__.py b/erpnext/accounts/doctype/unreconcile_payment/__init__.py
similarity index 100%
rename from erpnext/accounts/doctype/unreconcile_payments/__init__.py
rename to erpnext/accounts/doctype/unreconcile_payment/__init__.py
diff --git a/erpnext/accounts/doctype/unreconcile_payments/test_unreconcile_payments.py b/erpnext/accounts/doctype/unreconcile_payment/test_unreconcile_payment.py
similarity index 96%
rename from erpnext/accounts/doctype/unreconcile_payments/test_unreconcile_payments.py
rename to erpnext/accounts/doctype/unreconcile_payment/test_unreconcile_payment.py
index 78e04bf..f404d99 100644
--- a/erpnext/accounts/doctype/unreconcile_payments/test_unreconcile_payments.py
+++ b/erpnext/accounts/doctype/unreconcile_payment/test_unreconcile_payment.py
@@ -10,7 +10,7 @@
 from erpnext.accounts.test.accounts_mixin import AccountsTestMixin
 
 
-class TestUnreconcilePayments(AccountsTestMixin, FrappeTestCase):
+class TestUnreconcilePayment(AccountsTestMixin, FrappeTestCase):
 	def setUp(self):
 		self.create_company()
 		self.create_customer()
@@ -73,7 +73,7 @@
 
 		unreconcile = frappe.get_doc(
 			{
-				"doctype": "Unreconcile Payments",
+				"doctype": "Unreconcile Payment",
 				"company": self.company,
 				"voucher_type": pe.doctype,
 				"voucher_no": pe.name,
@@ -138,7 +138,7 @@
 
 		unreconcile = frappe.get_doc(
 			{
-				"doctype": "Unreconcile Payments",
+				"doctype": "Unreconcile Payment",
 				"company": self.company,
 				"voucher_type": pe2.doctype,
 				"voucher_no": pe2.name,
@@ -196,7 +196,7 @@
 
 		unreconcile = frappe.get_doc(
 			{
-				"doctype": "Unreconcile Payments",
+				"doctype": "Unreconcile Payment",
 				"company": self.company,
 				"voucher_type": pe.doctype,
 				"voucher_no": pe.name,
@@ -281,7 +281,7 @@
 
 		unreconcile = frappe.get_doc(
 			{
-				"doctype": "Unreconcile Payments",
+				"doctype": "Unreconcile Payment",
 				"company": self.company,
 				"voucher_type": pe2.doctype,
 				"voucher_no": pe2.name,
diff --git a/erpnext/accounts/doctype/unreconcile_payments/unreconcile_payments.js b/erpnext/accounts/doctype/unreconcile_payment/unreconcile_payment.js
similarity index 93%
rename from erpnext/accounts/doctype/unreconcile_payments/unreconcile_payments.js
rename to erpnext/accounts/doctype/unreconcile_payment/unreconcile_payment.js
index c522567..70cefb1 100644
--- a/erpnext/accounts/doctype/unreconcile_payments/unreconcile_payments.js
+++ b/erpnext/accounts/doctype/unreconcile_payment/unreconcile_payment.js
@@ -1,7 +1,7 @@
 // Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and contributors
 // For license information, please see license.txt
 
-frappe.ui.form.on("Unreconcile Payments", {
+frappe.ui.form.on("Unreconcile Payment", {
 	refresh(frm) {
 		frm.set_query("voucher_type", function() {
 			return {
diff --git a/erpnext/accounts/doctype/unreconcile_payments/unreconcile_payments.json b/erpnext/accounts/doctype/unreconcile_payment/unreconcile_payment.json
similarity index 95%
rename from erpnext/accounts/doctype/unreconcile_payments/unreconcile_payments.json
rename to erpnext/accounts/doctype/unreconcile_payment/unreconcile_payment.json
index f29e61b..f906dc6 100644
--- a/erpnext/accounts/doctype/unreconcile_payments/unreconcile_payments.json
+++ b/erpnext/accounts/doctype/unreconcile_payment/unreconcile_payment.json
@@ -21,7 +21,7 @@
    "fieldtype": "Link",
    "label": "Amended From",
    "no_copy": 1,
-   "options": "Unreconcile Payments",
+   "options": "Unreconcile Payment",
    "print_hide": 1,
    "read_only": 1
   },
@@ -61,7 +61,7 @@
  "modified": "2023-08-28 17:42:50.261377",
  "modified_by": "Administrator",
  "module": "Accounts",
- "name": "Unreconcile Payments",
+ "name": "Unreconcile Payment",
  "naming_rule": "Expression",
  "owner": "Administrator",
  "permissions": [
@@ -90,4 +90,4 @@
  "sort_order": "DESC",
  "states": [],
  "track_changes": 1
-}
\ No newline at end of file
+}
diff --git a/erpnext/accounts/doctype/unreconcile_payments/unreconcile_payments.py b/erpnext/accounts/doctype/unreconcile_payment/unreconcile_payment.py
similarity index 87%
rename from erpnext/accounts/doctype/unreconcile_payments/unreconcile_payments.py
rename to erpnext/accounts/doctype/unreconcile_payment/unreconcile_payment.py
index 4f9fb50..e258a73 100644
--- a/erpnext/accounts/doctype/unreconcile_payments/unreconcile_payments.py
+++ b/erpnext/accounts/doctype/unreconcile_payment/unreconcile_payment.py
@@ -15,7 +15,26 @@
 )
 
 
-class UnreconcilePayments(Document):
+class UnreconcilePayment(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
+
+		from erpnext.accounts.doctype.unreconcile_payment_entries.unreconcile_payment_entries import (
+			UnreconcilePaymentEntries,
+		)
+
+		allocations: DF.Table[UnreconcilePaymentEntries]
+		amended_from: DF.Link | None
+		company: DF.Link | None
+		voucher_no: DF.DynamicLink | None
+		voucher_type: DF.Link | None
+	# end: auto-generated types
+
 	def validate(self):
 		self.supported_types = ["Payment Entry", "Journal Entry"]
 		if not self.voucher_type in self.supported_types:
@@ -142,7 +161,7 @@
 		selections = frappe.json.loads(selections)
 		# assuming each row is a unique voucher
 		for row in selections:
-			unrecon = frappe.new_doc("Unreconcile Payments")
+			unrecon = frappe.new_doc("Unreconcile Payment")
 			unrecon.company = row.get("company")
 			unrecon.voucher_type = row.get("voucher_type")
 			unrecon.voucher_no = row.get("voucher_no")
diff --git a/erpnext/accounts/doctype/unreconcile_payment_entries/unreconcile_payment_entries.py b/erpnext/accounts/doctype/unreconcile_payment_entries/unreconcile_payment_entries.py
index c41545c..7c097b5 100644
--- a/erpnext/accounts/doctype/unreconcile_payment_entries/unreconcile_payment_entries.py
+++ b/erpnext/accounts/doctype/unreconcile_payment_entries/unreconcile_payment_entries.py
@@ -6,4 +6,25 @@
 
 
 class UnreconcilePaymentEntries(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: DF.Data | None
+		account_currency: DF.Link | None
+		allocated_amount: DF.Currency
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		party: DF.Data | None
+		party_type: DF.Data | None
+		reference_doctype: DF.Link | None
+		reference_name: DF.DynamicLink | None
+		unlinked: DF.Check
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/general_ledger.py b/erpnext/accounts/general_ledger.py
index 70a8470..030a41e 100644
--- a/erpnext/accounts/general_ledger.py
+++ b/erpnext/accounts/general_ledger.py
@@ -597,7 +597,30 @@
 
 		is_opening = any(d.get("is_opening") == "Yes" for d in gl_entries)
 		validate_against_pcv(is_opening, gl_entries[0]["posting_date"], gl_entries[0]["company"])
-		if not partial_cancel:
+		if partial_cancel:
+			# Partial cancel is only used by `Advance` in separate account feature.
+			# Only cancel GL entries for unlinked reference using `voucher_detail_no`
+			gle = frappe.qb.DocType("GL Entry")
+			for x in gl_entries:
+				query = (
+					frappe.qb.update(gle)
+					.set(gle.is_cancelled, True)
+					.set(gle.modified, now())
+					.set(gle.modified_by, frappe.session.user)
+					.where(
+						(gle.company == x.company)
+						& (gle.account == x.account)
+						& (gle.party_type == x.party_type)
+						& (gle.party == x.party)
+						& (gle.voucher_type == x.voucher_type)
+						& (gle.voucher_no == x.voucher_no)
+						& (gle.against_voucher_type == x.against_voucher_type)
+						& (gle.against_voucher == x.against_voucher)
+						& (gle.voucher_detail_no == x.voucher_detail_no)
+					)
+				)
+				query.run()
+		else:
 			set_as_cancel(gl_entries[0]["voucher_type"], gl_entries[0]["voucher_no"])
 
 		for entry in gl_entries:
diff --git a/erpnext/accounts/party.py b/erpnext/accounts/party.py
index 371474e..1efe35c 100644
--- a/erpnext/accounts/party.py
+++ b/erpnext/accounts/party.py
@@ -195,7 +195,7 @@
 	company_address=None,
 	shipping_address=None,
 	*,
-	ignore_permissions=False
+	ignore_permissions=False,
 ):
 	billing_address_field = (
 		"customer_address" if party_type == "Lead" else party_type.lower() + "_address"
@@ -236,8 +236,10 @@
 		if shipping_address:
 			party_details.update(
 				shipping_address=shipping_address,
-				shipping_address_display=render_address(shipping_address),
-				**get_fetch_values(doctype, "shipping_address", shipping_address)
+				shipping_address_display=render_address(
+					shipping_address, check_permissions=not ignore_permissions
+				),
+				**get_fetch_values(doctype, "shipping_address", shipping_address),
 			)
 
 		if party_details.company_address:
@@ -248,7 +250,7 @@
 					party_details.company_address_display
 					or render_address(party_details.company_address, check_permissions=False)
 				),
-				**get_fetch_values(doctype, "billing_address", party_details.company_address)
+				**get_fetch_values(doctype, "billing_address", party_details.company_address),
 			)
 
 			# shipping address - if not already set
@@ -256,7 +258,7 @@
 				party_details.update(
 					shipping_address=party_details.billing_address,
 					shipping_address_display=party_details.billing_address_display,
-					**get_fetch_values(doctype, "shipping_address", party_details.billing_address)
+					**get_fetch_values(doctype, "shipping_address", party_details.billing_address),
 				)
 
 	party_address, shipping_address = (
@@ -979,6 +981,9 @@
 	if party:
 		query = query.where(ple.party == party)
 
+	if invoice_doctypes := frappe.get_hooks("invoice_doctypes"):
+		query = query.where(ple.voucher_type.notin(invoice_doctypes))
+
 	data = query.run()
 	if data:
 		return frappe._dict(data)
diff --git a/erpnext/accounts/report/accounts_payable/accounts_payable.js b/erpnext/accounts/report/accounts_payable/accounts_payable.js
index 10362db..b608ebc 100644
--- a/erpnext/accounts/report/accounts_payable/accounts_payable.js
+++ b/erpnext/accounts/report/accounts_payable/accounts_payable.js
@@ -150,6 +150,11 @@
 			"fieldtype": "Check",
 		},
 		{
+			"fieldname": "for_revaluation_journals",
+			"label": __("Revaluation Journals"),
+			"fieldtype": "Check",
+		},
+		{
 			"fieldname": "ignore_accounts",
 			"label": __("Group by Voucher"),
 			"fieldtype": "Check",
diff --git a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py
index 706d743..eaf9f42 100644
--- a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py
+++ b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py
@@ -7,7 +7,7 @@
 import frappe
 from frappe import _, qb, scrub
 from frappe.query_builder import Criterion
-from frappe.query_builder.functions import Date, Sum
+from frappe.query_builder.functions import Date, Substring, Sum
 from frappe.utils import cint, cstr, flt, getdate, nowdate
 
 from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import (
@@ -285,8 +285,8 @@
 
 			must_consider = False
 			if self.filters.get("for_revaluation_journals"):
-				if (abs(row.outstanding) > 1.0 / 10**self.currency_precision) or (
-					(abs(row.outstanding_in_account_currency) > 1.0 / 10**self.currency_precision)
+				if (abs(row.outstanding) > 0.0 / 10**self.currency_precision) or (
+					(abs(row.outstanding_in_account_currency) > 0.0 / 10**self.currency_precision)
 				):
 					must_consider = True
 			else:
@@ -764,7 +764,12 @@
 		)
 
 		if self.filters.get("show_remarks"):
-			query = query.select(ple.remarks)
+			if remarks_length := frappe.db.get_single_value(
+				"Accounts Settings", "receivable_payable_remarks_length"
+			):
+				query = query.select(Substring(ple.remarks, 1, remarks_length).as_("remarks"))
+			else:
+				query = query.select(ple.remarks)
 
 		if self.filters.get("group_by_party"):
 			query = query.orderby(self.ple.party, self.ple.posting_date)
@@ -1082,7 +1087,7 @@
 			)
 
 		if self.filters.show_remarks:
-			self.add_column(label=_("Remarks"), fieldname="remarks", fieldtype="Text", width=200),
+			self.add_column(label=_("Remarks"), fieldname="remarks", fieldtype="Text", width=200)
 
 	def add_column(self, label, fieldname=None, fieldtype="Currency", options=None, width=120):
 		if not fieldname:
diff --git a/erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.py b/erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.py
index d50cf07..22b5c6b 100644
--- a/erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.py
+++ b/erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.py
@@ -8,7 +8,7 @@
 
 from erpnext.accounts.party import get_partywise_advanced_payment_amount
 from erpnext.accounts.report.accounts_receivable.accounts_receivable import ReceivablePayableReport
-from erpnext.accounts.utils import get_party_types_from_account_type
+from erpnext.accounts.utils import get_currency_precision, get_party_types_from_account_type
 
 
 def execute(filters=None):
@@ -34,6 +34,7 @@
 	def get_data(self, args):
 		self.data = []
 		self.receivables = ReceivablePayableReport(self.filters).run(args)[1]
+		self.currency_precision = get_currency_precision() or 2
 
 		self.get_party_total(args)
 
@@ -57,7 +58,7 @@
 			gl_balance_map = get_gl_balance(self.filters.report_date, self.filters.company)
 
 		for party, party_dict in self.party_total.items():
-			if party_dict.outstanding == 0:
+			if flt(party_dict.outstanding, self.currency_precision) == 0:
 				continue
 
 			row = frappe._dict()
diff --git a/erpnext/accounts/report/general_ledger/general_ledger.py b/erpnext/accounts/report/general_ledger/general_ledger.py
index 94cd293..fa557a1 100644
--- a/erpnext/accounts/report/general_ledger/general_ledger.py
+++ b/erpnext/accounts/report/general_ledger/general_ledger.py
@@ -164,7 +164,12 @@
 		credit_in_account_currency """
 
 	if filters.get("show_remarks"):
-		select_fields += """,remarks"""
+		if remarks_length := frappe.db.get_single_value(
+			"Accounts Settings", "general_ledger_remarks_length"
+		):
+			select_fields += f",substr(remarks, 1, {remarks_length}) as 'remarks'"
+		else:
+			select_fields += """,remarks"""
 
 	order_by_statement = "order by posting_date, account, creation"
 
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 ad196a9..9c6e2d0 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
@@ -319,7 +319,7 @@
 			`tabPurchase Invoice`.posting_date, `tabPurchase Invoice`.credit_to, `tabPurchase Invoice`.company,
 			`tabPurchase Invoice`.supplier, `tabPurchase Invoice`.remarks, `tabPurchase Invoice`.base_net_total,
 			`tabPurchase Invoice`.unrealized_profit_loss_account,
-			`tabPurchase Invoice Item`.`item_code`, `tabPurchase Invoice Item`.description,
+			`tabPurchase Invoice Item`.`item_code`, `tabPurchase Invoice Item`.description, `tabPurchase Invoice Item`.`item_group`,
 			`tabPurchase Invoice Item`.`item_name` as pi_item_name, `tabPurchase Invoice Item`.`item_group` as pi_item_group,
 			`tabItem`.`item_name` as i_item_name, `tabItem`.`item_group` as i_item_group,
 			`tabPurchase Invoice Item`.`project`, `tabPurchase Invoice Item`.`purchase_order`,
diff --git a/erpnext/accounts/report/purchase_register/purchase_register.js b/erpnext/accounts/report/purchase_register/purchase_register.js
index 57cb703..cf11ed0 100644
--- a/erpnext/accounts/report/purchase_register/purchase_register.js
+++ b/erpnext/accounts/report/purchase_register/purchase_register.js
@@ -23,6 +23,12 @@
 			"options": "Supplier"
 		},
 		{
+			"fieldname":"supplier_group",
+			"label": __("Supplier Group"),
+			"fieldtype": "Link",
+			"options": "Supplier Group"
+		},
+		{
 			"fieldname":"company",
 			"label": __("Company"),
 			"fieldtype": "Link",
diff --git a/erpnext/accounts/report/purchase_register/purchase_register.py b/erpnext/accounts/report/purchase_register/purchase_register.py
index 162e5b5..9721987 100644
--- a/erpnext/accounts/report/purchase_register/purchase_register.py
+++ b/erpnext/accounts/report/purchase_register/purchase_register.py
@@ -407,6 +407,8 @@
 
 	if filters.get("supplier"):
 		query = query.where(pi.supplier == filters.supplier)
+	if filters.get("supplier_group"):
+		query = query.where(pi.supplier_group == filters.supplier_group)
 
 	query = get_conditions(filters, query, "Purchase Invoice")
 
diff --git a/erpnext/accounts/report/sales_register/sales_register.js b/erpnext/accounts/report/sales_register/sales_register.js
index 1a41172..4578ac3 100644
--- a/erpnext/accounts/report/sales_register/sales_register.js
+++ b/erpnext/accounts/report/sales_register/sales_register.js
@@ -23,6 +23,12 @@
 			"options": "Customer"
 		},
 		{
+			"fieldname":"customer_group",
+			"label": __("Customer Group"),
+			"fieldtype": "Link",
+			"options": "Customer Group"
+		},
+		{
 			"fieldname":"company",
 			"label": __("Company"),
 			"fieldtype": "Link",
diff --git a/erpnext/accounts/report/sales_register/sales_register.py b/erpnext/accounts/report/sales_register/sales_register.py
index 0ba7186..ec6dd72 100644
--- a/erpnext/accounts/report/sales_register/sales_register.py
+++ b/erpnext/accounts/report/sales_register/sales_register.py
@@ -449,6 +449,9 @@
 	if filters.get("customer"):
 		query = query.where(si.customer == filters.customer)
 
+	if filters.get("customer_group"):
+		query = query.where(si.customer_group == filters.customer_group)
+
 	query = get_conditions(filters, query, "Sales Invoice")
 	query = apply_common_conditions(
 		filters, query, doctype="Sales Invoice", child_doctype="Sales Invoice Item"
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 06c9e44..f6c7bd3 100644
--- a/erpnext/accounts/report/tax_withholding_details/tax_withholding_details.py
+++ b/erpnext/accounts/report/tax_withholding_details/tax_withholding_details.py
@@ -184,6 +184,16 @@
 				"width": 180,
 			}
 		)
+	else:
+		columns.append(
+			{
+				"label": _(filters.get("party_type")),
+				"fieldname": "party",
+				"fieldtype": "Dynamic Link",
+				"options": "party_type",
+				"width": 180,
+			}
+		)
 
 	columns.extend(
 		[
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 82f97f1..2b5566f 100644
--- a/erpnext/accounts/report/tds_computation_summary/tds_computation_summary.py
+++ b/erpnext/accounts/report/tds_computation_summary/tds_computation_summary.py
@@ -1,7 +1,7 @@
 import frappe
 from frappe import _
 
-from erpnext.accounts.report.tds_payable_monthly.tds_payable_monthly import (
+from erpnext.accounts.report.tax_withholding_details.tax_withholding_details import (
 	get_result,
 	get_tds_docs,
 )
diff --git a/erpnext/accounts/utils.py b/erpnext/accounts/utils.py
index 31bc6fd..f88e26e 100644
--- a/erpnext/accounts/utils.py
+++ b/erpnext/accounts/utils.py
@@ -53,6 +53,9 @@
 def get_fiscal_year(
 	date=None, fiscal_year=None, label="Date", verbose=1, company=None, as_dict=False, boolean=False
 ):
+	if isinstance(boolean, str):
+		boolean = frappe.json.loads(boolean)
+
 	fiscal_years = get_fiscal_years(
 		date, fiscal_year, label, verbose, company, as_dict=as_dict, boolean=boolean
 	)
@@ -180,6 +183,7 @@
 	cost_center=None,
 	ignore_account_permission=False,
 	account_type=None,
+	start_date=None,
 ):
 	if not account and frappe.form_dict.get("account"):
 		account = frappe.form_dict.get("account")
@@ -193,6 +197,8 @@
 		cost_center = frappe.form_dict.get("cost_center")
 
 	cond = ["is_cancelled=0"]
+	if start_date:
+		cond.append("posting_date >= %s" % frappe.db.escape(cstr(start_date)))
 	if date:
 		cond.append("posting_date <= %s" % frappe.db.escape(cstr(date)))
 	else:
@@ -466,7 +472,11 @@
 		# cancel advance entry
 		doc = frappe.get_doc(voucher_type, voucher_no)
 		frappe.flags.ignore_party_validation = True
-		_delete_pl_entries(voucher_type, voucher_no)
+
+		# For payments with `Advance` in separate account feature enabled, only new ledger entries are posted for each reference.
+		# No need to cancel/delete payment ledger entries
+		if not (voucher_type == "Payment Entry" and doc.book_advance_payments_in_separate_party_account):
+			_delete_pl_entries(voucher_type, voucher_no)
 
 		for entry in entries:
 			check_if_advance_entry_modified(entry)
@@ -481,23 +491,26 @@
 				entry.update({"referenced_row": referenced_row})
 				doc.make_exchange_gain_loss_journal([entry])
 			else:
-				update_reference_in_payment_entry(
+				referenced_row = update_reference_in_payment_entry(
 					entry, doc, do_not_save=True, skip_ref_details_update_for_pe=skip_ref_details_update_for_pe
 				)
 
 		doc.save(ignore_permissions=True)
 		# re-submit advance entry
 		doc = frappe.get_doc(entry.voucher_type, entry.voucher_no)
-		gl_map = doc.build_gl_map()
-		create_payment_ledger_entry(gl_map, update_outstanding="No", cancel=0, adv_adj=1)
+
+		if voucher_type == "Payment Entry" and doc.book_advance_payments_in_separate_party_account:
+			# both ledgers must be posted to for `Advance` in separate account feature
+			doc.make_advance_gl_entries(referenced_row, update_outstanding="No")
+		else:
+			gl_map = doc.build_gl_map()
+			create_payment_ledger_entry(gl_map, update_outstanding="No", cancel=0, adv_adj=1)
 
 		# Only update outstanding for newly linked vouchers
 		for entry in entries:
 			update_voucher_outstanding(
 				entry.against_voucher_type, entry.against_voucher, entry.account, entry.party_type, entry.party
 			)
-			if voucher_type == "Payment Entry":
-				doc.make_advance_gl_entries(entry.against_voucher_type, entry.against_voucher)
 
 		frappe.flags.ignore_party_validation = False
 
@@ -670,11 +683,12 @@
 			new_row.docstatus = 1
 			for field in list(reference_details):
 				new_row.set(field, reference_details[field])
-
+			row = new_row
 	else:
 		new_row = payment_entry.append("references")
 		new_row.docstatus = 1
 		new_row.update(reference_details)
+		row = new_row
 
 	payment_entry.flags.ignore_validate_update_after_submit = True
 	payment_entry.clear_unallocated_reference_document_rows()
@@ -689,6 +703,7 @@
 
 	if not do_not_save:
 		payment_entry.save(ignore_permissions=True)
+	return row
 
 
 def cancel_exchange_gain_loss_journal(
@@ -865,7 +880,13 @@
 			try:
 				pe_doc = frappe.get_doc("Payment Entry", pe)
 				pe_doc.set_amounts()
-				pe_doc.make_advance_gl_entries(against_voucher_type=ref_type, against_voucher=ref_no, cancel=1)
+
+				# Call cancel on only removed reference
+				references = [
+					x for x in pe_doc.references if x.reference_doctype == ref_type and x.reference_name == ref_no
+				]
+				[pe_doc.make_advance_gl_entries(x, cancel=1) for x in references]
+
 				pe_doc.clear_unallocated_reference_document_rows()
 				pe_doc.validate_payment_type_with_outstanding()
 			except Exception as e:
@@ -1830,6 +1851,30 @@
 					Table("outstanding").amount_in_account_currency >= self.max_outstanding
 				)
 
+		if self.limit and self.get_invoices:
+			outstanding_vouchers = (
+				qb.from_(ple)
+				.select(
+					ple.against_voucher_no.as_("voucher_no"),
+					Sum(ple.amount_in_account_currency).as_("amount_in_account_currency"),
+				)
+				.where(ple.delinked == 0)
+				.where(Criterion.all(filter_on_against_voucher_no))
+				.where(Criterion.all(self.common_filter))
+				.where(Criterion.all(self.dimensions_filter))
+				.where(Criterion.all(self.voucher_posting_date))
+				.groupby(ple.against_voucher_type, ple.against_voucher_no, ple.party_type, ple.party)
+				.orderby(ple.posting_date, ple.voucher_no)
+				.having(qb.Field("amount_in_account_currency") > 0)
+				.limit(self.limit)
+				.run()
+			)
+			if outstanding_vouchers:
+				filter_on_voucher_no.append(ple.voucher_no.isin([x[0] for x in outstanding_vouchers]))
+				filter_on_against_voucher_no.append(
+					ple.against_voucher_no.isin([x[0] for x in outstanding_vouchers])
+				)
+
 		# build query for voucher amount
 		query_voucher_amount = (
 			qb.from_(ple)
diff --git a/erpnext/assets/doctype/asset/asset.js b/erpnext/assets/doctype/asset/asset.js
index d378fbd..58fd6d4 100644
--- a/erpnext/assets/doctype/asset/asset.js
+++ b/erpnext/assets/doctype/asset/asset.js
@@ -214,30 +214,43 @@
 		})
 	},
 
-	render_depreciation_schedule_view: function(frm, depr_schedule) {
+	render_depreciation_schedule_view: function(frm, asset_depr_schedule_doc) {
 		let wrapper = $(frm.fields_dict["depreciation_schedule_view"].wrapper).empty();
 
 		let data = [];
 
-		depr_schedule.forEach((sch) => {
+		asset_depr_schedule_doc.depreciation_schedule.forEach((sch) => {
 			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' }),
-				sch['journal_entry'] || ''
+				sch['journal_entry'] || '',
 			];
+
+			if (asset_depr_schedule_doc.shift_based) {
+				row.push(sch['shift']);
+			}
+
 			data.push(row);
 		});
 
+		let columns = [
+			{name: __("No."), editable: false, resizable: false, format: value => value, width: 60},
+			{name: __("Schedule Date"), editable: false, resizable: false, width: 270},
+			{name: __("Depreciation Amount"), editable: false, resizable: false, width: 164},
+			{name: __("Accumulated Depreciation Amount"), editable: false, resizable: false, width: 164},
+		];
+
+		if (asset_depr_schedule_doc.shift_based) {
+			columns.push({name: __("Journal Entry"), editable: false, resizable: false, format: value => `<a href="/app/journal-entry/${value}">${value}</a>`, width: 245});
+			columns.push({name: __("Shift"), editable: false, resizable: false, width: 59});
+		} else {
+			columns.push({name: __("Journal Entry"), editable: false, resizable: false, format: value => `<a href="/app/journal-entry/${value}">${value}</a>`, width: 304});
+		}
+
 		let datatable = new frappe.DataTable(wrapper.get(0), {
-			columns: [
-				{name: __("No."), editable: false, resizable: false, format: value => value, width: 60},
-				{name: __("Schedule Date"), editable: false, resizable: false, width: 270},
-				{name: __("Depreciation Amount"), editable: false, resizable: false, width: 164},
-				{name: __("Accumulated Depreciation Amount"), editable: false, resizable: false, width: 164},
-				{name: __("Journal Entry"), editable: false, resizable: false, format: value => `<a href="/app/journal-entry/${value}">${value}</a>`, width: 304}
-			],
+			columns: columns,
 			data: data,
 			layout: "fluid",
 			serialNoColumn: false,
@@ -272,8 +285,8 @@
 				asset_values.push(flt(frm.doc.gross_purchase_amount - frm.doc.opening_accumulated_depreciation, precision('gross_purchase_amount')));
 			}
 
-			let depr_schedule = (await frappe.call(
-				"erpnext.assets.doctype.asset_depreciation_schedule.asset_depreciation_schedule.get_depr_schedule",
+			let asset_depr_schedule_doc = (await frappe.call(
+				"erpnext.assets.doctype.asset_depreciation_schedule.asset_depreciation_schedule.get_asset_depr_schedule_doc",
 				{
 					asset_name: frm.doc.name,
 					status: "Active",
@@ -281,7 +294,7 @@
 				}
 			)).message;
 
-			$.each(depr_schedule || [], function(i, v) {
+			$.each(asset_depr_schedule_doc.depreciation_schedule || [], function(i, v) {
 				x_intervals.push(frappe.format(v.schedule_date, { fieldtype: 'Date' }));
 				var asset_value = flt(frm.doc.gross_purchase_amount - v.accumulated_depreciation_amount, precision('gross_purchase_amount'));
 				if(v.journal_entry) {
@@ -296,7 +309,7 @@
 			});
 
 			frm.toggle_display(["depreciation_schedule_view"], 1);
-			frm.events.render_depreciation_schedule_view(frm, depr_schedule);
+			frm.events.render_depreciation_schedule_view(frm, asset_depr_schedule_doc);
 		} else {
 			if(frm.doc.opening_accumulated_depreciation) {
 				x_intervals.push(frappe.format(frm.doc.creation.split(" ")[0], { fieldtype: 'Date' }));
diff --git a/erpnext/assets/doctype/asset/asset.json b/erpnext/assets/doctype/asset/asset.json
index 40f51ab..540a4f5 100644
--- a/erpnext/assets/doctype/asset/asset.json
+++ b/erpnext/assets/doctype/asset/asset.json
@@ -481,11 +481,11 @@
    "read_only": 1
   },
   {
-   "depends_on": "eval.doc.asset_quantity",
+   "default": "1",
    "fieldname": "asset_quantity",
    "fieldtype": "Int",
    "label": "Asset Quantity",
-   "read_only": 1
+   "read_only_depends_on": "eval:!doc.is_existing_asset && !doc.is_composite_asset"
   },
   {
    "fieldname": "depr_entry_posting_status",
@@ -572,7 +572,7 @@
    "link_fieldname": "target_asset"
   }
  ],
- "modified": "2023-10-27 17:03:46.629617",
+ "modified": "2023-11-20 20:57:37.010467",
  "modified_by": "Administrator",
  "module": "Assets",
  "name": "Asset",
diff --git a/erpnext/assets/doctype/asset/asset.py b/erpnext/assets/doctype/asset/asset.py
index 3c570d1..5fb2d36 100644
--- a/erpnext/assets/doctype/asset/asset.py
+++ b/erpnext/assets/doctype/asset/asset.py
@@ -40,18 +40,109 @@
 
 
 class Asset(AccountsController):
+	# 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
+
+		from erpnext.assets.doctype.asset_finance_book.asset_finance_book import AssetFinanceBook
+
+		amended_from: DF.Link | None
+		asset_category: DF.Link | None
+		asset_name: DF.Data
+		asset_owner: DF.Literal["", "Company", "Supplier", "Customer"]
+		asset_owner_company: DF.Link | None
+		asset_quantity: DF.Int
+		available_for_use_date: DF.Date
+		booked_fixed_asset: DF.Check
+		calculate_depreciation: DF.Check
+		capitalized_in: DF.Link | None
+		company: DF.Link
+		comprehensive_insurance: DF.Data | None
+		cost_center: DF.Link | None
+		custodian: DF.Link | None
+		customer: DF.Link | None
+		default_finance_book: DF.Link | None
+		department: DF.Link | None
+		depr_entry_posting_status: DF.Literal["", "Successful", "Failed"]
+		depreciation_method: DF.Literal["", "Straight Line", "Double Declining Balance", "Manual"]
+		disposal_date: DF.Date | None
+		finance_books: DF.Table[AssetFinanceBook]
+		frequency_of_depreciation: DF.Int
+		gross_purchase_amount: DF.Currency
+		image: DF.AttachImage | None
+		insurance_end_date: DF.Date | None
+		insurance_start_date: DF.Date | None
+		insured_value: DF.Data | None
+		insurer: DF.Data | None
+		is_composite_asset: DF.Check
+		is_existing_asset: DF.Check
+		is_fully_depreciated: DF.Check
+		item_code: DF.Link
+		item_name: DF.ReadOnly | None
+		journal_entry_for_scrap: DF.Link | None
+		location: DF.Link
+		maintenance_required: DF.Check
+		naming_series: DF.Literal["ACC-ASS-.YYYY.-"]
+		next_depreciation_date: DF.Date | None
+		number_of_depreciations_booked: DF.Int
+		opening_accumulated_depreciation: DF.Currency
+		policy_number: DF.Data | None
+		purchase_date: DF.Date
+		purchase_invoice: DF.Link | None
+		purchase_receipt: DF.Link | None
+		purchase_receipt_amount: DF.Currency
+		split_from: DF.Link | None
+		status: DF.Literal[
+			"Draft",
+			"Submitted",
+			"Partially Depreciated",
+			"Fully Depreciated",
+			"Sold",
+			"Scrapped",
+			"In Maintenance",
+			"Out of Order",
+			"Issue",
+			"Receipt",
+			"Capitalized",
+			"Decapitalized",
+		]
+		supplier: DF.Link | None
+		total_number_of_depreciations: DF.Int
+		value_after_depreciation: DF.Currency
+	# end: auto-generated types
+
 	def validate(self):
 		self.validate_asset_values()
 		self.validate_asset_and_reference()
 		self.validate_item()
 		self.validate_cost_center()
 		self.set_missing_values()
-		self.validate_finance_books()
-		if not self.split_from:
-			self.prepare_depreciation_data()
-			update_draft_asset_depr_schedules(self)
 		self.validate_gross_and_purchase_amount()
 		self.validate_expected_value_after_useful_life()
+		self.validate_finance_books()
+
+		if not self.split_from:
+			self.prepare_depreciation_data()
+
+			if self.calculate_depreciation:
+				update_draft_asset_depr_schedules(self)
+
+				if frappe.db.exists("Asset", self.name):
+					asset_depr_schedules_names = make_draft_asset_depr_schedules_if_not_present(self)
+
+					if asset_depr_schedules_names:
+						asset_depr_schedules_links = get_comma_separated_links(
+							asset_depr_schedules_names, "Asset Depreciation Schedule"
+						)
+						frappe.msgprint(
+							_(
+								"Asset Depreciation Schedules created:<br>{0}<br><br>Please check, edit if needed, and submit the Asset."
+							).format(asset_depr_schedules_links)
+						)
 
 		self.status = self.get_status()
 
@@ -61,17 +152,7 @@
 		if not self.booked_fixed_asset and self.validate_make_gl_entry():
 			self.make_gl_entries()
 		if self.calculate_depreciation and not self.split_from:
-			asset_depr_schedules_names = make_draft_asset_depr_schedules_if_not_present(self)
 			convert_draft_asset_depr_schedules_into_active(self)
-			if asset_depr_schedules_names:
-				asset_depr_schedules_links = get_comma_separated_links(
-					asset_depr_schedules_names, "Asset Depreciation Schedule"
-				)
-				frappe.msgprint(
-					_(
-						"Asset Depreciation Schedules created:<br>{0}<br><br>Please check, edit if needed, and submit the Asset."
-					).format(asset_depr_schedules_links)
-				)
 		self.set_status()
 		add_asset_activity(self.name, _("Asset submitted"))
 
@@ -819,10 +900,12 @@
 				"total_number_of_depreciations": d.total_number_of_depreciations,
 				"frequency_of_depreciation": d.frequency_of_depreciation,
 				"daily_prorata_based": d.daily_prorata_based,
+				"shift_based": d.shift_based,
 				"salvage_value_percentage": d.salvage_value_percentage,
 				"expected_value_after_useful_life": flt(gross_purchase_amount)
 				* flt(d.salvage_value_percentage / 100),
 				"depreciation_start_date": d.depreciation_start_date or nowdate(),
+				"rate_of_depreciation": d.rate_of_depreciation,
 			}
 		)
 
diff --git a/erpnext/assets/doctype/asset/depreciation.py b/erpnext/assets/doctype/asset/depreciation.py
index 84a428c..66930c0 100644
--- a/erpnext/assets/doctype/asset/depreciation.py
+++ b/erpnext/assets/doctype/asset/depreciation.py
@@ -509,6 +509,9 @@
 
 
 def depreciate_asset(asset_doc, date, notes):
+	if not asset_doc.calculate_depreciation:
+		return
+
 	asset_doc.flags.ignore_validate_update_after_submit = True
 
 	make_new_active_asset_depr_schedules_and_cancel_current_ones(
@@ -521,6 +524,9 @@
 
 
 def reset_depreciation_schedule(asset_doc, date, notes):
+	if not asset_doc.calculate_depreciation:
+		return
+
 	asset_doc.flags.ignore_validate_update_after_submit = True
 
 	make_new_active_asset_depr_schedules_and_cancel_current_ones(
diff --git a/erpnext/assets/doctype/asset/test_asset.py b/erpnext/assets/doctype/asset/test_asset.py
index 9e3ec6f..dc80aa5 100644
--- a/erpnext/assets/doctype/asset/test_asset.py
+++ b/erpnext/assets/doctype/asset/test_asset.py
@@ -149,12 +149,7 @@
 			("Creditors - _TC", 0.0, 100000.0),
 		)
 
-		gle = frappe.db.sql(
-			"""select account, debit, credit from `tabGL Entry`
-			where voucher_type='Purchase Invoice' and voucher_no = %s
-			order by account""",
-			pi.name,
-		)
+		gle = get_gl_entries("Purchase Invoice", pi.name)
 		self.assertSequenceEqual(gle, expected_gle)
 
 		pi.cancel()
@@ -264,12 +259,7 @@
 			),
 		)
 
-		gle = frappe.db.sql(
-			"""select account, debit, credit from `tabGL Entry`
-			where voucher_type='Journal Entry' and voucher_no = %s
-			order by account""",
-			asset.journal_entry_for_scrap,
-		)
+		gle = get_gl_entries("Journal Entry", asset.journal_entry_for_scrap)
 		self.assertSequenceEqual(gle, expected_gle)
 
 		restore_asset(asset.name)
@@ -345,13 +335,7 @@
 			("Debtors - _TC", 25000.0, 0.0),
 		)
 
-		gle = frappe.db.sql(
-			"""select account, debit, credit from `tabGL Entry`
-			where voucher_type='Sales Invoice' and voucher_no = %s
-			order by account""",
-			si.name,
-		)
-
+		gle = get_gl_entries("Sales Invoice", si.name)
 		self.assertSequenceEqual(gle, expected_gle)
 
 		si.cancel()
@@ -425,13 +409,7 @@
 			("Debtors - _TC", 40000.0, 0.0),
 		)
 
-		gle = frappe.db.sql(
-			"""select account, debit, credit from `tabGL Entry`
-			where voucher_type='Sales Invoice' and voucher_no = %s
-			order by account""",
-			si.name,
-		)
-
+		gle = get_gl_entries("Sales Invoice", si.name)
 		self.assertSequenceEqual(gle, expected_gle)
 
 	def test_asset_with_maintenance_required_status_after_sale(self):
@@ -572,13 +550,7 @@
 			("CWIP Account - _TC", 5250.0, 0.0),
 		)
 
-		pr_gle = frappe.db.sql(
-			"""select account, debit, credit from `tabGL Entry`
-			where voucher_type='Purchase Receipt' and voucher_no = %s
-			order by account""",
-			pr.name,
-		)
-
+		pr_gle = get_gl_entries("Purchase Receipt", pr.name)
 		self.assertSequenceEqual(pr_gle, expected_gle)
 
 		pi = make_invoice(pr.name)
@@ -591,13 +563,7 @@
 			("Creditors - _TC", 0.0, 5500.0),
 		)
 
-		pi_gle = frappe.db.sql(
-			"""select account, debit, credit from `tabGL Entry`
-			where voucher_type='Purchase Invoice' and voucher_no = %s
-			order by account""",
-			pi.name,
-		)
-
+		pi_gle = get_gl_entries("Purchase Invoice", pi.name)
 		self.assertSequenceEqual(pi_gle, expected_gle)
 
 		asset = frappe.db.get_value("Asset", {"purchase_receipt": pr.name, "docstatus": 0}, "name")
@@ -624,13 +590,7 @@
 
 		expected_gle = (("_Test Fixed Asset - _TC", 5250.0, 0.0), ("CWIP Account - _TC", 0.0, 5250.0))
 
-		gle = frappe.db.sql(
-			"""select account, debit, credit from `tabGL Entry`
-			where voucher_type='Asset' and voucher_no = %s
-			order by account""",
-			asset_doc.name,
-		)
-
+		gle = get_gl_entries("Asset", asset_doc.name)
 		self.assertSequenceEqual(gle, expected_gle)
 
 	def test_asset_cwip_toggling_cases(self):
@@ -653,10 +613,7 @@
 		asset_doc.available_for_use_date = nowdate()
 		asset_doc.calculate_depreciation = 0
 		asset_doc.submit()
-		gle = frappe.db.sql(
-			"""select name from `tabGL Entry` where voucher_type='Asset' and voucher_no = %s""",
-			asset_doc.name,
-		)
+		gle = get_gl_entries("Asset", asset_doc.name)
 		self.assertFalse(gle)
 
 		# case 1 -- PR with cwip disabled, Asset with cwip enabled
@@ -670,10 +627,7 @@
 		asset_doc.available_for_use_date = nowdate()
 		asset_doc.calculate_depreciation = 0
 		asset_doc.submit()
-		gle = frappe.db.sql(
-			"""select name from `tabGL Entry` where voucher_type='Asset' and voucher_no = %s""",
-			asset_doc.name,
-		)
+		gle = get_gl_entries("Asset", asset_doc.name)
 		self.assertFalse(gle)
 
 		# case 2 -- PR with cwip enabled, Asset with cwip disabled
@@ -686,10 +640,7 @@
 		asset_doc.available_for_use_date = nowdate()
 		asset_doc.calculate_depreciation = 0
 		asset_doc.submit()
-		gle = frappe.db.sql(
-			"""select name from `tabGL Entry` where voucher_type='Asset' and voucher_no = %s""",
-			asset_doc.name,
-		)
+		gle = get_gl_entries("Asset", asset_doc.name)
 		self.assertTrue(gle)
 
 		# case 3 -- PI with cwip disabled, Asset with cwip enabled
@@ -702,10 +653,7 @@
 		asset_doc.available_for_use_date = nowdate()
 		asset_doc.calculate_depreciation = 0
 		asset_doc.submit()
-		gle = frappe.db.sql(
-			"""select name from `tabGL Entry` where voucher_type='Asset' and voucher_no = %s""",
-			asset_doc.name,
-		)
+		gle = get_gl_entries("Asset", asset_doc.name)
 		self.assertFalse(gle)
 
 		# case 4 -- PI with cwip enabled, Asset with cwip disabled
@@ -718,10 +666,7 @@
 		asset_doc.available_for_use_date = nowdate()
 		asset_doc.calculate_depreciation = 0
 		asset_doc.submit()
-		gle = frappe.db.sql(
-			"""select name from `tabGL Entry` where voucher_type='Asset' and voucher_no = %s""",
-			asset_doc.name,
-		)
+		gle = get_gl_entries("Asset", asset_doc.name)
 		self.assertTrue(gle)
 
 		frappe.db.set_value("Asset Category", "Computers", "enable_cwip_accounting", cwip)
@@ -1055,7 +1000,11 @@
 			},
 		)
 
-		depreciation_amount = get_depreciation_amount(asset, 100000, asset.finance_books[0])
+		asset_depr_schedule_doc = get_asset_depr_schedule_doc(asset.name, "Active")
+
+		depreciation_amount = get_depreciation_amount(
+			asset_depr_schedule_doc, asset, 100000, asset.finance_books[0]
+		)
 		self.assertEqual(depreciation_amount, 30000)
 
 	def test_make_depr_schedule(self):
@@ -1701,6 +1650,30 @@
 
 		self.assertRaises(frappe.ValidationError, jv.insert)
 
+	def test_multi_currency_asset_pr_creation(self):
+		pr = make_purchase_receipt(
+			item_code="Macbook Pro",
+			qty=1,
+			rate=100.0,
+			location="Test Location",
+			supplier="_Test Supplier USD",
+			currency="USD",
+		)
+
+		pr.submit()
+		self.assertTrue(get_gl_entries("Purchase Receipt", pr.name))
+
+
+def get_gl_entries(doctype, docname):
+	gl_entry = frappe.qb.DocType("GL Entry")
+	return (
+		frappe.qb.from_(gl_entry)
+		.select(gl_entry.account, gl_entry.debit, gl_entry.credit)
+		.where((gl_entry.voucher_type == doctype) & (gl_entry.voucher_no == docname))
+		.orderby(gl_entry.account)
+		.run()
+	)
+
 
 def create_asset_data():
 	if not frappe.db.exists("Asset Category", "Computers"):
@@ -1763,6 +1736,7 @@
 				"expected_value_after_useful_life": args.expected_value_after_useful_life or 0,
 				"depreciation_start_date": args.depreciation_start_date,
 				"daily_prorata_based": args.daily_prorata_based or 0,
+				"shift_based": args.shift_based or 0,
 			},
 		)
 
diff --git a/erpnext/assets/doctype/asset_activity/asset_activity.py b/erpnext/assets/doctype/asset_activity/asset_activity.py
index 28e1b3e..a64cb1a 100644
--- a/erpnext/assets/doctype/asset_activity/asset_activity.py
+++ b/erpnext/assets/doctype/asset_activity/asset_activity.py
@@ -6,6 +6,20 @@
 
 
 class AssetActivity(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
+
+		asset: DF.Link
+		date: DF.Datetime
+		subject: DF.SmallText
+		user: DF.Link
+	# end: auto-generated types
+
 	pass
 
 
diff --git a/erpnext/assets/doctype/asset_capitalization/asset_capitalization.py b/erpnext/assets/doctype/asset_capitalization/asset_capitalization.py
index 728764b..66997ca 100644
--- a/erpnext/assets/doctype/asset_capitalization/asset_capitalization.py
+++ b/erpnext/assets/doctype/asset_capitalization/asset_capitalization.py
@@ -49,6 +49,61 @@
 
 
 class AssetCapitalization(StockController):
+	# 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
+
+		from erpnext.assets.doctype.asset_capitalization_asset_item.asset_capitalization_asset_item import (
+			AssetCapitalizationAssetItem,
+		)
+		from erpnext.assets.doctype.asset_capitalization_service_item.asset_capitalization_service_item import (
+			AssetCapitalizationServiceItem,
+		)
+		from erpnext.assets.doctype.asset_capitalization_stock_item.asset_capitalization_stock_item import (
+			AssetCapitalizationStockItem,
+		)
+
+		amended_from: DF.Link | None
+		asset_items: DF.Table[AssetCapitalizationAssetItem]
+		asset_items_total: DF.Currency
+		capitalization_method: DF.Literal[
+			"", "Create a new composite asset", "Choose a WIP composite asset"
+		]
+		company: DF.Link
+		cost_center: DF.Link | None
+		entry_type: DF.Literal["Capitalization", "Decapitalization"]
+		finance_book: DF.Link | None
+		naming_series: DF.Literal["ACC-ASC-.YYYY.-"]
+		posting_date: DF.Date
+		posting_time: DF.Time
+		service_items: DF.Table[AssetCapitalizationServiceItem]
+		service_items_total: DF.Currency
+		set_posting_time: DF.Check
+		stock_items: DF.Table[AssetCapitalizationStockItem]
+		stock_items_total: DF.Currency
+		target_asset: DF.Link | None
+		target_asset_location: DF.Link | None
+		target_asset_name: DF.Data | None
+		target_batch_no: DF.Link | None
+		target_fixed_asset_account: DF.Link | None
+		target_has_batch_no: DF.Check
+		target_has_serial_no: DF.Check
+		target_incoming_rate: DF.Currency
+		target_is_fixed_asset: DF.Check
+		target_item_code: DF.Link | None
+		target_item_name: DF.Data | None
+		target_qty: DF.Float
+		target_serial_no: DF.SmallText | None
+		target_stock_uom: DF.Link | None
+		target_warehouse: DF.Link | None
+		title: DF.Data | None
+		total_value: DF.Currency
+	# end: auto-generated types
+
 	def validate(self):
 		self.validate_posting_time()
 		self.set_missing_values(for_validate=True)
diff --git a/erpnext/assets/doctype/asset_capitalization_asset_item/asset_capitalization_asset_item.py b/erpnext/assets/doctype/asset_capitalization_asset_item/asset_capitalization_asset_item.py
index ba356d6..003973f 100644
--- a/erpnext/assets/doctype/asset_capitalization_asset_item/asset_capitalization_asset_item.py
+++ b/erpnext/assets/doctype/asset_capitalization_asset_item/asset_capitalization_asset_item.py
@@ -6,4 +6,26 @@
 
 
 class AssetCapitalizationAssetItem(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
+
+		asset: DF.Link
+		asset_name: DF.Data | None
+		asset_value: DF.Currency
+		cost_center: DF.Link | None
+		current_asset_value: DF.Currency
+		finance_book: DF.Link | None
+		fixed_asset_account: DF.Link | None
+		item_code: DF.Link
+		item_name: DF.Data | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/assets/doctype/asset_capitalization_service_item/asset_capitalization_service_item.py b/erpnext/assets/doctype/asset_capitalization_service_item/asset_capitalization_service_item.py
index 28d018e..93457f8 100644
--- a/erpnext/assets/doctype/asset_capitalization_service_item/asset_capitalization_service_item.py
+++ b/erpnext/assets/doctype/asset_capitalization_service_item/asset_capitalization_service_item.py
@@ -6,4 +6,25 @@
 
 
 class AssetCapitalizationServiceItem(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
+
+		amount: DF.Currency
+		cost_center: DF.Link | None
+		expense_account: DF.Link
+		item_code: DF.Link | None
+		item_name: DF.Data | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		qty: DF.Float
+		rate: DF.Currency
+		uom: DF.Link | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/assets/doctype/asset_capitalization_stock_item/asset_capitalization_stock_item.py b/erpnext/assets/doctype/asset_capitalization_stock_item/asset_capitalization_stock_item.py
index 5d6f98d..122cbb6 100644
--- a/erpnext/assets/doctype/asset_capitalization_stock_item/asset_capitalization_stock_item.py
+++ b/erpnext/assets/doctype/asset_capitalization_stock_item/asset_capitalization_stock_item.py
@@ -6,4 +6,29 @@
 
 
 class AssetCapitalizationStockItem(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
+
+		actual_qty: DF.Float
+		amount: DF.Currency
+		batch_no: DF.Link | None
+		cost_center: DF.Link | None
+		item_code: DF.Link
+		item_name: DF.Data | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		serial_and_batch_bundle: DF.Link | None
+		serial_no: DF.SmallText | None
+		stock_qty: DF.Float
+		stock_uom: DF.Link
+		valuation_rate: DF.Currency
+		warehouse: DF.Link
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/assets/doctype/asset_category/asset_category.py b/erpnext/assets/doctype/asset_category/asset_category.py
index 8d35141..034ec55 100644
--- a/erpnext/assets/doctype/asset_category/asset_category.py
+++ b/erpnext/assets/doctype/asset_category/asset_category.py
@@ -9,6 +9,25 @@
 
 
 class AssetCategory(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
+
+		from erpnext.assets.doctype.asset_category_account.asset_category_account import (
+			AssetCategoryAccount,
+		)
+		from erpnext.assets.doctype.asset_finance_book.asset_finance_book import AssetFinanceBook
+
+		accounts: DF.Table[AssetCategoryAccount]
+		asset_category_name: DF.Data
+		enable_cwip_accounting: DF.Check
+		finance_books: DF.Table[AssetFinanceBook]
+	# end: auto-generated types
+
 	def validate(self):
 		self.validate_finance_books()
 		self.validate_account_types()
diff --git a/erpnext/assets/doctype/asset_category_account/asset_category_account.py b/erpnext/assets/doctype/asset_category_account/asset_category_account.py
index e06d233..2798f1c 100644
--- a/erpnext/assets/doctype/asset_category_account/asset_category_account.py
+++ b/erpnext/assets/doctype/asset_category_account/asset_category_account.py
@@ -6,4 +6,22 @@
 
 
 class AssetCategoryAccount(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
+
+		accumulated_depreciation_account: DF.Link | None
+		capital_work_in_progress_account: DF.Link | None
+		company_name: DF.Link
+		depreciation_expense_account: DF.Link | None
+		fixed_asset_account: DF.Link
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/assets/doctype/asset_depreciation_schedule/asset_depreciation_schedule.js b/erpnext/assets/doctype/asset_depreciation_schedule/asset_depreciation_schedule.js
index 3d2dff1..c99297d 100644
--- a/erpnext/assets/doctype/asset_depreciation_schedule/asset_depreciation_schedule.js
+++ b/erpnext/assets/doctype/asset_depreciation_schedule/asset_depreciation_schedule.js
@@ -8,11 +8,13 @@
 	},
 
 	make_schedules_editable: function(frm) {
-		var is_editable = frm.doc.depreciation_method == "Manual" ? true : false;
+		var is_manual_hence_editable = frm.doc.depreciation_method === "Manual" ? true : false;
+		var is_shift_hence_editable = frm.doc.shift_based ? true : false;
 
-		frm.toggle_enable("depreciation_schedule", is_editable);
-		frm.fields_dict["depreciation_schedule"].grid.toggle_enable("schedule_date", is_editable);
-		frm.fields_dict["depreciation_schedule"].grid.toggle_enable("depreciation_amount", is_editable);
+		frm.toggle_enable("depreciation_schedule", is_manual_hence_editable || is_shift_hence_editable);
+		frm.fields_dict["depreciation_schedule"].grid.toggle_enable("schedule_date", is_manual_hence_editable);
+		frm.fields_dict["depreciation_schedule"].grid.toggle_enable("depreciation_amount", is_manual_hence_editable);
+		frm.fields_dict["depreciation_schedule"].grid.toggle_enable("shift", is_shift_hence_editable);
 	}
 });
 
diff --git a/erpnext/assets/doctype/asset_depreciation_schedule/asset_depreciation_schedule.json b/erpnext/assets/doctype/asset_depreciation_schedule/asset_depreciation_schedule.json
index 8d8b463..be35914 100644
--- a/erpnext/assets/doctype/asset_depreciation_schedule/asset_depreciation_schedule.json
+++ b/erpnext/assets/doctype/asset_depreciation_schedule/asset_depreciation_schedule.json
@@ -20,6 +20,7 @@
   "total_number_of_depreciations",
   "rate_of_depreciation",
   "daily_prorata_based",
+  "shift_based",
   "column_break_8",
   "frequency_of_depreciation",
   "expected_value_after_useful_life",
@@ -184,12 +185,20 @@
    "label": "Depreciate based on daily pro-rata",
    "print_hide": 1,
    "read_only": 1
+  },
+  {
+   "default": "0",
+   "depends_on": "eval:doc.depreciation_method == \"Straight Line\"",
+   "fieldname": "shift_based",
+   "fieldtype": "Check",
+   "label": "Depreciate based on shifts",
+   "read_only": 1
   }
  ],
  "index_web_pages_for_search": 1,
  "is_submittable": 1,
  "links": [],
- "modified": "2023-11-03 21:32:15.021796",
+ "modified": "2023-11-29 00:57:00.461998",
  "modified_by": "Administrator",
  "module": "Assets",
  "name": "Asset Depreciation Schedule",
diff --git a/erpnext/assets/doctype/asset_depreciation_schedule/asset_depreciation_schedule.py b/erpnext/assets/doctype/asset_depreciation_schedule/asset_depreciation_schedule.py
index 7305691..0021140 100644
--- a/erpnext/assets/doctype/asset_depreciation_schedule/asset_depreciation_schedule.py
+++ b/erpnext/assets/doctype/asset_depreciation_schedule/asset_depreciation_schedule.py
@@ -21,11 +21,46 @@
 
 
 class AssetDepreciationSchedule(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
+
+		from erpnext.assets.doctype.depreciation_schedule.depreciation_schedule import (
+			DepreciationSchedule,
+		)
+
+		amended_from: DF.Link | None
+		asset: DF.Link
+		daily_prorata_based: DF.Check
+		depreciation_method: DF.Literal[
+			"", "Straight Line", "Double Declining Balance", "Written Down Value", "Manual"
+		]
+		depreciation_schedule: DF.Table[DepreciationSchedule]
+		expected_value_after_useful_life: DF.Currency
+		finance_book: DF.Link | None
+		finance_book_id: DF.Int
+		frequency_of_depreciation: DF.Int
+		gross_purchase_amount: DF.Currency
+		naming_series: DF.Literal["ACC-ADS-.YYYY.-"]
+		notes: DF.SmallText | None
+		number_of_depreciations_booked: DF.Int
+		opening_accumulated_depreciation: DF.Currency
+		rate_of_depreciation: DF.Percent
+		shift_based: DF.Check
+		status: DF.Literal["Draft", "Active", "Cancelled"]
+		total_number_of_depreciations: DF.Int
+	# end: auto-generated types
+
 	def before_save(self):
 		if not self.finance_book_id:
 			self.prepare_draft_asset_depr_schedule_data_from_asset_name_and_fb_name(
 				self.asset, self.finance_book
 			)
+		self.update_shift_depr_schedule()
 
 	def validate(self):
 		self.validate_another_asset_depr_schedule_does_not_exist()
@@ -73,6 +108,16 @@
 	def on_cancel(self):
 		self.db_set("status", "Cancelled")
 
+	def update_shift_depr_schedule(self):
+		if not self.shift_based or self.docstatus != 0:
+			return
+
+		asset_doc = frappe.get_doc("Asset", self.asset)
+		fb_row = asset_doc.finance_books[self.finance_book_id - 1]
+
+		self.make_depr_schedule(asset_doc, fb_row)
+		self.set_accumulated_depreciation(asset_doc, fb_row)
+
 	def prepare_draft_asset_depr_schedule_data_from_asset_name_and_fb_name(self, asset_name, fb_name):
 		asset_doc = frappe.get_doc("Asset", asset_name)
 
@@ -154,13 +199,14 @@
 		self.rate_of_depreciation = row.rate_of_depreciation
 		self.expected_value_after_useful_life = row.expected_value_after_useful_life
 		self.daily_prorata_based = row.daily_prorata_based
+		self.shift_based = row.shift_based
 		self.status = "Draft"
 
 	def make_depr_schedule(
 		self,
 		asset_doc,
 		row,
-		date_of_disposal,
+		date_of_disposal=None,
 		update_asset_finance_book_row=True,
 		value_after_depreciation=None,
 	):
@@ -181,6 +227,8 @@
 		num_of_depreciations_completed = 0
 		depr_schedule = []
 
+		self.schedules_before_clearing = self.get("depreciation_schedule")
+
 		for schedule in self.get("depreciation_schedule"):
 			if schedule.journal_entry:
 				num_of_depreciations_completed += 1
@@ -246,6 +294,7 @@
 				prev_depreciation_amount = 0
 
 			depreciation_amount = get_depreciation_amount(
+				self,
 				asset_doc,
 				value_after_depreciation,
 				row,
@@ -282,10 +331,7 @@
 				)
 
 				if depreciation_amount > 0:
-					self.add_depr_schedule_row(
-						date_of_disposal,
-						depreciation_amount,
-					)
+					self.add_depr_schedule_row(date_of_disposal, depreciation_amount, n)
 
 				break
 
@@ -369,10 +415,7 @@
 				skip_row = True
 
 			if flt(depreciation_amount, asset_doc.precision("gross_purchase_amount")) > 0:
-				self.add_depr_schedule_row(
-					schedule_date,
-					depreciation_amount,
-				)
+				self.add_depr_schedule_row(schedule_date, depreciation_amount, n)
 
 	# to ensure that final accumulated depreciation amount is accurate
 	def get_adjusted_depreciation_amount(
@@ -394,16 +437,22 @@
 	def get_depreciation_amount_for_first_row(self):
 		return self.get("depreciation_schedule")[0].depreciation_amount
 
-	def add_depr_schedule_row(
-		self,
-		schedule_date,
-		depreciation_amount,
-	):
+	def add_depr_schedule_row(self, schedule_date, depreciation_amount, schedule_idx):
+		if self.shift_based:
+			shift = (
+				self.schedules_before_clearing[schedule_idx].shift
+				if self.schedules_before_clearing and len(self.schedules_before_clearing) > schedule_idx
+				else frappe.get_cached_value("Asset Shift Factor", {"default": 1}, "shift_name")
+			)
+		else:
+			shift = None
+
 		self.append(
 			"depreciation_schedule",
 			{
 				"schedule_date": schedule_date,
 				"depreciation_amount": depreciation_amount,
+				"shift": shift,
 			},
 		)
 
@@ -445,6 +494,7 @@
 				and i == max(straight_line_idx) - 1
 				and not date_of_disposal
 				and not date_of_return
+				and not row.shift_based
 			):
 				depreciation_amount += flt(
 					value_after_depreciation - flt(row.expected_value_after_useful_life),
@@ -527,6 +577,7 @@
 
 
 def get_depreciation_amount(
+	asset_depr_schedule,
 	asset,
 	depreciable_value,
 	fb_row,
@@ -537,7 +588,7 @@
 ):
 	if fb_row.depreciation_method in ("Straight Line", "Manual"):
 		return get_straight_line_or_manual_depr_amount(
-			asset, fb_row, schedule_idx, number_of_pending_depreciations
+			asset_depr_schedule, asset, fb_row, schedule_idx, number_of_pending_depreciations
 		)
 	else:
 		rate_of_depreciation = get_updated_rate_of_depreciation_for_wdv_and_dd(
@@ -559,8 +610,11 @@
 
 
 def get_straight_line_or_manual_depr_amount(
-	asset, row, schedule_idx, number_of_pending_depreciations
+	asset_depr_schedule, asset, row, schedule_idx, number_of_pending_depreciations
 ):
+	if row.shift_based:
+		return get_shift_depr_amount(asset_depr_schedule, asset, row, schedule_idx)
+
 	# if the Depreciation Schedule is being modified after Asset Repair due to increase in asset life and value
 	if asset.flags.increase_in_asset_life:
 		return (flt(row.value_after_depreciation) - flt(row.expected_value_after_useful_life)) / (
@@ -655,6 +709,41 @@
 			) / flt(row.total_number_of_depreciations - asset.number_of_depreciations_booked)
 
 
+def get_shift_depr_amount(asset_depr_schedule, asset, row, schedule_idx):
+	if asset_depr_schedule.get("__islocal") and not asset.flags.shift_allocation:
+		return (
+			flt(asset.gross_purchase_amount)
+			- flt(asset.opening_accumulated_depreciation)
+			- flt(row.expected_value_after_useful_life)
+		) / flt(row.total_number_of_depreciations - asset.number_of_depreciations_booked)
+
+	asset_shift_factors_map = get_asset_shift_factors_map()
+	shift = (
+		asset_depr_schedule.schedules_before_clearing[schedule_idx].shift
+		if len(asset_depr_schedule.schedules_before_clearing) > schedule_idx
+		else None
+	)
+	shift_factor = asset_shift_factors_map.get(shift) if shift else 0
+
+	shift_factors_sum = sum(
+		flt(asset_shift_factors_map.get(schedule.shift))
+		for schedule in asset_depr_schedule.schedules_before_clearing
+	)
+
+	return (
+		(
+			flt(asset.gross_purchase_amount)
+			- flt(asset.opening_accumulated_depreciation)
+			- flt(row.expected_value_after_useful_life)
+		)
+		/ flt(shift_factors_sum)
+	) * shift_factor
+
+
+def get_asset_shift_factors_map():
+	return dict(frappe.db.get_all("Asset Shift Factor", ["shift_name", "shift_factor"], as_list=True))
+
+
 def get_wdv_or_dd_depr_amount(
 	depreciable_value,
 	rate_of_depreciation,
@@ -803,7 +892,12 @@
 
 
 def get_temp_asset_depr_schedule_doc(
-	asset_doc, row, date_of_disposal=None, date_of_return=None, update_asset_finance_book_row=False
+	asset_doc,
+	row,
+	date_of_disposal=None,
+	date_of_return=None,
+	update_asset_finance_book_row=False,
+	new_depr_schedule=None,
 ):
 	current_asset_depr_schedule_doc = get_asset_depr_schedule_doc(
 		asset_doc.name, "Active", row.finance_book
@@ -818,6 +912,21 @@
 
 	temp_asset_depr_schedule_doc = frappe.copy_doc(current_asset_depr_schedule_doc)
 
+	if new_depr_schedule:
+		temp_asset_depr_schedule_doc.depreciation_schedule = []
+
+		for schedule in new_depr_schedule:
+			temp_asset_depr_schedule_doc.append(
+				"depreciation_schedule",
+				{
+					"schedule_date": schedule.schedule_date,
+					"depreciation_amount": schedule.depreciation_amount,
+					"accumulated_depreciation_amount": schedule.accumulated_depreciation_amount,
+					"journal_entry": schedule.journal_entry,
+					"shift": schedule.shift,
+				},
+			)
+
 	temp_asset_depr_schedule_doc.prepare_draft_asset_depr_schedule_data(
 		asset_doc,
 		row,
@@ -839,6 +948,7 @@
 	return asset_depr_schedule_doc.get("depreciation_schedule")
 
 
+@frappe.whitelist()
 def get_asset_depr_schedule_doc(asset_name, status, finance_book=None):
 	asset_depr_schedule_name = get_asset_depr_schedule_name(asset_name, status, finance_book)
 
diff --git a/erpnext/assets/doctype/asset_finance_book/asset_finance_book.json b/erpnext/assets/doctype/asset_finance_book/asset_finance_book.json
index e597d5f..25ae7a4 100644
--- a/erpnext/assets/doctype/asset_finance_book/asset_finance_book.json
+++ b/erpnext/assets/doctype/asset_finance_book/asset_finance_book.json
@@ -9,6 +9,7 @@
   "depreciation_method",
   "total_number_of_depreciations",
   "daily_prorata_based",
+  "shift_based",
   "column_break_5",
   "frequency_of_depreciation",
   "depreciation_start_date",
@@ -97,12 +98,19 @@
    "fieldname": "daily_prorata_based",
    "fieldtype": "Check",
    "label": "Depreciate based on daily pro-rata"
+  },
+  {
+   "default": "0",
+   "depends_on": "eval:doc.depreciation_method == \"Straight Line\"",
+   "fieldname": "shift_based",
+   "fieldtype": "Check",
+   "label": "Depreciate based on shifts"
   }
  ],
  "index_web_pages_for_search": 1,
  "istable": 1,
  "links": [],
- "modified": "2023-11-03 21:30:24.266601",
+ "modified": "2023-11-29 00:57:07.579777",
  "modified_by": "Administrator",
  "module": "Assets",
  "name": "Asset Finance Book",
diff --git a/erpnext/assets/doctype/asset_finance_book/asset_finance_book.py b/erpnext/assets/doctype/asset_finance_book/asset_finance_book.py
index 292ca13..f812a08 100644
--- a/erpnext/assets/doctype/asset_finance_book/asset_finance_book.py
+++ b/erpnext/assets/doctype/asset_finance_book/asset_finance_book.py
@@ -6,4 +6,30 @@
 
 
 class AssetFinanceBook(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
+
+		daily_prorata_based: DF.Check
+		depreciation_method: DF.Literal[
+			"", "Straight Line", "Double Declining Balance", "Written Down Value", "Manual"
+		]
+		depreciation_start_date: DF.Date | None
+		expected_value_after_useful_life: DF.Currency
+		finance_book: DF.Link | None
+		frequency_of_depreciation: DF.Int
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		rate_of_depreciation: DF.Percent
+		salvage_value_percentage: DF.Percent
+		shift_based: DF.Check
+		total_number_of_depreciations: DF.Int
+		value_after_depreciation: DF.Currency
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/assets/doctype/asset_maintenance/asset_maintenance.py b/erpnext/assets/doctype/asset_maintenance/asset_maintenance.py
index 125d4bf..063fe99 100644
--- a/erpnext/assets/doctype/asset_maintenance/asset_maintenance.py
+++ b/erpnext/assets/doctype/asset_maintenance/asset_maintenance.py
@@ -10,6 +10,29 @@
 
 
 class AssetMaintenance(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
+
+		from erpnext.assets.doctype.asset_maintenance_task.asset_maintenance_task import (
+			AssetMaintenanceTask,
+		)
+
+		asset_category: DF.ReadOnly | None
+		asset_maintenance_tasks: DF.Table[AssetMaintenanceTask]
+		asset_name: DF.Link
+		company: DF.Link
+		item_code: DF.ReadOnly | None
+		item_name: DF.ReadOnly | None
+		maintenance_manager: DF.Data | None
+		maintenance_manager_name: DF.ReadOnly | None
+		maintenance_team: DF.Link
+	# end: auto-generated types
+
 	def validate(self):
 		for task in self.get("asset_maintenance_tasks"):
 			if task.end_date and (getdate(task.start_date) >= getdate(task.end_date)):
diff --git a/erpnext/assets/doctype/asset_maintenance_log/asset_maintenance_log.py b/erpnext/assets/doctype/asset_maintenance_log/asset_maintenance_log.py
index ff791b2..009bcc3 100644
--- a/erpnext/assets/doctype/asset_maintenance_log/asset_maintenance_log.py
+++ b/erpnext/assets/doctype/asset_maintenance_log/asset_maintenance_log.py
@@ -11,6 +11,34 @@
 
 
 class AssetMaintenanceLog(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
+
+		actions_performed: DF.TextEditor | None
+		amended_from: DF.Link | None
+		asset_maintenance: DF.Link | None
+		asset_name: DF.ReadOnly | None
+		assign_to_name: DF.ReadOnly | None
+		certificate_attachement: DF.Attach | None
+		completion_date: DF.Date | None
+		description: DF.ReadOnly | None
+		due_date: DF.Date | None
+		has_certificate: DF.Check
+		item_code: DF.ReadOnly | None
+		item_name: DF.ReadOnly | None
+		maintenance_status: DF.Literal["Planned", "Completed", "Cancelled", "Overdue"]
+		maintenance_type: DF.ReadOnly | None
+		naming_series: DF.Literal["ACC-AML-.YYYY.-"]
+		periodicity: DF.Data | None
+		task: DF.Link | None
+		task_name: DF.Data | None
+	# end: auto-generated types
+
 	def validate(self):
 		if getdate(self.due_date) < getdate(nowdate()) and self.maintenance_status not in [
 			"Completed",
diff --git a/erpnext/assets/doctype/asset_maintenance_task/asset_maintenance_task.py b/erpnext/assets/doctype/asset_maintenance_task/asset_maintenance_task.py
index 1078208..f3a21b5 100644
--- a/erpnext/assets/doctype/asset_maintenance_task/asset_maintenance_task.py
+++ b/erpnext/assets/doctype/asset_maintenance_task/asset_maintenance_task.py
@@ -6,4 +6,31 @@
 
 
 class AssetMaintenanceTask(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
+
+		assign_to: DF.Link | None
+		assign_to_name: DF.ReadOnly | None
+		certificate_required: DF.Check
+		description: DF.TextEditor | None
+		end_date: DF.Date | None
+		last_completion_date: DF.Date | None
+		maintenance_status: DF.Literal["Planned", "Overdue", "Cancelled"]
+		maintenance_task: DF.Data
+		maintenance_type: DF.Literal["Preventive Maintenance", "Calibration"]
+		next_due_date: DF.Date | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		periodicity: DF.Literal[
+			"", "Daily", "Weekly", "Monthly", "Quarterly", "Half-yearly", "Yearly", "2 Yearly", "3 Yearly"
+		]
+		start_date: DF.Date
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/assets/doctype/asset_maintenance_team/asset_maintenance_team.py b/erpnext/assets/doctype/asset_maintenance_team/asset_maintenance_team.py
index 938c99b..b2219f0 100644
--- a/erpnext/assets/doctype/asset_maintenance_team/asset_maintenance_team.py
+++ b/erpnext/assets/doctype/asset_maintenance_team/asset_maintenance_team.py
@@ -6,4 +6,23 @@
 
 
 class AssetMaintenanceTeam(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
+
+		from erpnext.assets.doctype.maintenance_team_member.maintenance_team_member import (
+			MaintenanceTeamMember,
+		)
+
+		company: DF.Link
+		maintenance_manager: DF.Link | None
+		maintenance_manager_name: DF.ReadOnly | None
+		maintenance_team_members: DF.Table[MaintenanceTeamMember]
+		maintenance_team_name: DF.Data
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/assets/doctype/asset_movement/asset_movement.py b/erpnext/assets/doctype/asset_movement/asset_movement.py
index 620aad8..0d8efcb 100644
--- a/erpnext/assets/doctype/asset_movement/asset_movement.py
+++ b/erpnext/assets/doctype/asset_movement/asset_movement.py
@@ -11,6 +11,25 @@
 
 
 class AssetMovement(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
+
+		from erpnext.assets.doctype.asset_movement_item.asset_movement_item import AssetMovementItem
+
+		amended_from: DF.Link | None
+		assets: DF.Table[AssetMovementItem]
+		company: DF.Link
+		purpose: DF.Literal["", "Issue", "Receipt", "Transfer"]
+		reference_doctype: DF.Link | None
+		reference_name: DF.DynamicLink | None
+		transaction_date: DF.Datetime
+	# end: auto-generated types
+
 	def validate(self):
 		self.validate_asset()
 		self.validate_location()
diff --git a/erpnext/assets/doctype/asset_movement_item/asset_movement_item.py b/erpnext/assets/doctype/asset_movement_item/asset_movement_item.py
index e25226d..1a5302b 100644
--- a/erpnext/assets/doctype/asset_movement_item/asset_movement_item.py
+++ b/erpnext/assets/doctype/asset_movement_item/asset_movement_item.py
@@ -7,4 +7,24 @@
 
 
 class AssetMovementItem(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
+
+		asset: DF.Link
+		asset_name: DF.Data | None
+		company: DF.Link | None
+		from_employee: DF.Link | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		source_location: DF.Link | None
+		target_location: DF.Link | None
+		to_employee: DF.Link | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/assets/doctype/asset_repair/asset_repair.py b/erpnext/assets/doctype/asset_repair/asset_repair.py
index 9c2b8bc..c0fb3c2 100644
--- a/erpnext/assets/doctype/asset_repair/asset_repair.py
+++ b/erpnext/assets/doctype/asset_repair/asset_repair.py
@@ -17,6 +17,42 @@
 
 
 class AssetRepair(AccountsController):
+	# 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
+
+		from erpnext.assets.doctype.asset_repair_consumed_item.asset_repair_consumed_item import (
+			AssetRepairConsumedItem,
+		)
+
+		actions_performed: DF.LongText | None
+		amended_from: DF.Link | None
+		asset: DF.Link
+		asset_name: DF.ReadOnly | None
+		capitalize_repair_cost: DF.Check
+		company: DF.Link | None
+		completion_date: DF.Datetime | None
+		cost_center: DF.Link | None
+		description: DF.LongText | None
+		downtime: DF.Data | None
+		failure_date: DF.Datetime
+		increase_in_asset_life: DF.Int
+		naming_series: DF.Literal["ACC-ASR-.YYYY.-"]
+		project: DF.Link | None
+		purchase_invoice: DF.Link | None
+		repair_cost: DF.Currency
+		repair_status: DF.Literal["Pending", "Completed", "Cancelled"]
+		stock_consumption: DF.Check
+		stock_entry: DF.Link | None
+		stock_items: DF.Table[AssetRepairConsumedItem]
+		total_repair_cost: DF.Currency
+		warehouse: DF.Link | None
+	# end: auto-generated types
+
 	def validate(self):
 		self.asset_doc = frappe.get_doc("Asset", self.asset)
 		self.update_status()
diff --git a/erpnext/assets/doctype/asset_repair_consumed_item/asset_repair_consumed_item.py b/erpnext/assets/doctype/asset_repair_consumed_item/asset_repair_consumed_item.py
index 2a8d64e..ab43cfe 100644
--- a/erpnext/assets/doctype/asset_repair_consumed_item/asset_repair_consumed_item.py
+++ b/erpnext/assets/doctype/asset_repair_consumed_item/asset_repair_consumed_item.py
@@ -6,4 +6,23 @@
 
 
 class AssetRepairConsumedItem(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
+
+		consumed_quantity: DF.Data | None
+		item_code: DF.Link | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		serial_and_batch_bundle: DF.Link | None
+		serial_no: DF.SmallText | None
+		total_value: DF.Currency
+		valuation_rate: DF.Currency
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/accounts/doctype/unreconcile_payments/__init__.py b/erpnext/assets/doctype/asset_shift_allocation/__init__.py
similarity index 100%
copy from erpnext/accounts/doctype/unreconcile_payments/__init__.py
copy to erpnext/assets/doctype/asset_shift_allocation/__init__.py
diff --git a/erpnext/assets/doctype/asset_shift_allocation/asset_shift_allocation.js b/erpnext/assets/doctype/asset_shift_allocation/asset_shift_allocation.js
new file mode 100644
index 0000000..54df693
--- /dev/null
+++ b/erpnext/assets/doctype/asset_shift_allocation/asset_shift_allocation.js
@@ -0,0 +1,14 @@
+// Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+frappe.ui.form.on('Asset Shift Allocation', {
+	onload: function(frm) {
+		frm.events.make_schedules_editable(frm);
+	},
+
+	make_schedules_editable: function(frm) {
+		frm.toggle_enable("depreciation_schedule", true);
+		frm.fields_dict["depreciation_schedule"].grid.toggle_enable("schedule_date", false);
+		frm.fields_dict["depreciation_schedule"].grid.toggle_enable("depreciation_amount", false);
+		frm.fields_dict["depreciation_schedule"].grid.toggle_enable("shift", true);
+	}
+});
diff --git a/erpnext/assets/doctype/asset_shift_allocation/asset_shift_allocation.json b/erpnext/assets/doctype/asset_shift_allocation/asset_shift_allocation.json
new file mode 100644
index 0000000..89fa298
--- /dev/null
+++ b/erpnext/assets/doctype/asset_shift_allocation/asset_shift_allocation.json
@@ -0,0 +1,111 @@
+{
+ "actions": [],
+ "autoname": "naming_series:",
+ "creation": "2023-11-24 15:07:44.652133",
+ "doctype": "DocType",
+ "engine": "InnoDB",
+ "field_order": [
+  "section_break_esaa",
+  "asset",
+  "naming_series",
+  "column_break_tdae",
+  "finance_book",
+  "amended_from",
+  "depreciation_schedule_section",
+  "depreciation_schedule"
+ ],
+ "fields": [
+  {
+   "fieldname": "section_break_esaa",
+   "fieldtype": "Section Break"
+  },
+  {
+   "fieldname": "amended_from",
+   "fieldtype": "Link",
+   "label": "Amended From",
+   "no_copy": 1,
+   "options": "Asset Shift Allocation",
+   "print_hide": 1,
+   "read_only": 1,
+   "search_index": 1
+  },
+  {
+   "fieldname": "asset",
+   "fieldtype": "Link",
+   "in_list_view": 1,
+   "label": "Asset",
+   "options": "Asset",
+   "reqd": 1
+  },
+  {
+   "fieldname": "column_break_tdae",
+   "fieldtype": "Column Break"
+  },
+  {
+   "fieldname": "finance_book",
+   "fieldtype": "Link",
+   "label": "Finance Book",
+   "options": "Finance Book"
+  },
+  {
+   "depends_on": "eval:!doc.__islocal",
+   "fieldname": "depreciation_schedule_section",
+   "fieldtype": "Section Break",
+   "label": "Depreciation Schedule"
+  },
+  {
+   "fieldname": "depreciation_schedule",
+   "fieldtype": "Table",
+   "label": "Depreciation Schedule",
+   "options": "Depreciation Schedule"
+  },
+  {
+   "fieldname": "naming_series",
+   "fieldtype": "Select",
+   "label": "Naming Series",
+   "options": "ACC-ASA-.YYYY.-",
+   "reqd": 1
+  }
+ ],
+ "index_web_pages_for_search": 1,
+ "is_submittable": 1,
+ "links": [],
+ "modified": "2023-11-29 04:05:04.683518",
+ "modified_by": "Administrator",
+ "module": "Assets",
+ "name": "Asset Shift Allocation",
+ "naming_rule": "By \"Naming Series\" field",
+ "owner": "Administrator",
+ "permissions": [
+  {
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "System Manager",
+   "share": 1,
+   "write": 1
+  },
+  {
+   "amend": 1,
+   "cancel": 1,
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "Accounts User",
+   "share": 1,
+   "submit": 1,
+   "write": 1
+  }
+ ],
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "states": []
+}
\ No newline at end of file
diff --git a/erpnext/assets/doctype/asset_shift_allocation/asset_shift_allocation.py b/erpnext/assets/doctype/asset_shift_allocation/asset_shift_allocation.py
new file mode 100644
index 0000000..13915c7
--- /dev/null
+++ b/erpnext/assets/doctype/asset_shift_allocation/asset_shift_allocation.py
@@ -0,0 +1,281 @@
+# Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+import frappe
+from frappe import _
+from frappe.model.document import Document
+from frappe.utils import (
+	add_months,
+	cint,
+	flt,
+	get_last_day,
+	get_link_to_form,
+	is_last_day_of_the_month,
+)
+
+from erpnext.assets.doctype.asset_activity.asset_activity import add_asset_activity
+from erpnext.assets.doctype.asset_depreciation_schedule.asset_depreciation_schedule import (
+	get_asset_depr_schedule_doc,
+	get_asset_shift_factors_map,
+	get_temp_asset_depr_schedule_doc,
+)
+
+
+class AssetShiftAllocation(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
+
+		from erpnext.assets.doctype.depreciation_schedule.depreciation_schedule import (
+			DepreciationSchedule,
+		)
+
+		amended_from: DF.Link | None
+		asset: DF.Link
+		depreciation_schedule: DF.Table[DepreciationSchedule]
+		finance_book: DF.Link | None
+		naming_series: DF.Literal["ACC-ASA-.YYYY.-"]
+	# end: auto-generated types
+
+	def after_insert(self):
+		self.fetch_and_set_depr_schedule()
+
+	def validate(self):
+		self.asset_depr_schedule_doc = get_asset_depr_schedule_doc(
+			self.asset, "Active", self.finance_book
+		)
+
+		self.validate_invalid_shift_change()
+		self.update_depr_schedule()
+
+	def on_submit(self):
+		self.create_new_asset_depr_schedule()
+
+	def fetch_and_set_depr_schedule(self):
+		if self.asset_depr_schedule_doc:
+			if self.asset_depr_schedule_doc.shift_based:
+				for schedule in self.asset_depr_schedule_doc.get("depreciation_schedule"):
+					self.append(
+						"depreciation_schedule",
+						{
+							"schedule_date": schedule.schedule_date,
+							"depreciation_amount": schedule.depreciation_amount,
+							"accumulated_depreciation_amount": schedule.accumulated_depreciation_amount,
+							"journal_entry": schedule.journal_entry,
+							"shift": schedule.shift,
+						},
+					)
+
+				self.flags.ignore_validate = True
+				self.save()
+			else:
+				frappe.throw(
+					_(
+						"Asset Depreciation Schedule for Asset {0} and Finance Book {1} is not using shift based depreciation"
+					).format(self.asset, self.finance_book)
+				)
+		else:
+			frappe.throw(
+				_("Asset Depreciation Schedule not found for Asset {0} and Finance Book {1}").format(
+					self.asset, self.finance_book
+				)
+			)
+
+	def validate_invalid_shift_change(self):
+		if not self.get("depreciation_schedule") or self.docstatus == 1:
+			return
+
+		for i, sch in enumerate(self.depreciation_schedule):
+			if (
+				sch.journal_entry and self.asset_depr_schedule_doc.depreciation_schedule[i].shift != sch.shift
+			):
+				frappe.throw(
+					_(
+						"Row {0}: Shift cannot be changed since the depreciation has already been processed"
+					).format(i)
+				)
+
+	def update_depr_schedule(self):
+		if not self.get("depreciation_schedule") or self.docstatus == 1:
+			return
+
+		self.allocate_shift_diff_in_depr_schedule()
+
+		asset_doc = frappe.get_doc("Asset", self.asset)
+		fb_row = asset_doc.finance_books[self.asset_depr_schedule_doc.finance_book_id - 1]
+
+		asset_doc.flags.shift_allocation = True
+
+		temp_depr_schedule = get_temp_asset_depr_schedule_doc(
+			asset_doc, fb_row, new_depr_schedule=self.depreciation_schedule
+		).get("depreciation_schedule")
+
+		self.depreciation_schedule = []
+
+		for schedule in temp_depr_schedule:
+			self.append(
+				"depreciation_schedule",
+				{
+					"schedule_date": schedule.schedule_date,
+					"depreciation_amount": schedule.depreciation_amount,
+					"accumulated_depreciation_amount": schedule.accumulated_depreciation_amount,
+					"journal_entry": schedule.journal_entry,
+					"shift": schedule.shift,
+				},
+			)
+
+	def allocate_shift_diff_in_depr_schedule(self):
+		asset_shift_factors_map = get_asset_shift_factors_map()
+		reverse_asset_shift_factors_map = {
+			asset_shift_factors_map[k]: k for k in asset_shift_factors_map
+		}
+
+		original_shift_factors_sum = sum(
+			flt(asset_shift_factors_map.get(schedule.shift))
+			for schedule in self.asset_depr_schedule_doc.depreciation_schedule
+		)
+
+		new_shift_factors_sum = sum(
+			flt(asset_shift_factors_map.get(schedule.shift)) for schedule in self.depreciation_schedule
+		)
+
+		diff = new_shift_factors_sum - original_shift_factors_sum
+
+		if diff > 0:
+			for i, schedule in reversed(list(enumerate(self.depreciation_schedule))):
+				if diff <= 0:
+					break
+
+				shift_factor = flt(asset_shift_factors_map.get(schedule.shift))
+
+				if shift_factor <= diff:
+					self.depreciation_schedule.pop()
+					diff -= shift_factor
+				else:
+					try:
+						self.depreciation_schedule[i].shift = reverse_asset_shift_factors_map.get(
+							shift_factor - diff
+						)
+						diff = 0
+					except Exception:
+						frappe.throw(_("Could not auto update shifts. Shift with shift factor {0} needed.")).format(
+							shift_factor - diff
+						)
+		elif diff < 0:
+			shift_factors = list(asset_shift_factors_map.values())
+			desc_shift_factors = sorted(shift_factors, reverse=True)
+			depr_schedule_len_diff = self.asset_depr_schedule_doc.total_number_of_depreciations - len(
+				self.depreciation_schedule
+			)
+			subsets_result = []
+
+			if depr_schedule_len_diff > 0:
+				num_rows_to_add = depr_schedule_len_diff
+
+				while not subsets_result and num_rows_to_add > 0:
+					find_subsets_with_sum(shift_factors, num_rows_to_add, abs(diff), [], subsets_result)
+					if subsets_result:
+						break
+					num_rows_to_add -= 1
+
+				if subsets_result:
+					for i in range(num_rows_to_add):
+						schedule_date = add_months(
+							self.depreciation_schedule[-1].schedule_date,
+							cint(self.asset_depr_schedule_doc.frequency_of_depreciation),
+						)
+
+						if is_last_day_of_the_month(self.depreciation_schedule[-1].schedule_date):
+							schedule_date = get_last_day(schedule_date)
+
+						self.append(
+							"depreciation_schedule",
+							{
+								"schedule_date": schedule_date,
+								"shift": reverse_asset_shift_factors_map.get(subsets_result[0][i]),
+							},
+						)
+
+			if depr_schedule_len_diff <= 0 or not subsets_result:
+				for i, schedule in reversed(list(enumerate(self.depreciation_schedule))):
+					diff = abs(diff)
+
+					if diff <= 0:
+						break
+
+					shift_factor = flt(asset_shift_factors_map.get(schedule.shift))
+
+					if shift_factor <= diff:
+						for sf in desc_shift_factors:
+							if sf - shift_factor <= diff:
+								self.depreciation_schedule[i].shift = reverse_asset_shift_factors_map.get(sf)
+								diff -= sf - shift_factor
+								break
+					else:
+						try:
+							self.depreciation_schedule[i].shift = reverse_asset_shift_factors_map.get(
+								shift_factor + diff
+							)
+							diff = 0
+						except Exception:
+							frappe.throw(_("Could not auto update shifts. Shift with shift factor {0} needed.")).format(
+								shift_factor + diff
+							)
+
+	def create_new_asset_depr_schedule(self):
+		new_asset_depr_schedule_doc = frappe.copy_doc(self.asset_depr_schedule_doc)
+
+		new_asset_depr_schedule_doc.depreciation_schedule = []
+
+		for schedule in self.depreciation_schedule:
+			new_asset_depr_schedule_doc.append(
+				"depreciation_schedule",
+				{
+					"schedule_date": schedule.schedule_date,
+					"depreciation_amount": schedule.depreciation_amount,
+					"accumulated_depreciation_amount": schedule.accumulated_depreciation_amount,
+					"journal_entry": schedule.journal_entry,
+					"shift": schedule.shift,
+				},
+			)
+
+		notes = _(
+			"This schedule was created when Asset {0}'s shifts were adjusted through Asset Shift Allocation {1}."
+		).format(
+			get_link_to_form("Asset", self.asset),
+			get_link_to_form(self.doctype, self.name),
+		)
+
+		new_asset_depr_schedule_doc.notes = notes
+
+		self.asset_depr_schedule_doc.flags.should_not_cancel_depreciation_entries = True
+		self.asset_depr_schedule_doc.cancel()
+
+		new_asset_depr_schedule_doc.submit()
+
+		add_asset_activity(
+			self.asset,
+			_("Asset's depreciation schedule updated after Asset Shift Allocation {0}").format(
+				get_link_to_form(self.doctype, self.name)
+			),
+		)
+
+
+def find_subsets_with_sum(numbers, k, target_sum, current_subset, result):
+	if k == 0 and target_sum == 0:
+		result.append(current_subset.copy())
+		return
+	if k <= 0 or target_sum <= 0 or not numbers:
+		return
+
+	# Include the current number in the subset
+	find_subsets_with_sum(
+		numbers, k - 1, target_sum - numbers[0], current_subset + [numbers[0]], result
+	)
+
+	# Exclude the current number from the subset
+	find_subsets_with_sum(numbers[1:], k, target_sum, current_subset, result)
diff --git a/erpnext/assets/doctype/asset_shift_allocation/test_asset_shift_allocation.py b/erpnext/assets/doctype/asset_shift_allocation/test_asset_shift_allocation.py
new file mode 100644
index 0000000..8d00a24
--- /dev/null
+++ b/erpnext/assets/doctype/asset_shift_allocation/test_asset_shift_allocation.py
@@ -0,0 +1,113 @@
+# Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+
+import frappe
+from frappe.tests.utils import FrappeTestCase
+from frappe.utils import cstr
+
+from erpnext.assets.doctype.asset.test_asset import create_asset
+from erpnext.assets.doctype.asset_depreciation_schedule.asset_depreciation_schedule import (
+	get_depr_schedule,
+)
+
+
+class TestAssetShiftAllocation(FrappeTestCase):
+	@classmethod
+	def setUpClass(cls):
+		create_asset_shift_factors()
+
+	@classmethod
+	def tearDownClass(cls):
+		frappe.db.rollback()
+
+	def test_asset_shift_allocation(self):
+		asset = create_asset(
+			calculate_depreciation=1,
+			available_for_use_date="2023-01-01",
+			purchase_date="2023-01-01",
+			gross_purchase_amount=120000,
+			depreciation_start_date="2023-01-31",
+			total_number_of_depreciations=12,
+			frequency_of_depreciation=1,
+			shift_based=1,
+			submit=1,
+		)
+
+		expected_schedules = [
+			["2023-01-31", 10000.0, 10000.0, "Single"],
+			["2023-02-28", 10000.0, 20000.0, "Single"],
+			["2023-03-31", 10000.0, 30000.0, "Single"],
+			["2023-04-30", 10000.0, 40000.0, "Single"],
+			["2023-05-31", 10000.0, 50000.0, "Single"],
+			["2023-06-30", 10000.0, 60000.0, "Single"],
+			["2023-07-31", 10000.0, 70000.0, "Single"],
+			["2023-08-31", 10000.0, 80000.0, "Single"],
+			["2023-09-30", 10000.0, 90000.0, "Single"],
+			["2023-10-31", 10000.0, 100000.0, "Single"],
+			["2023-11-30", 10000.0, 110000.0, "Single"],
+			["2023-12-31", 10000.0, 120000.0, "Single"],
+		]
+
+		schedules = [
+			[cstr(d.schedule_date), d.depreciation_amount, d.accumulated_depreciation_amount, d.shift]
+			for d in get_depr_schedule(asset.name, "Active")
+		]
+
+		self.assertEqual(schedules, expected_schedules)
+
+		asset_shift_allocation = frappe.get_doc(
+			{"doctype": "Asset Shift Allocation", "asset": asset.name}
+		).insert()
+
+		schedules = [
+			[cstr(d.schedule_date), d.depreciation_amount, d.accumulated_depreciation_amount, d.shift]
+			for d in asset_shift_allocation.get("depreciation_schedule")
+		]
+
+		self.assertEqual(schedules, expected_schedules)
+
+		asset_shift_allocation = frappe.get_doc("Asset Shift Allocation", asset_shift_allocation.name)
+		asset_shift_allocation.depreciation_schedule[4].shift = "Triple"
+		asset_shift_allocation.save()
+
+		schedules = [
+			[cstr(d.schedule_date), d.depreciation_amount, d.accumulated_depreciation_amount, d.shift]
+			for d in asset_shift_allocation.get("depreciation_schedule")
+		]
+
+		expected_schedules = [
+			["2023-01-31", 10000.0, 10000.0, "Single"],
+			["2023-02-28", 10000.0, 20000.0, "Single"],
+			["2023-03-31", 10000.0, 30000.0, "Single"],
+			["2023-04-30", 10000.0, 40000.0, "Single"],
+			["2023-05-31", 20000.0, 60000.0, "Triple"],
+			["2023-06-30", 10000.0, 70000.0, "Single"],
+			["2023-07-31", 10000.0, 80000.0, "Single"],
+			["2023-08-31", 10000.0, 90000.0, "Single"],
+			["2023-09-30", 10000.0, 100000.0, "Single"],
+			["2023-10-31", 10000.0, 110000.0, "Single"],
+			["2023-11-30", 10000.0, 120000.0, "Single"],
+		]
+
+		self.assertEqual(schedules, expected_schedules)
+
+		asset_shift_allocation.submit()
+
+		schedules = [
+			[cstr(d.schedule_date), d.depreciation_amount, d.accumulated_depreciation_amount, d.shift]
+			for d in get_depr_schedule(asset.name, "Active")
+		]
+
+		self.assertEqual(schedules, expected_schedules)
+
+
+def create_asset_shift_factors():
+	shifts = [
+		{"doctype": "Asset Shift Factor", "shift_name": "Half", "shift_factor": 0.5, "default": 0},
+		{"doctype": "Asset Shift Factor", "shift_name": "Single", "shift_factor": 1, "default": 1},
+		{"doctype": "Asset Shift Factor", "shift_name": "Double", "shift_factor": 1.5, "default": 0},
+		{"doctype": "Asset Shift Factor", "shift_name": "Triple", "shift_factor": 2, "default": 0},
+	]
+
+	for s in shifts:
+		frappe.get_doc(s).insert()
diff --git a/erpnext/accounts/doctype/unreconcile_payments/__init__.py b/erpnext/assets/doctype/asset_shift_factor/__init__.py
similarity index 100%
copy from erpnext/accounts/doctype/unreconcile_payments/__init__.py
copy to erpnext/assets/doctype/asset_shift_factor/__init__.py
diff --git a/erpnext/assets/doctype/asset_shift_factor/asset_shift_factor.js b/erpnext/assets/doctype/asset_shift_factor/asset_shift_factor.js
new file mode 100644
index 0000000..88887fe
--- /dev/null
+++ b/erpnext/assets/doctype/asset_shift_factor/asset_shift_factor.js
@@ -0,0 +1,8 @@
+// Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+// frappe.ui.form.on("Asset Shift Factor", {
+// 	refresh(frm) {
+
+// 	},
+// });
diff --git a/erpnext/assets/doctype/asset_shift_factor/asset_shift_factor.json b/erpnext/assets/doctype/asset_shift_factor/asset_shift_factor.json
new file mode 100644
index 0000000..fd04ffc
--- /dev/null
+++ b/erpnext/assets/doctype/asset_shift_factor/asset_shift_factor.json
@@ -0,0 +1,74 @@
+{
+ "actions": [],
+ "allow_rename": 1,
+ "autoname": "field:shift_name",
+ "creation": "2023-11-27 18:16:03.980086",
+ "doctype": "DocType",
+ "engine": "InnoDB",
+ "field_order": [
+  "shift_name",
+  "shift_factor",
+  "default"
+ ],
+ "fields": [
+  {
+   "fieldname": "shift_name",
+   "fieldtype": "Data",
+   "in_list_view": 1,
+   "label": "Shift Name",
+   "reqd": 1,
+   "unique": 1
+  },
+  {
+   "fieldname": "shift_factor",
+   "fieldtype": "Float",
+   "in_list_view": 1,
+   "label": "Shift Factor",
+   "reqd": 1
+  },
+  {
+   "default": "0",
+   "fieldname": "default",
+   "fieldtype": "Check",
+   "in_list_view": 1,
+   "label": "Default"
+  }
+ ],
+ "index_web_pages_for_search": 1,
+ "links": [],
+ "modified": "2023-11-29 04:04:24.272872",
+ "modified_by": "Administrator",
+ "module": "Assets",
+ "name": "Asset Shift Factor",
+ "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
+  },
+  {
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "Accounts User",
+   "share": 1,
+   "write": 1
+  }
+ ],
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "states": []
+}
\ No newline at end of file
diff --git a/erpnext/assets/doctype/asset_shift_factor/asset_shift_factor.py b/erpnext/assets/doctype/asset_shift_factor/asset_shift_factor.py
new file mode 100644
index 0000000..365a817
--- /dev/null
+++ b/erpnext/assets/doctype/asset_shift_factor/asset_shift_factor.py
@@ -0,0 +1,37 @@
+# Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+import frappe
+from frappe import _
+from frappe.model.document import Document
+
+
+class AssetShiftFactor(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
+
+		default: DF.Check
+		shift_factor: DF.Float
+		shift_name: DF.Data
+	# end: auto-generated types
+
+	def validate(self):
+		self.validate_default()
+
+	def validate_default(self):
+		if self.default:
+			existing_default_shift_factor = frappe.db.get_value(
+				"Asset Shift Factor", {"default": 1}, "name"
+			)
+
+			if existing_default_shift_factor:
+				frappe.throw(
+					_("Asset Shift Factor {0} is set as default currently. Please change it first.").format(
+						frappe.bold(existing_default_shift_factor)
+					)
+				)
diff --git a/erpnext/assets/doctype/asset_shift_factor/test_asset_shift_factor.py b/erpnext/assets/doctype/asset_shift_factor/test_asset_shift_factor.py
new file mode 100644
index 0000000..7507367
--- /dev/null
+++ b/erpnext/assets/doctype/asset_shift_factor/test_asset_shift_factor.py
@@ -0,0 +1,9 @@
+# Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+
+# import frappe
+from frappe.tests.utils import FrappeTestCase
+
+
+class TestAssetShiftFactor(FrappeTestCase):
+	pass
diff --git a/erpnext/assets/doctype/asset_value_adjustment/asset_value_adjustment.py b/erpnext/assets/doctype/asset_value_adjustment/asset_value_adjustment.py
index 9be7243..769571c 100644
--- a/erpnext/assets/doctype/asset_value_adjustment/asset_value_adjustment.py
+++ b/erpnext/assets/doctype/asset_value_adjustment/asset_value_adjustment.py
@@ -19,6 +19,27 @@
 
 
 class AssetValueAdjustment(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
+
+		amended_from: DF.Link | None
+		asset: DF.Link
+		asset_category: DF.ReadOnly | None
+		company: DF.Link | None
+		cost_center: DF.Link | None
+		current_asset_value: DF.Currency
+		date: DF.Date
+		difference_amount: DF.Currency
+		finance_book: DF.Link | None
+		journal_entry: DF.Link | None
+		new_asset_value: DF.Currency
+	# end: auto-generated types
+
 	def validate(self):
 		self.validate_date()
 		self.set_current_asset_value()
diff --git a/erpnext/assets/doctype/asset_value_adjustment/test_asset_value_adjustment.py b/erpnext/assets/doctype/asset_value_adjustment/test_asset_value_adjustment.py
index 5d49759..2c97bae 100644
--- a/erpnext/assets/doctype/asset_value_adjustment/test_asset_value_adjustment.py
+++ b/erpnext/assets/doctype/asset_value_adjustment/test_asset_value_adjustment.py
@@ -18,6 +18,9 @@
 class TestAssetValueAdjustment(unittest.TestCase):
 	def setUp(self):
 		create_asset_data()
+		frappe.db.set_value(
+			"Company", "_Test Company", "capital_work_in_progress_account", "CWIP Account - _TC"
+		)
 
 	def test_current_asset_value(self):
 		pr = make_purchase_receipt(
diff --git a/erpnext/assets/doctype/depreciation_schedule/depreciation_schedule.json b/erpnext/assets/doctype/depreciation_schedule/depreciation_schedule.json
index 884e0c6..ef706e8 100644
--- a/erpnext/assets/doctype/depreciation_schedule/depreciation_schedule.json
+++ b/erpnext/assets/doctype/depreciation_schedule/depreciation_schedule.json
@@ -12,6 +12,7 @@
   "column_break_3",
   "accumulated_depreciation_amount",
   "journal_entry",
+  "shift",
   "make_depreciation_entry"
  ],
  "fields": [
@@ -57,11 +58,17 @@
    "fieldname": "make_depreciation_entry",
    "fieldtype": "Button",
    "label": "Make Depreciation Entry"
+  },
+  {
+   "fieldname": "shift",
+   "fieldtype": "Link",
+   "label": "Shift",
+   "options": "Asset Shift Factor"
   }
  ],
  "istable": 1,
  "links": [],
- "modified": "2023-07-26 12:56:48.718736",
+ "modified": "2023-11-27 18:28:35.325376",
  "modified_by": "Administrator",
  "module": "Assets",
  "name": "Depreciation Schedule",
diff --git a/erpnext/assets/doctype/depreciation_schedule/depreciation_schedule.py b/erpnext/assets/doctype/depreciation_schedule/depreciation_schedule.py
index b597c58..41aade6 100644
--- a/erpnext/assets/doctype/depreciation_schedule/depreciation_schedule.py
+++ b/erpnext/assets/doctype/depreciation_schedule/depreciation_schedule.py
@@ -6,4 +6,22 @@
 
 
 class DepreciationSchedule(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
+
+		accumulated_depreciation_amount: DF.Currency
+		depreciation_amount: DF.Currency
+		journal_entry: DF.Link | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		schedule_date: DF.Date
+		shift: DF.Link | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/assets/doctype/linked_location/linked_location.py b/erpnext/assets/doctype/linked_location/linked_location.py
index e1257f3..35e6d8b 100644
--- a/erpnext/assets/doctype/linked_location/linked_location.py
+++ b/erpnext/assets/doctype/linked_location/linked_location.py
@@ -6,4 +6,18 @@
 
 
 class LinkedLocation(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
+
+		location: DF.Link
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/assets/doctype/location/location.py b/erpnext/assets/doctype/location/location.py
index 5bff3dd..01228f4 100644
--- a/erpnext/assets/doctype/location/location.py
+++ b/erpnext/assets/doctype/location/location.py
@@ -13,6 +13,27 @@
 
 
 class Location(NestedSet):
+	# 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
+
+		area: DF.Float
+		area_uom: DF.Link | None
+		is_container: DF.Check
+		is_group: DF.Check
+		latitude: DF.Float
+		lft: DF.Int
+		location_name: DF.Data
+		longitude: DF.Float
+		old_parent: DF.Data | None
+		parent_location: DF.Link | None
+		rgt: DF.Int
+	# end: auto-generated types
+
 	nsm_parent_field = "parent_location"
 
 	def validate(self):
diff --git a/erpnext/assets/doctype/maintenance_team_member/maintenance_team_member.py b/erpnext/assets/doctype/maintenance_team_member/maintenance_team_member.py
index c3ede94..80a6a56 100644
--- a/erpnext/assets/doctype/maintenance_team_member/maintenance_team_member.py
+++ b/erpnext/assets/doctype/maintenance_team_member/maintenance_team_member.py
@@ -6,4 +6,20 @@
 
 
 class MaintenanceTeamMember(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
+
+		full_name: DF.Data | None
+		maintenance_role: DF.Link
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		team_member: DF.Link
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/bulk_transaction/doctype/bulk_transaction_log/bulk_transaction_log.js b/erpnext/bulk_transaction/doctype/bulk_transaction_log/bulk_transaction_log.js
index 0073170..dc54d60 100644
--- a/erpnext/bulk_transaction/doctype/bulk_transaction_log/bulk_transaction_log.js
+++ b/erpnext/bulk_transaction/doctype/bulk_transaction_log/bulk_transaction_log.js
@@ -1,30 +1,21 @@
-// Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and contributors
+// Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and contributors
 // For license information, please see license.txt
 
-frappe.ui.form.on('Bulk Transaction Log', {
-
-	refresh: function(frm) {
-		frm.disable_save();
-		frm.add_custom_button(__('Retry Failed Transactions'), ()=>{
-			frappe.confirm(__("Retry Failing Transactions ?"), ()=>{
-				query(frm, 1);
-			}
-			);
-		});
-	}
+frappe.ui.form.on("Bulk Transaction Log", {
+	refresh(frm) {
+		frm.add_custom_button(__('Succeeded Entries'), function() {
+			frappe.set_route('List', 'Bulk Transaction Log Detail', {'date': frm.doc.date, 'transaction_status': "Success"});
+		}, __("View"));
+		frm.add_custom_button(__('Failed Entries'), function() {
+			frappe.set_route('List', 'Bulk Transaction Log Detail', {'date': frm.doc.date, 'transaction_status': "Failed"});
+		}, __("View"));
+		if (frm.doc.failed) {
+			frm.add_custom_button(__('Retry Failed Transactions'), function() {
+				frappe.call({
+					method: "erpnext.utilities.bulk_transaction.retry",
+					args: {date: frm.doc.date}
+				});
+			});
+		}
+	},
 });
-
-function query(frm) {
-	frappe.call({
-		method: "erpnext.bulk_transaction.doctype.bulk_transaction_log.bulk_transaction_log.retry_failing_transaction",
-		args: {
-			log_date: frm.doc.log_date
-		}
-	}).then((r) => {
-		if (r.message === "No Failed Records") {
-			frappe.show_alert(__(r.message), 5);
-		} else {
-			frappe.show_alert(__("Retrying Failed Transactions"), 5);
-		}
-	});
-}
\ No newline at end of file
diff --git a/erpnext/bulk_transaction/doctype/bulk_transaction_log/bulk_transaction_log.json b/erpnext/bulk_transaction/doctype/bulk_transaction_log/bulk_transaction_log.json
index da42cf1..75cb358 100644
--- a/erpnext/bulk_transaction/doctype/bulk_transaction_log/bulk_transaction_log.json
+++ b/erpnext/bulk_transaction/doctype/bulk_transaction_log/bulk_transaction_log.json
@@ -1,31 +1,64 @@
 {
  "actions": [],
- "allow_rename": 1,
- "creation": "2021-11-30 13:41:16.343827",
+ "allow_copy": 1,
+ "creation": "2023-11-09 20:14:45.139593",
+ "default_view": "List",
  "doctype": "DocType",
- "editable_grid": 1,
  "engine": "InnoDB",
  "field_order": [
-  "log_date",
-  "logger_data"
+  "date",
+  "column_break_bsan",
+  "log_entries",
+  "section_break_mdmv",
+  "succeeded",
+  "column_break_qryp",
+  "failed"
  ],
  "fields": [
   {
-   "fieldname": "log_date",
+   "fieldname": "date",
    "fieldtype": "Date",
-   "label": "Log Date",
+   "in_list_view": 1,
+   "in_standard_filter": 1,
+   "label": "Date",
    "read_only": 1
   },
   {
-   "fieldname": "logger_data",
-   "fieldtype": "Table",
-   "label": "Logger Data",
-   "options": "Bulk Transaction Log Detail"
+   "fieldname": "log_entries",
+   "fieldtype": "Int",
+   "in_list_view": 1,
+   "label": "Log Entries",
+   "read_only": 1
+  },
+  {
+   "fieldname": "column_break_bsan",
+   "fieldtype": "Column Break"
+  },
+  {
+   "fieldname": "section_break_mdmv",
+   "fieldtype": "Section Break"
+  },
+  {
+   "fieldname": "succeeded",
+   "fieldtype": "Int",
+   "label": "Succeeded",
+   "read_only": 1
+  },
+  {
+   "fieldname": "column_break_qryp",
+   "fieldtype": "Column Break"
+  },
+  {
+   "fieldname": "failed",
+   "fieldtype": "Int",
+   "label": "Failed",
+   "read_only": 1
   }
  ],
- "index_web_pages_for_search": 1,
+ "in_create": 1,
+ "is_virtual": 1,
  "links": [],
- "modified": "2022-02-03 17:23:02.935325",
+ "modified": "2023-11-11 04:52:49.347376",
  "modified_by": "Administrator",
  "module": "Bulk Transaction",
  "name": "Bulk Transaction Log",
@@ -47,5 +80,5 @@
  "sort_field": "modified",
  "sort_order": "DESC",
  "states": [],
- "track_changes": 1
+ "title_field": "date"
 }
\ No newline at end of file
diff --git a/erpnext/bulk_transaction/doctype/bulk_transaction_log/bulk_transaction_log.py b/erpnext/bulk_transaction/doctype/bulk_transaction_log/bulk_transaction_log.py
index 0596be4..2733d07 100644
--- a/erpnext/bulk_transaction/doctype/bulk_transaction_log/bulk_transaction_log.py
+++ b/erpnext/bulk_transaction/doctype/bulk_transaction_log/bulk_transaction_log.py
@@ -1,67 +1,126 @@
-# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and contributors
+# Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and contributors
 # For license information, please see license.txt
 
-from datetime import date
-
 import frappe
+from frappe import qb
 from frappe.model.document import Document
-
-from erpnext.utilities.bulk_transaction import task, update_logger
+from frappe.query_builder.functions import Count
+from frappe.utils import cint
+from pypika import Order
 
 
 class BulkTransactionLog(Document):
-	pass
+	# begin: auto-generated types
+	# This code is auto-generated. Do not modify anything in this block.
 
+	from typing import TYPE_CHECKING
 
-@frappe.whitelist()
-def retry_failing_transaction(log_date=None):
-	if not log_date:
-		log_date = str(date.today())
-	btp = frappe.qb.DocType("Bulk Transaction Log Detail")
-	data = (
-		frappe.qb.from_(btp)
-		.select(btp.transaction_name, btp.from_doctype, btp.to_doctype)
-		.distinct()
-		.where(btp.retried != 1)
-		.where(btp.transaction_status == "Failed")
-		.where(btp.date == log_date)
-	).run(as_dict=True)
+	if TYPE_CHECKING:
+		from frappe.types import DF
 
-	if data:
-		if len(data) > 10:
-			frappe.enqueue(job, queue="long", job_name="bulk_retry", data=data, log_date=log_date)
-		else:
-			job(data, log_date)
-	else:
-		return "No Failed Records"
+		date: DF.Date | None
+		failed: DF.Int
+		log_entries: DF.Int
+		succeeded: DF.Int
+	# end: auto-generated types
 
+	def db_insert(self, *args, **kwargs):
+		pass
 
-def job(data, log_date):
-	for d in data:
-		failed = []
-		try:
-			frappe.db.savepoint("before_creation_of_record")
-			task(d.transaction_name, d.from_doctype, d.to_doctype)
-		except Exception as e:
-			frappe.db.rollback(save_point="before_creation_of_record")
-			failed.append(e)
-			update_logger(
-				d.transaction_name,
-				e,
-				d.from_doctype,
-				d.to_doctype,
-				status="Failed",
-				log_date=log_date,
-				restarted=1,
+	def load_from_db(self):
+		log_detail = qb.DocType("Bulk Transaction Log Detail")
+
+		has_records = frappe.db.sql(
+			f"select exists (select * from `tabBulk Transaction Log Detail` where date = '{self.name}');"
+		)[0][0]
+		if not has_records:
+			raise frappe.DoesNotExistError
+
+		succeeded_logs = (
+			qb.from_(log_detail)
+			.select(Count(log_detail.date).as_("count"))
+			.where((log_detail.date == self.name) & (log_detail.transaction_status == "Success"))
+			.run()
+		)[0][0] or 0
+		failed_logs = (
+			qb.from_(log_detail)
+			.select(Count(log_detail.date).as_("count"))
+			.where((log_detail.date == self.name) & (log_detail.transaction_status == "Failed"))
+			.run()
+		)[0][0] or 0
+		total_logs = succeeded_logs + failed_logs
+		transaction_log = frappe._dict(
+			{
+				"date": self.name,
+				"count": total_logs,
+				"succeeded": succeeded_logs,
+				"failed": failed_logs,
+			}
+		)
+		super(Document, self).__init__(serialize_transaction_log(transaction_log))
+
+	@staticmethod
+	def get_list(args):
+		filter_date = parse_list_filters(args)
+		limit = cint(args.get("page_length")) or 20
+		log_detail = qb.DocType("Bulk Transaction Log Detail")
+
+		dates_query = (
+			qb.from_(log_detail)
+			.select(log_detail.date)
+			.distinct()
+			.orderby(log_detail.date, order=Order.desc)
+			.limit(limit)
+		)
+		if filter_date:
+			dates_query = dates_query.where(log_detail.date == filter_date)
+		dates = dates_query.run()
+
+		transaction_logs = []
+		if dates:
+			transaction_logs_query = (
+				qb.from_(log_detail)
+				.select(log_detail.date.as_("date"), Count(log_detail.date).as_("count"))
+				.where(log_detail.date.isin(dates))
+				.orderby(log_detail.date, order=Order.desc)
+				.groupby(log_detail.date)
+				.limit(limit)
 			)
+			transaction_logs = transaction_logs_query.run(as_dict=True)
 
-		if not failed:
-			update_logger(
-				d.transaction_name,
-				None,
-				d.from_doctype,
-				d.to_doctype,
-				status="Success",
-				log_date=log_date,
-				restarted=1,
-			)
+		return [serialize_transaction_log(x) for x in transaction_logs]
+
+	@staticmethod
+	def get_count(args):
+		pass
+
+	@staticmethod
+	def get_stats(args):
+		pass
+
+	def db_update(self, *args, **kwargs):
+		pass
+
+	def delete(self):
+		pass
+
+
+def serialize_transaction_log(data):
+	return frappe._dict(
+		name=data.date,
+		date=data.date,
+		log_entries=data.count,
+		succeeded=data.succeeded,
+		failed=data.failed,
+	)
+
+
+def parse_list_filters(args):
+	# parse date filter
+	filter_date = None
+	for fil in args.get("filters"):
+		if isinstance(fil, list):
+			for elem in fil:
+				if elem == "date":
+					filter_date = fil[3]
+	return filter_date
diff --git a/erpnext/bulk_transaction/doctype/bulk_transaction_log/test_bulk_transaction_log.py b/erpnext/bulk_transaction/doctype/bulk_transaction_log/test_bulk_transaction_log.py
index c673be8..01bb615 100644
--- a/erpnext/bulk_transaction/doctype/bulk_transaction_log/test_bulk_transaction_log.py
+++ b/erpnext/bulk_transaction/doctype/bulk_transaction_log/test_bulk_transaction_log.py
@@ -1,79 +1,9 @@
-# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors
+# Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and Contributors
 # See license.txt
 
-import unittest
-from datetime import date
-
-import frappe
-
-from erpnext.utilities.bulk_transaction import transaction_processing
+# import frappe
+from frappe.tests.utils import FrappeTestCase
 
 
-class TestBulkTransactionLog(unittest.TestCase):
-	def setUp(self):
-		create_company()
-		create_customer()
-		create_item()
-
-	def test_entry_in_log(self):
-		so_name = create_so()
-		transaction_processing([{"name": so_name}], "Sales Order", "Sales Invoice")
-		doc = frappe.get_doc("Bulk Transaction Log", str(date.today()))
-		for d in doc.get("logger_data"):
-			if d.transaction_name == so_name:
-				self.assertEqual(d.transaction_name, so_name)
-				self.assertEqual(d.transaction_status, "Success")
-				self.assertEqual(d.from_doctype, "Sales Order")
-				self.assertEqual(d.to_doctype, "Sales Invoice")
-				self.assertEqual(d.retried, 0)
-
-
-def create_company():
-	if not frappe.db.exists("Company", "_Test Company"):
-		frappe.get_doc(
-			{
-				"doctype": "Company",
-				"company_name": "_Test Company",
-				"country": "India",
-				"default_currency": "INR",
-			}
-		).insert()
-
-
-def create_customer():
-	if not frappe.db.exists("Customer", "Bulk Customer"):
-		frappe.get_doc({"doctype": "Customer", "customer_name": "Bulk Customer"}).insert()
-
-
-def create_item():
-	if not frappe.db.exists("Item", "MK"):
-		frappe.get_doc(
-			{
-				"doctype": "Item",
-				"item_code": "MK",
-				"item_name": "Milk",
-				"description": "Milk",
-				"item_group": "Products",
-			}
-		).insert()
-
-
-def create_so(intent=None):
-	so = frappe.new_doc("Sales Order")
-	so.customer = "Bulk Customer"
-	so.company = "_Test Company"
-	so.transaction_date = date.today()
-
-	so.set_warehouse = "Finished Goods - _TC"
-	so.append(
-		"items",
-		{
-			"item_code": "MK",
-			"delivery_date": date.today(),
-			"qty": 10,
-			"rate": 80,
-		},
-	)
-	so.insert()
-	so.submit()
-	return so.name
+class TestBulkTransactionLog(FrappeTestCase):
+	pass
diff --git a/erpnext/bulk_transaction/doctype/bulk_transaction_log_detail/bulk_transaction_log_detail.js b/erpnext/bulk_transaction/doctype/bulk_transaction_log_detail/bulk_transaction_log_detail.js
new file mode 100644
index 0000000..5669601
--- /dev/null
+++ b/erpnext/bulk_transaction/doctype/bulk_transaction_log_detail/bulk_transaction_log_detail.js
@@ -0,0 +1,8 @@
+// Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+// frappe.ui.form.on("Bulk Transaction Log Detail", {
+// 	refresh(frm) {
+
+// 	},
+// });
diff --git a/erpnext/bulk_transaction/doctype/bulk_transaction_log_detail/bulk_transaction_log_detail.json b/erpnext/bulk_transaction/doctype/bulk_transaction_log_detail/bulk_transaction_log_detail.json
index 8262caa..9590325 100644
--- a/erpnext/bulk_transaction/doctype/bulk_transaction_log_detail/bulk_transaction_log_detail.json
+++ b/erpnext/bulk_transaction/doctype/bulk_transaction_log_detail/bulk_transaction_log_detail.json
@@ -6,12 +6,12 @@
  "editable_grid": 1,
  "engine": "InnoDB",
  "field_order": [
+  "from_doctype",
   "transaction_name",
   "date",
   "time",
   "transaction_status",
   "error_description",
-  "from_doctype",
   "to_doctype",
   "retried"
  ],
@@ -20,8 +20,11 @@
    "fieldname": "transaction_name",
    "fieldtype": "Dynamic Link",
    "in_list_view": 1,
+   "in_standard_filter": 1,
    "label": "Name",
-   "options": "from_doctype"
+   "options": "from_doctype",
+   "read_only": 1,
+   "search_index": 1
   },
   {
    "fieldname": "transaction_status",
@@ -39,9 +42,11 @@
   {
    "fieldname": "from_doctype",
    "fieldtype": "Link",
+   "in_standard_filter": 1,
    "label": "From Doctype",
    "options": "DocType",
-   "read_only": 1
+   "read_only": 1,
+   "search_index": 1
   },
   {
    "fieldname": "to_doctype",
@@ -54,8 +59,10 @@
    "fieldname": "date",
    "fieldtype": "Date",
    "in_list_view": 1,
+   "in_standard_filter": 1,
    "label": "Date ",
-   "read_only": 1
+   "read_only": 1,
+   "search_index": 1
   },
   {
    "fieldname": "time",
@@ -66,19 +73,33 @@
   {
    "fieldname": "retried",
    "fieldtype": "Int",
+   "in_list_view": 1,
    "label": "Retried",
    "read_only": 1
   }
  ],
+ "in_create": 1,
  "index_web_pages_for_search": 1,
- "istable": 1,
  "links": [],
- "modified": "2022-02-03 19:57:31.650359",
+ "modified": "2023-11-10 11:44:10.758342",
  "modified_by": "Administrator",
  "module": "Bulk Transaction",
  "name": "Bulk Transaction Log Detail",
  "owner": "Administrator",
- "permissions": [],
+ "permissions": [
+  {
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "System Manager",
+   "share": 1,
+   "write": 1
+  }
+ ],
  "sort_field": "modified",
  "sort_order": "DESC",
  "states": [],
diff --git a/erpnext/bulk_transaction/doctype/bulk_transaction_log_detail/bulk_transaction_log_detail.py b/erpnext/bulk_transaction/doctype/bulk_transaction_log_detail/bulk_transaction_log_detail.py
index 67795b9..9b8e170 100644
--- a/erpnext/bulk_transaction/doctype/bulk_transaction_log_detail/bulk_transaction_log_detail.py
+++ b/erpnext/bulk_transaction/doctype/bulk_transaction_log_detail/bulk_transaction_log_detail.py
@@ -6,4 +6,22 @@
 
 
 class BulkTransactionLogDetail(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
+
+		date: DF.Date | None
+		error_description: DF.LongText | None
+		from_doctype: DF.Link | None
+		retried: DF.Int
+		time: DF.Time | None
+		to_doctype: DF.Link | None
+		transaction_name: DF.DynamicLink | None
+		transaction_status: DF.Data | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/bulk_transaction/doctype/bulk_transaction_log_detail/test_bulk_transaction_log_detail.py b/erpnext/bulk_transaction/doctype/bulk_transaction_log_detail/test_bulk_transaction_log_detail.py
new file mode 100644
index 0000000..5217b60
--- /dev/null
+++ b/erpnext/bulk_transaction/doctype/bulk_transaction_log_detail/test_bulk_transaction_log_detail.py
@@ -0,0 +1,9 @@
+# Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+
+# import frappe
+from frappe.tests.utils import FrappeTestCase
+
+
+class TestBulkTransactionLogDetail(FrappeTestCase):
+	pass
diff --git a/erpnext/buying/doctype/buying_settings/buying_settings.json b/erpnext/buying/doctype/buying_settings/buying_settings.json
index 0599992..3f8559e 100644
--- a/erpnext/buying/doctype/buying_settings/buying_settings.json
+++ b/erpnext/buying/doctype/buying_settings/buying_settings.json
@@ -17,6 +17,7 @@
   "po_required",
   "pr_required",
   "blanket_order_allowance",
+  "project_update_frequency",
   "column_break_12",
   "maintain_same_rate",
   "set_landed_cost_based_on_purchase_invoice_rate",
@@ -28,7 +29,11 @@
   "subcontract",
   "backflush_raw_materials_of_subcontract_based_on",
   "column_break_11",
-  "over_transfer_allowance"
+  "over_transfer_allowance",
+  "section_break_xcug",
+  "auto_create_subcontracting_order",
+  "column_break_izrr",
+  "auto_create_purchase_receipt"
  ],
  "fields": [
   {
@@ -172,6 +177,36 @@
    "fieldname": "blanket_order_allowance",
    "fieldtype": "Float",
    "label": "Blanket Order Allowance (%)"
+  },
+  {
+   "fieldname": "section_break_xcug",
+   "fieldtype": "Section Break"
+  },
+  {
+   "fieldname": "column_break_izrr",
+   "fieldtype": "Column Break"
+  },
+  {
+   "default": "0",
+   "description": "Subcontracting Order (Draft) will be auto-created on submission of Purchase Order.",
+   "fieldname": "auto_create_subcontracting_order",
+   "fieldtype": "Check",
+   "label": "Auto Create Subcontracting Order"
+  },
+  {
+   "default": "0",
+   "description": "Purchase Receipt (Draft) will be auto-created on submission of Subcontracting Receipt.",
+   "fieldname": "auto_create_purchase_receipt",
+   "fieldtype": "Check",
+   "label": "Auto Create Purchase Receipt"
+  },
+  {
+   "default": "Each Transaction",
+   "description": "How often should Project be updated of Total Purchase Cost ?",
+   "fieldname": "project_update_frequency",
+   "fieldtype": "Select",
+   "label": "Update frequency of Project",
+   "options": "Each Transaction\nManual"
   }
  ],
  "icon": "fa fa-cog",
@@ -179,7 +214,7 @@
  "index_web_pages_for_search": 1,
  "issingle": 1,
  "links": [],
- "modified": "2023-10-25 14:03:32.520418",
+ "modified": "2023-11-28 13:01:18.403492",
  "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 4680a88..ec9b888 100644
--- a/erpnext/buying/doctype/buying_settings/buying_settings.py
+++ b/erpnext/buying/doctype/buying_settings/buying_settings.py
@@ -9,6 +9,38 @@
 
 
 class BuyingSettings(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
+
+		allow_multiple_items: DF.Check
+		auto_create_purchase_receipt: DF.Check
+		auto_create_subcontracting_order: DF.Check
+		backflush_raw_materials_of_subcontract_based_on: DF.Literal[
+			"BOM", "Material Transferred for Subcontract"
+		]
+		bill_for_rejected_quantity_in_purchase_invoice: DF.Check
+		blanket_order_allowance: DF.Float
+		buying_price_list: DF.Link | None
+		disable_last_purchase_rate: DF.Check
+		maintain_same_rate: DF.Check
+		maintain_same_rate_action: DF.Literal["Stop", "Warn"]
+		over_transfer_allowance: DF.Float
+		po_required: DF.Literal["No", "Yes"]
+		pr_required: DF.Literal["No", "Yes"]
+		project_update_frequency: DF.Literal["Each Transaction", "Manual"]
+		role_to_override_stop_action: DF.Link | None
+		set_landed_cost_based_on_purchase_invoice_rate: DF.Check
+		show_pay_button: DF.Check
+		supp_master_name: DF.Literal["Supplier Name", "Naming Series", "Auto Name"]
+		supplier_group: DF.Link | None
+		use_transaction_date_exchange_rate: DF.Check
+	# end: auto-generated types
+
 	def validate(self):
 		for key in ["supplier_group", "supp_master_name", "maintain_same_rate", "buying_price_list"]:
 			frappe.db.set_default(key, self.get(key, ""))
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.py b/erpnext/buying/doctype/purchase_order/purchase_order.py
index 2d7dbd6..e57896d 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.py
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.py
@@ -8,7 +8,7 @@
 from frappe import _, msgprint
 from frappe.desk.notifications import clear_doctype_notifications
 from frappe.model.mapper import get_mapped_doc
-from frappe.utils import cint, cstr, flt
+from frappe.utils import cint, cstr, flt, get_link_to_form
 
 from erpnext.accounts.doctype.sales_invoice.sales_invoice import (
 	unlink_inter_company_doc,
@@ -36,6 +36,137 @@
 
 
 class PurchaseOrder(BuyingController):
+	# 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
+
+		from erpnext.accounts.doctype.payment_schedule.payment_schedule import PaymentSchedule
+		from erpnext.accounts.doctype.pricing_rule_detail.pricing_rule_detail import PricingRuleDetail
+		from erpnext.accounts.doctype.purchase_taxes_and_charges.purchase_taxes_and_charges import (
+			PurchaseTaxesandCharges,
+		)
+		from erpnext.buying.doctype.purchase_order_item.purchase_order_item import PurchaseOrderItem
+		from erpnext.buying.doctype.purchase_order_item_supplied.purchase_order_item_supplied import (
+			PurchaseOrderItemSupplied,
+		)
+
+		additional_discount_percentage: DF.Float
+		address_display: DF.SmallText | None
+		advance_paid: DF.Currency
+		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
+		base_in_words: DF.Data | None
+		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
+		base_total_taxes_and_charges: DF.Currency
+		billing_address: DF.Link | None
+		billing_address_display: DF.SmallText | None
+		buying_price_list: DF.Link | None
+		company: DF.Link
+		contact_display: DF.SmallText | None
+		contact_email: DF.SmallText | None
+		contact_mobile: DF.SmallText | None
+		contact_person: DF.Link | None
+		conversion_rate: DF.Float
+		cost_center: DF.Link | None
+		currency: DF.Link
+		customer: DF.Link | None
+		customer_contact_display: DF.SmallText | None
+		customer_contact_email: DF.Code | None
+		customer_contact_mobile: DF.SmallText | None
+		customer_contact_person: DF.Link | None
+		customer_name: DF.Data | None
+		disable_rounded_total: DF.Check
+		discount_amount: DF.Currency
+		from_date: DF.Date | None
+		grand_total: DF.Currency
+		group_same_items: DF.Check
+		ignore_pricing_rule: DF.Check
+		in_words: DF.Data | None
+		incoterm: DF.Link | None
+		inter_company_order_reference: DF.Link | None
+		is_internal_supplier: DF.Check
+		is_old_subcontracting_flow: DF.Check
+		is_subcontracted: DF.Check
+		items: DF.Table[PurchaseOrderItem]
+		language: DF.Data | None
+		letter_head: DF.Link | None
+		named_place: DF.Data | None
+		naming_series: DF.Literal["PUR-ORD-.YYYY.-"]
+		net_total: DF.Currency
+		order_confirmation_date: DF.Date | None
+		order_confirmation_no: DF.Data | None
+		other_charges_calculation: DF.LongText | None
+		party_account_currency: DF.Link | None
+		payment_schedule: DF.Table[PaymentSchedule]
+		payment_terms_template: DF.Link | None
+		per_billed: DF.Percent
+		per_received: DF.Percent
+		plc_conversion_rate: DF.Float
+		price_list_currency: DF.Link | None
+		pricing_rules: DF.Table[PricingRuleDetail]
+		project: DF.Link | None
+		ref_sq: DF.Link | None
+		represents_company: DF.Link | None
+		rounded_total: DF.Currency
+		rounding_adjustment: DF.Currency
+		scan_barcode: DF.Data | None
+		schedule_date: DF.Date | None
+		select_print_heading: DF.Link | None
+		set_from_warehouse: DF.Link | None
+		set_reserve_warehouse: DF.Link | None
+		set_warehouse: DF.Link | None
+		shipping_address: DF.Link | None
+		shipping_address_display: DF.SmallText | None
+		shipping_rule: DF.Link | None
+		status: DF.Literal[
+			"",
+			"Draft",
+			"On Hold",
+			"To Receive and Bill",
+			"To Bill",
+			"To Receive",
+			"Completed",
+			"Cancelled",
+			"Closed",
+			"Delivered",
+		]
+		supplied_items: DF.Table[PurchaseOrderItemSupplied]
+		supplier: DF.Link
+		supplier_address: DF.Link | None
+		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
+		taxes_and_charges_deducted: DF.Currency
+		tc_name: DF.Link | None
+		terms: DF.TextEditor | None
+		title: DF.Data
+		to_date: DF.Date | None
+		total: DF.Currency
+		total_net_weight: DF.Float
+		total_qty: DF.Float
+		total_taxes_and_charges: DF.Currency
+		transaction_date: DF.Date
+	# end: auto-generated types
+
 	def __init__(self, *args, **kwargs):
 		super(PurchaseOrder, self).__init__(*args, **kwargs)
 		self.status_updater = [
@@ -90,6 +221,10 @@
 		self.reset_default_field_value("set_warehouse", "items", "warehouse")
 
 	def validate_with_previous_doc(self):
+		mri_compare_fields = [["project", "="], ["item_code", "="]]
+		if self.is_subcontracted:
+			mri_compare_fields = [["project", "="]]
+
 		super(PurchaseOrder, self).validate_with_previous_doc(
 			{
 				"Supplier Quotation": {
@@ -112,7 +247,7 @@
 				},
 				"Material Request Item": {
 					"ref_dn_field": "material_request_item",
-					"compare_fields": [["project", "="], ["item_code", "="]],
+					"compare_fields": mri_compare_fields,
 					"is_child_table": True,
 				},
 			}
@@ -286,23 +421,6 @@
 				check_list.append(d.material_request)
 				check_on_hold_or_closed_status("Material Request", d.material_request)
 
-	def update_requested_qty(self):
-		material_request_map = {}
-		for d in self.get("items"):
-			if d.material_request_item:
-				material_request_map.setdefault(d.material_request, []).append(d.material_request_item)
-
-		for mr, mr_item_rows in material_request_map.items():
-			if mr and mr_item_rows:
-				mr_obj = frappe.get_doc("Material Request", mr)
-
-				if mr_obj.status in ["Stopped", "Cancelled"]:
-					frappe.throw(
-						_("Material Request {0} is cancelled or stopped").format(mr), frappe.InvalidStatusError
-					)
-
-				mr_obj.update_requested_qty(mr_item_rows)
-
 	def update_ordered_qty(self, po_item_rows=None):
 		"""update requested qty (before ordered_qty is updated)"""
 		item_wh_list = []
@@ -344,7 +462,9 @@
 			self.update_status_updater()
 
 		self.update_prevdoc_status()
-		self.update_requested_qty()
+		if not self.is_subcontracted or self.is_old_subcontracting_flow:
+			self.update_requested_qty()
+
 		self.update_ordered_qty()
 		self.validate_budget()
 		self.update_reserved_qty_for_subcontract()
@@ -360,6 +480,8 @@
 
 		update_linked_doc(self.doctype, self.name, self.inter_company_order_reference)
 
+		self.auto_create_subcontracting_order()
+
 	def on_cancel(self):
 		self.ignore_linked_doctypes = ("GL Entry", "Payment Ledger Entry")
 		super(PurchaseOrder, self).on_cancel()
@@ -379,7 +501,9 @@
 
 		# Must be called after updating ordered qty in Material Request
 		# bin uses Material Request Items to recalculate & update
-		self.update_requested_qty()
+		if not self.is_subcontracted or self.is_old_subcontracting_flow:
+			self.update_requested_qty()
+
 		self.update_ordered_qty()
 
 		self.update_blanket_order()
@@ -487,6 +611,25 @@
 
 		return result
 
+	def update_ordered_qty_in_so_for_removed_items(self, removed_items):
+		"""
+		Updates ordered_qty in linked SO when item rows are removed using Update Items
+		"""
+		if not self.is_against_so():
+			return
+		for item in removed_items:
+			prev_ordered_qty = frappe.get_cached_value(
+				"Sales Order Item", item.get("sales_order_item"), "ordered_qty"
+			)
+			frappe.db.set_value(
+				"Sales Order Item", item.get("sales_order_item"), "ordered_qty", prev_ordered_qty - item.qty
+			)
+
+	def auto_create_subcontracting_order(self):
+		if self.is_subcontracted and not self.is_old_subcontracting_flow:
+			if frappe.db.get_single_value("Buying Settings", "auto_create_subcontracting_order"):
+				make_subcontracting_order(self.name, save=True, notify=True)
+
 
 def item_last_purchase_rate(name, conversion_rate, item_code, conversion_factor=1.0):
 	"""get last purchase rate for an item"""
@@ -573,8 +716,6 @@
 		set_missing_values,
 	)
 
-	doc.set_onload("ignore_price_list", True)
-
 	return doc
 
 
@@ -654,7 +795,6 @@
 		postprocess,
 		ignore_permissions=ignore_permissions,
 	)
-	doc.set_onload("ignore_price_list", True)
 
 	return doc
 
@@ -689,8 +829,30 @@
 
 
 @frappe.whitelist()
-def make_subcontracting_order(source_name, target_doc=None):
-	return get_mapped_subcontracting_order(source_name, target_doc)
+def make_subcontracting_order(
+	source_name, target_doc=None, save=False, submit=False, notify=False
+):
+	target_doc = get_mapped_subcontracting_order(source_name, target_doc)
+
+	if (save or submit) and frappe.has_permission(target_doc.doctype, "create"):
+		target_doc.save()
+
+		if submit and frappe.has_permission(target_doc.doctype, "submit", target_doc):
+			try:
+				target_doc.submit()
+			except Exception as e:
+				target_doc.add_comment("Comment", _("Submit Action Failed") + "<br><br>" + str(e))
+
+		if notify:
+			frappe.msgprint(
+				_("Subcontracting Order {0} created.").format(
+					get_link_to_form(target_doc.doctype, target_doc.name)
+				),
+				indicator="green",
+				alert=True,
+			)
+
+	return target_doc
 
 
 def get_mapped_subcontracting_order(source_name, target_doc=None):
@@ -716,7 +878,11 @@
 			},
 			"Purchase Order Item": {
 				"doctype": "Subcontracting Order Service Item",
-				"field_map": {},
+				"field_map": {
+					"name": "purchase_order_item",
+					"material_request": "material_request",
+					"material_request_item": "material_request_item",
+				},
 				"field_no_map": [],
 			},
 		},
@@ -742,8 +908,8 @@
 
 @frappe.whitelist()
 def is_subcontracting_order_created(po_name) -> bool:
-	count = frappe.db.count(
-		"Subcontracting Order", {"purchase_order": po_name, "status": ["not in", ["Draft", "Cancelled"]]}
+	return (
+		True
+		if frappe.db.exists("Subcontracting Order", {"purchase_order": po_name, "docstatus": ["=", 1]})
+		else False
 	)
-
-	return True if count else False
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order_dashboard.py b/erpnext/buying/doctype/purchase_order/purchase_order_dashboard.py
index 05b5a8e..36fe079 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order_dashboard.py
+++ b/erpnext/buying/doctype/purchase_order/purchase_order_dashboard.py
@@ -22,7 +22,10 @@
 				"label": _("Reference"),
 				"items": ["Material Request", "Supplier Quotation", "Project", "Auto Repeat"],
 			},
-			{"label": _("Sub-contracting"), "items": ["Subcontracting Order", "Stock Entry"]},
+			{
+				"label": _("Sub-contracting"),
+				"items": ["Subcontracting Order", "Subcontracting Receipt", "Stock Entry"],
+			},
 			{"label": _("Internal"), "items": ["Sales Order"]},
 		],
 	}
diff --git a/erpnext/buying/doctype/purchase_order/test_purchase_order.py b/erpnext/buying/doctype/purchase_order/test_purchase_order.py
index 55c01e8..f80a00a 100644
--- a/erpnext/buying/doctype/purchase_order/test_purchase_order.py
+++ b/erpnext/buying/doctype/purchase_order/test_purchase_order.py
@@ -16,7 +16,7 @@
 	make_purchase_invoice as make_pi_from_po,
 )
 from erpnext.buying.doctype.purchase_order.purchase_order import make_purchase_receipt
-from erpnext.controllers.accounts_controller import update_child_qty_rate
+from erpnext.controllers.accounts_controller import InvalidQtyError, update_child_qty_rate
 from erpnext.manufacturing.doctype.blanket_order.test_blanket_order import make_blanket_order
 from erpnext.stock.doctype.item.test_item import make_item
 from erpnext.stock.doctype.material_request.material_request import make_purchase_order
@@ -27,6 +27,21 @@
 
 
 class TestPurchaseOrder(FrappeTestCase):
+	def test_purchase_order_qty(self):
+		po = create_purchase_order(qty=1, do_not_save=True)
+		po.append(
+			"items",
+			{
+				"item_code": "_Test Item",
+				"qty": -1,
+				"rate": 10,
+			},
+		)
+		self.assertRaises(frappe.NonNegativeError, po.save)
+
+		po.items[1].qty = 0
+		self.assertRaises(InvalidQtyError, po.save)
+
 	def test_make_purchase_receipt(self):
 		po = create_purchase_order(do_not_submit=True)
 		self.assertRaises(frappe.ValidationError, make_purchase_receipt, po.name)
@@ -966,6 +981,38 @@
 		self.assertEqual(po.items[0].qty, 30)
 		self.assertEqual(po.items[0].fg_item_qty, 30)
 
+	@change_settings("Buying Settings", {"auto_create_subcontracting_order": 1})
+	def test_auto_create_subcontracting_order(self):
+		from erpnext.controllers.tests.test_subcontracting_controller import (
+			make_bom_for_subcontracted_items,
+			make_raw_materials,
+			make_service_items,
+			make_subcontracted_items,
+		)
+
+		make_subcontracted_items()
+		make_raw_materials()
+		make_service_items()
+		make_bom_for_subcontracted_items()
+
+		service_items = [
+			{
+				"warehouse": "_Test Warehouse - _TC",
+				"item_code": "Subcontracted Service Item 7",
+				"qty": 10,
+				"rate": 100,
+				"fg_item": "Subcontracted Item SA7",
+				"fg_item_qty": 10,
+			},
+		]
+		po = create_purchase_order(
+			rm_items=service_items,
+			is_subcontracted=1,
+			supplier_warehouse="_Test Warehouse 1 - _TC",
+		)
+
+		self.assertTrue(frappe.db.get_value("Subcontracting Order", {"purchase_order": po.name}))
+
 
 def prepare_data_for_internal_transfer():
 	from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_internal_supplier
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 2b6ffb7..98c1b38 100644
--- a/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json
+++ b/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json
@@ -189,6 +189,7 @@
    "fieldtype": "Column Break"
   },
   {
+   "fetch_from": "item_code.image",
    "fieldname": "image",
    "fieldtype": "Attach",
    "hidden": 1,
@@ -213,6 +214,7 @@
    "fieldtype": "Float",
    "in_list_view": 1,
    "label": "Quantity",
+   "non_negative": 1,
    "oldfieldname": "qty",
    "oldfieldtype": "Currency",
    "print_width": "60px",
@@ -916,7 +918,7 @@
  "index_web_pages_for_search": 1,
  "istable": 1,
  "links": [],
- "modified": "2023-11-06 11:00:53.596417",
+ "modified": "2023-11-24 13:24:41.298416",
  "modified_by": "Administrator",
  "module": "Buying",
  "name": "Purchase Order Item",
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 a8bafda..e9cc2b4 100644
--- a/erpnext/buying/doctype/purchase_order_item/purchase_order_item.py
+++ b/erpnext/buying/doctype/purchase_order_item/purchase_order_item.py
@@ -7,6 +7,93 @@
 
 
 class PurchaseOrderItem(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
+
+		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
+		base_price_list_rate: DF.Currency
+		base_rate: DF.Currency
+		base_rate_with_margin: DF.Currency
+		billed_amt: DF.Currency
+		blanket_order: DF.Link | None
+		blanket_order_rate: DF.Currency
+		bom: DF.Link | None
+		brand: DF.Link | None
+		company_total_stock: DF.Float
+		conversion_factor: DF.Float
+		cost_center: DF.Link | None
+		delivered_by_supplier: DF.Check
+		description: DF.TextEditor | None
+		discount_amount: DF.Currency
+		discount_percentage: DF.Percent
+		expected_delivery_date: DF.Date | None
+		expense_account: DF.Link | None
+		fg_item: DF.Link | None
+		fg_item_qty: DF.Float
+		from_warehouse: DF.Link | None
+		image: DF.Attach | None
+		include_exploded_items: DF.Check
+		is_fixed_asset: DF.Check
+		is_free_item: DF.Check
+		item_code: DF.Link
+		item_group: DF.Link | None
+		item_name: DF.Data
+		item_tax_rate: DF.Code | None
+		item_tax_template: DF.Link | None
+		last_purchase_rate: DF.Currency
+		manufacturer: DF.Link | None
+		manufacturer_part_no: DF.Data | None
+		margin_rate_or_amount: DF.Float
+		margin_type: DF.Literal["", "Percentage", "Amount"]
+		material_request: DF.Link | None
+		material_request_item: DF.Data | None
+		net_amount: DF.Currency
+		net_rate: DF.Currency
+		page_break: DF.Check
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		price_list_rate: DF.Currency
+		pricing_rules: DF.SmallText | None
+		product_bundle: DF.Link | None
+		production_plan: DF.Link | None
+		production_plan_item: DF.Data | None
+		production_plan_sub_assembly_item: DF.Data | None
+		project: DF.Link | None
+		qty: DF.Float
+		rate: DF.Currency
+		rate_with_margin: DF.Currency
+		received_qty: DF.Float
+		returned_qty: DF.Float
+		sales_order: DF.Link | None
+		sales_order_item: DF.Data | None
+		sales_order_packed_item: DF.Data | None
+		schedule_date: DF.Date
+		stock_qty: DF.Float
+		stock_uom: DF.Link
+		stock_uom_rate: DF.Currency
+		supplier_part_no: DF.Data | None
+		supplier_quotation: DF.Link | None
+		supplier_quotation_item: DF.Link | None
+		total_weight: DF.Float
+		uom: DF.Link
+		warehouse: DF.Link | None
+		weight_per_unit: DF.Float
+		weight_uom: DF.Link | None
+		wip_composite_asset: DF.Link | None
+	# end: auto-generated types
+
 	pass
 
 
diff --git a/erpnext/buying/doctype/purchase_order_item_supplied/purchase_order_item_supplied.py b/erpnext/buying/doctype/purchase_order_item_supplied/purchase_order_item_supplied.py
index c69b5ed..6844347 100644
--- a/erpnext/buying/doctype/purchase_order_item_supplied/purchase_order_item_supplied.py
+++ b/erpnext/buying/doctype/purchase_order_item_supplied/purchase_order_item_supplied.py
@@ -6,4 +6,31 @@
 
 
 class PurchaseOrderItemSupplied(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
+
+		amount: DF.Currency
+		bom_detail_no: DF.Data | None
+		consumed_qty: DF.Float
+		conversion_factor: DF.Float
+		main_item_code: DF.Link | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		rate: DF.Currency
+		reference_name: DF.Data | None
+		required_qty: DF.Float
+		reserve_warehouse: DF.Link | None
+		returned_qty: DF.Float
+		rm_item_code: DF.Link | None
+		stock_uom: DF.Link | None
+		supplied_qty: DF.Float
+		total_supplied_qty: DF.Float
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/buying/doctype/purchase_receipt_item_supplied/purchase_receipt_item_supplied.py b/erpnext/buying/doctype/purchase_receipt_item_supplied/purchase_receipt_item_supplied.py
index 7b67921..6ed0971 100644
--- a/erpnext/buying/doctype/purchase_receipt_item_supplied/purchase_receipt_item_supplied.py
+++ b/erpnext/buying/doctype/purchase_receipt_item_supplied/purchase_receipt_item_supplied.py
@@ -6,4 +6,33 @@
 
 
 class PurchaseReceiptItemSupplied(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
+
+		amount: DF.Currency
+		batch_no: DF.Link | None
+		bom_detail_no: DF.Data | None
+		consumed_qty: DF.Float
+		conversion_factor: DF.Float
+		current_stock: DF.Float
+		description: DF.TextEditor | None
+		item_name: DF.Data | None
+		main_item_code: DF.Link | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		purchase_order: DF.Link | None
+		rate: DF.Currency
+		reference_name: DF.Data | None
+		required_qty: DF.Float
+		rm_item_code: DF.Link | None
+		serial_no: DF.Text | None
+		stock_uom: DF.Link | None
+	# end: auto-generated types
+
 	pass
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 6b39982..eea8cd5 100644
--- a/erpnext/buying/doctype/request_for_quotation/request_for_quotation.py
+++ b/erpnext/buying/doctype/request_for_quotation/request_for_quotation.py
@@ -23,6 +23,45 @@
 
 
 class RequestforQuotation(BuyingController):
+	# 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
+
+		from erpnext.buying.doctype.request_for_quotation_item.request_for_quotation_item import (
+			RequestforQuotationItem,
+		)
+		from erpnext.buying.doctype.request_for_quotation_supplier.request_for_quotation_supplier import (
+			RequestforQuotationSupplier,
+		)
+
+		amended_from: DF.Link | None
+		billing_address: DF.Link | None
+		billing_address_display: DF.SmallText | None
+		company: DF.Link
+		email_template: DF.Link | None
+		incoterm: DF.Link | None
+		items: DF.Table[RequestforQuotationItem]
+		letter_head: DF.Link | None
+		message_for_supplier: DF.TextEditor
+		named_place: DF.Data | None
+		naming_series: DF.Literal["PUR-RFQ-.YYYY.-"]
+		opportunity: DF.Link | None
+		schedule_date: DF.Date | None
+		select_print_heading: DF.Link | None
+		send_attached_files: DF.Check
+		send_document_print: DF.Check
+		status: DF.Literal["", "Draft", "Submitted", "Cancelled"]
+		suppliers: DF.Table[RequestforQuotationSupplier]
+		tc_name: DF.Link | None
+		terms: DF.TextEditor | None
+		transaction_date: DF.Date
+		vendor: DF.Link | None
+	# end: auto-generated types
+
 	def validate(self):
 		self.validate_duplicate_supplier()
 		self.validate_supplier_list()
diff --git a/erpnext/buying/doctype/request_for_quotation_item/request_for_quotation_item.json b/erpnext/buying/doctype/request_for_quotation_item/request_for_quotation_item.json
index 82fcfa2..6cdd2ba 100644
--- a/erpnext/buying/doctype/request_for_quotation_item/request_for_quotation_item.json
+++ b/erpnext/buying/doctype/request_for_quotation_item/request_for_quotation_item.json
@@ -87,6 +87,7 @@
    "width": "300px"
   },
   {
+   "fetch_from": "item_code.image",
    "fieldname": "image",
    "fieldtype": "Attach",
    "hidden": 1,
@@ -260,13 +261,15 @@
  "index_web_pages_for_search": 1,
  "istable": 1,
  "links": [],
- "modified": "2020-09-24 17:26:46.276934",
+ "modified": "2023-11-14 18:34:48.327224",
  "modified_by": "Administrator",
  "module": "Buying",
  "name": "Request for Quotation Item",
+ "naming_rule": "Random",
  "owner": "Administrator",
  "permissions": [],
  "sort_field": "modified",
  "sort_order": "DESC",
+ "states": [],
  "track_changes": 1
-}
+}
\ No newline at end of file
diff --git a/erpnext/buying/doctype/request_for_quotation_item/request_for_quotation_item.py b/erpnext/buying/doctype/request_for_quotation_item/request_for_quotation_item.py
index 096aede..2ea7730 100644
--- a/erpnext/buying/doctype/request_for_quotation_item/request_for_quotation_item.py
+++ b/erpnext/buying/doctype/request_for_quotation_item/request_for_quotation_item.py
@@ -6,4 +6,35 @@
 
 
 class RequestforQuotationItem(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
+
+		brand: DF.Link | None
+		conversion_factor: DF.Float
+		description: DF.TextEditor | None
+		image: DF.Attach | None
+		item_code: DF.Link
+		item_group: DF.Link | None
+		item_name: DF.Data | None
+		material_request: DF.Link | None
+		material_request_item: DF.Data | None
+		page_break: DF.Check
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		project_name: DF.Link | None
+		qty: DF.Float
+		schedule_date: DF.Date
+		stock_qty: DF.Float
+		stock_uom: DF.Link
+		supplier_part_no: DF.Data | None
+		uom: DF.Link
+		warehouse: DF.Link | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/buying/doctype/request_for_quotation_supplier/request_for_quotation_supplier.py b/erpnext/buying/doctype/request_for_quotation_supplier/request_for_quotation_supplier.py
index dbaad47..47aa5ee 100644
--- a/erpnext/buying/doctype/request_for_quotation_supplier/request_for_quotation_supplier.py
+++ b/erpnext/buying/doctype/request_for_quotation_supplier/request_for_quotation_supplier.py
@@ -6,4 +6,24 @@
 
 
 class RequestforQuotationSupplier(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
+
+		contact: DF.Link | None
+		email_id: DF.Data | None
+		email_sent: DF.Check
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		quote_status: DF.Literal["Pending", "Received"]
+		send_email: DF.Check
+		supplier: DF.Link
+		supplier_name: DF.ReadOnly | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/buying/doctype/supplier/supplier.py b/erpnext/buying/doctype/supplier/supplier.py
index 31bf439..c8ed5aa 100644
--- a/erpnext/buying/doctype/supplier/supplier.py
+++ b/erpnext/buying/doctype/supplier/supplier.py
@@ -21,6 +21,60 @@
 
 
 class Supplier(TransactionBase):
+	# 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
+
+		from erpnext.accounts.doctype.allowed_to_transact_with.allowed_to_transact_with import (
+			AllowedToTransactWith,
+		)
+		from erpnext.accounts.doctype.party_account.party_account import PartyAccount
+		from erpnext.utilities.doctype.portal_user.portal_user import PortalUser
+
+		accounts: DF.Table[PartyAccount]
+		allow_purchase_invoice_creation_without_purchase_order: DF.Check
+		allow_purchase_invoice_creation_without_purchase_receipt: DF.Check
+		companies: DF.Table[AllowedToTransactWith]
+		country: DF.Link | None
+		default_bank_account: DF.Link | None
+		default_currency: DF.Link | None
+		default_price_list: DF.Link | None
+		disabled: DF.Check
+		email_id: DF.ReadOnly | None
+		hold_type: DF.Literal["", "All", "Invoices", "Payments"]
+		image: DF.AttachImage | None
+		is_frozen: DF.Check
+		is_internal_supplier: DF.Check
+		is_transporter: DF.Check
+		language: DF.Link | None
+		mobile_no: DF.ReadOnly | None
+		naming_series: DF.Literal["SUP-.YYYY.-"]
+		on_hold: DF.Check
+		payment_terms: DF.Link | None
+		portal_users: DF.Table[PortalUser]
+		prevent_pos: DF.Check
+		prevent_rfqs: DF.Check
+		primary_address: DF.Text | None
+		release_date: DF.Date | None
+		represents_company: DF.Link | None
+		supplier_details: DF.Text | None
+		supplier_group: DF.Link | None
+		supplier_name: DF.Data
+		supplier_primary_address: DF.Link | None
+		supplier_primary_contact: DF.Link | None
+		supplier_type: DF.Literal["Company", "Individual", "Proprietorship", "Partnership"]
+		tax_category: DF.Link | None
+		tax_id: DF.Data | None
+		tax_withholding_category: DF.Link | None
+		warn_pos: DF.Check
+		warn_rfqs: DF.Check
+		website: DF.Data | None
+	# end: auto-generated types
+
 	def onload(self):
 		"""Load address and contacts in `__onload`"""
 		load_address_and_contact(self)
@@ -165,16 +219,17 @@
 @frappe.validate_and_sanitize_search_inputs
 def get_supplier_primary_contact(doctype, txt, searchfield, start, page_len, filters):
 	supplier = filters.get("supplier")
-	return frappe.db.sql(
-		"""
-		SELECT
-			`tabContact`.name from `tabContact`,
-			`tabDynamic Link`
-		WHERE
-			`tabContact`.name = `tabDynamic Link`.parent
-			and `tabDynamic Link`.link_name = %(supplier)s
-			and `tabDynamic Link`.link_doctype = 'Supplier'
-			and `tabContact`.name like %(txt)s
-		""",
-		{"supplier": supplier, "txt": "%%%s%%" % txt},
-	)
+	contact = frappe.qb.DocType("Contact")
+	dynamic_link = frappe.qb.DocType("Dynamic Link")
+
+	return (
+		frappe.qb.from_(contact)
+		.join(dynamic_link)
+		.on(contact.name == dynamic_link.parent)
+		.select(contact.name, contact.email_id)
+		.where(
+			(dynamic_link.link_name == supplier)
+			& (dynamic_link.link_doctype == "Supplier")
+			& (contact.name.like("%{0}%".format(txt)))
+		)
+	).run(as_dict=False)
diff --git a/erpnext/buying/doctype/supplier_quotation/supplier_quotation.json b/erpnext/buying/doctype/supplier_quotation/supplier_quotation.json
index ad1aa2b..1891261 100644
--- a/erpnext/buying/doctype/supplier_quotation/supplier_quotation.json
+++ b/erpnext/buying/doctype/supplier_quotation/supplier_quotation.json
@@ -20,6 +20,10 @@
   "valid_till",
   "quotation_number",
   "amended_from",
+  "accounting_dimensions_section",
+  "cost_center",
+  "dimension_col_break",
+  "project",
   "currency_and_price_list",
   "currency",
   "conversion_rate",
@@ -896,6 +900,27 @@
    "fieldtype": "Small Text",
    "label": "Billing Address Details",
    "read_only": 1
+  },
+  {
+   "fieldname": "cost_center",
+   "fieldtype": "Link",
+   "label": "Cost Center",
+   "options": "Cost Center"
+  },
+  {
+   "fieldname": "project",
+   "fieldtype": "Link",
+   "label": "Project",
+   "options": "Project"
+  },
+  {
+   "fieldname": "dimension_col_break",
+   "fieldtype": "Column Break"
+  },
+  {
+   "fieldname": "accounting_dimensions_section",
+   "fieldtype": "Section Break",
+   "label": "Accounting Dimensions"
   }
  ],
  "icon": "fa fa-shopping-cart",
@@ -903,7 +928,7 @@
  "index_web_pages_for_search": 1,
  "is_submittable": 1,
  "links": [],
- "modified": "2023-11-03 13:21:40.172508",
+ "modified": "2023-11-17 12:34:30.083077",
  "modified_by": "Administrator",
  "module": "Buying",
  "name": "Supplier Quotation",
diff --git a/erpnext/buying/doctype/supplier_quotation/supplier_quotation.py b/erpnext/buying/doctype/supplier_quotation/supplier_quotation.py
index 2dd748b..e2b737b 100644
--- a/erpnext/buying/doctype/supplier_quotation/supplier_quotation.py
+++ b/erpnext/buying/doctype/supplier_quotation/supplier_quotation.py
@@ -14,6 +14,95 @@
 
 
 class SupplierQuotation(BuyingController):
+	# 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
+
+		from erpnext.accounts.doctype.pricing_rule_detail.pricing_rule_detail import PricingRuleDetail
+		from erpnext.accounts.doctype.purchase_taxes_and_charges.purchase_taxes_and_charges import (
+			PurchaseTaxesandCharges,
+		)
+		from erpnext.buying.doctype.supplier_quotation_item.supplier_quotation_item import (
+			SupplierQuotationItem,
+		)
+
+		additional_discount_percentage: DF.Float
+		address_display: DF.SmallText | None
+		amended_from: DF.Link | None
+		apply_discount_on: DF.Literal["", "Grand Total", "Net Total"]
+		auto_repeat: DF.Link | None
+		base_discount_amount: DF.Currency
+		base_grand_total: DF.Currency
+		base_in_words: DF.Data | None
+		base_net_total: DF.Currency
+		base_rounded_total: DF.Currency
+		base_rounding_adjustment: DF.Currency
+		base_taxes_and_charges_added: DF.Currency
+		base_taxes_and_charges_deducted: DF.Currency
+		base_total: DF.Currency
+		base_total_taxes_and_charges: DF.Currency
+		billing_address: DF.Link | None
+		billing_address_display: DF.SmallText | None
+		buying_price_list: DF.Link | None
+		company: DF.Link
+		contact_display: DF.SmallText | None
+		contact_email: DF.Data | None
+		contact_mobile: DF.SmallText | None
+		contact_person: DF.Link | None
+		conversion_rate: DF.Float
+		cost_center: DF.Link | None
+		currency: DF.Link
+		disable_rounded_total: DF.Check
+		discount_amount: DF.Currency
+		grand_total: DF.Currency
+		group_same_items: DF.Check
+		ignore_pricing_rule: DF.Check
+		in_words: DF.Data | None
+		incoterm: DF.Link | None
+		is_subcontracted: DF.Check
+		items: DF.Table[SupplierQuotationItem]
+		language: DF.Data | None
+		letter_head: DF.Link | None
+		named_place: DF.Data | None
+		naming_series: DF.Literal["PUR-SQTN-.YYYY.-"]
+		net_total: DF.Currency
+		opportunity: DF.Link | None
+		other_charges_calculation: DF.LongText | None
+		plc_conversion_rate: DF.Float
+		price_list_currency: DF.Link | None
+		pricing_rules: DF.Table[PricingRuleDetail]
+		project: DF.Link | None
+		quotation_number: DF.Data | None
+		rounded_total: DF.Currency
+		rounding_adjustment: DF.Currency
+		select_print_heading: DF.Link | None
+		shipping_address: DF.Link | None
+		shipping_address_display: DF.SmallText | None
+		shipping_rule: DF.Link | None
+		status: DF.Literal["", "Draft", "Submitted", "Stopped", "Cancelled", "Expired"]
+		supplier: DF.Link
+		supplier_address: DF.Link | None
+		supplier_name: DF.Data | None
+		tax_category: DF.Link | None
+		taxes: DF.Table[PurchaseTaxesandCharges]
+		taxes_and_charges: DF.Link | None
+		taxes_and_charges_added: DF.Currency
+		taxes_and_charges_deducted: DF.Currency
+		tc_name: DF.Link | None
+		terms: DF.TextEditor | None
+		title: DF.Data | None
+		total: DF.Currency
+		total_net_weight: DF.Float
+		total_qty: DF.Float
+		total_taxes_and_charges: DF.Currency
+		transaction_date: DF.Date
+		valid_till: DF.Date | None
+	# end: auto-generated types
+
 	def validate(self):
 		super(SupplierQuotation, self).validate()
 
@@ -168,7 +257,6 @@
 		set_missing_values,
 	)
 
-	doclist.set_onload("ignore_price_list", True)
 	return doclist
 
 
diff --git a/erpnext/buying/doctype/supplier_quotation_item/supplier_quotation_item.json b/erpnext/buying/doctype/supplier_quotation_item/supplier_quotation_item.json
index 8d491fb..a6229b5 100644
--- a/erpnext/buying/doctype/supplier_quotation_item/supplier_quotation_item.json
+++ b/erpnext/buying/doctype/supplier_quotation_item/supplier_quotation_item.json
@@ -68,6 +68,8 @@
   "column_break_15",
   "manufacturer_part_no",
   "ad_sec_break",
+  "cost_center",
+  "dimension_col_break",
   "project",
   "section_break_44",
   "page_break"
@@ -553,19 +555,31 @@
    "fieldname": "expected_delivery_date",
    "fieldtype": "Date",
    "label": "Expected Delivery Date"
+  },
+  {
+   "fieldname": "cost_center",
+   "fieldtype": "Link",
+   "label": "Cost Center",
+   "options": "Cost Center"
+  },
+  {
+   "fieldname": "dimension_col_break",
+   "fieldtype": "Column Break"
   }
  ],
  "idx": 1,
  "index_web_pages_for_search": 1,
  "istable": 1,
  "links": [],
- "modified": "2020-10-19 12:36:26.913211",
+ "modified": "2023-11-17 12:25:26.235367",
  "modified_by": "Administrator",
  "module": "Buying",
  "name": "Supplier Quotation Item",
+ "naming_rule": "Random",
  "owner": "Administrator",
  "permissions": [],
  "sort_field": "modified",
  "sort_order": "DESC",
+ "states": [],
  "track_changes": 1
-}
+}
\ No newline at end of file
diff --git a/erpnext/buying/doctype/supplier_quotation_item/supplier_quotation_item.py b/erpnext/buying/doctype/supplier_quotation_item/supplier_quotation_item.py
index 672de1a..d2f4a59 100644
--- a/erpnext/buying/doctype/supplier_quotation_item/supplier_quotation_item.py
+++ b/erpnext/buying/doctype/supplier_quotation_item/supplier_quotation_item.py
@@ -6,4 +6,62 @@
 
 
 class SupplierQuotationItem(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
+
+		amount: DF.Currency
+		base_amount: DF.Currency
+		base_net_amount: DF.Currency
+		base_net_rate: DF.Currency
+		base_price_list_rate: DF.Currency
+		base_rate: DF.Currency
+		brand: DF.Link | None
+		conversion_factor: DF.Float
+		cost_center: DF.Link | None
+		description: DF.TextEditor | None
+		discount_amount: DF.Currency
+		discount_percentage: DF.Percent
+		expected_delivery_date: DF.Date | None
+		image: DF.Attach | None
+		is_free_item: DF.Check
+		item_code: DF.Link
+		item_group: DF.Link | None
+		item_name: DF.Data | None
+		item_tax_rate: DF.Code | None
+		item_tax_template: DF.Link | None
+		lead_time_days: DF.Int
+		manufacturer: DF.Link | None
+		manufacturer_part_no: DF.Data | None
+		material_request: DF.Link | None
+		material_request_item: DF.Data | None
+		net_amount: DF.Currency
+		net_rate: DF.Currency
+		page_break: DF.Check
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		prevdoc_doctype: DF.Data | None
+		price_list_rate: DF.Currency
+		pricing_rules: DF.SmallText | None
+		project: DF.Link | None
+		qty: DF.Float
+		rate: DF.Currency
+		request_for_quotation: DF.Link | None
+		request_for_quotation_item: DF.Data | None
+		sales_order: DF.Link | None
+		stock_qty: DF.Float
+		stock_uom: DF.Link
+		supplier_part_no: DF.Data | None
+		total_weight: DF.Float
+		uom: DF.Link
+		warehouse: DF.Link | None
+		weight_per_unit: DF.Float
+		weight_uom: DF.Link | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/buying/doctype/supplier_scorecard/supplier_scorecard.py b/erpnext/buying/doctype/supplier_scorecard/supplier_scorecard.py
index 683a12a..0a6024f 100644
--- a/erpnext/buying/doctype/supplier_scorecard/supplier_scorecard.py
+++ b/erpnext/buying/doctype/supplier_scorecard/supplier_scorecard.py
@@ -16,6 +16,38 @@
 
 
 class SupplierScorecard(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
+
+		from erpnext.buying.doctype.supplier_scorecard_scoring_criteria.supplier_scorecard_scoring_criteria import (
+			SupplierScorecardScoringCriteria,
+		)
+		from erpnext.buying.doctype.supplier_scorecard_scoring_standing.supplier_scorecard_scoring_standing import (
+			SupplierScorecardScoringStanding,
+		)
+
+		criteria: DF.Table[SupplierScorecardScoringCriteria]
+		employee: DF.Link | None
+		indicator_color: DF.Data | None
+		notify_employee: DF.Check
+		notify_supplier: DF.Check
+		period: DF.Literal["Per Week", "Per Month", "Per Year"]
+		prevent_pos: DF.Check
+		prevent_rfqs: DF.Check
+		standings: DF.Table[SupplierScorecardScoringStanding]
+		status: DF.Data | None
+		supplier: DF.Link | None
+		supplier_score: DF.Data | None
+		warn_pos: DF.Check
+		warn_rfqs: DF.Check
+		weighting_function: DF.SmallText
+	# end: auto-generated types
+
 	def validate(self):
 		self.validate_standings()
 		self.validate_criteria_weights()
diff --git a/erpnext/buying/doctype/supplier_scorecard_criteria/supplier_scorecard_criteria.py b/erpnext/buying/doctype/supplier_scorecard_criteria/supplier_scorecard_criteria.py
index ab7d487..f19ab94 100644
--- a/erpnext/buying/doctype/supplier_scorecard_criteria/supplier_scorecard_criteria.py
+++ b/erpnext/buying/doctype/supplier_scorecard_criteria/supplier_scorecard_criteria.py
@@ -14,6 +14,20 @@
 
 
 class SupplierScorecardCriteria(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
+
+		criteria_name: DF.Data
+		formula: DF.SmallText
+		max_score: DF.Float
+		weight: DF.Percent
+	# end: auto-generated types
+
 	def validate(self):
 		self.validate_variables()
 		self.validate_formula()
diff --git a/erpnext/buying/doctype/supplier_scorecard_period/supplier_scorecard_period.py b/erpnext/buying/doctype/supplier_scorecard_period/supplier_scorecard_period.py
index 1967df2..e6ef166 100644
--- a/erpnext/buying/doctype/supplier_scorecard_period/supplier_scorecard_period.py
+++ b/erpnext/buying/doctype/supplier_scorecard_period/supplier_scorecard_period.py
@@ -14,6 +14,32 @@
 
 
 class SupplierScorecardPeriod(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
+
+		from erpnext.buying.doctype.supplier_scorecard_scoring_criteria.supplier_scorecard_scoring_criteria import (
+			SupplierScorecardScoringCriteria,
+		)
+		from erpnext.buying.doctype.supplier_scorecard_scoring_variable.supplier_scorecard_scoring_variable import (
+			SupplierScorecardScoringVariable,
+		)
+
+		amended_from: DF.Link | None
+		criteria: DF.Table[SupplierScorecardScoringCriteria]
+		end_date: DF.Date
+		naming_series: DF.Literal["PU-SSP-.YYYY.-"]
+		scorecard: DF.Link
+		start_date: DF.Date
+		supplier: DF.Link
+		total_score: DF.Percent
+		variables: DF.Table[SupplierScorecardScoringVariable]
+	# end: auto-generated types
+
 	def validate(self):
 		self.validate_criteria_weights()
 		self.calculate_variables()
diff --git a/erpnext/buying/doctype/supplier_scorecard_scoring_criteria/supplier_scorecard_scoring_criteria.py b/erpnext/buying/doctype/supplier_scorecard_scoring_criteria/supplier_scorecard_scoring_criteria.py
index 3a6de59..4c77742 100644
--- a/erpnext/buying/doctype/supplier_scorecard_scoring_criteria/supplier_scorecard_scoring_criteria.py
+++ b/erpnext/buying/doctype/supplier_scorecard_scoring_criteria/supplier_scorecard_scoring_criteria.py
@@ -6,4 +6,22 @@
 
 
 class SupplierScorecardScoringCriteria(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
+
+		criteria_name: DF.Link
+		formula: DF.SmallText | None
+		max_score: DF.Float
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		score: DF.Percent
+		weight: DF.Percent
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/buying/doctype/supplier_scorecard_scoring_standing/supplier_scorecard_scoring_standing.py b/erpnext/buying/doctype/supplier_scorecard_scoring_standing/supplier_scorecard_scoring_standing.py
index 8d66e64..35e4177 100644
--- a/erpnext/buying/doctype/supplier_scorecard_scoring_standing/supplier_scorecard_scoring_standing.py
+++ b/erpnext/buying/doctype/supplier_scorecard_scoring_standing/supplier_scorecard_scoring_standing.py
@@ -6,4 +6,28 @@
 
 
 class SupplierScorecardScoringStanding(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
+
+		employee_link: DF.Link | None
+		max_grade: DF.Percent
+		min_grade: DF.Percent
+		notify_employee: DF.Check
+		notify_supplier: DF.Check
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		prevent_pos: DF.Check
+		prevent_rfqs: DF.Check
+		standing_color: DF.Literal["Blue", "Purple", "Green", "Yellow", "Orange", "Red"]
+		standing_name: DF.Link | None
+		warn_pos: DF.Check
+		warn_rfqs: DF.Check
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/buying/doctype/supplier_scorecard_scoring_variable/supplier_scorecard_scoring_variable.py b/erpnext/buying/doctype/supplier_scorecard_scoring_variable/supplier_scorecard_scoring_variable.py
index f13eb5b..41b4748 100644
--- a/erpnext/buying/doctype/supplier_scorecard_scoring_variable/supplier_scorecard_scoring_variable.py
+++ b/erpnext/buying/doctype/supplier_scorecard_scoring_variable/supplier_scorecard_scoring_variable.py
@@ -6,4 +6,22 @@
 
 
 class SupplierScorecardScoringVariable(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
+
+		description: DF.SmallText | None
+		param_name: DF.Data | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		path: DF.Data | None
+		value: DF.Float
+		variable_label: DF.Link
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/buying/doctype/supplier_scorecard_standing/supplier_scorecard_standing.py b/erpnext/buying/doctype/supplier_scorecard_standing/supplier_scorecard_standing.py
index 929e8a3..690838a 100644
--- a/erpnext/buying/doctype/supplier_scorecard_standing/supplier_scorecard_standing.py
+++ b/erpnext/buying/doctype/supplier_scorecard_standing/supplier_scorecard_standing.py
@@ -7,6 +7,27 @@
 
 
 class SupplierScorecardStanding(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
+
+		employee_link: DF.Link | None
+		max_grade: DF.Percent
+		min_grade: DF.Percent
+		notify_employee: DF.Check
+		notify_supplier: DF.Check
+		prevent_pos: DF.Check
+		prevent_rfqs: DF.Check
+		standing_color: DF.Literal["Blue", "Purple", "Green", "Yellow", "Orange", "Red"]
+		standing_name: DF.Data | None
+		warn_pos: DF.Check
+		warn_rfqs: DF.Check
+	# end: auto-generated types
+
 	pass
 
 
diff --git a/erpnext/buying/doctype/supplier_scorecard_variable/supplier_scorecard_variable.py b/erpnext/buying/doctype/supplier_scorecard_variable/supplier_scorecard_variable.py
index 6c91a04..19be89d 100644
--- a/erpnext/buying/doctype/supplier_scorecard_variable/supplier_scorecard_variable.py
+++ b/erpnext/buying/doctype/supplier_scorecard_variable/supplier_scorecard_variable.py
@@ -16,6 +16,21 @@
 
 
 class SupplierScorecardVariable(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
+
+		description: DF.SmallText | None
+		is_custom: DF.Check
+		param_name: DF.Data
+		path: DF.Data
+		variable_label: DF.Data
+	# end: auto-generated types
+
 	def validate(self):
 		self.validate_path_exists()
 
diff --git a/erpnext/communication/doctype/communication_medium/communication_medium.py b/erpnext/communication/doctype/communication_medium/communication_medium.py
index 6dfdb73..a5b3083 100644
--- a/erpnext/communication/doctype/communication_medium/communication_medium.py
+++ b/erpnext/communication/doctype/communication_medium/communication_medium.py
@@ -7,4 +7,24 @@
 
 
 class CommunicationMedium(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
+
+		from erpnext.communication.doctype.communication_medium_timeslot.communication_medium_timeslot import (
+			CommunicationMediumTimeslot,
+		)
+
+		catch_all: DF.Link | None
+		communication_channel: DF.Literal
+		communication_medium_type: DF.Literal["Voice", "Email", "Chat"]
+		disabled: DF.Check
+		provider: DF.Link | None
+		timeslots: DF.Table[CommunicationMediumTimeslot]
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/communication/doctype/communication_medium_timeslot/communication_medium_timeslot.py b/erpnext/communication/doctype/communication_medium_timeslot/communication_medium_timeslot.py
index b65eba7..4cd65fa 100644
--- a/erpnext/communication/doctype/communication_medium_timeslot/communication_medium_timeslot.py
+++ b/erpnext/communication/doctype/communication_medium_timeslot/communication_medium_timeslot.py
@@ -7,4 +7,23 @@
 
 
 class CommunicationMediumTimeslot(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
+
+		day_of_week: DF.Literal[
+			"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"
+		]
+		employee_group: DF.Link
+		from_time: DF.Time
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		to_time: DF.Time
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py
index c129b76..a6e2ae5 100644
--- a/erpnext/controllers/accounts_controller.py
+++ b/erpnext/controllers/accounts_controller.py
@@ -71,6 +71,10 @@
 	pass
 
 
+class InvalidQtyError(frappe.ValidationError):
+	pass
+
+
 force_item_fields = (
 	"item_group",
 	"brand",
@@ -239,7 +243,7 @@
 				references_map.setdefault(x.parent, []).append(x.name)
 
 			for doc, rows in references_map.items():
-				unreconcile_doc = frappe.get_doc("Unreconcile Payments", doc)
+				unreconcile_doc = frappe.get_doc("Unreconcile Payment", doc)
 				for row in rows:
 					unreconcile_doc.remove(unreconcile_doc.get("allocations", {"name": row})[0])
 
@@ -248,9 +252,9 @@
 				unreconcile_doc.save(ignore_permissions=True)
 
 		# delete docs upon parent doc deletion
-		unreconcile_docs = frappe.db.get_all("Unreconcile Payments", filters={"voucher_no": self.name})
+		unreconcile_docs = frappe.db.get_all("Unreconcile Payment", filters={"voucher_no": self.name})
 		for x in unreconcile_docs:
-			_doc = frappe.get_doc("Unreconcile Payments", x.name)
+			_doc = frappe.get_doc("Unreconcile Payment", x.name)
 			if _doc.docstatus == 1:
 				_doc.cancel()
 			_doc.delete()
@@ -625,6 +629,7 @@
 
 					args["doctype"] = self.doctype
 					args["name"] = self.name
+					args["child_doctype"] = item.doctype
 					args["child_docname"] = item.name
 					args["ignore_pricing_rule"] = (
 						self.ignore_pricing_rule if hasattr(self, "ignore_pricing_rule") else 0
@@ -910,10 +915,16 @@
 			return flt(args.get(field, 0) / self.get("conversion_rate", 1))
 
 	def validate_qty_is_not_zero(self):
-		if self.doctype != "Purchase Receipt":
-			for item in self.items:
-				if not item.qty:
-					frappe.throw(_("Item quantity can not be zero"))
+		if self.doctype == "Purchase Receipt":
+			return
+
+		for item in self.items:
+			if not flt(item.qty):
+				frappe.throw(
+					msg=_("Row #{0}: Item quantity cannot be zero").format(item.idx),
+					title=_("Invalid Quantity"),
+					exc=InvalidQtyError,
+				)
 
 	def validate_account_currency(self, account, account_currency=None):
 		valid_currency = [self.company_currency]
@@ -2953,6 +2964,9 @@
 		d.cancel()
 		d.delete()
 
+	if parent.doctype == "Purchase Order":
+		parent.update_ordered_qty_in_so_for_removed_items(deleted_children)
+
 	# need to update ordered qty in Material Request first
 	# bin uses Material Request Items to recalculate & update
 	parent.update_prevdoc_status()
@@ -3147,16 +3161,19 @@
 		conv_fac_precision = child_item.precision("conversion_factor") or 2
 		qty_precision = child_item.precision("qty") or 2
 
-		if flt(child_item.billed_amt, rate_precision) > flt(
-			flt(d.get("rate"), rate_precision) * flt(d.get("qty"), qty_precision), rate_precision
-		):
+		# 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 amount is greater than billed amount for Item {1}.").format(
 					child_item.idx, child_item.item_code
 				)
 			)
 		else:
-			child_item.rate = flt(d.get("rate"), rate_precision)
+			child_item.rate = row_rate
 
 		if d.get("conversion_factor"):
 			if child_item.stock_uom == child_item.uom:
@@ -3240,7 +3257,10 @@
 
 	if parent_doctype == "Purchase Order":
 		update_last_purchase_rate(parent, is_submit=1)
-		parent.update_prevdoc_status()
+
+		if any_qty_changed or items_added_or_removed or any_conversion_factor_changed:
+			parent.update_prevdoc_status()
+
 		parent.update_requested_qty()
 		parent.update_ordered_qty()
 		parent.update_ordered_and_reserved_qty()
diff --git a/erpnext/controllers/buying_controller.py b/erpnext/controllers/buying_controller.py
index ece08d8..3d863e9 100644
--- a/erpnext/controllers/buying_controller.py
+++ b/erpnext/controllers/buying_controller.py
@@ -118,6 +118,7 @@
 							"company": self.company,
 							"voucher_type": self.doctype,
 							"voucher_no": self.name,
+							"voucher_detail_no": row.name,
 						},
 						raise_error_if_no_rate=False,
 					)
@@ -365,7 +366,7 @@
 						{
 							"item_code": d.item_code,
 							"warehouse": d.get("from_warehouse"),
-							"posting_date": self.get("posting_date") or self.get("transation_date"),
+							"posting_date": self.get("posting_date") or self.get("transaction_date"),
 							"posting_time": posting_time,
 							"qty": -1 * flt(d.get("stock_qty")),
 							"serial_and_batch_bundle": d.get("serial_and_batch_bundle"),
@@ -373,6 +374,7 @@
 							"voucher_type": self.doctype,
 							"voucher_no": self.name,
 							"allow_zero_valuation": d.get("allow_zero_valuation"),
+							"voucher_detail_no": d.name,
 						},
 						raise_error_if_no_rate=False,
 					)
@@ -440,7 +442,7 @@
 
 				if allow_to_edit_stock_qty:
 					d.stock_qty = flt(d.stock_qty, d.precision("stock_qty"))
-					if d.get("received_stock_qty"):
+					if d.get("received_stock_qty") and d.meta.get_field("received_stock_qty"):
 						d.received_stock_qty = flt(d.received_stock_qty, d.precision("received_stock_qty"))
 
 	def validate_purchase_return(self):
@@ -758,7 +760,7 @@
 				"calculate_depreciation": 0,
 				"purchase_receipt_amount": purchase_amount,
 				"gross_purchase_amount": purchase_amount,
-				"asset_quantity": row.qty if is_grouped_asset else 0,
+				"asset_quantity": row.qty if is_grouped_asset else 1,
 				"purchase_receipt": self.name if self.doctype == "Purchase Receipt" else None,
 				"purchase_invoice": self.name if self.doctype == "Purchase Invoice" else None,
 			}
diff --git a/erpnext/controllers/sales_and_purchase_return.py b/erpnext/controllers/sales_and_purchase_return.py
index 165e17b..81e71e3 100644
--- a/erpnext/controllers/sales_and_purchase_return.py
+++ b/erpnext/controllers/sales_and_purchase_return.py
@@ -356,6 +356,7 @@
 			if doc.doctype == "Sales Invoice" or doc.doctype == "POS Invoice":
 				doc.consolidated_invoice = ""
 				doc.set("payments", [])
+				doc.update_billed_amount_in_delivery_note = True
 				for data in source.payments:
 					paid_amount = 0.00
 					base_paid_amount = 0.00
@@ -390,7 +391,10 @@
 		if doc.get("discount_amount"):
 			doc.discount_amount = -1 * source.discount_amount
 
-		if doctype != "Subcontracting Receipt":
+		if doctype == "Subcontracting Receipt":
+			doc.set_warehouse = source.set_warehouse
+			doc.supplier_warehouse = source.supplier_warehouse
+		else:
 			doc.run_method("calculate_taxes_and_totals")
 
 	def update_item(source_doc, target_doc, source_parent):
@@ -582,8 +586,6 @@
 		set_missing_values,
 	)
 
-	doclist.set_onload("ignore_price_list", True)
-
 	return doclist
 
 
diff --git a/erpnext/controllers/selling_controller.py b/erpnext/controllers/selling_controller.py
index d34fbeb..fdadb30 100644
--- a/erpnext/controllers/selling_controller.py
+++ b/erpnext/controllers/selling_controller.py
@@ -350,11 +350,12 @@
 		return il
 
 	def has_product_bundle(self, item_code):
-		return frappe.db.sql(
-			"""select name from `tabProduct Bundle`
-			where new_item_code=%s and docstatus != 2""",
-			item_code,
-		)
+		product_bundle = frappe.qb.DocType("Product Bundle")
+		return (
+			frappe.qb.from_(product_bundle)
+			.select(product_bundle.name)
+			.where((product_bundle.new_item_code == item_code) & (product_bundle.disabled == 0))
+		).run()
 
 	def get_already_delivered_qty(self, current_docname, so, so_detail):
 		delivered_via_dn = frappe.db.sql(
@@ -443,6 +444,7 @@
 							"company": self.company,
 							"voucher_type": self.doctype,
 							"voucher_no": self.name,
+							"voucher_detail_no": d.name,
 							"allow_zero_valuation": d.get("allow_zero_valuation"),
 						},
 						raise_error_if_no_rate=False,
diff --git a/erpnext/controllers/subcontracting_controller.py b/erpnext/controllers/subcontracting_controller.py
index 5fa66b1..9555902 100644
--- a/erpnext/controllers/subcontracting_controller.py
+++ b/erpnext/controllers/subcontracting_controller.py
@@ -626,6 +626,18 @@
 						(row.item_code, row.get(self.subcontract_data.order_field))
 					] -= row.qty
 
+	def __set_rate_for_serial_and_batch_bundle(self):
+		if self.doctype != "Subcontracting Receipt":
+			return
+
+		for row in self.get(self.raw_material_table):
+			if not row.get("serial_and_batch_bundle"):
+				continue
+
+			row.rate = frappe.get_cached_value(
+				"Serial and Batch Bundle", row.serial_and_batch_bundle, "avg_rate"
+			)
+
 	def __modify_serial_and_batch_bundle(self):
 		if self.is_new():
 			return
@@ -681,6 +693,7 @@
 		self.__remove_changed_rows()
 		self.__set_supplied_items()
 		self.__modify_serial_and_batch_bundle()
+		self.__set_rate_for_serial_and_batch_bundle()
 
 	def __validate_batch_no(self, row, key):
 		if row.get("batch_no") and row.get("batch_no") not in self.__transferred_items.get(key).get(
@@ -867,6 +880,7 @@
 							"posting_date": self.posting_date,
 							"posting_time": self.posting_time,
 							"qty": -1 * item.consumed_qty,
+							"voucher_detail_no": item.name,
 							"serial_and_batch_bundle": item.serial_and_batch_bundle,
 						}
 					)
@@ -939,6 +953,23 @@
 
 		return self._sub_contracted_items
 
+	def update_requested_qty(self):
+		material_request_map = {}
+		for d in self.get("items"):
+			if d.material_request_item:
+				material_request_map.setdefault(d.material_request, []).append(d.material_request_item)
+
+		for mr, mr_item_rows in material_request_map.items():
+			if mr and mr_item_rows:
+				mr_obj = frappe.get_doc("Material Request", mr)
+
+				if mr_obj.status in ["Stopped", "Cancelled"]:
+					frappe.throw(
+						_("Material Request {0} is cancelled or stopped").format(mr), frappe.InvalidStatusError
+					)
+
+				mr_obj.update_requested_qty(mr_item_rows)
+
 
 def get_item_details(items):
 	item = frappe.qb.DocType("Item")
diff --git a/erpnext/controllers/taxes_and_totals.py b/erpnext/controllers/taxes_and_totals.py
index 96284d6..f9f68a1 100644
--- a/erpnext/controllers/taxes_and_totals.py
+++ b/erpnext/controllers/taxes_and_totals.py
@@ -54,6 +54,7 @@
 		if self.doc.apply_discount_on == "Grand Total" and self.doc.get("is_cash_or_non_trade_discount"):
 			self.doc.grand_total -= self.doc.discount_amount
 			self.doc.base_grand_total -= self.doc.base_discount_amount
+			self.doc.rounding_adjustment = self.doc.base_rounding_adjustment = 0.0
 			self.set_rounded_total()
 
 		self.calculate_shipping_charges()
diff --git a/erpnext/controllers/tests/test_subcontracting_controller.py b/erpnext/controllers/tests/test_subcontracting_controller.py
index 6b61ae9..47762ac 100644
--- a/erpnext/controllers/tests/test_subcontracting_controller.py
+++ b/erpnext/controllers/tests/test_subcontracting_controller.py
@@ -1001,6 +1001,7 @@
 		"Subcontracted Item SA5": {},
 		"Subcontracted Item SA6": {},
 		"Subcontracted Item SA7": {},
+		"Subcontracted Item SA8": {},
 	}
 
 	for item, properties in sub_contracted_items.items():
@@ -1020,6 +1021,7 @@
 		},
 		"Subcontracted SRM Item 4": {"has_serial_no": 1, "serial_no_series": "SRII.####"},
 		"Subcontracted SRM Item 5": {"has_serial_no": 1, "serial_no_series": "SRIID.####"},
+		"Subcontracted SRM Item 8": {},
 	}
 
 	for item, properties in raw_materials.items():
@@ -1043,6 +1045,7 @@
 		"Subcontracted Service Item 5": {},
 		"Subcontracted Service Item 6": {},
 		"Subcontracted Service Item 7": {},
+		"Subcontracted Service Item 8": {},
 	}
 
 	for item, properties in service_items.items():
@@ -1066,6 +1069,7 @@
 		"Subcontracted Item SA5": ["Subcontracted SRM Item 5"],
 		"Subcontracted Item SA6": ["Subcontracted SRM Item 3"],
 		"Subcontracted Item SA7": ["Subcontracted SRM Item 1"],
+		"Subcontracted Item SA8": ["Subcontracted SRM Item 8"],
 	}
 
 	for item_code, raw_materials in boms.items():
diff --git a/erpnext/crm/doctype/appointment/appointment.py b/erpnext/crm/doctype/appointment/appointment.py
index bd49bdc..7be6fdc 100644
--- a/erpnext/crm/doctype/appointment/appointment.py
+++ b/erpnext/crm/doctype/appointment/appointment.py
@@ -14,6 +14,26 @@
 
 
 class Appointment(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
+
+		appointment_with: DF.Link | None
+		calendar_event: DF.Link | None
+		customer_details: DF.LongText | None
+		customer_email: DF.Data
+		customer_name: DF.Data
+		customer_phone_number: DF.Data | None
+		customer_skype: DF.Data | None
+		party: DF.DynamicLink | None
+		scheduled_time: DF.Datetime
+		status: DF.Literal["Open", "Unverified", "Closed"]
+	# end: auto-generated types
+
 	def find_lead_by_email(self):
 		lead_list = frappe.get_list(
 			"Lead", filters={"email_id": self.customer_email}, ignore_permissions=True
diff --git a/erpnext/crm/doctype/appointment_booking_settings/appointment_booking_settings.py b/erpnext/crm/doctype/appointment_booking_settings/appointment_booking_settings.py
index e43f460..77e8727 100644
--- a/erpnext/crm/doctype/appointment_booking_settings/appointment_booking_settings.py
+++ b/erpnext/crm/doctype/appointment_booking_settings/appointment_booking_settings.py
@@ -10,6 +10,32 @@
 
 
 class AppointmentBookingSettings(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.automation.doctype.assignment_rule_user.assignment_rule_user import (
+			AssignmentRuleUser,
+		)
+		from frappe.types import DF
+
+		from erpnext.crm.doctype.appointment_booking_slots.appointment_booking_slots import (
+			AppointmentBookingSlots,
+		)
+
+		advance_booking_days: DF.Int
+		agent_list: DF.TableMultiSelect[AssignmentRuleUser]
+		appointment_duration: DF.Int
+		availability_of_slots: DF.Table[AppointmentBookingSlots]
+		email_reminders: DF.Check
+		enable_scheduling: DF.Check
+		holiday_list: DF.Link
+		number_of_agents: DF.Int
+		success_redirect_url: DF.Data | None
+	# end: auto-generated types
+
 	agent_list = []  # Hack
 	min_date = "01/01/1970 "
 	format_string = "%d/%m/%Y %H:%M:%S"
diff --git a/erpnext/crm/doctype/appointment_booking_slots/appointment_booking_slots.py b/erpnext/crm/doctype/appointment_booking_slots/appointment_booking_slots.py
index 756c849..ee936dd 100644
--- a/erpnext/crm/doctype/appointment_booking_slots/appointment_booking_slots.py
+++ b/erpnext/crm/doctype/appointment_booking_slots/appointment_booking_slots.py
@@ -7,4 +7,22 @@
 
 
 class AppointmentBookingSlots(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
+
+		day_of_week: DF.Literal[
+			"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"
+		]
+		from_time: DF.Time
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		to_time: DF.Time
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/crm/doctype/availability_of_slots/availability_of_slots.py b/erpnext/crm/doctype/availability_of_slots/availability_of_slots.py
index 4294e6d..67b6fde 100644
--- a/erpnext/crm/doctype/availability_of_slots/availability_of_slots.py
+++ b/erpnext/crm/doctype/availability_of_slots/availability_of_slots.py
@@ -7,4 +7,22 @@
 
 
 class AvailabilityOfSlots(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
+
+		day_of_week: DF.Literal[
+			"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"
+		]
+		from_time: DF.Time
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		to_time: DF.Time
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/crm/doctype/campaign/campaign.py b/erpnext/crm/doctype/campaign/campaign.py
index 5d06075..5e14b0e 100644
--- a/erpnext/crm/doctype/campaign/campaign.py
+++ b/erpnext/crm/doctype/campaign/campaign.py
@@ -7,6 +7,24 @@
 
 
 class Campaign(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
+
+		from erpnext.crm.doctype.campaign_email_schedule.campaign_email_schedule import (
+			CampaignEmailSchedule,
+		)
+
+		campaign_name: DF.Data
+		campaign_schedules: DF.Table[CampaignEmailSchedule]
+		description: DF.Text | None
+		naming_series: DF.Literal["SAL-CAM-.YYYY.-"]
+	# end: auto-generated types
+
 	def autoname(self):
 		if frappe.defaults.get_global_default("campaign_naming_by") != "Naming Series":
 			self.name = self.campaign_name
diff --git a/erpnext/crm/doctype/campaign_email_schedule/campaign_email_schedule.py b/erpnext/crm/doctype/campaign_email_schedule/campaign_email_schedule.py
index de9b5a1..fdafab2 100644
--- a/erpnext/crm/doctype/campaign_email_schedule/campaign_email_schedule.py
+++ b/erpnext/crm/doctype/campaign_email_schedule/campaign_email_schedule.py
@@ -7,4 +7,19 @@
 
 
 class CampaignEmailSchedule(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
+
+		email_template: DF.Link
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		send_after_days: DF.Int
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/crm/doctype/competitor/competitor.json b/erpnext/crm/doctype/competitor/competitor.json
index 280441f..fd6da23 100644
--- a/erpnext/crm/doctype/competitor/competitor.json
+++ b/erpnext/crm/doctype/competitor/competitor.json
@@ -29,8 +29,16 @@
   }
  ],
  "index_web_pages_for_search": 1,
- "links": [],
- "modified": "2021-10-21 12:43:59.106807",
+ "links": [
+  {
+   "is_child_table": 1,
+   "link_doctype": "Competitor Detail",
+   "link_fieldname": "competitor",
+   "parent_doctype": "Quotation",
+   "table_fieldname": "competitors"
+  }
+ ],
+ "modified": "2023-11-23 19:33:54.284279",
  "modified_by": "Administrator",
  "module": "CRM",
  "name": "Competitor",
@@ -64,5 +72,6 @@
  "quick_entry": 1,
  "sort_field": "modified",
  "sort_order": "DESC",
+ "states": [],
  "track_changes": 1
 }
\ No newline at end of file
diff --git a/erpnext/crm/doctype/competitor/competitor.py b/erpnext/crm/doctype/competitor/competitor.py
index a292e461..fdd8cba 100644
--- a/erpnext/crm/doctype/competitor/competitor.py
+++ b/erpnext/crm/doctype/competitor/competitor.py
@@ -6,4 +6,16 @@
 
 
 class Competitor(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
+
+		competitor_name: DF.Data
+		website: DF.Data | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/crm/doctype/competitor_detail/competitor_detail.py b/erpnext/crm/doctype/competitor_detail/competitor_detail.py
index 0ef7560..6c7984f 100644
--- a/erpnext/crm/doctype/competitor_detail/competitor_detail.py
+++ b/erpnext/crm/doctype/competitor_detail/competitor_detail.py
@@ -6,4 +6,18 @@
 
 
 class CompetitorDetail(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
+
+		competitor: DF.Link
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/crm/doctype/contract/contract.py b/erpnext/crm/doctype/contract/contract.py
index 1c2470b..6f9dcde 100644
--- a/erpnext/crm/doctype/contract/contract.py
+++ b/erpnext/crm/doctype/contract/contract.py
@@ -9,6 +9,42 @@
 
 
 class Contract(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
+
+		from erpnext.crm.doctype.contract_fulfilment_checklist.contract_fulfilment_checklist import (
+			ContractFulfilmentChecklist,
+		)
+
+		amended_from: DF.Link | None
+		contract_template: DF.Link | None
+		contract_terms: DF.TextEditor
+		document_name: DF.DynamicLink | None
+		document_type: DF.Literal[
+			"", "Quotation", "Project", "Sales Order", "Purchase Order", "Sales Invoice", "Purchase Invoice"
+		]
+		end_date: DF.Date | None
+		fulfilment_deadline: DF.Date | None
+		fulfilment_status: DF.Literal["N/A", "Unfulfilled", "Partially Fulfilled", "Fulfilled", "Lapsed"]
+		fulfilment_terms: DF.Table[ContractFulfilmentChecklist]
+		ip_address: DF.Data | None
+		is_signed: DF.Check
+		party_name: DF.DynamicLink
+		party_type: DF.Literal["Customer", "Supplier", "Employee"]
+		party_user: DF.Link | None
+		requires_fulfilment: DF.Check
+		signed_by_company: DF.Link | None
+		signed_on: DF.Datetime | None
+		signee: DF.Data | None
+		start_date: DF.Date | None
+		status: DF.Literal["Unsigned", "Active", "Inactive"]
+	# end: auto-generated types
+
 	def autoname(self):
 		name = self.party_name
 
diff --git a/erpnext/crm/doctype/contract_fulfilment_checklist/contract_fulfilment_checklist.py b/erpnext/crm/doctype/contract_fulfilment_checklist/contract_fulfilment_checklist.py
index 4e4e998..43984c3 100644
--- a/erpnext/crm/doctype/contract_fulfilment_checklist/contract_fulfilment_checklist.py
+++ b/erpnext/crm/doctype/contract_fulfilment_checklist/contract_fulfilment_checklist.py
@@ -6,4 +6,21 @@
 
 
 class ContractFulfilmentChecklist(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
+
+		amended_from: DF.Link | None
+		fulfilled: DF.Check
+		notes: DF.Text | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		requirement: DF.Data | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/crm/doctype/contract_template/contract_template.py b/erpnext/crm/doctype/contract_template/contract_template.py
index a5b0ee0..7001975 100644
--- a/erpnext/crm/doctype/contract_template/contract_template.py
+++ b/erpnext/crm/doctype/contract_template/contract_template.py
@@ -10,6 +10,24 @@
 
 
 class ContractTemplate(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
+
+		from erpnext.crm.doctype.contract_template_fulfilment_terms.contract_template_fulfilment_terms import (
+			ContractTemplateFulfilmentTerms,
+		)
+
+		contract_terms: DF.TextEditor | None
+		fulfilment_terms: DF.Table[ContractTemplateFulfilmentTerms]
+		requires_fulfilment: DF.Check
+		title: DF.Data | None
+	# end: auto-generated types
+
 	def validate(self):
 		if self.contract_terms:
 			validate_template(self.contract_terms)
diff --git a/erpnext/crm/doctype/contract_template_fulfilment_terms/contract_template_fulfilment_terms.py b/erpnext/crm/doctype/contract_template_fulfilment_terms/contract_template_fulfilment_terms.py
index 18600d9..597940b 100644
--- a/erpnext/crm/doctype/contract_template_fulfilment_terms/contract_template_fulfilment_terms.py
+++ b/erpnext/crm/doctype/contract_template_fulfilment_terms/contract_template_fulfilment_terms.py
@@ -6,4 +6,18 @@
 
 
 class ContractTemplateFulfilmentTerms(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
+
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		requirement: DF.Data | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/crm/doctype/crm_note/crm_note.py b/erpnext/crm/doctype/crm_note/crm_note.py
index 6c7eeb4..531978c 100644
--- a/erpnext/crm/doctype/crm_note/crm_note.py
+++ b/erpnext/crm/doctype/crm_note/crm_note.py
@@ -6,4 +6,21 @@
 
 
 class CRMNote(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
+
+		added_by: DF.Link | None
+		added_on: DF.Datetime | None
+		name: DF.Int | None
+		note: DF.TextEditor | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/crm/doctype/crm_settings/crm_settings.py b/erpnext/crm/doctype/crm_settings/crm_settings.py
index 98cf7d8..499a6d7 100644
--- a/erpnext/crm/doctype/crm_settings/crm_settings.py
+++ b/erpnext/crm/doctype/crm_settings/crm_settings.py
@@ -6,5 +6,21 @@
 
 
 class CRMSettings(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
+
+		allow_lead_duplication_based_on_emails: DF.Check
+		auto_creation_of_contact: DF.Check
+		campaign_naming_by: DF.Literal["Campaign Name", "Naming Series"]
+		carry_forward_communication_and_comments: DF.Check
+		close_opportunity_after_days: DF.Int
+		default_valid_till: DF.Data | None
+	# end: auto-generated types
+
 	def validate(self):
 		frappe.db.set_default("campaign_naming_by", self.get("campaign_naming_by", ""))
diff --git a/erpnext/crm/doctype/email_campaign/email_campaign.py b/erpnext/crm/doctype/email_campaign/email_campaign.py
index 9ec54ff..17cf0e4 100644
--- a/erpnext/crm/doctype/email_campaign/email_campaign.py
+++ b/erpnext/crm/doctype/email_campaign/email_campaign.py
@@ -10,6 +10,23 @@
 
 
 class EmailCampaign(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
+
+		campaign_name: DF.Link
+		email_campaign_for: DF.Literal["", "Lead", "Contact", "Email Group"]
+		end_date: DF.Date | None
+		recipient: DF.DynamicLink
+		sender: DF.Link | None
+		start_date: DF.Date
+		status: DF.Literal["", "Scheduled", "In Progress", "Completed", "Unsubscribed"]
+	# end: auto-generated types
+
 	def validate(self):
 		self.set_date()
 		# checking if email is set for lead. Not checking for contact as email is a mandatory field for contact.
diff --git a/erpnext/crm/doctype/lead/lead.py b/erpnext/crm/doctype/lead/lead.py
index fdec88d..f0fc1aa 100644
--- a/erpnext/crm/doctype/lead/lead.py
+++ b/erpnext/crm/doctype/lead/lead.py
@@ -19,6 +19,72 @@
 
 
 class Lead(SellingController, CRMNote):
+	# 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
+
+		from erpnext.crm.doctype.crm_note.crm_note import CRMNote
+
+		annual_revenue: DF.Currency
+		blog_subscriber: DF.Check
+		campaign_name: DF.Link | None
+		city: DF.Data | None
+		company: DF.Link | None
+		company_name: DF.Data | None
+		country: DF.Link | None
+		customer: DF.Link | None
+		disabled: DF.Check
+		email_id: DF.Data | None
+		fax: DF.Data | None
+		first_name: DF.Data | None
+		gender: DF.Link | None
+		image: DF.AttachImage | None
+		industry: DF.Link | None
+		job_title: DF.Data | None
+		language: DF.Link | None
+		last_name: DF.Data | None
+		lead_name: DF.Data | None
+		lead_owner: DF.Link | None
+		market_segment: DF.Link | None
+		middle_name: DF.Data | None
+		mobile_no: DF.Data | None
+		naming_series: DF.Literal["CRM-LEAD-.YYYY.-"]
+		no_of_employees: DF.Literal["1-10", "11-50", "51-200", "201-500", "501-1000", "1000+"]
+		notes: DF.Table[CRMNote]
+		phone: DF.Data | None
+		phone_ext: DF.Data | None
+		qualification_status: DF.Literal["Unqualified", "In Process", "Qualified"]
+		qualified_by: DF.Link | None
+		qualified_on: DF.Date | None
+		request_type: DF.Literal[
+			"", "Product Enquiry", "Request for Information", "Suggestions", "Other"
+		]
+		salutation: DF.Link | None
+		source: DF.Link | None
+		state: DF.Data | None
+		status: DF.Literal[
+			"Lead",
+			"Open",
+			"Replied",
+			"Opportunity",
+			"Quotation",
+			"Lost Quotation",
+			"Interested",
+			"Converted",
+			"Do Not Contact",
+		]
+		territory: DF.Link | None
+		title: DF.Data | None
+		type: DF.Literal["", "Client", "Channel Partner", "Consultant"]
+		unsubscribed: DF.Check
+		website: DF.Data | None
+		whatsapp_no: DF.Data | None
+	# end: auto-generated types
+
 	def onload(self):
 		customer = frappe.db.get_value("Customer", {"lead_name": self.name})
 		self.get("__onload").is_customer = customer
@@ -36,6 +102,15 @@
 	def before_insert(self):
 		self.contact_doc = None
 		if frappe.db.get_single_value("CRM Settings", "auto_creation_of_contact"):
+			if self.source == "Existing Customer" and self.customer:
+				contact = frappe.db.get_value(
+					"Dynamic Link",
+					{"link_doctype": "Customer", "link_name": self.customer},
+					"parent",
+				)
+				if contact:
+					self.contact_doc = frappe.get_doc("Contact", contact)
+					return
 			self.contact_doc = self.create_contact()
 
 	def after_insert(self):
diff --git a/erpnext/crm/doctype/lead_source/lead_source.py b/erpnext/crm/doctype/lead_source/lead_source.py
index d9e0028..b426a32 100644
--- a/erpnext/crm/doctype/lead_source/lead_source.py
+++ b/erpnext/crm/doctype/lead_source/lead_source.py
@@ -7,4 +7,16 @@
 
 
 class LeadSource(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
+
+		details: DF.TextEditor | None
+		source_name: DF.Data
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/crm/doctype/lost_reason_detail/lost_reason_detail.py b/erpnext/crm/doctype/lost_reason_detail/lost_reason_detail.py
index 51e4d5c..e711509 100644
--- a/erpnext/crm/doctype/lost_reason_detail/lost_reason_detail.py
+++ b/erpnext/crm/doctype/lost_reason_detail/lost_reason_detail.py
@@ -6,4 +6,18 @@
 
 
 class LostReasonDetail(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
+
+		lost_reason: DF.Link | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/crm/doctype/market_segment/market_segment.py b/erpnext/crm/doctype/market_segment/market_segment.py
index 766be85..1631802 100644
--- a/erpnext/crm/doctype/market_segment/market_segment.py
+++ b/erpnext/crm/doctype/market_segment/market_segment.py
@@ -6,4 +6,15 @@
 
 
 class MarketSegment(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
+
+		market_segment: DF.Data | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/crm/doctype/opportunity/opportunity.py b/erpnext/crm/doctype/opportunity/opportunity.py
index 2a8d65f..72e26de 100644
--- a/erpnext/crm/doctype/opportunity/opportunity.py
+++ b/erpnext/crm/doctype/opportunity/opportunity.py
@@ -25,6 +25,72 @@
 
 
 class Opportunity(TransactionBase, CRMNote):
+	# 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
+
+		from erpnext.crm.doctype.competitor_detail.competitor_detail import CompetitorDetail
+		from erpnext.crm.doctype.crm_note.crm_note import CRMNote
+		from erpnext.crm.doctype.opportunity_item.opportunity_item import OpportunityItem
+		from erpnext.crm.doctype.opportunity_lost_reason_detail.opportunity_lost_reason_detail import (
+			OpportunityLostReasonDetail,
+		)
+
+		address_display: DF.SmallText | None
+		amended_from: DF.Link | None
+		annual_revenue: DF.Currency
+		base_opportunity_amount: DF.Currency
+		base_total: DF.Currency
+		campaign: DF.Link | None
+		city: DF.Data | None
+		company: DF.Link
+		competitors: DF.TableMultiSelect[CompetitorDetail]
+		contact_display: DF.SmallText | None
+		contact_email: DF.Data | None
+		contact_mobile: DF.Data | None
+		contact_person: DF.Link | None
+		conversion_rate: DF.Float
+		country: DF.Link | None
+		currency: DF.Link | None
+		customer_address: DF.Link | None
+		customer_group: DF.Link | None
+		customer_name: DF.Data | None
+		expected_closing: DF.Date | None
+		first_response_time: DF.Duration | None
+		industry: DF.Link | None
+		items: DF.Table[OpportunityItem]
+		job_title: DF.Data | None
+		language: DF.Link | None
+		lost_reasons: DF.TableMultiSelect[OpportunityLostReasonDetail]
+		market_segment: DF.Link | None
+		naming_series: DF.Literal["CRM-OPP-.YYYY.-"]
+		no_of_employees: DF.Literal["1-10", "11-50", "51-200", "201-500", "501-1000", "1000+"]
+		notes: DF.Table[CRMNote]
+		opportunity_amount: DF.Currency
+		opportunity_from: DF.Link
+		opportunity_owner: DF.Link | None
+		opportunity_type: DF.Link | None
+		order_lost_reason: DF.SmallText | None
+		party_name: DF.DynamicLink
+		phone: DF.Data | None
+		phone_ext: DF.Data | None
+		probability: DF.Percent
+		sales_stage: DF.Link | None
+		source: DF.Link | None
+		state: DF.Data | None
+		status: DF.Literal["Open", "Quotation", "Converted", "Lost", "Replied", "Closed"]
+		territory: DF.Link | None
+		title: DF.Data | None
+		total: DF.Currency
+		transaction_date: DF.Date
+		website: DF.Data | None
+		whatsapp: DF.Data | None
+	# end: auto-generated types
+
 	def onload(self):
 		ref_doc = frappe.get_doc(self.opportunity_from, self.party_name)
 		load_address_and_contact(ref_doc)
diff --git a/erpnext/crm/doctype/opportunity_item/opportunity_item.json b/erpnext/crm/doctype/opportunity_item/opportunity_item.json
index 1b4973c..732f80d 100644
--- a/erpnext/crm/doctype/opportunity_item/opportunity_item.json
+++ b/erpnext/crm/doctype/opportunity_item/opportunity_item.json
@@ -103,6 +103,7 @@
    "fieldtype": "Column Break"
   },
   {
+   "fetch_from": "item_code.image",
    "fieldname": "image",
    "fieldtype": "Attach",
    "hidden": 1,
@@ -165,7 +166,7 @@
  "idx": 1,
  "istable": 1,
  "links": [],
- "modified": "2021-07-30 16:39:09.775720",
+ "modified": "2023-11-14 18:35:30.887278",
  "modified_by": "Administrator",
  "module": "CRM",
  "name": "Opportunity Item",
@@ -173,5 +174,6 @@
  "permissions": [],
  "sort_field": "modified",
  "sort_order": "DESC",
+ "states": [],
  "track_changes": 1
 }
\ No newline at end of file
diff --git a/erpnext/crm/doctype/opportunity_item/opportunity_item.py b/erpnext/crm/doctype/opportunity_item/opportunity_item.py
index 4d28587..b3b963e 100644
--- a/erpnext/crm/doctype/opportunity_item/opportunity_item.py
+++ b/erpnext/crm/doctype/opportunity_item/opportunity_item.py
@@ -6,4 +6,29 @@
 
 
 class OpportunityItem(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
+
+		amount: DF.Currency
+		base_amount: DF.Currency
+		base_rate: DF.Currency
+		brand: DF.Link | None
+		description: DF.TextEditor | None
+		image: DF.Attach | None
+		item_code: DF.Link | None
+		item_group: DF.Link | None
+		item_name: DF.Data | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		qty: DF.Float
+		rate: DF.Currency
+		uom: DF.Link | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/crm/doctype/opportunity_lost_reason/opportunity_lost_reason.py b/erpnext/crm/doctype/opportunity_lost_reason/opportunity_lost_reason.py
index 84a9a52..71f57ae 100644
--- a/erpnext/crm/doctype/opportunity_lost_reason/opportunity_lost_reason.py
+++ b/erpnext/crm/doctype/opportunity_lost_reason/opportunity_lost_reason.py
@@ -6,4 +6,15 @@
 
 
 class OpportunityLostReason(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
+
+		lost_reason: DF.Data | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/crm/doctype/opportunity_lost_reason_detail/opportunity_lost_reason_detail.py b/erpnext/crm/doctype/opportunity_lost_reason_detail/opportunity_lost_reason_detail.py
index d572185..7c434d3 100644
--- a/erpnext/crm/doctype/opportunity_lost_reason_detail/opportunity_lost_reason_detail.py
+++ b/erpnext/crm/doctype/opportunity_lost_reason_detail/opportunity_lost_reason_detail.py
@@ -7,4 +7,18 @@
 
 
 class OpportunityLostReasonDetail(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
+
+		lost_reason: DF.Link | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/crm/doctype/opportunity_type/opportunity_type.py b/erpnext/crm/doctype/opportunity_type/opportunity_type.py
index 1bb31ec..f944b5c 100644
--- a/erpnext/crm/doctype/opportunity_type/opportunity_type.py
+++ b/erpnext/crm/doctype/opportunity_type/opportunity_type.py
@@ -6,4 +6,15 @@
 
 
 class OpportunityType(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
+
+		description: DF.SmallText | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/crm/doctype/prospect/prospect.py b/erpnext/crm/doctype/prospect/prospect.py
index 8b66a83..7ecbe63 100644
--- a/erpnext/crm/doctype/prospect/prospect.py
+++ b/erpnext/crm/doctype/prospect/prospect.py
@@ -12,6 +12,34 @@
 
 
 class Prospect(CRMNote):
+	# 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
+
+		from erpnext.crm.doctype.crm_note.crm_note import CRMNote
+		from erpnext.crm.doctype.prospect_lead.prospect_lead import ProspectLead
+		from erpnext.crm.doctype.prospect_opportunity.prospect_opportunity import ProspectOpportunity
+
+		annual_revenue: DF.Currency
+		company: DF.Link
+		company_name: DF.Data | None
+		customer_group: DF.Link | None
+		fax: DF.Data | None
+		industry: DF.Link | None
+		leads: DF.Table[ProspectLead]
+		market_segment: DF.Link | None
+		no_of_employees: DF.Literal["1-10", "11-50", "51-200", "201-500", "501-1000", "1000+"]
+		notes: DF.Table[CRMNote]
+		opportunities: DF.Table[ProspectOpportunity]
+		prospect_owner: DF.Link | None
+		territory: DF.Link | None
+		website: DF.Data | None
+	# end: auto-generated types
+
 	def onload(self):
 		load_address_and_contact(self)
 
diff --git a/erpnext/crm/doctype/prospect_lead/prospect_lead.py b/erpnext/crm/doctype/prospect_lead/prospect_lead.py
index 40edbe0..f80c51e 100644
--- a/erpnext/crm/doctype/prospect_lead/prospect_lead.py
+++ b/erpnext/crm/doctype/prospect_lead/prospect_lead.py
@@ -6,4 +6,23 @@
 
 
 class ProspectLead(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
+
+		email: DF.Data | None
+		lead: DF.Link
+		lead_name: DF.Data | None
+		lead_owner: DF.Data | None
+		mobile_no: DF.Data | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		status: DF.Data | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/crm/doctype/prospect_opportunity/prospect_opportunity.py b/erpnext/crm/doctype/prospect_opportunity/prospect_opportunity.py
index 8f5d19a..a5f25a9 100644
--- a/erpnext/crm/doctype/prospect_opportunity/prospect_opportunity.py
+++ b/erpnext/crm/doctype/prospect_opportunity/prospect_opportunity.py
@@ -6,4 +6,26 @@
 
 
 class ProspectOpportunity(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
+
+		amount: DF.Currency
+		contact_person: DF.Link | None
+		currency: DF.Link | None
+		deal_owner: DF.Data | None
+		expected_closing: DF.Date | None
+		name: DF.Int | None
+		opportunity: DF.Link | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		probability: DF.Percent
+		stage: DF.Data | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/crm/doctype/sales_stage/sales_stage.py b/erpnext/crm/doctype/sales_stage/sales_stage.py
index d2099ed..aeb4ddb 100644
--- a/erpnext/crm/doctype/sales_stage/sales_stage.py
+++ b/erpnext/crm/doctype/sales_stage/sales_stage.py
@@ -6,4 +6,15 @@
 
 
 class SalesStage(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
+
+		stage_name: DF.Data | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_settings.py b/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_settings.py
index eb99345..ec7d71e 100644
--- a/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_settings.py
+++ b/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_settings.py
@@ -15,6 +15,22 @@
 
 
 class PlaidSettings(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
+
+		automatic_sync: DF.Check
+		enable_european_access: DF.Check
+		enabled: DF.Check
+		plaid_client_id: DF.Data | None
+		plaid_env: DF.Literal["sandbox", "development", "production"]
+		plaid_secret: DF.Password | None
+	# end: auto-generated types
+
 	@staticmethod
 	@frappe.whitelist()
 	def get_link_token():
diff --git a/erpnext/erpnext_integrations/doctype/quickbooks_migrator/quickbooks_migrator.py b/erpnext/erpnext_integrations/doctype/quickbooks_migrator/quickbooks_migrator.py
index da56997..ec7a6e9 100644
--- a/erpnext/erpnext_integrations/doctype/quickbooks_migrator/quickbooks_migrator.py
+++ b/erpnext/erpnext_integrations/doctype/quickbooks_migrator/quickbooks_migrator.py
@@ -34,6 +34,36 @@
 
 
 class QuickBooksMigrator(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
+
+		access_token: DF.SmallText | None
+		api_endpoint: DF.Data
+		authorization_endpoint: DF.Data
+		authorization_url: DF.Data
+		client_id: DF.Data
+		client_secret: DF.Data
+		code: DF.Data | None
+		company: DF.Link | None
+		default_cost_center: DF.Link | None
+		default_shipping_account: DF.Link | None
+		default_warehouse: DF.Link | None
+		quickbooks_company_id: DF.Data | None
+		redirect_url: DF.Data
+		refresh_token: DF.SmallText | None
+		scope: DF.Data
+		status: DF.Literal[
+			"Connecting to QuickBooks", "Connected to QuickBooks", "In Progress", "Complete", "Failed"
+		]
+		token_endpoint: DF.Data
+		undeposited_funds_account: DF.Link | None
+	# end: auto-generated types
+
 	def __init__(self, *args, **kwargs):
 		super(QuickBooksMigrator, self).__init__(*args, **kwargs)
 		self.oauth = OAuth2Session(
diff --git a/erpnext/erpnext_integrations/doctype/tally_migration/tally_migration.py b/erpnext/erpnext_integrations/doctype/tally_migration/tally_migration.py
index e6840f5..8ebca54 100644
--- a/erpnext/erpnext_integrations/doctype/tally_migration/tally_migration.py
+++ b/erpnext/erpnext_integrations/doctype/tally_migration/tally_migration.py
@@ -40,6 +40,39 @@
 
 
 class TallyMigration(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
+
+		addresses: DF.Attach | None
+		chart_of_accounts: DF.Attach | None
+		day_book_data: DF.Attach | None
+		default_cost_center: DF.Link | None
+		default_round_off_account: DF.Link | None
+		default_uom: DF.Link | None
+		default_warehouse: DF.Link | None
+		erpnext_company: DF.Data | None
+		failed_import_log: DF.Code | None
+		fixed_errors_log: DF.Code | None
+		is_day_book_data_imported: DF.Check
+		is_day_book_data_processed: DF.Check
+		is_master_data_imported: DF.Check
+		is_master_data_processed: DF.Check
+		items: DF.Attach | None
+		master_data: DF.Attach | None
+		parties: DF.Attach | None
+		status: DF.Data | None
+		tally_company: DF.Data | None
+		tally_creditors_account: DF.Data
+		tally_debtors_account: DF.Data
+		uoms: DF.Attach | None
+		vouchers: DF.Attach | None
+	# end: auto-generated types
+
 	def validate(self):
 		failed_import_log = json.loads(self.failed_import_log)
 		sorted_failed_import_log = sorted(failed_import_log, key=lambda row: row["doc"]["creation"])
diff --git a/erpnext/hooks.py b/erpnext/hooks.py
index 5483a10..17ad155 100644
--- a/erpnext/hooks.py
+++ b/erpnext/hooks.py
@@ -419,9 +419,8 @@
 		"erpnext.projects.doctype.project.project.collect_project_status",
 	],
 	"hourly_long": [
-		"erpnext.accounts.doctype.process_subscription.process_subscription.create_subscription_process",
 		"erpnext.stock.doctype.repost_item_valuation.repost_item_valuation.repost_entries",
-		"erpnext.bulk_transaction.doctype.bulk_transaction_log.bulk_transaction_log.retry_failing_transaction",
+		"erpnext.utilities.bulk_transaction.retry",
 	],
 	"daily": [
 		"erpnext.support.doctype.issue.issue.auto_close_tickets",
@@ -450,6 +449,7 @@
 		"erpnext.accounts.utils.auto_create_exchange_rate_revaluation_weekly",
 	],
 	"daily_long": [
+		"erpnext.accounts.doctype.process_subscription.process_subscription.create_subscription_process",
 		"erpnext.setup.doctype.email_digest.email_digest.send",
 		"erpnext.manufacturing.doctype.bom_update_tool.bom_update_tool.auto_update_latest_price_in_all_boms",
 		"erpnext.crm.utils.open_leads_opportunities_based_on_todays_event",
@@ -539,6 +539,8 @@
 	"Subcontracting Receipt",
 	"Subcontracting Receipt Item",
 	"Account Closing Balance",
+	"Supplier Quotation",
+	"Supplier Quotation Item",
 ]
 
 get_matching_queries = (
@@ -636,3 +638,10 @@
 extend_bootinfo = [
 	"erpnext.support.doctype.service_level_agreement.service_level_agreement.add_sla_doctypes",
 ]
+
+
+default_log_clearing_doctypes = {
+	"Repost Item Valuation": 60,
+}
+
+export_python_type_annotations = True
diff --git a/erpnext/maintenance/doctype/maintenance_schedule/maintenance_schedule.py b/erpnext/maintenance/doctype/maintenance_schedule/maintenance_schedule.py
index e5bb9e8..6100756 100644
--- a/erpnext/maintenance/doctype/maintenance_schedule/maintenance_schedule.py
+++ b/erpnext/maintenance/doctype/maintenance_schedule/maintenance_schedule.py
@@ -11,6 +11,40 @@
 
 
 class MaintenanceSchedule(TransactionBase):
+	# 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
+
+		from erpnext.maintenance.doctype.maintenance_schedule_detail.maintenance_schedule_detail import (
+			MaintenanceScheduleDetail,
+		)
+		from erpnext.maintenance.doctype.maintenance_schedule_item.maintenance_schedule_item import (
+			MaintenanceScheduleItem,
+		)
+
+		address_display: DF.SmallText | None
+		amended_from: DF.Link | None
+		company: DF.Link
+		contact_display: DF.SmallText | None
+		contact_email: DF.Data | None
+		contact_mobile: DF.Data | None
+		contact_person: DF.Link | None
+		customer: DF.Link | None
+		customer_address: DF.Link | None
+		customer_group: DF.Link | None
+		customer_name: DF.Data | None
+		items: DF.Table[MaintenanceScheduleItem]
+		naming_series: DF.Literal["MAT-MSH-.YYYY.-"]
+		schedules: DF.Table[MaintenanceScheduleDetail]
+		status: DF.Literal["", "Draft", "Submitted", "Cancelled"]
+		territory: DF.Link | None
+		transaction_date: DF.Date
+	# end: auto-generated types
+
 	@frappe.whitelist()
 	def generate_schedule(self):
 		if self.docstatus != 0:
diff --git a/erpnext/maintenance/doctype/maintenance_schedule_detail/maintenance_schedule_detail.py b/erpnext/maintenance/doctype/maintenance_schedule_detail/maintenance_schedule_detail.py
index cb20066..0bc3eee 100644
--- a/erpnext/maintenance/doctype/maintenance_schedule_detail/maintenance_schedule_detail.py
+++ b/erpnext/maintenance/doctype/maintenance_schedule_detail/maintenance_schedule_detail.py
@@ -6,4 +6,25 @@
 
 
 class MaintenanceScheduleDetail(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
+
+		actual_date: DF.Date | None
+		completion_status: DF.Literal["Pending", "Partially Completed", "Fully Completed"]
+		item_code: DF.Link | None
+		item_name: DF.Data | None
+		item_reference: DF.Link | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		sales_person: DF.Link | None
+		scheduled_date: DF.Date
+		serial_no: DF.SmallText | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/maintenance/doctype/maintenance_schedule_item/maintenance_schedule_item.py b/erpnext/maintenance/doctype/maintenance_schedule_item/maintenance_schedule_item.py
index b6ce0a5..448b081 100644
--- a/erpnext/maintenance/doctype/maintenance_schedule_item/maintenance_schedule_item.py
+++ b/erpnext/maintenance/doctype/maintenance_schedule_item/maintenance_schedule_item.py
@@ -6,4 +6,28 @@
 
 
 class MaintenanceScheduleItem(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
+
+		description: DF.TextEditor | None
+		end_date: DF.Date
+		item_code: DF.Link
+		item_name: DF.Data | None
+		no_of_visits: DF.Int
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		periodicity: DF.Literal["", "Weekly", "Monthly", "Quarterly", "Half Yearly", "Yearly", "Random"]
+		sales_order: DF.Link | None
+		sales_person: DF.Link | None
+		serial_and_batch_bundle: DF.Link | None
+		serial_no: DF.SmallText | None
+		start_date: DF.Date
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/maintenance/doctype/maintenance_visit/maintenance_visit.py b/erpnext/maintenance/doctype/maintenance_visit/maintenance_visit.py
index b900b21..e7df484 100644
--- a/erpnext/maintenance/doctype/maintenance_visit/maintenance_visit.py
+++ b/erpnext/maintenance/doctype/maintenance_visit/maintenance_visit.py
@@ -10,6 +10,42 @@
 
 
 class MaintenanceVisit(TransactionBase):
+	# 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
+
+		from erpnext.maintenance.doctype.maintenance_visit_purpose.maintenance_visit_purpose import (
+			MaintenanceVisitPurpose,
+		)
+
+		address_display: DF.SmallText | None
+		amended_from: DF.Link | None
+		company: DF.Link
+		completion_status: DF.Literal["", "Partially Completed", "Fully Completed"]
+		contact_display: DF.SmallText | None
+		contact_email: DF.Data | None
+		contact_mobile: DF.Data | None
+		contact_person: DF.Link | None
+		customer: DF.Link
+		customer_address: DF.Link | None
+		customer_feedback: DF.SmallText | None
+		customer_group: DF.Link | None
+		customer_name: DF.Data | None
+		maintenance_schedule: DF.Link | None
+		maintenance_schedule_detail: DF.Link | None
+		maintenance_type: DF.Literal["", "Scheduled", "Unscheduled", "Breakdown"]
+		mntc_date: DF.Date
+		mntc_time: DF.Time | None
+		naming_series: DF.Literal["MAT-MVS-.YYYY.-"]
+		purposes: DF.Table[MaintenanceVisitPurpose]
+		status: DF.Literal["", "Draft", "Cancelled", "Submitted"]
+		territory: DF.Link | None
+	# end: auto-generated types
+
 	def validate_serial_no(self):
 		for d in self.get("purposes"):
 			if d.serial_no and not frappe.db.exists("Serial No", d.serial_no):
diff --git a/erpnext/maintenance/doctype/maintenance_visit_purpose/maintenance_visit_purpose.py b/erpnext/maintenance/doctype/maintenance_visit_purpose/maintenance_visit_purpose.py
index 50d9a4e..3686941 100644
--- a/erpnext/maintenance/doctype/maintenance_visit_purpose/maintenance_visit_purpose.py
+++ b/erpnext/maintenance/doctype/maintenance_visit_purpose/maintenance_visit_purpose.py
@@ -6,4 +6,25 @@
 
 
 class MaintenanceVisitPurpose(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
+
+		description: DF.TextEditor
+		item_code: DF.Link | None
+		item_name: DF.Data | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		prevdoc_docname: DF.DynamicLink | None
+		prevdoc_doctype: DF.Link | None
+		serial_no: DF.Link | None
+		service_person: DF.Link
+		work_done: DF.SmallText
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/manufacturing/doctype/blanket_order/blanket_order.py b/erpnext/manufacturing/doctype/blanket_order/blanket_order.py
index 0135a4f..b5ab63e 100644
--- a/erpnext/manufacturing/doctype/blanket_order/blanket_order.py
+++ b/erpnext/manufacturing/doctype/blanket_order/blanket_order.py
@@ -13,6 +13,31 @@
 
 
 class BlanketOrder(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
+
+		from erpnext.manufacturing.doctype.blanket_order_item.blanket_order_item import BlanketOrderItem
+
+		amended_from: DF.Link | None
+		blanket_order_type: DF.Literal["", "Selling", "Purchasing"]
+		company: DF.Link
+		customer: DF.Link | None
+		customer_name: DF.Data | None
+		from_date: DF.Date
+		items: DF.Table[BlanketOrderItem]
+		naming_series: DF.Literal["MFG-BLR-.YYYY.-"]
+		supplier: DF.Link | None
+		supplier_name: DF.Data | None
+		tc_name: DF.Link | None
+		terms: DF.TextEditor | None
+		to_date: DF.Date
+	# end: auto-generated types
+
 	def validate(self):
 		self.validate_dates()
 		self.validate_duplicate_items()
diff --git a/erpnext/manufacturing/doctype/blanket_order_item/blanket_order_item.py b/erpnext/manufacturing/doctype/blanket_order_item/blanket_order_item.py
index ebce209..068c2e9 100644
--- a/erpnext/manufacturing/doctype/blanket_order_item/blanket_order_item.py
+++ b/erpnext/manufacturing/doctype/blanket_order_item/blanket_order_item.py
@@ -6,4 +6,23 @@
 
 
 class BlanketOrderItem(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
+
+		item_code: DF.Link
+		item_name: DF.Data | None
+		ordered_qty: DF.Float
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		qty: DF.Float
+		rate: DF.Currency
+		terms_and_conditions: DF.Text | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/manufacturing/doctype/bom/bom.py b/erpnext/manufacturing/doctype/bom/bom.py
index 229f885..71015a4 100644
--- a/erpnext/manufacturing/doctype/bom/bom.py
+++ b/erpnext/manufacturing/doctype/bom/bom.py
@@ -103,6 +103,71 @@
 
 
 class BOM(WebsiteGenerator):
+	# 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
+
+		from erpnext.manufacturing.doctype.bom_explosion_item.bom_explosion_item import BOMExplosionItem
+		from erpnext.manufacturing.doctype.bom_item.bom_item import BOMItem
+		from erpnext.manufacturing.doctype.bom_operation.bom_operation import BOMOperation
+		from erpnext.manufacturing.doctype.bom_scrap_item.bom_scrap_item import BOMScrapItem
+
+		allow_alternative_item: DF.Check
+		amended_from: DF.Link | None
+		base_operating_cost: DF.Currency
+		base_raw_material_cost: DF.Currency
+		base_scrap_material_cost: DF.Currency
+		base_total_cost: DF.Currency
+		bom_creator: DF.Link | None
+		bom_creator_item: DF.Data | None
+		buying_price_list: DF.Link | None
+		company: DF.Link
+		conversion_rate: DF.Float
+		currency: DF.Link
+		description: DF.SmallText | None
+		exploded_items: DF.Table[BOMExplosionItem]
+		fg_based_operating_cost: DF.Check
+		has_variants: DF.Check
+		image: DF.AttachImage | None
+		inspection_required: DF.Check
+		is_active: DF.Check
+		is_default: DF.Check
+		item: DF.Link
+		item_name: DF.Data | None
+		items: DF.Table[BOMItem]
+		operating_cost: DF.Currency
+		operating_cost_per_bom_quantity: DF.Currency
+		operations: DF.Table[BOMOperation]
+		plc_conversion_rate: DF.Float
+		price_list_currency: DF.Link | None
+		process_loss_percentage: DF.Percent
+		process_loss_qty: DF.Float
+		project: DF.Link | None
+		quality_inspection_template: DF.Link | None
+		quantity: DF.Float
+		raw_material_cost: DF.Currency
+		rm_cost_as_per: DF.Literal["Valuation Rate", "Last Purchase Rate", "Price List", "Manual"]
+		route: DF.SmallText | None
+		routing: DF.Link | None
+		scrap_items: DF.Table[BOMScrapItem]
+		scrap_material_cost: DF.Currency
+		set_rate_of_sub_assembly_item_based_on_bom: DF.Check
+		show_in_website: DF.Check
+		show_items: DF.Check
+		show_operations: DF.Check
+		thumbnail: DF.Data | None
+		total_cost: DF.Currency
+		transfer_material_against: DF.Literal["", "Work Order", "Job Card"]
+		uom: DF.Link | None
+		web_long_description: DF.TextEditor | None
+		website_image: DF.AttachImage | None
+		with_operations: DF.Check
+	# end: auto-generated types
+
 	website = frappe._dict(
 		# page_title_field = "item_name",
 		condition_field="show_in_website",
@@ -1330,7 +1395,7 @@
 
 	order_by = "idx desc, name, item_name"
 
-	fields = ["name", "item_group", "item_name", "description"]
+	fields = ["name", "item_name", "item_group", "description"]
 	fields.extend(
 		[field for field in searchfields if not field in ["name", "item_group", "description"]]
 	)
diff --git a/erpnext/manufacturing/doctype/bom_creator/bom_creator.js b/erpnext/manufacturing/doctype/bom_creator/bom_creator.js
index 0cf2b51..243e52d 100644
--- a/erpnext/manufacturing/doctype/bom_creator/bom_creator.js
+++ b/erpnext/manufacturing/doctype/bom_creator/bom_creator.js
@@ -15,7 +15,7 @@
 				|| frappe.bom_configurator.bom_configurator !== frm.doc.name)) {
 				frm.trigger("build_tree");
 			}
-		} else {
+		} else if (!frm.doc.items?.length ) {
 			let $parent = $(frm.fields_dict["bom_creator"].wrapper);
 			$parent.empty();
 			frm.trigger("make_new_entry");
diff --git a/erpnext/manufacturing/doctype/bom_creator/bom_creator.py b/erpnext/manufacturing/doctype/bom_creator/bom_creator.py
index 058caa3..bd010d9 100644
--- a/erpnext/manufacturing/doctype/bom_creator/bom_creator.py
+++ b/erpnext/manufacturing/doctype/bom_creator/bom_creator.py
@@ -6,7 +6,7 @@
 import frappe
 from frappe import _
 from frappe.model.document import Document
-from frappe.utils import flt
+from frappe.utils import cint, flt
 
 from erpnext.manufacturing.doctype.bom.bom import get_bom_item_rate
 
@@ -32,6 +32,39 @@
 
 
 class BOMCreator(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
+
+		from erpnext.manufacturing.doctype.bom_creator_item.bom_creator_item import BOMCreatorItem
+
+		amended_from: DF.Link | None
+		buying_price_list: DF.Link | None
+		company: DF.Link
+		conversion_rate: DF.Float
+		currency: DF.Link
+		default_warehouse: DF.Link | None
+		error_log: DF.Text | None
+		item_code: DF.Link
+		item_group: DF.Link | None
+		item_name: DF.Data | None
+		items: DF.Table[BOMCreatorItem]
+		plc_conversion_rate: DF.Float
+		price_list_currency: DF.Link | None
+		project: DF.Link | None
+		qty: DF.Float
+		raw_material_cost: DF.Currency
+		remarks: DF.TextEditor | None
+		rm_cost_as_per: DF.Literal["Valuation Rate", "Last Purchase Rate", "Price List", "Manual"]
+		set_rate_based_on_warehouse: DF.Check
+		status: DF.Literal["Draft", "Submitted", "In Progress", "Completed", "Failed", "Cancelled"]
+		uom: DF.Link | None
+	# end: auto-generated types
+
 	def before_save(self):
 		self.set_status()
 		self.set_is_expandable()
@@ -91,11 +124,19 @@
 		parent_reference = {row.idx: row.name for row in self.items}
 
 		for row in self.items:
-			if row.fg_reference_id:
+			ref_id = ""
+
+			if row.parent_row_no:
+				ref_id = parent_reference.get(cint(row.parent_row_no))
+
+			# Check whether the reference id of the FG Item has correct or not
+			if row.fg_reference_id and row.fg_reference_id == ref_id:
 				continue
 
 			if row.parent_row_no:
-				row.fg_reference_id = parent_reference.get(row.parent_row_no)
+				row.fg_reference_id = ref_id
+			elif row.fg_item == self.item_code:
+				row.fg_reference_id = self.name
 
 	@frappe.whitelist()
 	def add_boms(self):
diff --git a/erpnext/manufacturing/doctype/bom_creator_item/bom_creator_item.json b/erpnext/manufacturing/doctype/bom_creator_item/bom_creator_item.json
index fdb5d3a..56acd8a 100644
--- a/erpnext/manufacturing/doctype/bom_creator_item/bom_creator_item.json
+++ b/erpnext/manufacturing/doctype/bom_creator_item/bom_creator_item.json
@@ -215,7 +215,6 @@
    "fieldname": "parent_row_no",
    "fieldtype": "Data",
    "label": "Parent Row No",
-   "no_copy": 1,
    "print_hide": 1
   },
   {
@@ -231,7 +230,7 @@
  "index_web_pages_for_search": 1,
  "istable": 1,
  "links": [],
- "modified": "2023-08-07 11:52:30.492233",
+ "modified": "2023-11-16 13:34:06.321061",
  "modified_by": "Administrator",
  "module": "Manufacturing",
  "name": "BOM Creator Item",
diff --git a/erpnext/manufacturing/doctype/bom_creator_item/bom_creator_item.py b/erpnext/manufacturing/doctype/bom_creator_item/bom_creator_item.py
index 350c918..e172f36 100644
--- a/erpnext/manufacturing/doctype/bom_creator_item/bom_creator_item.py
+++ b/erpnext/manufacturing/doctype/bom_creator_item/bom_creator_item.py
@@ -6,4 +6,39 @@
 
 
 class BOMCreatorItem(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
+
+		amount: DF.Currency
+		base_amount: DF.Currency
+		base_rate: DF.Currency
+		bom_created: DF.Check
+		conversion_factor: DF.Float
+		description: DF.SmallText | None
+		do_not_explode: DF.Check
+		fg_item: DF.Link
+		fg_reference_id: DF.Data | None
+		instruction: DF.SmallText | None
+		is_expandable: DF.Check
+		item_code: DF.Link
+		item_group: DF.Link | None
+		item_name: DF.Data | None
+		parent: DF.Data
+		parent_row_no: DF.Data | None
+		parentfield: DF.Data
+		parenttype: DF.Data
+		qty: DF.Float
+		rate: DF.Currency
+		source_warehouse: DF.Link | None
+		sourced_by_supplier: DF.Check
+		stock_qty: DF.Float
+		stock_uom: DF.Link | None
+		uom: DF.Link | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/manufacturing/doctype/bom_explosion_item/bom_explosion_item.json b/erpnext/manufacturing/doctype/bom_explosion_item/bom_explosion_item.json
index 9b1db63..c75ac32 100644
--- a/erpnext/manufacturing/doctype/bom_explosion_item/bom_explosion_item.json
+++ b/erpnext/manufacturing/doctype/bom_explosion_item/bom_explosion_item.json
@@ -85,6 +85,7 @@
    "fieldtype": "Column Break"
   },
   {
+   "fetch_from": "item_code.image",
    "fieldname": "image",
    "fieldtype": "Attach",
    "hidden": 1,
@@ -169,7 +170,7 @@
  "index_web_pages_for_search": 1,
  "istable": 1,
  "links": [],
- "modified": "2022-05-27 13:42:23.305455",
+ "modified": "2023-11-14 18:35:40.856895",
  "modified_by": "Administrator",
  "module": "Manufacturing",
  "name": "BOM Explosion Item",
diff --git a/erpnext/manufacturing/doctype/bom_explosion_item/bom_explosion_item.py b/erpnext/manufacturing/doctype/bom_explosion_item/bom_explosion_item.py
index cbcba34..98e254f 100644
--- a/erpnext/manufacturing/doctype/bom_explosion_item/bom_explosion_item.py
+++ b/erpnext/manufacturing/doctype/bom_explosion_item/bom_explosion_item.py
@@ -6,4 +6,30 @@
 
 
 class BOMExplosionItem(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
+
+		amount: DF.Currency
+		description: DF.TextEditor | None
+		image: DF.Attach | None
+		include_item_in_manufacturing: DF.Check
+		item_code: DF.Link | None
+		item_name: DF.Data | None
+		operation: DF.Link | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		qty_consumed_per_unit: DF.Float
+		rate: DF.Currency
+		source_warehouse: DF.Link | None
+		sourced_by_supplier: DF.Check
+		stock_qty: DF.Float
+		stock_uom: DF.Link | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/manufacturing/doctype/bom_item/bom_item.json b/erpnext/manufacturing/doctype/bom_item/bom_item.json
index c526611..cb58af1 100644
--- a/erpnext/manufacturing/doctype/bom_item/bom_item.json
+++ b/erpnext/manufacturing/doctype/bom_item/bom_item.json
@@ -111,6 +111,7 @@
    "fieldtype": "Column Break"
   },
   {
+   "fetch_from": "item_code.image",
    "fieldname": "image",
    "fieldtype": "Attach",
    "hidden": 1,
@@ -289,7 +290,7 @@
  "index_web_pages_for_search": 1,
  "istable": 1,
  "links": [],
- "modified": "2022-07-28 10:20:51.559010",
+ "modified": "2023-11-14 18:35:51.378513",
  "modified_by": "Administrator",
  "module": "Manufacturing",
  "name": "BOM Item",
diff --git a/erpnext/manufacturing/doctype/bom_item/bom_item.py b/erpnext/manufacturing/doctype/bom_item/bom_item.py
index 28a4b20..466253b 100644
--- a/erpnext/manufacturing/doctype/bom_item/bom_item.py
+++ b/erpnext/manufacturing/doctype/bom_item/bom_item.py
@@ -6,4 +6,40 @@
 
 
 class BOMItem(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
+
+		allow_alternative_item: DF.Check
+		amount: DF.Currency
+		base_amount: DF.Currency
+		base_rate: DF.Currency
+		bom_no: DF.Link | None
+		conversion_factor: DF.Float
+		description: DF.TextEditor | None
+		do_not_explode: DF.Check
+		has_variants: DF.Check
+		image: DF.Attach | None
+		include_item_in_manufacturing: DF.Check
+		item_code: DF.Link
+		item_name: DF.Data | None
+		operation: DF.Link | None
+		original_item: DF.Link | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		qty: DF.Float
+		qty_consumed_per_unit: DF.Float
+		rate: DF.Currency
+		source_warehouse: DF.Link | None
+		sourced_by_supplier: DF.Check
+		stock_qty: DF.Float
+		stock_uom: DF.Link | None
+		uom: DF.Link
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/manufacturing/doctype/bom_operation/bom_operation.py b/erpnext/manufacturing/doctype/bom_operation/bom_operation.py
index 0ddc280..66ac028 100644
--- a/erpnext/manufacturing/doctype/bom_operation/bom_operation.py
+++ b/erpnext/manufacturing/doctype/bom_operation/bom_operation.py
@@ -6,4 +6,33 @@
 
 
 class BOMOperation(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
+
+		base_cost_per_unit: DF.Float
+		base_hour_rate: DF.Currency
+		base_operating_cost: DF.Currency
+		batch_size: DF.Int
+		cost_per_unit: DF.Float
+		description: DF.TextEditor | None
+		fixed_time: DF.Check
+		hour_rate: DF.Currency
+		image: DF.Attach | None
+		operating_cost: DF.Currency
+		operation: DF.Link
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		sequence_id: DF.Int
+		set_cost_based_on_bom_qty: DF.Check
+		time_in_mins: DF.Float
+		workstation: DF.Link | None
+		workstation_type: DF.Link | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/manufacturing/doctype/bom_scrap_item/bom_scrap_item.py b/erpnext/manufacturing/doctype/bom_scrap_item/bom_scrap_item.py
index f400303b..043bbc6 100644
--- a/erpnext/manufacturing/doctype/bom_scrap_item/bom_scrap_item.py
+++ b/erpnext/manufacturing/doctype/bom_scrap_item/bom_scrap_item.py
@@ -6,4 +6,25 @@
 
 
 class BOMScrapItem(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
+
+		amount: DF.Currency
+		base_amount: DF.Currency
+		base_rate: DF.Currency
+		item_code: DF.Link
+		item_name: DF.Data | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		rate: DF.Currency
+		stock_qty: DF.Float
+		stock_uom: DF.Link | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/manufacturing/doctype/bom_update_batch/bom_update_batch.py b/erpnext/manufacturing/doctype/bom_update_batch/bom_update_batch.py
index f952e43..c3793be 100644
--- a/erpnext/manufacturing/doctype/bom_update_batch/bom_update_batch.py
+++ b/erpnext/manufacturing/doctype/bom_update_batch/bom_update_batch.py
@@ -6,4 +6,21 @@
 
 
 class BOMUpdateBatch(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
+
+		batch_no: DF.Int
+		boms_updated: DF.LongText | None
+		level: DF.Int
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		status: DF.Literal["Pending", "Completed"]
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/manufacturing/doctype/bom_update_log/bom_update_log.py b/erpnext/manufacturing/doctype/bom_update_log/bom_update_log.py
index e986746..198b9b8 100644
--- a/erpnext/manufacturing/doctype/bom_update_log/bom_update_log.py
+++ b/erpnext/manufacturing/doctype/bom_update_log/bom_update_log.py
@@ -24,6 +24,27 @@
 
 
 class BOMUpdateLog(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
+
+		from erpnext.manufacturing.doctype.bom_update_batch.bom_update_batch import BOMUpdateBatch
+
+		amended_from: DF.Link | None
+		bom_batches: DF.Table[BOMUpdateBatch]
+		current_bom: DF.Link | None
+		current_level: DF.Int
+		error_log: DF.Link | None
+		new_bom: DF.Link | None
+		processed_boms: DF.LongText | None
+		status: DF.Literal["Queued", "In Progress", "Completed", "Failed"]
+		update_type: DF.Literal["Replace BOM", "Update Cost"]
+	# end: auto-generated types
+
 	@staticmethod
 	def clear_old_logs(days=None):
 		days = days or 90
diff --git a/erpnext/manufacturing/doctype/bom_update_tool/bom_update_tool.py b/erpnext/manufacturing/doctype/bom_update_tool/bom_update_tool.py
index d16fcd0..9552116 100644
--- a/erpnext/manufacturing/doctype/bom_update_tool/bom_update_tool.py
+++ b/erpnext/manufacturing/doctype/bom_update_tool/bom_update_tool.py
@@ -12,6 +12,18 @@
 
 
 class BOMUpdateTool(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
+
+		current_bom: DF.Link
+		new_bom: DF.Link
+	# end: auto-generated types
+
 	pass
 
 
diff --git a/erpnext/manufacturing/doctype/bom_website_item/bom_website_item.py b/erpnext/manufacturing/doctype/bom_website_item/bom_website_item.py
index 33256a3..8c6321f 100644
--- a/erpnext/manufacturing/doctype/bom_website_item/bom_website_item.py
+++ b/erpnext/manufacturing/doctype/bom_website_item/bom_website_item.py
@@ -6,4 +6,22 @@
 
 
 class BOMWebsiteItem(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
+
+		description: DF.TextEditor | None
+		item_code: DF.Link | None
+		item_name: DF.Data | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		qty: DF.Float
+		website_image: DF.Attach | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/manufacturing/doctype/bom_website_operation/bom_website_operation.py b/erpnext/manufacturing/doctype/bom_website_operation/bom_website_operation.py
index f8e2792..b43b861 100644
--- a/erpnext/manufacturing/doctype/bom_website_operation/bom_website_operation.py
+++ b/erpnext/manufacturing/doctype/bom_website_operation/bom_website_operation.py
@@ -6,4 +6,22 @@
 
 
 class BOMWebsiteOperation(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
+
+		operation: DF.Link
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		thumbnail: DF.Data | None
+		time_in_mins: DF.Float
+		website_image: DF.Attach | None
+		workstation: DF.Link | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/manufacturing/doctype/downtime_entry/downtime_entry.py b/erpnext/manufacturing/doctype/downtime_entry/downtime_entry.py
index 4602816..1366ada 100644
--- a/erpnext/manufacturing/doctype/downtime_entry/downtime_entry.py
+++ b/erpnext/manufacturing/doctype/downtime_entry/downtime_entry.py
@@ -7,6 +7,33 @@
 
 
 class DowntimeEntry(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
+
+		downtime: DF.Float
+		from_time: DF.Datetime
+		naming_series: DF.Literal["DT-"]
+		operator: DF.Link
+		remarks: DF.Text | None
+		stop_reason: DF.Literal[
+			"",
+			"Excessive machine set up time",
+			"Unplanned machine maintenance",
+			"On-machine press checks",
+			"Machine operator errors",
+			"Machine malfunction",
+			"Electricity down",
+			"Other",
+		]
+		to_time: DF.Datetime
+		workstation: DF.Link
+	# end: auto-generated types
+
 	def validate(self):
 		if self.from_time and self.to_time:
 			self.downtime = time_diff_in_hours(self.to_time, self.from_time) * 60
diff --git a/erpnext/manufacturing/doctype/job_card/job_card.py b/erpnext/manufacturing/doctype/job_card/job_card.py
index db6bc80..d696cc4 100644
--- a/erpnext/manufacturing/doctype/job_card/job_card.py
+++ b/erpnext/manufacturing/doctype/job_card/job_card.py
@@ -51,6 +51,82 @@
 
 
 class JobCard(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
+
+		from erpnext.manufacturing.doctype.job_card_item.job_card_item import JobCardItem
+		from erpnext.manufacturing.doctype.job_card_operation.job_card_operation import JobCardOperation
+		from erpnext.manufacturing.doctype.job_card_scheduled_time.job_card_scheduled_time import (
+			JobCardScheduledTime,
+		)
+		from erpnext.manufacturing.doctype.job_card_scrap_item.job_card_scrap_item import (
+			JobCardScrapItem,
+		)
+		from erpnext.manufacturing.doctype.job_card_time_log.job_card_time_log import JobCardTimeLog
+
+		actual_end_date: DF.Datetime | None
+		actual_start_date: DF.Datetime | None
+		amended_from: DF.Link | None
+		barcode: DF.Barcode | None
+		batch_no: DF.Link | None
+		bom_no: DF.Link | None
+		company: DF.Link
+		current_time: DF.Int
+		employee: DF.TableMultiSelect[JobCardTimeLog]
+		expected_end_date: DF.Datetime | None
+		expected_start_date: DF.Datetime | None
+		for_job_card: DF.Link | None
+		for_operation: DF.Link | None
+		for_quantity: DF.Float
+		hour_rate: DF.Currency
+		is_corrective_job_card: DF.Check
+		item_name: DF.ReadOnly | None
+		items: DF.Table[JobCardItem]
+		job_started: DF.Check
+		naming_series: DF.Literal["PO-JOB.#####"]
+		operation: DF.Link
+		operation_id: DF.Data | None
+		operation_row_number: DF.Literal
+		posting_date: DF.Date | None
+		process_loss_qty: DF.Float
+		production_item: DF.Link | None
+		project: DF.Link | None
+		quality_inspection: DF.Link | None
+		quality_inspection_template: DF.Link | None
+		remarks: DF.SmallText | None
+		requested_qty: DF.Float
+		scheduled_time_logs: DF.Table[JobCardScheduledTime]
+		scrap_items: DF.Table[JobCardScrapItem]
+		sequence_id: DF.Int
+		serial_and_batch_bundle: DF.Link | None
+		serial_no: DF.SmallText | None
+		started_time: DF.Datetime | None
+		status: DF.Literal[
+			"Open",
+			"Work In Progress",
+			"Material Transferred",
+			"On Hold",
+			"Submitted",
+			"Cancelled",
+			"Completed",
+		]
+		sub_operations: DF.Table[JobCardOperation]
+		time_logs: DF.Table[JobCardTimeLog]
+		time_required: DF.Float
+		total_completed_qty: DF.Float
+		total_time_in_mins: DF.Float
+		transferred_qty: DF.Float
+		wip_warehouse: DF.Link
+		work_order: DF.Link
+		workstation: DF.Link
+		workstation_type: DF.Link | None
+	# end: auto-generated types
+
 	def onload(self):
 		excess_transfer = frappe.db.get_single_value(
 			"Manufacturing Settings", "job_card_excess_transfer"
@@ -185,7 +261,7 @@
 			# override capacity for employee
 			production_capacity = 1
 
-		if time_logs and production_capacity > len(time_logs):
+		if not self.has_overlap(production_capacity, time_logs):
 			return {}
 
 		if self.workstation_type and time_logs:
@@ -195,6 +271,39 @@
 
 		return time_logs[-1]
 
+	def has_overlap(self, production_capacity, time_logs):
+		overlap = False
+		if production_capacity == 1 and len(time_logs) > 0:
+			return True
+
+		# Check overlap exists or not between the overlapping time logs with the current Job Card
+		for row in time_logs:
+			count = 1
+			for next_row in time_logs:
+				if row.name == next_row.name:
+					continue
+
+				if (
+					(
+						get_datetime(next_row.from_time) >= get_datetime(row.from_time)
+						and get_datetime(next_row.from_time) <= get_datetime(row.to_time)
+					)
+					or (
+						get_datetime(next_row.to_time) >= get_datetime(row.from_time)
+						and get_datetime(next_row.to_time) <= get_datetime(row.to_time)
+					)
+					or (
+						get_datetime(next_row.from_time) <= get_datetime(row.from_time)
+						and get_datetime(next_row.to_time) >= get_datetime(row.to_time)
+					)
+				):
+					count += 1
+
+			if count > production_capacity:
+				return True
+
+		return overlap
+
 	def get_time_logs(self, args, doctype, check_next_available_slot=False):
 		jc = frappe.qb.DocType("Job Card")
 		jctl = frappe.qb.DocType(doctype)
@@ -211,7 +320,14 @@
 		query = (
 			frappe.qb.from_(jctl)
 			.from_(jc)
-			.select(jc.name.as_("name"), jctl.from_time, jctl.to_time, jc.workstation, jc.workstation_type)
+			.select(
+				jc.name.as_("name"),
+				jctl.name.as_("row_name"),
+				jctl.from_time,
+				jctl.to_time,
+				jc.workstation,
+				jc.workstation_type,
+			)
 			.where(
 				(jctl.parent == jc.name)
 				& (Criterion.any(time_conditions))
diff --git a/erpnext/manufacturing/doctype/job_card_item/job_card_item.py b/erpnext/manufacturing/doctype/job_card_item/job_card_item.py
index 51a7b41..ecf0823 100644
--- a/erpnext/manufacturing/doctype/job_card_item/job_card_item.py
+++ b/erpnext/manufacturing/doctype/job_card_item/job_card_item.py
@@ -6,4 +6,27 @@
 
 
 class JobCardItem(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
+
+		allow_alternative_item: DF.Check
+		description: DF.Text | None
+		item_code: DF.Link | None
+		item_group: DF.Link | None
+		item_name: DF.Data | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		required_qty: DF.Float
+		source_warehouse: DF.Link | None
+		stock_uom: DF.Link | None
+		transferred_qty: DF.Float
+		uom: DF.Link | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/manufacturing/doctype/job_card_operation/job_card_operation.py b/erpnext/manufacturing/doctype/job_card_operation/job_card_operation.py
index de44071..4d32dd4 100644
--- a/erpnext/manufacturing/doctype/job_card_operation/job_card_operation.py
+++ b/erpnext/manufacturing/doctype/job_card_operation/job_card_operation.py
@@ -7,4 +7,21 @@
 
 
 class JobCardOperation(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
+
+		completed_qty: DF.Float
+		completed_time: DF.Data | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		status: DF.Literal["Complete", "Pause", "Pending", "Work In Progress"]
+		sub_operation: DF.Link | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/manufacturing/doctype/job_card_scheduled_time/job_card_scheduled_time.py b/erpnext/manufacturing/doctype/job_card_scheduled_time/job_card_scheduled_time.py
index e50b153..b9f44dc 100644
--- a/erpnext/manufacturing/doctype/job_card_scheduled_time/job_card_scheduled_time.py
+++ b/erpnext/manufacturing/doctype/job_card_scheduled_time/job_card_scheduled_time.py
@@ -6,4 +6,20 @@
 
 
 class JobCardScheduledTime(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
+
+		from_time: DF.Datetime | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		time_in_mins: DF.Float
+		to_time: DF.Datetime | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/manufacturing/doctype/job_card_scrap_item/job_card_scrap_item.py b/erpnext/manufacturing/doctype/job_card_scrap_item/job_card_scrap_item.py
index 372df1b..e4b926e 100644
--- a/erpnext/manufacturing/doctype/job_card_scrap_item/job_card_scrap_item.py
+++ b/erpnext/manufacturing/doctype/job_card_scrap_item/job_card_scrap_item.py
@@ -5,4 +5,22 @@
 
 
 class JobCardScrapItem(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
+
+		description: DF.SmallText | None
+		item_code: DF.Link
+		item_name: DF.Data | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		stock_qty: DF.Float
+		stock_uom: DF.Link | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/manufacturing/doctype/job_card_time_log/job_card_time_log.py b/erpnext/manufacturing/doctype/job_card_time_log/job_card_time_log.py
index 2b3ead3..ba802a9 100644
--- a/erpnext/manufacturing/doctype/job_card_time_log/job_card_time_log.py
+++ b/erpnext/manufacturing/doctype/job_card_time_log/job_card_time_log.py
@@ -6,4 +6,23 @@
 
 
 class JobCardTimeLog(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
+
+		completed_qty: DF.Float
+		employee: DF.Link | None
+		from_time: DF.Datetime | None
+		operation: DF.Link | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		time_in_mins: DF.Float
+		to_time: DF.Datetime | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/manufacturing/doctype/manufacturing_settings/manufacturing_settings.py b/erpnext/manufacturing/doctype/manufacturing_settings/manufacturing_settings.py
index 730a857..bfc8f4e 100644
--- a/erpnext/manufacturing/doctype/manufacturing_settings/manufacturing_settings.py
+++ b/erpnext/manufacturing/doctype/manufacturing_settings/manufacturing_settings.py
@@ -9,6 +9,32 @@
 
 
 class ManufacturingSettings(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
+
+		add_corrective_operation_cost_in_finished_good_valuation: DF.Check
+		allow_overtime: DF.Check
+		allow_production_on_holidays: DF.Check
+		backflush_raw_materials_based_on: DF.Literal["BOM", "Material Transferred for Manufacture"]
+		capacity_planning_for_days: DF.Int
+		default_fg_warehouse: DF.Link | None
+		default_scrap_warehouse: DF.Link | None
+		default_wip_warehouse: DF.Link | None
+		disable_capacity_planning: DF.Check
+		job_card_excess_transfer: DF.Check
+		make_serial_no_batch_from_work_order: DF.Check
+		material_consumption: DF.Check
+		mins_between_operations: DF.Int
+		overproduction_percentage_for_sales_order: DF.Percent
+		overproduction_percentage_for_work_order: DF.Percent
+		update_bom_costs_automatically: DF.Check
+	# end: auto-generated types
+
 	pass
 
 
diff --git a/erpnext/manufacturing/doctype/material_request_plan_item/material_request_plan_item.py b/erpnext/manufacturing/doctype/material_request_plan_item/material_request_plan_item.py
index 3d5a7ce..aa1c722 100644
--- a/erpnext/manufacturing/doctype/material_request_plan_item/material_request_plan_item.py
+++ b/erpnext/manufacturing/doctype/material_request_plan_item/material_request_plan_item.py
@@ -6,4 +6,38 @@
 
 
 class MaterialRequestPlanItem(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
+
+		actual_qty: DF.Float
+		conversion_factor: DF.Float
+		description: DF.TextEditor | None
+		from_warehouse: DF.Link | None
+		item_code: DF.Link
+		item_name: DF.Data | None
+		material_request_type: DF.Literal[
+			"", "Purchase", "Material Transfer", "Material Issue", "Manufacture", "Customer Provided"
+		]
+		min_order_qty: DF.Float
+		ordered_qty: DF.Float
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		projected_qty: DF.Float
+		quantity: DF.Float
+		requested_qty: DF.Float
+		required_bom_qty: DF.Float
+		reserved_qty_for_production: DF.Float
+		safety_stock: DF.Float
+		sales_order: DF.Link | None
+		schedule_date: DF.Date | None
+		uom: DF.Link | None
+		warehouse: DF.Link
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/manufacturing/doctype/operation/operation.py b/erpnext/manufacturing/doctype/operation/operation.py
index 9c8f9ac..3969291 100644
--- a/erpnext/manufacturing/doctype/operation/operation.py
+++ b/erpnext/manufacturing/doctype/operation/operation.py
@@ -8,6 +8,26 @@
 
 
 class Operation(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
+
+		from erpnext.manufacturing.doctype.sub_operation.sub_operation import SubOperation
+
+		batch_size: DF.Int
+		create_job_card_based_on_batch_size: DF.Check
+		description: DF.Text | None
+		is_corrective_operation: DF.Check
+		quality_inspection_template: DF.Link | None
+		sub_operations: DF.Table[SubOperation]
+		total_operation_time: DF.Float
+		workstation: DF.Link | None
+	# end: auto-generated types
+
 	def validate(self):
 		if not self.description:
 			self.description = self.name
diff --git a/erpnext/manufacturing/doctype/production_plan/production_plan.py b/erpnext/manufacturing/doctype/production_plan/production_plan.py
index 6efb762..955821f 100644
--- a/erpnext/manufacturing/doctype/production_plan/production_plan.py
+++ b/erpnext/manufacturing/doctype/production_plan/production_plan.py
@@ -33,6 +33,81 @@
 
 
 class ProductionPlan(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
+
+		from erpnext.manufacturing.doctype.material_request_plan_item.material_request_plan_item import (
+			MaterialRequestPlanItem,
+		)
+		from erpnext.manufacturing.doctype.production_plan_item.production_plan_item import (
+			ProductionPlanItem,
+		)
+		from erpnext.manufacturing.doctype.production_plan_item_reference.production_plan_item_reference import (
+			ProductionPlanItemReference,
+		)
+		from erpnext.manufacturing.doctype.production_plan_material_request.production_plan_material_request import (
+			ProductionPlanMaterialRequest,
+		)
+		from erpnext.manufacturing.doctype.production_plan_material_request_warehouse.production_plan_material_request_warehouse import (
+			ProductionPlanMaterialRequestWarehouse,
+		)
+		from erpnext.manufacturing.doctype.production_plan_sales_order.production_plan_sales_order import (
+			ProductionPlanSalesOrder,
+		)
+		from erpnext.manufacturing.doctype.production_plan_sub_assembly_item.production_plan_sub_assembly_item import (
+			ProductionPlanSubAssemblyItem,
+		)
+
+		amended_from: DF.Link | None
+		combine_items: DF.Check
+		combine_sub_items: DF.Check
+		company: DF.Link
+		customer: DF.Link | None
+		for_warehouse: DF.Link | None
+		from_date: DF.Date | None
+		from_delivery_date: DF.Date | None
+		get_items_from: DF.Literal["", "Sales Order", "Material Request"]
+		ignore_existing_ordered_qty: DF.Check
+		include_non_stock_items: DF.Check
+		include_safety_stock: DF.Check
+		include_subcontracted_items: DF.Check
+		item_code: DF.Link | None
+		material_requests: DF.Table[ProductionPlanMaterialRequest]
+		mr_items: DF.Table[MaterialRequestPlanItem]
+		naming_series: DF.Literal["MFG-PP-.YYYY.-"]
+		po_items: DF.Table[ProductionPlanItem]
+		posting_date: DF.Date
+		prod_plan_references: DF.Table[ProductionPlanItemReference]
+		project: DF.Link | None
+		sales_order_status: DF.Literal["", "To Deliver and Bill", "To Bill", "To Deliver"]
+		sales_orders: DF.Table[ProductionPlanSalesOrder]
+		skip_available_sub_assembly_item: DF.Check
+		status: DF.Literal[
+			"",
+			"Draft",
+			"Submitted",
+			"Not Started",
+			"In Process",
+			"Completed",
+			"Closed",
+			"Cancelled",
+			"Material Requested",
+		]
+		sub_assembly_items: DF.Table[ProductionPlanSubAssemblyItem]
+		sub_assembly_warehouse: DF.Link | None
+		to_date: DF.Date | None
+		to_delivery_date: DF.Date | None
+		total_planned_qty: DF.Float
+		total_produced_qty: DF.Float
+		warehouse: DF.Link | None
+		warehouses: DF.TableMultiSelect[ProductionPlanMaterialRequestWarehouse]
+	# end: auto-generated types
+
 	def validate(self):
 		self.set_pending_qty_in_row_without_reference()
 		self.calculate_total_planned_qty()
diff --git a/erpnext/manufacturing/doctype/production_plan_item/production_plan_item.py b/erpnext/manufacturing/doctype/production_plan_item/production_plan_item.py
index cc79ac3..316923b 100644
--- a/erpnext/manufacturing/doctype/production_plan_item/production_plan_item.py
+++ b/erpnext/manufacturing/doctype/production_plan_item/production_plan_item.py
@@ -6,4 +6,35 @@
 
 
 class ProductionPlanItem(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
+
+		bom_no: DF.Link
+		description: DF.TextEditor | None
+		include_exploded_items: DF.Check
+		item_code: DF.Link
+		item_reference: DF.Data | None
+		material_request: DF.Link | None
+		material_request_item: DF.Data | None
+		ordered_qty: DF.Float
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		pending_qty: DF.Float
+		planned_qty: DF.Float
+		planned_start_date: DF.Datetime
+		produced_qty: DF.Float
+		product_bundle_item: DF.Link | None
+		sales_order: DF.Link | None
+		sales_order_item: DF.Data | None
+		stock_uom: DF.Link
+		temporary_name: DF.Data | None
+		warehouse: DF.Link | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/manufacturing/doctype/production_plan_item_reference/production_plan_item_reference.py b/erpnext/manufacturing/doctype/production_plan_item_reference/production_plan_item_reference.py
index 81d2eca..d95bf8c 100644
--- a/erpnext/manufacturing/doctype/production_plan_item_reference/production_plan_item_reference.py
+++ b/erpnext/manufacturing/doctype/production_plan_item_reference/production_plan_item_reference.py
@@ -7,4 +7,21 @@
 
 
 class ProductionPlanItemReference(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
+
+		item_reference: DF.Data | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		qty: DF.Data | None
+		sales_order: DF.Link | None
+		sales_order_item: DF.Data | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/manufacturing/doctype/production_plan_material_request/production_plan_material_request.py b/erpnext/manufacturing/doctype/production_plan_material_request/production_plan_material_request.py
index 83b1789..efcba22 100644
--- a/erpnext/manufacturing/doctype/production_plan_material_request/production_plan_material_request.py
+++ b/erpnext/manufacturing/doctype/production_plan_material_request/production_plan_material_request.py
@@ -6,4 +6,19 @@
 
 
 class ProductionPlanMaterialRequest(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
+
+		material_request: DF.Link
+		material_request_date: DF.Date | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/manufacturing/doctype/production_plan_material_request_warehouse/production_plan_material_request_warehouse.py b/erpnext/manufacturing/doctype/production_plan_material_request_warehouse/production_plan_material_request_warehouse.py
index a66ff44..13e27e5 100644
--- a/erpnext/manufacturing/doctype/production_plan_material_request_warehouse/production_plan_material_request_warehouse.py
+++ b/erpnext/manufacturing/doctype/production_plan_material_request_warehouse/production_plan_material_request_warehouse.py
@@ -7,4 +7,18 @@
 
 
 class ProductionPlanMaterialRequestWarehouse(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
+
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		warehouse: DF.Link | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/manufacturing/doctype/production_plan_sales_order/production_plan_sales_order.py b/erpnext/manufacturing/doctype/production_plan_sales_order/production_plan_sales_order.py
index 3f38529..7f793b5 100644
--- a/erpnext/manufacturing/doctype/production_plan_sales_order/production_plan_sales_order.py
+++ b/erpnext/manufacturing/doctype/production_plan_sales_order/production_plan_sales_order.py
@@ -6,4 +6,21 @@
 
 
 class ProductionPlanSalesOrder(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
+
+		customer: DF.Link | None
+		grand_total: DF.Currency
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		sales_order: DF.Link
+		sales_order_date: DF.Date | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/manufacturing/doctype/production_plan_sub_assembly_item/production_plan_sub_assembly_item.py b/erpnext/manufacturing/doctype/production_plan_sub_assembly_item/production_plan_sub_assembly_item.py
index 069667a..ad1d655 100644
--- a/erpnext/manufacturing/doctype/production_plan_sub_assembly_item/production_plan_sub_assembly_item.py
+++ b/erpnext/manufacturing/doctype/production_plan_sub_assembly_item/production_plan_sub_assembly_item.py
@@ -7,4 +7,37 @@
 
 
 class ProductionPlanSubAssemblyItem(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
+
+		actual_qty: DF.Float
+		bom_level: DF.Int
+		bom_no: DF.Link | None
+		description: DF.SmallText | None
+		fg_warehouse: DF.Link | None
+		indent: DF.Int
+		item_name: DF.Data | None
+		parent: DF.Data
+		parent_item_code: DF.Link | None
+		parentfield: DF.Data
+		parenttype: DF.Data
+		production_item: DF.Link | None
+		production_plan_item: DF.Data | None
+		projected_qty: DF.Float
+		purchase_order: DF.Link | None
+		qty: DF.Float
+		received_qty: DF.Float
+		schedule_date: DF.Datetime | None
+		stock_uom: DF.Link | None
+		supplier: DF.Link | None
+		type_of_manufacturing: DF.Literal["In House", "Subcontract", "Material Request"]
+		uom: DF.Link | None
+		wo_produced_qty: DF.Float
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/manufacturing/doctype/routing/routing.py b/erpnext/manufacturing/doctype/routing/routing.py
index d4c37cf..4bef380 100644
--- a/erpnext/manufacturing/doctype/routing/routing.py
+++ b/erpnext/manufacturing/doctype/routing/routing.py
@@ -9,6 +9,21 @@
 
 
 class Routing(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
+
+		from erpnext.manufacturing.doctype.bom_operation.bom_operation import BOMOperation
+
+		disabled: DF.Check
+		operations: DF.Table[BOMOperation]
+		routing_name: DF.Data | None
+	# end: auto-generated types
+
 	def validate(self):
 		self.calculate_operating_cost()
 		self.set_routing_id()
diff --git a/erpnext/manufacturing/doctype/sub_operation/sub_operation.py b/erpnext/manufacturing/doctype/sub_operation/sub_operation.py
index c86058e..f4bb62e 100644
--- a/erpnext/manufacturing/doctype/sub_operation/sub_operation.py
+++ b/erpnext/manufacturing/doctype/sub_operation/sub_operation.py
@@ -7,4 +7,20 @@
 
 
 class SubOperation(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
+
+		description: DF.SmallText | None
+		operation: DF.Link | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		time_in_mins: DF.Float
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/manufacturing/doctype/work_order/test_work_order.py b/erpnext/manufacturing/doctype/work_order/test_work_order.py
index 0ae7657..e2c8f07 100644
--- a/erpnext/manufacturing/doctype/work_order/test_work_order.py
+++ b/erpnext/manufacturing/doctype/work_order/test_work_order.py
@@ -921,6 +921,20 @@
 			"Test RM Item 2 for Scrap Item Test",
 		]
 
+		from_time = add_days(now(), -1)
+		job_cards = frappe.get_all(
+			"Job Card Time Log",
+			fields=["distinct parent as name", "docstatus"],
+			filters={"from_time": (">", from_time)},
+			order_by="creation asc",
+		)
+
+		for job_card in job_cards:
+			if job_card.docstatus == 1:
+				frappe.get_doc("Job Card", job_card.name).cancel()
+
+			frappe.delete_doc("Job Card Time Log", job_card.name)
+
 		company = "_Test Company with perpetual inventory"
 		for item_code in items:
 			create_item(
diff --git a/erpnext/manufacturing/doctype/work_order/work_order.py b/erpnext/manufacturing/doctype/work_order/work_order.py
index 36a0cae..78bfc76 100644
--- a/erpnext/manufacturing/doctype/work_order/work_order.py
+++ b/erpnext/manufacturing/doctype/work_order/work_order.py
@@ -64,6 +64,80 @@
 
 
 class WorkOrder(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
+
+		from erpnext.manufacturing.doctype.work_order_item.work_order_item import WorkOrderItem
+		from erpnext.manufacturing.doctype.work_order_operation.work_order_operation import (
+			WorkOrderOperation,
+		)
+
+		actual_end_date: DF.Datetime | None
+		actual_operating_cost: DF.Currency
+		actual_start_date: DF.Datetime | None
+		additional_operating_cost: DF.Currency
+		allow_alternative_item: DF.Check
+		amended_from: DF.Link | None
+		batch_size: DF.Float
+		bom_no: DF.Link
+		company: DF.Link
+		corrective_operation_cost: DF.Currency
+		description: DF.SmallText | None
+		expected_delivery_date: DF.Date | None
+		fg_warehouse: DF.Link
+		from_wip_warehouse: DF.Check
+		has_batch_no: DF.Check
+		has_serial_no: DF.Check
+		image: DF.AttachImage | None
+		item_name: DF.Data | None
+		lead_time: DF.Float
+		material_request: DF.Link | None
+		material_request_item: DF.Data | None
+		material_transferred_for_manufacturing: DF.Float
+		naming_series: DF.Literal["MFG-WO-.YYYY.-"]
+		operations: DF.Table[WorkOrderOperation]
+		planned_end_date: DF.Datetime | None
+		planned_operating_cost: DF.Currency
+		planned_start_date: DF.Datetime
+		process_loss_qty: DF.Float
+		produced_qty: DF.Float
+		product_bundle_item: DF.Link | None
+		production_item: DF.Link
+		production_plan: DF.Link | None
+		production_plan_item: DF.Data | None
+		production_plan_sub_assembly_item: DF.Data | None
+		project: DF.Link | None
+		qty: DF.Float
+		required_items: DF.Table[WorkOrderItem]
+		sales_order: DF.Link | None
+		sales_order_item: DF.Data | None
+		scrap_warehouse: DF.Link | None
+		skip_transfer: DF.Check
+		source_warehouse: DF.Link | None
+		status: DF.Literal[
+			"",
+			"Draft",
+			"Submitted",
+			"Not Started",
+			"In Process",
+			"Completed",
+			"Stopped",
+			"Closed",
+			"Cancelled",
+		]
+		stock_uom: DF.Link | None
+		total_operating_cost: DF.Currency
+		transfer_material_against: DF.Literal["", "Work Order", "Job Card"]
+		update_consumed_material_cost_in_project: DF.Check
+		use_multi_level_bom: DF.Check
+		wip_warehouse: DF.Link | None
+	# end: auto-generated types
+
 	def onload(self):
 		ms = frappe.get_doc("Manufacturing Settings")
 		self.set_onload("material_consumption", ms.material_consumption)
diff --git a/erpnext/manufacturing/doctype/work_order_item/work_order_item.py b/erpnext/manufacturing/doctype/work_order_item/work_order_item.py
index 1792747..267ca5d 100644
--- a/erpnext/manufacturing/doctype/work_order_item/work_order_item.py
+++ b/erpnext/manufacturing/doctype/work_order_item/work_order_item.py
@@ -7,6 +7,34 @@
 
 
 class WorkOrderItem(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
+
+		allow_alternative_item: DF.Check
+		amount: DF.Currency
+		available_qty_at_source_warehouse: DF.Float
+		available_qty_at_wip_warehouse: DF.Float
+		consumed_qty: DF.Float
+		description: DF.Text | None
+		include_item_in_manufacturing: DF.Check
+		item_code: DF.Link | None
+		item_name: DF.Data | None
+		operation: DF.Link | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		rate: DF.Currency
+		required_qty: DF.Float
+		returned_qty: DF.Float
+		source_warehouse: DF.Link | None
+		transferred_qty: DF.Float
+	# end: auto-generated types
+
 	pass
 
 
diff --git a/erpnext/manufacturing/doctype/work_order_operation/work_order_operation.py b/erpnext/manufacturing/doctype/work_order_operation/work_order_operation.py
index 6bda58e..5bd3ab1 100644
--- a/erpnext/manufacturing/doctype/work_order_operation/work_order_operation.py
+++ b/erpnext/manufacturing/doctype/work_order_operation/work_order_operation.py
@@ -6,4 +6,36 @@
 
 
 class WorkOrderOperation(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
+
+		actual_end_time: DF.Datetime | None
+		actual_operating_cost: DF.Currency
+		actual_operation_time: DF.Float
+		actual_start_time: DF.Datetime | None
+		batch_size: DF.Float
+		bom: DF.Link | None
+		completed_qty: DF.Float
+		description: DF.TextEditor | None
+		hour_rate: DF.Float
+		operation: DF.Link
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		planned_end_time: DF.Datetime | None
+		planned_operating_cost: DF.Currency
+		planned_start_time: DF.Datetime | None
+		process_loss_qty: DF.Float
+		sequence_id: DF.Int
+		status: DF.Literal["Pending", "Work in Progress", "Completed"]
+		time_in_mins: DF.Float
+		workstation: DF.Link | None
+		workstation_type: DF.Link | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/manufacturing/doctype/workstation/workstation.py b/erpnext/manufacturing/doctype/workstation/workstation.py
index ac271b7..0a247fc 100644
--- a/erpnext/manufacturing/doctype/workstation/workstation.py
+++ b/erpnext/manufacturing/doctype/workstation/workstation.py
@@ -32,6 +32,31 @@
 
 
 class Workstation(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
+
+		from erpnext.manufacturing.doctype.workstation_working_hour.workstation_working_hour import (
+			WorkstationWorkingHour,
+		)
+
+		description: DF.Text | None
+		holiday_list: DF.Link | None
+		hour_rate: DF.Currency
+		hour_rate_consumable: DF.Currency
+		hour_rate_electricity: DF.Currency
+		hour_rate_labour: DF.Currency
+		hour_rate_rent: DF.Currency
+		production_capacity: DF.Int
+		working_hours: DF.Table[WorkstationWorkingHour]
+		workstation_name: DF.Data
+		workstation_type: DF.Link | None
+	# end: auto-generated types
+
 	def before_save(self):
 		self.set_data_based_on_workstation_type()
 		self.set_hour_rate()
diff --git a/erpnext/manufacturing/doctype/workstation_type/workstation_type.py b/erpnext/manufacturing/doctype/workstation_type/workstation_type.py
index 8c1e230..0f151a2 100644
--- a/erpnext/manufacturing/doctype/workstation_type/workstation_type.py
+++ b/erpnext/manufacturing/doctype/workstation_type/workstation_type.py
@@ -7,6 +7,23 @@
 
 
 class WorkstationType(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
+
+		description: DF.SmallText | None
+		hour_rate: DF.Currency
+		hour_rate_consumable: DF.Currency
+		hour_rate_electricity: DF.Currency
+		hour_rate_labour: DF.Currency
+		hour_rate_rent: DF.Currency
+		workstation_type: DF.Data
+	# end: auto-generated types
+
 	def before_save(self):
 		self.set_hour_rate()
 
diff --git a/erpnext/manufacturing/doctype/workstation_working_hour/workstation_working_hour.py b/erpnext/manufacturing/doctype/workstation_working_hour/workstation_working_hour.py
index 99fb552..6754d66 100644
--- a/erpnext/manufacturing/doctype/workstation_working_hour/workstation_working_hour.py
+++ b/erpnext/manufacturing/doctype/workstation_working_hour/workstation_working_hour.py
@@ -6,4 +6,20 @@
 
 
 class WorkstationWorkingHour(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
+
+		enabled: DF.Check
+		end_time: DF.Time
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		start_time: DF.Time
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index d5aa11d..d9b5478 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -259,6 +259,7 @@
 erpnext.patches.v15_0.saudi_depreciation_warning
 erpnext.patches.v15_0.delete_saudi_doctypes
 erpnext.patches.v14_0.show_loan_management_deprecation_warning
+erpnext.patches.v14_0.clear_reconciliation_values_from_singles
 execute:frappe.rename_doc("Report", "TDS Payable Monthly", "Tax Withholding Details", force=True)
 
 [post_model_sync]
@@ -303,7 +304,6 @@
 erpnext.patches.v14_0.create_accounting_dimensions_for_asset_capitalization
 erpnext.patches.v14_0.update_partial_tds_fields
 erpnext.patches.v14_0.create_incoterms_and_migrate_shipment
-erpnext.patches.v14_0.setup_clear_repost_logs
 erpnext.patches.v14_0.create_accounting_dimensions_for_payment_request
 erpnext.patches.v14_0.update_entry_type_for_journal_entry
 erpnext.patches.v14_0.change_autoname_for_tax_withheld_vouchers
@@ -344,12 +344,13 @@
 erpnext.patches.v15_0.update_sre_from_voucher_details
 erpnext.patches.v14_0.rename_over_order_allowance_field
 erpnext.patches.v14_0.migrate_delivery_stop_lock_field
-execute:frappe.db.set_single_value("Payment Reconciliation", "invoice_limit", 50)
-execute:frappe.db.set_single_value("Payment Reconciliation", "payment_limit", 50)
 erpnext.patches.v14_0.add_default_for_repost_settings
 erpnext.patches.v15_0.rename_daily_depreciation_to_depreciation_amount_based_on_num_days_in_month
 erpnext.patches.v15_0.rename_depreciation_amount_based_on_num_days_in_month_to_daily_prorata_based
 erpnext.patches.v15_0.set_reserved_stock_in_bin
+erpnext.patches.v14_0.create_accounting_dimensions_in_supplier_quotation
+erpnext.patches.v14_0.update_zero_asset_quantity_field
+execute:frappe.db.set_single_value("Buying Settings", "project_update_frequency", "Each Transaction")
 erpnext.patches.v15_0.create_advance_payment_status
 # below migration patch should always run last
 erpnext.patches.v14_0.migrate_gl_to_payment_ledger
diff --git a/erpnext/patches/v13_0/convert_qi_parameter_to_link_field.py b/erpnext/patches/v13_0/convert_qi_parameter_to_link_field.py
index e53bdf8..08ddbbf 100644
--- a/erpnext/patches/v13_0/convert_qi_parameter_to_link_field.py
+++ b/erpnext/patches/v13_0/convert_qi_parameter_to_link_field.py
@@ -21,6 +21,9 @@
 	params = set({x.casefold(): x for x in params}.values())
 
 	for parameter in params:
+		if frappe.db.exists("Quality Inspection Parameter", parameter):
+			continue
+
 		frappe.get_doc(
 			{"doctype": "Quality Inspection Parameter", "parameter": parameter, "description": parameter}
 		).insert(ignore_permissions=True)
diff --git a/erpnext/patches/v14_0/clear_reconciliation_values_from_singles.py b/erpnext/patches/v14_0/clear_reconciliation_values_from_singles.py
new file mode 100644
index 0000000..c1f5b60
--- /dev/null
+++ b/erpnext/patches/v14_0/clear_reconciliation_values_from_singles.py
@@ -0,0 +1,17 @@
+from frappe import qb
+
+
+def execute():
+	"""
+	Clear `tabSingles` and Payment Reconciliation tables of values
+	"""
+	singles = qb.DocType("Singles")
+	qb.from_(singles).delete().where(singles.doctype == "Payment Reconciliation").run()
+	doctypes = [
+		"Payment Reconciliation Invoice",
+		"Payment Reconciliation Payment",
+		"Payment Reconciliation Allocation",
+	]
+	for x in doctypes:
+		dt = qb.DocType(x)
+		qb.from_(dt).delete().run()
diff --git a/erpnext/patches/v14_0/create_accounting_dimensions_in_supplier_quotation.py b/erpnext/patches/v14_0/create_accounting_dimensions_in_supplier_quotation.py
new file mode 100644
index 0000000..6966db1
--- /dev/null
+++ b/erpnext/patches/v14_0/create_accounting_dimensions_in_supplier_quotation.py
@@ -0,0 +1,8 @@
+from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import (
+	create_accounting_dimensions_for_doctype,
+)
+
+
+def execute():
+	create_accounting_dimensions_for_doctype(doctype="Supplier Quotation")
+	create_accounting_dimensions_for_doctype(doctype="Supplier Quotation Item")
diff --git a/erpnext/patches/v14_0/setup_clear_repost_logs.py b/erpnext/patches/v14_0/setup_clear_repost_logs.py
deleted file mode 100644
index be9ddca..0000000
--- a/erpnext/patches/v14_0/setup_clear_repost_logs.py
+++ /dev/null
@@ -1,8 +0,0 @@
-# Copyright (c) 2022, Frappe Technologies Pvt. Ltd. and Contributors
-# License: MIT. See LICENSE
-
-from erpnext.setup.install import setup_log_settings
-
-
-def execute():
-	setup_log_settings()
diff --git a/erpnext/patches/v14_0/update_zero_asset_quantity_field.py b/erpnext/patches/v14_0/update_zero_asset_quantity_field.py
new file mode 100644
index 0000000..0480f9b
--- /dev/null
+++ b/erpnext/patches/v14_0/update_zero_asset_quantity_field.py
@@ -0,0 +1,6 @@
+import frappe
+
+
+def execute():
+	asset = frappe.qb.DocType("Asset")
+	frappe.qb.update(asset).set(asset.asset_quantity, 1).where(asset.asset_quantity == 0).run()
diff --git a/erpnext/patches/v15_0/create_asset_depreciation_schedules_from_assets.py b/erpnext/patches/v15_0/create_asset_depreciation_schedules_from_assets.py
index 9a2a39f..793497b 100644
--- a/erpnext/patches/v15_0/create_asset_depreciation_schedules_from_assets.py
+++ b/erpnext/patches/v15_0/create_asset_depreciation_schedules_from_assets.py
@@ -86,6 +86,7 @@
 			afb.frequency_of_depreciation,
 			afb.rate_of_depreciation,
 			afb.expected_value_after_useful_life,
+			afb.shift_based,
 		)
 		.where(asset.docstatus < 2)
 		.orderby(afb.idx)
diff --git a/erpnext/portal/doctype/homepage/homepage.py b/erpnext/portal/doctype/homepage/homepage.py
index c0a0c07..3539b28 100644
--- a/erpnext/portal/doctype/homepage/homepage.py
+++ b/erpnext/portal/doctype/homepage/homepage.py
@@ -8,6 +8,24 @@
 
 
 class Homepage(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
+		description: DF.Text
+		hero_image: DF.AttachImage | None
+		hero_section: DF.Link | None
+		hero_section_based_on: DF.Literal["Default", "Slideshow", "Homepage Section"]
+		slideshow: DF.Link | None
+		tag_line: DF.Data
+		title: DF.Data | None
+	# end: auto-generated types
+
 	def validate(self):
 		if not self.description:
 			self.description = frappe._("This is an example website auto-generated from ERPNext")
diff --git a/erpnext/portal/doctype/homepage_section/homepage_section.py b/erpnext/portal/doctype/homepage_section/homepage_section.py
index 7181aff..9499ce3 100644
--- a/erpnext/portal/doctype/homepage_section/homepage_section.py
+++ b/erpnext/portal/doctype/homepage_section/homepage_section.py
@@ -7,6 +7,25 @@
 
 
 class HomepageSection(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
+
+		from erpnext.portal.doctype.homepage_section_card.homepage_section_card import (
+			HomepageSectionCard,
+		)
+
+		no_of_columns: DF.Literal["1", "2", "3", "4", "6"]
+		section_based_on: DF.Literal["Cards", "Custom HTML"]
+		section_cards: DF.Table[HomepageSectionCard]
+		section_html: DF.Code | None
+		section_order: DF.Int
+	# end: auto-generated types
+
 	@property
 	def column_value(self):
 		return cint(12 / cint(self.no_of_columns or 3))
diff --git a/erpnext/portal/doctype/homepage_section_card/homepage_section_card.py b/erpnext/portal/doctype/homepage_section_card/homepage_section_card.py
index eeff63c..ce2fe31 100644
--- a/erpnext/portal/doctype/homepage_section_card/homepage_section_card.py
+++ b/erpnext/portal/doctype/homepage_section_card/homepage_section_card.py
@@ -6,4 +6,22 @@
 
 
 class HomepageSectionCard(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
+
+		content: DF.Text | None
+		image: DF.AttachImage | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		route: DF.Data | None
+		subtitle: DF.Data | None
+		title: DF.Data
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/portal/doctype/website_attribute/website_attribute.py b/erpnext/portal/doctype/website_attribute/website_attribute.py
index 58a7376..2e4a1e3 100644
--- a/erpnext/portal/doctype/website_attribute/website_attribute.py
+++ b/erpnext/portal/doctype/website_attribute/website_attribute.py
@@ -6,4 +6,18 @@
 
 
 class WebsiteAttribute(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
+
+		attribute: DF.Link
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/portal/doctype/website_filter_field/website_filter_field.py b/erpnext/portal/doctype/website_filter_field/website_filter_field.py
index 8067ebb..7c48e9d 100644
--- a/erpnext/portal/doctype/website_filter_field/website_filter_field.py
+++ b/erpnext/portal/doctype/website_filter_field/website_filter_field.py
@@ -6,4 +6,18 @@
 
 
 class WebsiteFilterField(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
+
+		fieldname: DF.Autocomplete | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/projects/doctype/activity_cost/activity_cost.py b/erpnext/projects/doctype/activity_cost/activity_cost.py
index b99aa1e..257bcc4 100644
--- a/erpnext/projects/doctype/activity_cost/activity_cost.py
+++ b/erpnext/projects/doctype/activity_cost/activity_cost.py
@@ -12,6 +12,23 @@
 
 
 class ActivityCost(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
+
+		activity_type: DF.Link
+		billing_rate: DF.Currency
+		costing_rate: DF.Currency
+		department: DF.Link | None
+		employee: DF.Link | None
+		employee_name: DF.Data | None
+		title: DF.Data | None
+	# end: auto-generated types
+
 	def validate(self):
 		self.set_title()
 		self.check_unique()
diff --git a/erpnext/projects/doctype/activity_type/activity_type.py b/erpnext/projects/doctype/activity_type/activity_type.py
index 5151098..b5903bb 100644
--- a/erpnext/projects/doctype/activity_type/activity_type.py
+++ b/erpnext/projects/doctype/activity_type/activity_type.py
@@ -6,4 +6,18 @@
 
 
 class ActivityType(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
+
+		activity_type: DF.Data
+		billing_rate: DF.Currency
+		costing_rate: DF.Currency
+		disabled: DF.Check
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/projects/doctype/dependent_task/dependent_task.py b/erpnext/projects/doctype/dependent_task/dependent_task.py
index 73ce8f9..f4c2762 100644
--- a/erpnext/projects/doctype/dependent_task/dependent_task.py
+++ b/erpnext/projects/doctype/dependent_task/dependent_task.py
@@ -6,4 +6,18 @@
 
 
 class DependentTask(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
+
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		task: DF.Link | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/projects/doctype/project/project.js b/erpnext/projects/doctype/project/project.js
index f366f77..2dac399 100644
--- a/erpnext/projects/doctype/project/project.js
+++ b/erpnext/projects/doctype/project/project.js
@@ -68,6 +68,10 @@
 				frm.events.create_duplicate(frm);
 			}, __("Actions"));
 
+			frm.add_custom_button(__('Update Total Purchase Cost'), () => {
+				frm.events.update_total_purchase_cost(frm);
+			}, __("Actions"));
+
 			frm.trigger("set_project_status_button");
 
 
@@ -92,6 +96,22 @@
 
 	},
 
+	update_total_purchase_cost: function(frm) {
+		frappe.call({
+			method: "erpnext.projects.doctype.project.project.recalculate_project_total_purchase_cost",
+			args: {project: frm.doc.name},
+			freeze: true,
+			freeze_message: __('Recalculating Purchase Cost against this Project...'),
+			callback: function(r) {
+				if (r && !r.exc) {
+					frappe.msgprint(__('Total Purchase Cost has been updated'));
+					frm.refresh();
+				}
+			}
+
+		});
+	},
+
 	set_project_status_button: function(frm) {
 		frm.add_custom_button(__('Set Project Status'), () => {
 			let d = new frappe.ui.Dialog({
diff --git a/erpnext/projects/doctype/project/project.py b/erpnext/projects/doctype/project/project.py
index e9aed1a..4f2e395 100644
--- a/erpnext/projects/doctype/project/project.py
+++ b/erpnext/projects/doctype/project/project.py
@@ -4,11 +4,11 @@
 
 import frappe
 from email_reply_parser import EmailReplyParser
-from frappe import _
+from frappe import _, qb
 from frappe.desk.reportview import get_match_cond
 from frappe.model.document import Document
 from frappe.query_builder import Interval
-from frappe.query_builder.functions import Count, CurDate, Date, UnixTimestamp
+from frappe.query_builder.functions import Count, CurDate, Date, Sum, UnixTimestamp
 from frappe.utils import add_days, flt, get_datetime, get_time, get_url, nowtime, today
 from frappe.utils.user import is_website_user
 
@@ -249,12 +249,7 @@
 			self.per_gross_margin = (self.gross_margin / flt(self.total_billed_amount)) * 100
 
 	def update_purchase_costing(self):
-		total_purchase_cost = frappe.db.sql(
-			"""select sum(base_net_amount)
-			from `tabPurchase Invoice Item` where project = %s and docstatus=1""",
-			self.name,
-		)
-
+		total_purchase_cost = calculate_total_purchase_cost(self.name)
 		self.total_purchase_cost = total_purchase_cost and total_purchase_cost[0][0] or 0
 
 	def update_sales_amount(self):
@@ -695,3 +690,29 @@
 
 def get_users_email(doc):
 	return [d.email for d in doc.users if frappe.db.get_value("User", d.user, "enabled")]
+
+
+def calculate_total_purchase_cost(project: str | None = None):
+	if project:
+		pitem = qb.DocType("Purchase Invoice Item")
+		frappe.qb.DocType("Purchase Invoice Item")
+		total_purchase_cost = (
+			qb.from_(pitem)
+			.select(Sum(pitem.base_net_amount))
+			.where((pitem.project == project) & (pitem.docstatus == 1))
+			.run(as_list=True)
+		)
+		return total_purchase_cost
+	return None
+
+
+@frappe.whitelist()
+def recalculate_project_total_purchase_cost(project: str | None = None):
+	if project:
+		total_purchase_cost = calculate_total_purchase_cost(project)
+		frappe.db.set_value(
+			"Project",
+			project,
+			"total_purchase_cost",
+			(total_purchase_cost and total_purchase_cost[0][0] or 0),
+		)
diff --git a/erpnext/projects/doctype/project_template/project_template.py b/erpnext/projects/doctype/project_template/project_template.py
index 89afb1b..c08fc9d 100644
--- a/erpnext/projects/doctype/project_template/project_template.py
+++ b/erpnext/projects/doctype/project_template/project_template.py
@@ -9,6 +9,22 @@
 
 
 class ProjectTemplate(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
+
+		from erpnext.projects.doctype.project_template_task.project_template_task import (
+			ProjectTemplateTask,
+		)
+
+		project_type: DF.Link | None
+		tasks: DF.Table[ProjectTemplateTask]
+	# end: auto-generated types
+
 	def validate(self):
 		self.validate_dependencies()
 
diff --git a/erpnext/projects/doctype/project_template_task/project_template_task.py b/erpnext/projects/doctype/project_template_task/project_template_task.py
index 01ec935..d0d031b 100644
--- a/erpnext/projects/doctype/project_template_task/project_template_task.py
+++ b/erpnext/projects/doctype/project_template_task/project_template_task.py
@@ -7,4 +7,19 @@
 
 
 class ProjectTemplateTask(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
+
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		subject: DF.ReadOnly | None
+		task: DF.Link
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/projects/doctype/project_type/project_type.py b/erpnext/projects/doctype/project_type/project_type.py
index 4a3724d..38e3155 100644
--- a/erpnext/projects/doctype/project_type/project_type.py
+++ b/erpnext/projects/doctype/project_type/project_type.py
@@ -8,6 +8,18 @@
 
 
 class ProjectType(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
+
+		description: DF.Text | None
+		project_type: DF.Data
+	# end: auto-generated types
+
 	def on_trash(self):
 		if self.name == "External":
 			frappe.throw(_("You cannot delete Project Type 'External'"))
diff --git a/erpnext/projects/doctype/project_update/project_update.py b/erpnext/projects/doctype/project_update/project_update.py
index 175f787..53934d0 100644
--- a/erpnext/projects/doctype/project_update/project_update.py
+++ b/erpnext/projects/doctype/project_update/project_update.py
@@ -7,6 +7,25 @@
 
 
 class ProjectUpdate(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
+
+		from erpnext.projects.doctype.project_user.project_user import ProjectUser
+
+		amended_from: DF.Link | None
+		date: DF.Date | None
+		naming_series: DF.Data | None
+		project: DF.Link
+		sent: DF.Check
+		time: DF.Time | None
+		users: DF.Table[ProjectUser]
+	# end: auto-generated types
+
 	pass
 
 
diff --git a/erpnext/projects/doctype/project_user/project_user.py b/erpnext/projects/doctype/project_user/project_user.py
index a52bcb1..358a16a 100644
--- a/erpnext/projects/doctype/project_user/project_user.py
+++ b/erpnext/projects/doctype/project_user/project_user.py
@@ -6,4 +6,24 @@
 
 
 class ProjectUser(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
+
+		email: DF.ReadOnly | None
+		full_name: DF.ReadOnly | None
+		image: DF.ReadOnly | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		project_status: DF.Text | None
+		user: DF.Link
+		view_attachments: DF.Check
+		welcome_email_sent: DF.Check
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/projects/doctype/projects_settings/projects_settings.py b/erpnext/projects/doctype/projects_settings/projects_settings.py
index db1dc45..9d94018 100644
--- a/erpnext/projects/doctype/projects_settings/projects_settings.py
+++ b/erpnext/projects/doctype/projects_settings/projects_settings.py
@@ -6,4 +6,17 @@
 
 
 class ProjectsSettings(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
+
+		ignore_employee_time_overlap: DF.Check
+		ignore_user_time_overlap: DF.Check
+		ignore_workstation_time_overlap: DF.Check
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/projects/doctype/task/task.json b/erpnext/projects/doctype/task/task.json
index 25a5455..4d2d225 100644
--- a/erpnext/projects/doctype/task/task.json
+++ b/erpnext/projects/doctype/task/task.json
@@ -57,6 +57,7 @@
  ],
  "fields": [
   {
+   "allow_in_quick_entry": 1,
    "fieldname": "subject",
    "fieldtype": "Data",
    "in_global_search": 1,
@@ -66,6 +67,7 @@
    "search_index": 1
   },
   {
+   "allow_in_quick_entry": 1,
    "bold": 1,
    "fieldname": "project",
    "fieldtype": "Link",
@@ -396,7 +398,7 @@
  "is_tree": 1,
  "links": [],
  "max_attachments": 5,
- "modified": "2023-09-28 13:52:05.861175",
+ "modified": "2023-11-20 11:42:41.884069",
  "modified_by": "Administrator",
  "module": "Projects",
  "name": "Task",
@@ -416,6 +418,7 @@
    "write": 1
   }
  ],
+ "quick_entry": 1,
  "search_fields": "subject",
  "show_name_in_global_search": 1,
  "show_preview_popup": 1,
diff --git a/erpnext/projects/doctype/task/task.py b/erpnext/projects/doctype/task/task.py
index 333d4d9..22df846 100755
--- a/erpnext/projects/doctype/task/task.py
+++ b/erpnext/projects/doctype/task/task.py
@@ -18,6 +18,56 @@
 
 
 class Task(NestedSet):
+	# 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
+
+		from erpnext.projects.doctype.task_depends_on.task_depends_on import TaskDependsOn
+
+		act_end_date: DF.Date | None
+		act_start_date: DF.Date | None
+		actual_time: DF.Float
+		closing_date: DF.Date | None
+		color: DF.Color | None
+		company: DF.Link | None
+		completed_by: DF.Link | None
+		completed_on: DF.Date | None
+		department: DF.Link | None
+		depends_on: DF.Table[TaskDependsOn]
+		depends_on_tasks: DF.Code | None
+		description: DF.TextEditor | None
+		duration: DF.Int
+		exp_end_date: DF.Date | None
+		exp_start_date: DF.Date | None
+		expected_time: DF.Float
+		is_group: DF.Check
+		is_milestone: DF.Check
+		is_template: DF.Check
+		issue: DF.Link | None
+		lft: DF.Int
+		old_parent: DF.Data | None
+		parent_task: DF.Link | None
+		priority: DF.Literal["Low", "Medium", "High", "Urgent"]
+		progress: DF.Percent
+		project: DF.Link | None
+		review_date: DF.Date | None
+		rgt: DF.Int
+		start: DF.Int
+		status: DF.Literal[
+			"Open", "Working", "Pending Review", "Overdue", "Template", "Completed", "Cancelled"
+		]
+		subject: DF.Data
+		task_weight: DF.Float
+		template_task: DF.Data | None
+		total_billing_amount: DF.Currency
+		total_costing_amount: DF.Currency
+		type: DF.Link | None
+	# end: auto-generated types
+
 	nsm_parent_field = "parent_task"
 
 	def get_customer_details(self):
diff --git a/erpnext/projects/doctype/task_depends_on/task_depends_on.py b/erpnext/projects/doctype/task_depends_on/task_depends_on.py
index 0db1f81..c1cc21a 100644
--- a/erpnext/projects/doctype/task_depends_on/task_depends_on.py
+++ b/erpnext/projects/doctype/task_depends_on/task_depends_on.py
@@ -6,4 +6,20 @@
 
 
 class TaskDependsOn(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
+
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		project: DF.Text | None
+		subject: DF.Text | None
+		task: DF.Link | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/projects/doctype/task_type/task_type.py b/erpnext/projects/doctype/task_type/task_type.py
index 08bed69..40d69e2 100644
--- a/erpnext/projects/doctype/task_type/task_type.py
+++ b/erpnext/projects/doctype/task_type/task_type.py
@@ -7,4 +7,16 @@
 
 
 class TaskType(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
+
+		description: DF.SmallText | None
+		weight: DF.Float
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/projects/doctype/timesheet/timesheet.js b/erpnext/projects/doctype/timesheet/timesheet.js
index d1d07a7..eb7a97e 100644
--- a/erpnext/projects/doctype/timesheet/timesheet.js
+++ b/erpnext/projects/doctype/timesheet/timesheet.js
@@ -111,6 +111,7 @@
 
 		frm.trigger('setup_filters');
 		frm.trigger('set_dynamic_field_label');
+		frm.trigger('set_route_options_for_new_task');
 	},
 
 	customer: function(frm) {
@@ -172,6 +173,14 @@
 		frm.refresh_fields();
 	},
 
+	set_route_options_for_new_task: (frm) => {
+		let task_field = frm.get_docfield('time_logs', 'task');
+
+		if (task_field) {
+			task_field.get_route_options_for_new_doc = (row) => ({'project': row.doc.project});
+		}
+	},
+
 	make_invoice: function(frm) {
 		let fields = [{
 			"fieldtype": "Link",
diff --git a/erpnext/projects/doctype/timesheet/timesheet.py b/erpnext/projects/doctype/timesheet/timesheet.py
index 11156f4..b9d801c 100644
--- a/erpnext/projects/doctype/timesheet/timesheet.py
+++ b/erpnext/projects/doctype/timesheet/timesheet.py
@@ -71,6 +71,12 @@
 		if args.is_billable:
 			if flt(args.billing_hours) == 0.0:
 				args.billing_hours = args.hours
+			elif flt(args.billing_hours) > flt(args.hours):
+				frappe.msgprint(
+					_("Warning - Row {0}: Billing Hours are more than Actual Hours").format(args.idx),
+					indicator="orange",
+					alert=True,
+				)
 		else:
 			args.billing_hours = 0
 
diff --git a/erpnext/projects/doctype/timesheet_detail/timesheet_detail.py b/erpnext/projects/doctype/timesheet_detail/timesheet_detail.py
index d527a3c..cd61da1 100644
--- a/erpnext/projects/doctype/timesheet_detail/timesheet_detail.py
+++ b/erpnext/projects/doctype/timesheet_detail/timesheet_detail.py
@@ -6,4 +6,38 @@
 
 
 class TimesheetDetail(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
+
+		activity_type: DF.Link | None
+		base_billing_amount: DF.Currency
+		base_billing_rate: DF.Currency
+		base_costing_amount: DF.Currency
+		base_costing_rate: DF.Currency
+		billing_amount: DF.Currency
+		billing_hours: DF.Float
+		billing_rate: DF.Currency
+		completed: DF.Check
+		costing_amount: DF.Currency
+		costing_rate: DF.Currency
+		description: DF.SmallText | None
+		expected_hours: DF.Float
+		from_time: DF.Datetime | None
+		hours: DF.Float
+		is_billable: DF.Check
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		project: DF.Link | None
+		project_name: DF.Data | None
+		sales_invoice: DF.Link | None
+		task: DF.Link | None
+		to_time: DF.Datetime | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/public/js/communication.js b/erpnext/public/js/communication.js
index 7ce8b09..f205d88 100644
--- a/erpnext/public/js/communication.js
+++ b/erpnext/public/js/communication.js
@@ -13,7 +13,7 @@
 				frappe.confirm(__(confirm_msg, [__("Issue")]), () => {
 					frm.trigger('make_issue_from_communication');
 				})
-			}, "Create");
+			}, __("Create"));
 		}
 
 		if(!in_list(["Lead", "Opportunity"], frm.doc.reference_doctype)) {
diff --git a/erpnext/public/js/controllers/taxes_and_totals.js b/erpnext/public/js/controllers/taxes_and_totals.js
index 6b613ce..d24c4e6 100644
--- a/erpnext/public/js/controllers/taxes_and_totals.js
+++ b/erpnext/public/js/controllers/taxes_and_totals.js
@@ -43,6 +43,9 @@
 		if (this.frm.doc.apply_discount_on == "Grand Total" && this.frm.doc.is_cash_or_non_trade_discount) {
 			this.frm.doc.grand_total -= this.frm.doc.discount_amount;
 			this.frm.doc.base_grand_total -= this.frm.doc.base_discount_amount;
+			this.frm.doc.rounding_adjustment = 0;
+			this.frm.doc.base_rounding_adjustment = 0;
+			this.set_rounded_total();
 		}
 
 		await this.calculate_shipping_charges();
diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js
index 2c40f49..8c0d84b 100644
--- a/erpnext/public/js/controllers/transaction.js
+++ b/erpnext/public/js/controllers/transaction.js
@@ -357,7 +357,7 @@
 
 	onload_post_render() {
 		if(this.frm.doc.__islocal && !(this.frm.doc.taxes || []).length
-			&& !(this.frm.doc.__onload ? this.frm.doc.__onload.load_after_mapping : false)) {
+			&& !this.frm.doc.__onload?.load_after_mapping) {
 			frappe.after_ajax(() => this.apply_default_taxes());
 		} else if(this.frm.doc.__islocal && this.frm.doc.company && this.frm.doc["items"]
 			&& !this.frm.doc.is_pos) {
@@ -512,6 +512,7 @@
 							cost_center: item.cost_center,
 							tax_category: me.frm.doc.tax_category,
 							item_tax_template: item.item_tax_template,
+							child_doctype: item.doctype,
 							child_docname: item.name,
 							is_old_subcontracting_flow: me.frm.doc.is_old_subcontracting_flow,
 						}
@@ -963,9 +964,9 @@
 		let me = this;
 		this.set_dynamic_labels();
 		let company_currency = this.get_company_currency();
-		// Added `ignore_price_list` to determine if document is loading after mapping from another doc
+		// Added `load_after_mapping` to determine if document is loading after mapping from another doc
 		if(this.frm.doc.currency && this.frm.doc.currency !== company_currency
-				&& !(this.frm.doc.__onload && this.frm.doc.__onload.ignore_price_list)) {
+				&& !this.frm.doc.__onload?.load_after_mapping) {
 
 			this.get_exchange_rate(transaction_date, this.frm.doc.currency, company_currency,
 				function(exchange_rate) {
@@ -997,7 +998,7 @@
 		}
 
 		if(flt(this.frm.doc.conversion_rate)>0.0) {
-			if(this.frm.doc.__onload && this.frm.doc.__onload.ignore_price_list) {
+			if(this.frm.doc.__onload?.load_after_mapping) {
 				this.calculate_taxes_and_totals();
 			} else if (!this.in_apply_price_list){
 				this.apply_price_list();
@@ -1084,9 +1085,9 @@
 		this.set_dynamic_labels();
 
 		var company_currency = this.get_company_currency();
-		// Added `ignore_price_list` to determine if document is loading after mapping from another doc
+		// Added `load_after_mapping` to determine if document is loading after mapping from another doc
 		if(this.frm.doc.price_list_currency !== company_currency  &&
-				!(this.frm.doc.__onload && this.frm.doc.__onload.ignore_price_list)) {
+				!this.frm.doc.__onload?.load_after_mapping) {
 			this.get_exchange_rate(this.frm.doc.posting_date, this.frm.doc.price_list_currency, company_currency,
 				function(exchange_rate) {
 					me.frm.set_value("plc_conversion_rate", exchange_rate);
@@ -1475,7 +1476,7 @@
 		}
 
 		// Target doc created from a mapped doc
-		if (this.frm.doc.__onload && this.frm.doc.__onload.ignore_price_list) {
+		if (this.frm.doc.__onload?.load_after_mapping) {
 			// Calculate totals even though pricing rule is not applied.
 			// `apply_pricing_rule` is triggered due to change in data which most likely contributes to Total.
 			if (calculate_taxes_and_totals) me.calculate_taxes_and_totals();
diff --git a/erpnext/public/js/financial_statements.js b/erpnext/public/js/financial_statements.js
index 907a775..1b10d8a 100644
--- a/erpnext/public/js/financial_statements.js
+++ b/erpnext/public/js/financial_statements.js
@@ -139,7 +139,6 @@
 			"label": __("Start Year"),
 			"fieldtype": "Link",
 			"options": "Fiscal Year",
-			"default": erpnext.utils.get_fiscal_year(frappe.datetime.get_today()),
 			"reqd": 1,
 			"depends_on": "eval:doc.filter_based_on == 'Fiscal Year'"
 		},
@@ -148,7 +147,6 @@
 			"label": __("End Year"),
 			"fieldtype": "Link",
 			"options": "Fiscal Year",
-			"default": erpnext.utils.get_fiscal_year(frappe.datetime.get_today()),
 			"reqd": 1,
 			"depends_on": "eval:doc.filter_based_on == 'Fiscal Year'"
 		},
@@ -197,5 +195,13 @@
 		}
 	]
 
+	// Dynamically set 'default' values for fiscal year filters
+	let fy_filters = filters.filter(x=>{return ["from_fiscal_year", "to_fiscal_year"].includes(x.fieldname);})
+	let fiscal_year = erpnext.utils.get_fiscal_year(frappe.datetime.get_today(), false, true);
+	if (fiscal_year) {
+		let fy = erpnext.utils.get_fiscal_year(frappe.datetime.get_today(), false, false);
+		fy_filters.forEach(x=>{x.default = fy;})
+	}
+
 	return filters;
 }
diff --git a/erpnext/public/js/utils.js b/erpnext/public/js/utils.js
index d435711..25fc754 100755
--- a/erpnext/public/js/utils.js
+++ b/erpnext/public/js/utils.js
@@ -404,7 +404,7 @@
 		});
 	},
 
-	get_fiscal_year: function(date, with_dates=false) {
+	get_fiscal_year: function(date, with_dates=false, boolean=false) {
 		if(!date) {
 			date = frappe.datetime.get_today();
 		}
@@ -413,7 +413,8 @@
 		frappe.call({
 			method: "erpnext.accounts.utils.get_fiscal_year",
 			args: {
-				date: date
+				date: date,
+				boolean: boolean
 			},
 			async: false,
 			callback: function(r) {
diff --git a/erpnext/public/js/utils/sales_common.js b/erpnext/public/js/utils/sales_common.js
index 1d6daa5..5514963 100644
--- a/erpnext/public/js/utils/sales_common.js
+++ b/erpnext/public/js/utils/sales_common.js
@@ -369,6 +369,11 @@
 					}
 				}
 			}
+
+			coupon_code() {
+				this.frm.set_value("discount_amount", 0);
+				this.frm.set_value("additional_discount_percentage", 0);
+			}
 		};
 	}
 }
diff --git a/erpnext/public/js/utils/serial_no_batch_selector.js b/erpnext/public/js/utils/serial_no_batch_selector.js
index 9267801..0de6774 100644
--- a/erpnext/public/js/utils/serial_no_batch_selector.js
+++ b/erpnext/public/js/utils/serial_no_batch_selector.js
@@ -31,8 +31,19 @@
 			secondary_action: () => this.edit_full_form(),
 		});
 
-		this.dialog.set_value("qty", this.item.qty);
+		this.dialog.set_value("qty", this.item.qty).then(() => {
+			if (this.item.serial_no) {
+				this.dialog.set_value("scan_serial_no", this.item.serial_no);
+				frappe.model.set_value(this.item.doctype, this.item.name, 'serial_no', '');
+			} else if (this.item.batch_no) {
+				this.dialog.set_value("scan_batch_no", this.item.batch_no);
+				frappe.model.set_value(this.item.doctype, this.item.name, 'batch_no', '');
+			}
+		});
+
 		this.dialog.show();
+		this.$scan_btn = this.dialog.$wrapper.find(".link-btn");
+		this.$scan_btn.css("display", "inline");
 	}
 
 	get_serial_no_filters() {
@@ -95,6 +106,7 @@
 		if (this.item.has_serial_no) {
 			fields.push({
 				fieldtype: 'Data',
+				options: 'Barcode',
 				fieldname: 'scan_serial_no',
 				label: __('Scan Serial No'),
 				get_query: () => {
@@ -106,15 +118,10 @@
 			});
 		}
 
-		if (this.item.has_batch_no && this.item.has_serial_no) {
-			fields.push({
-				fieldtype: 'Column Break',
-			});
-		}
-
-		if (this.item.has_batch_no) {
+		if (this.item.has_batch_no && !this.item.has_serial_no) {
 			fields.push({
 				fieldtype: 'Data',
+				options: 'Barcode',
 				fieldname: 'scan_batch_no',
 				label: __('Scan Batch No'),
 				onchange: () => this.update_serial_batch_no()
@@ -309,6 +316,14 @@
 	}
 
 	get_auto_data() {
+		if (this.item.serial_and_batch_bundle || this.item.rejected_serial_and_batch_bundle) {
+			return;
+		}
+
+		if (this.item.serial_no || this.item.batch_no) {
+			return;
+		}
+
 		let { qty, based_on } = this.dialog.get_values();
 
 		if (!based_on) {
@@ -340,16 +355,57 @@
 		const { scan_serial_no, scan_batch_no } = this.dialog.get_values();
 
 		if (scan_serial_no) {
-			this.dialog.fields_dict.entries.df.data.push({
-				serial_no: scan_serial_no
+			let existing_row = this.dialog.fields_dict.entries.df.data.filter(d => {
+				if (d.serial_no === scan_serial_no) {
+					return d
+				}
 			});
 
-			this.dialog.fields_dict.scan_serial_no.set_value('');
+			if (existing_row?.length) {
+				frappe.throw(__('Serial No {0} already exists', [scan_serial_no]));
+			}
+
+			if (!this.item.has_batch_no) {
+				this.dialog.fields_dict.entries.df.data.push({
+					serial_no: scan_serial_no
+				});
+
+				this.dialog.fields_dict.scan_serial_no.set_value('');
+			} else {
+				frappe.call({
+					method: 'erpnext.stock.doctype.serial_and_batch_bundle.serial_and_batch_bundle.get_batch_no_from_serial_no',
+					args: {
+						serial_no: scan_serial_no,
+					},
+					callback: (r) => {
+						if (r.message) {
+							this.dialog.fields_dict.entries.df.data.push({
+								serial_no: scan_serial_no,
+								batch_no: r.message
+							});
+
+							this.dialog.fields_dict.scan_serial_no.set_value('');
+						}
+					}
+
+				})
+			}
 		} else if (scan_batch_no) {
-			this.dialog.fields_dict.entries.df.data.push({
-				batch_no: scan_batch_no
+			let existing_row = this.dialog.fields_dict.entries.df.data.filter(d => {
+				if (d.batch_no === scan_batch_no) {
+					return d
+				}
 			});
 
+			if (existing_row?.length) {
+				existing_row[0].qty += 1;
+			} else {
+				this.dialog.fields_dict.entries.df.data.push({
+					batch_no: scan_batch_no,
+					qty: 1
+				});
+			}
+
 			this.dialog.fields_dict.scan_batch_no.set_value('');
 		}
 
diff --git a/erpnext/public/js/utils/unreconcile.js b/erpnext/public/js/utils/unreconcile.js
index fa00ed2..79490a1 100644
--- a/erpnext/public/js/utils/unreconcile.js
+++ b/erpnext/public/js/utils/unreconcile.js
@@ -1,6 +1,6 @@
 frappe.provide('erpnext.accounts');
 
-erpnext.accounts.unreconcile_payments = {
+erpnext.accounts.unreconcile_payment = {
 	add_unreconcile_btn(frm) {
 		if (frm.doc.docstatus == 1) {
 			if(((frm.doc.doctype == "Journal Entry") && (frm.doc.voucher_type != "Journal Entry"))
@@ -10,7 +10,7 @@
 			}
 
 			frappe.call({
-				"method": "erpnext.accounts.doctype.unreconcile_payments.unreconcile_payments.doc_has_references",
+				"method": "erpnext.accounts.doctype.unreconcile_payment.unreconcile_payment.doc_has_references",
 				"args": {
 					"doctype": frm.doc.doctype,
 					"docname": frm.doc.name
@@ -18,7 +18,7 @@
 				callback: function(r) {
 					if (r.message) {
 						frm.add_custom_button(__("UnReconcile"), function() {
-							erpnext.accounts.unreconcile_payments.build_unreconcile_dialog(frm);
+							erpnext.accounts.unreconcile_payment.build_unreconcile_dialog(frm);
 						}, __('Actions'));
 					}
 				}
@@ -74,7 +74,7 @@
 
 			// get linked payments
 			frappe.call({
-				"method": "erpnext.accounts.doctype.unreconcile_payments.unreconcile_payments.get_linked_payments_for_doc",
+				"method": "erpnext.accounts.doctype.unreconcile_payment.unreconcile_payment.get_linked_payments_for_doc",
 				"args": {
 					"company": frm.doc.company,
 					"doctype": frm.doc.doctype,
@@ -96,8 +96,8 @@
 
 								let selected_allocations = values.allocations.filter(x=>x.__checked);
 								if (selected_allocations.length > 0) {
-									let selection_map = erpnext.accounts.unreconcile_payments.build_selection_map(frm, selected_allocations);
-									erpnext.accounts.unreconcile_payments.create_unreconcile_docs(selection_map);
+									let selection_map = erpnext.accounts.unreconcile_payment.build_selection_map(frm, selected_allocations);
+									erpnext.accounts.unreconcile_payment.create_unreconcile_docs(selection_map);
 									d.hide();
 
 								} else {
@@ -115,7 +115,7 @@
 
 	create_unreconcile_docs(selection_map) {
 		frappe.call({
-			"method": "erpnext.accounts.doctype.unreconcile_payments.unreconcile_payments.create_unreconcile_doc_for_selection",
+			"method": "erpnext.accounts.doctype.unreconcile_payment.unreconcile_payment.create_unreconcile_doc_for_selection",
 			"args": {
 				"selections": selection_map
 			},
diff --git a/erpnext/quality_management/doctype/non_conformance/non_conformance.py b/erpnext/quality_management/doctype/non_conformance/non_conformance.py
index a2198f3..5817b99 100644
--- a/erpnext/quality_management/doctype/non_conformance/non_conformance.py
+++ b/erpnext/quality_management/doctype/non_conformance/non_conformance.py
@@ -7,4 +7,22 @@
 
 
 class NonConformance(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
+
+		corrective_action: DF.TextEditor | None
+		details: DF.TextEditor | None
+		full_name: DF.Data | None
+		preventive_action: DF.TextEditor | None
+		procedure: DF.Link
+		process_owner: DF.Data | None
+		status: DF.Literal["Open", "Resolved", "Cancelled"]
+		subject: DF.Data
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/quality_management/doctype/quality_action/quality_action.py b/erpnext/quality_management/doctype/quality_action/quality_action.py
index f7cd94d..3ef46e3 100644
--- a/erpnext/quality_management/doctype/quality_action/quality_action.py
+++ b/erpnext/quality_management/doctype/quality_action/quality_action.py
@@ -6,5 +6,27 @@
 
 
 class QualityAction(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
+
+		from erpnext.quality_management.doctype.quality_action_resolution.quality_action_resolution import (
+			QualityActionResolution,
+		)
+
+		corrective_preventive: DF.Literal["Corrective", "Preventive"]
+		date: DF.Date | None
+		feedback: DF.Link | None
+		goal: DF.Link | None
+		procedure: DF.Link | None
+		resolutions: DF.Table[QualityActionResolution]
+		review: DF.Link | None
+		status: DF.Literal["Open", "Completed"]
+	# end: auto-generated types
+
 	def validate(self):
 		self.status = "Open" if any([d.status == "Open" for d in self.resolutions]) else "Completed"
diff --git a/erpnext/quality_management/doctype/quality_action_resolution/quality_action_resolution.py b/erpnext/quality_management/doctype/quality_action_resolution/quality_action_resolution.py
index 7ede3e4de..5bdd513 100644
--- a/erpnext/quality_management/doctype/quality_action_resolution/quality_action_resolution.py
+++ b/erpnext/quality_management/doctype/quality_action_resolution/quality_action_resolution.py
@@ -7,4 +7,22 @@
 
 
 class QualityActionResolution(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
+
+		completion_by: DF.Date | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		problem: DF.LongText | None
+		resolution: DF.TextEditor | None
+		responsible: DF.Link | None
+		status: DF.Literal["Open", "Completed"]
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/quality_management/doctype/quality_feedback/quality_feedback.py b/erpnext/quality_management/doctype/quality_feedback/quality_feedback.py
index cc8ce26..8dc8061 100644
--- a/erpnext/quality_management/doctype/quality_feedback/quality_feedback.py
+++ b/erpnext/quality_management/doctype/quality_feedback/quality_feedback.py
@@ -7,6 +7,24 @@
 
 
 class QualityFeedback(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
+
+		from erpnext.quality_management.doctype.quality_feedback_parameter.quality_feedback_parameter import (
+			QualityFeedbackParameter,
+		)
+
+		document_name: DF.DynamicLink
+		document_type: DF.Literal["User", "Customer"]
+		parameters: DF.Table[QualityFeedbackParameter]
+		template: DF.Link
+	# end: auto-generated types
+
 	@frappe.whitelist()
 	def set_parameters(self):
 		if self.template and not getattr(self, "parameters", []):
diff --git a/erpnext/quality_management/doctype/quality_feedback_parameter/quality_feedback_parameter.py b/erpnext/quality_management/doctype/quality_feedback_parameter/quality_feedback_parameter.py
index ff2c841..a86ba32 100644
--- a/erpnext/quality_management/doctype/quality_feedback_parameter/quality_feedback_parameter.py
+++ b/erpnext/quality_management/doctype/quality_feedback_parameter/quality_feedback_parameter.py
@@ -7,4 +7,20 @@
 
 
 class QualityFeedbackParameter(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
+
+		feedback: DF.TextEditor | None
+		parameter: DF.Data | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		rating: DF.Literal["", "1", "2", "3", "4", "5"]
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/quality_management/doctype/quality_feedback_template/quality_feedback_template.py b/erpnext/quality_management/doctype/quality_feedback_template/quality_feedback_template.py
index 4590f9d..df9def3 100644
--- a/erpnext/quality_management/doctype/quality_feedback_template/quality_feedback_template.py
+++ b/erpnext/quality_management/doctype/quality_feedback_template/quality_feedback_template.py
@@ -7,4 +7,20 @@
 
 
 class QualityFeedbackTemplate(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
+
+		from erpnext.quality_management.doctype.quality_feedback_template_parameter.quality_feedback_template_parameter import (
+			QualityFeedbackTemplateParameter,
+		)
+
+		parameters: DF.Table[QualityFeedbackTemplateParameter]
+		template: DF.Data
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/quality_management/doctype/quality_feedback_template_parameter/quality_feedback_template_parameter.py b/erpnext/quality_management/doctype/quality_feedback_template_parameter/quality_feedback_template_parameter.py
index 13e215f..7795dab 100644
--- a/erpnext/quality_management/doctype/quality_feedback_template_parameter/quality_feedback_template_parameter.py
+++ b/erpnext/quality_management/doctype/quality_feedback_template_parameter/quality_feedback_template_parameter.py
@@ -7,4 +7,18 @@
 
 
 class QualityFeedbackTemplateParameter(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
+
+		parameter: DF.Data | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/quality_management/doctype/quality_goal/quality_goal.py b/erpnext/quality_management/doctype/quality_goal/quality_goal.py
index 22ba810..6bcc743 100644
--- a/erpnext/quality_management/doctype/quality_goal/quality_goal.py
+++ b/erpnext/quality_management/doctype/quality_goal/quality_goal.py
@@ -6,5 +6,56 @@
 
 
 class QualityGoal(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
+
+		from erpnext.quality_management.doctype.quality_goal_objective.quality_goal_objective import (
+			QualityGoalObjective,
+		)
+
+		date: DF.Literal[
+			"1",
+			"2",
+			"3",
+			"4",
+			"5",
+			"6",
+			"7",
+			"8",
+			"9",
+			"10",
+			"11",
+			"12",
+			"13",
+			"14",
+			"15",
+			"16",
+			"17",
+			"18",
+			"19",
+			"20",
+			"21",
+			"22",
+			"23",
+			"24",
+			"25",
+			"26",
+			"27",
+			"28",
+			"29",
+			"30",
+		]
+		frequency: DF.Literal["None", "Daily", "Weekly", "Monthly", "Quarterly"]
+		goal: DF.Data
+		objectives: DF.Table[QualityGoalObjective]
+		procedure: DF.Link | None
+		weekday: DF.Literal["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
+	# end: auto-generated types
+
 	def validate(self):
 		pass
diff --git a/erpnext/quality_management/doctype/quality_goal_objective/quality_goal_objective.py b/erpnext/quality_management/doctype/quality_goal_objective/quality_goal_objective.py
index eaa8db2..325c2e4 100644
--- a/erpnext/quality_management/doctype/quality_goal_objective/quality_goal_objective.py
+++ b/erpnext/quality_management/doctype/quality_goal_objective/quality_goal_objective.py
@@ -7,4 +7,20 @@
 
 
 class QualityGoalObjective(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
+
+		objective: DF.Text
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		target: DF.Data | None
+		uom: DF.Link | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/quality_management/doctype/quality_meeting/quality_meeting.py b/erpnext/quality_management/doctype/quality_meeting/quality_meeting.py
index 481b3c1..a8dd564 100644
--- a/erpnext/quality_management/doctype/quality_meeting/quality_meeting.py
+++ b/erpnext/quality_management/doctype/quality_meeting/quality_meeting.py
@@ -6,4 +6,24 @@
 
 
 class QualityMeeting(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
+
+		from erpnext.quality_management.doctype.quality_meeting_agenda.quality_meeting_agenda import (
+			QualityMeetingAgenda,
+		)
+		from erpnext.quality_management.doctype.quality_meeting_minutes.quality_meeting_minutes import (
+			QualityMeetingMinutes,
+		)
+
+		agenda: DF.Table[QualityMeetingAgenda]
+		minutes: DF.Table[QualityMeetingMinutes]
+		status: DF.Literal["Open", "Closed"]
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/quality_management/doctype/quality_meeting_agenda/quality_meeting_agenda.py b/erpnext/quality_management/doctype/quality_meeting_agenda/quality_meeting_agenda.py
index c2f5b3f..edf4fd6 100644
--- a/erpnext/quality_management/doctype/quality_meeting_agenda/quality_meeting_agenda.py
+++ b/erpnext/quality_management/doctype/quality_meeting_agenda/quality_meeting_agenda.py
@@ -7,4 +7,18 @@
 
 
 class QualityMeetingAgenda(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
+
+		agenda: DF.TextEditor | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/quality_management/doctype/quality_meeting_minutes/quality_meeting_minutes.py b/erpnext/quality_management/doctype/quality_meeting_minutes/quality_meeting_minutes.py
index f6998df..c6237d9 100644
--- a/erpnext/quality_management/doctype/quality_meeting_minutes/quality_meeting_minutes.py
+++ b/erpnext/quality_management/doctype/quality_meeting_minutes/quality_meeting_minutes.py
@@ -7,4 +7,20 @@
 
 
 class QualityMeetingMinutes(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
+
+		document_name: DF.DynamicLink | None
+		document_type: DF.Literal["Quality Review", "Quality Action", "Quality Feedback"]
+		minute: DF.TextEditor | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/quality_management/doctype/quality_procedure/quality_procedure.py b/erpnext/quality_management/doctype/quality_procedure/quality_procedure.py
index 6834abc..8a67d92 100644
--- a/erpnext/quality_management/doctype/quality_procedure/quality_procedure.py
+++ b/erpnext/quality_management/doctype/quality_procedure/quality_procedure.py
@@ -8,6 +8,29 @@
 
 
 class QualityProcedure(NestedSet):
+	# 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
+
+		from erpnext.quality_management.doctype.quality_procedure_process.quality_procedure_process import (
+			QualityProcedureProcess,
+		)
+
+		is_group: DF.Check
+		lft: DF.Int
+		old_parent: DF.Data | None
+		parent_quality_procedure: DF.Link | None
+		process_owner: DF.Link | None
+		process_owner_full_name: DF.Data | None
+		processes: DF.Table[QualityProcedureProcess]
+		quality_procedure_name: DF.Data
+		rgt: DF.Int
+	# end: auto-generated types
+
 	nsm_parent_field = "parent_quality_procedure"
 
 	def before_save(self):
diff --git a/erpnext/quality_management/doctype/quality_procedure_process/quality_procedure_process.py b/erpnext/quality_management/doctype/quality_procedure_process/quality_procedure_process.py
index a03c871..2626fbd 100644
--- a/erpnext/quality_management/doctype/quality_procedure_process/quality_procedure_process.py
+++ b/erpnext/quality_management/doctype/quality_procedure_process/quality_procedure_process.py
@@ -7,4 +7,19 @@
 
 
 class QualityProcedureProcess(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
+
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		procedure: DF.Link | None
+		process_description: DF.TextEditor | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/quality_management/doctype/quality_review/quality_review.py b/erpnext/quality_management/doctype/quality_review/quality_review.py
index f691005..bf4a403 100644
--- a/erpnext/quality_management/doctype/quality_review/quality_review.py
+++ b/erpnext/quality_management/doctype/quality_review/quality_review.py
@@ -7,6 +7,26 @@
 
 
 class QualityReview(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
+
+		from erpnext.quality_management.doctype.quality_review_objective.quality_review_objective import (
+			QualityReviewObjective,
+		)
+
+		additional_information: DF.Text | None
+		date: DF.Date | None
+		goal: DF.Link
+		procedure: DF.Link | None
+		reviews: DF.Table[QualityReviewObjective]
+		status: DF.Literal["Open", "Passed", "Failed"]
+	# end: auto-generated types
+
 	def validate(self):
 		# fetch targets from goal
 		if not self.reviews:
diff --git a/erpnext/quality_management/doctype/quality_review_objective/quality_review_objective.py b/erpnext/quality_management/doctype/quality_review_objective/quality_review_objective.py
index 462a971..9406f58 100644
--- a/erpnext/quality_management/doctype/quality_review_objective/quality_review_objective.py
+++ b/erpnext/quality_management/doctype/quality_review_objective/quality_review_objective.py
@@ -7,4 +7,22 @@
 
 
 class QualityReviewObjective(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
+
+		objective: DF.Text | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		review: DF.TextEditor | None
+		status: DF.Literal["Open", "Passed", "Failed"]
+		target: DF.Data | None
+		uom: DF.Link | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/regional/doctype/import_supplier_invoice/import_supplier_invoice.py b/erpnext/regional/doctype/import_supplier_invoice/import_supplier_invoice.py
index c52685e..bf338d6 100644
--- a/erpnext/regional/doctype/import_supplier_invoice/import_supplier_invoice.py
+++ b/erpnext/regional/doctype/import_supplier_invoice/import_supplier_invoice.py
@@ -18,6 +18,24 @@
 
 
 class ImportSupplierInvoice(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
+		default_buying_price_list: DF.Link
+		invoice_series: DF.Literal["ACC-PINV-.YYYY.-"]
+		item_code: DF.Link
+		status: DF.Data | None
+		supplier_group: DF.Link
+		tax_account: DF.Link
+		zip_file: DF.Attach | None
+	# end: auto-generated types
+
 	def validate(self):
 		if not frappe.db.get_value("Stock Settings", fieldname="stock_uom"):
 			frappe.throw(_("Please set default UOM in Stock Settings"))
diff --git a/erpnext/regional/doctype/lower_deduction_certificate/lower_deduction_certificate.py b/erpnext/regional/doctype/lower_deduction_certificate/lower_deduction_certificate.py
index 6ae04c1..72b3a49 100644
--- a/erpnext/regional/doctype/lower_deduction_certificate/lower_deduction_certificate.py
+++ b/erpnext/regional/doctype/lower_deduction_certificate/lower_deduction_certificate.py
@@ -11,6 +11,26 @@
 
 
 class LowerDeductionCertificate(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
+
+		certificate_limit: DF.Currency
+		certificate_no: DF.Data
+		company: DF.Link
+		fiscal_year: DF.Link
+		pan_no: DF.Data
+		rate: DF.Percent
+		supplier: DF.Link
+		tax_withholding_category: DF.Link
+		valid_from: DF.Date
+		valid_upto: DF.Date
+	# end: auto-generated types
+
 	def validate(self):
 		self.validate_dates()
 		self.validate_supplier_against_tax_category()
diff --git a/erpnext/regional/doctype/south_africa_vat_settings/south_africa_vat_settings.py b/erpnext/regional/doctype/south_africa_vat_settings/south_africa_vat_settings.py
index 4c3e8a7..aa3cd4b 100644
--- a/erpnext/regional/doctype/south_africa_vat_settings/south_africa_vat_settings.py
+++ b/erpnext/regional/doctype/south_africa_vat_settings/south_africa_vat_settings.py
@@ -6,4 +6,20 @@
 
 
 class SouthAfricaVATSettings(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
+
+		from erpnext.accounts.doctype.south_africa_vat_account.south_africa_vat_account import (
+			SouthAfricaVATAccount,
+		)
+
+		company: DF.Link
+		vat_accounts: DF.Table[SouthAfricaVATAccount]
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/regional/doctype/uae_vat_account/uae_vat_account.py b/erpnext/regional/doctype/uae_vat_account/uae_vat_account.py
index f2fc34d..0a69aed 100644
--- a/erpnext/regional/doctype/uae_vat_account/uae_vat_account.py
+++ b/erpnext/regional/doctype/uae_vat_account/uae_vat_account.py
@@ -7,4 +7,18 @@
 
 
 class UAEVATAccount(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: DF.Link | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/regional/doctype/uae_vat_settings/uae_vat_settings.py b/erpnext/regional/doctype/uae_vat_settings/uae_vat_settings.py
index 1af32e4..95ffdd3 100644
--- a/erpnext/regional/doctype/uae_vat_settings/uae_vat_settings.py
+++ b/erpnext/regional/doctype/uae_vat_settings/uae_vat_settings.py
@@ -7,4 +7,18 @@
 
 
 class UAEVATSettings(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
+
+		from erpnext.regional.doctype.uae_vat_account.uae_vat_account import UAEVATAccount
+
+		company: DF.Link
+		uae_vat_accounts: DF.Table[UAEVATAccount]
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/regional/report/uae_vat_201/uae_vat_201.py b/erpnext/regional/report/uae_vat_201/uae_vat_201.py
index 59ef58b..6ef21e5 100644
--- a/erpnext/regional/report/uae_vat_201/uae_vat_201.py
+++ b/erpnext/regional/report/uae_vat_201/uae_vat_201.py
@@ -141,7 +141,7 @@
 		return frappe.db.sql(
 			"""
 			select
-				s.vat_emirate as emirate, sum(i.base_amount) as total, sum(i.tax_amount)
+				s.vat_emirate as emirate, sum(i.base_net_amount) as total, sum(i.tax_amount)
 			from
 				`tabSales Invoice Item` i inner join `tabSales Invoice` s
 			on
@@ -356,7 +356,7 @@
 			frappe.db.sql(
 				"""
 			select
-				sum(i.base_amount) as total
+				sum(i.base_net_amount) as total
 			from
 				`tabSales Invoice Item` i inner join `tabSales Invoice` s
 			on
@@ -383,7 +383,7 @@
 			frappe.db.sql(
 				"""
 			select
-				sum(i.base_amount) as total
+				sum(i.base_net_amount) as total
 			from
 				`tabSales Invoice Item` i inner join `tabSales Invoice` s
 			on
diff --git a/erpnext/selling/doctype/customer/customer.json b/erpnext/selling/doctype/customer/customer.json
index 3b97123..31bbbcf 100644
--- a/erpnext/selling/doctype/customer/customer.json
+++ b/erpnext/selling/doctype/customer/customer.json
@@ -665,7 +665,7 @@
  "search_fields": "customer_name,customer_group,territory, mobile_no,primary_address",
  "show_name_in_global_search": 1,
  "sort_field": "modified",
- "sort_order": "ASC",
+ "sort_order": "DESC",
  "states": [],
  "title_field": "customer_name",
  "track_changes": 1
diff --git a/erpnext/selling/doctype/customer/customer.py b/erpnext/selling/doctype/customer/customer.py
index 459fc9f..efb9820 100644
--- a/erpnext/selling/doctype/customer/customer.py
+++ b/erpnext/selling/doctype/customer/customer.py
@@ -23,6 +23,70 @@
 
 
 class Customer(TransactionBase):
+	# 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
+
+		from erpnext.accounts.doctype.allowed_to_transact_with.allowed_to_transact_with import (
+			AllowedToTransactWith,
+		)
+		from erpnext.accounts.doctype.party_account.party_account import PartyAccount
+		from erpnext.selling.doctype.customer_credit_limit.customer_credit_limit import (
+			CustomerCreditLimit,
+		)
+		from erpnext.selling.doctype.sales_team.sales_team import SalesTeam
+		from erpnext.utilities.doctype.portal_user.portal_user import PortalUser
+
+		account_manager: DF.Link | None
+		accounts: DF.Table[PartyAccount]
+		companies: DF.Table[AllowedToTransactWith]
+		credit_limits: DF.Table[CustomerCreditLimit]
+		customer_details: DF.Text | None
+		customer_group: DF.Link | None
+		customer_name: DF.Data
+		customer_pos_id: DF.Data | None
+		customer_primary_address: DF.Link | None
+		customer_primary_contact: DF.Link | None
+		customer_type: DF.Literal["Company", "Individual", "Proprietorship", "Partnership"]
+		default_bank_account: DF.Link | None
+		default_commission_rate: DF.Float
+		default_currency: DF.Link | None
+		default_price_list: DF.Link | None
+		default_sales_partner: DF.Link | None
+		disabled: DF.Check
+		dn_required: DF.Check
+		email_id: DF.ReadOnly | None
+		gender: DF.Link | None
+		image: DF.AttachImage | None
+		industry: DF.Link | None
+		is_frozen: DF.Check
+		is_internal_customer: DF.Check
+		language: DF.Link | None
+		lead_name: DF.Link | None
+		loyalty_program: DF.Link | None
+		loyalty_program_tier: DF.Data | None
+		market_segment: DF.Link | None
+		mobile_no: DF.ReadOnly | None
+		naming_series: DF.Literal["CUST-.YYYY.-"]
+		opportunity_name: DF.Link | None
+		payment_terms: DF.Link | None
+		portal_users: DF.Table[PortalUser]
+		primary_address: DF.Text | None
+		represents_company: DF.Link | None
+		sales_team: DF.Table[SalesTeam]
+		salutation: DF.Link | None
+		so_required: DF.Check
+		tax_category: DF.Link | None
+		tax_id: DF.Data | None
+		tax_withholding_category: DF.Link | None
+		territory: DF.Link | None
+		website: DF.Data | None
+	# end: auto-generated types
+
 	def onload(self):
 		"""Load address and contacts in `__onload`"""
 		load_address_and_contact(self)
@@ -523,7 +587,8 @@
 		"""
 		select sum(debit) - sum(credit)
 		from `tabGL Entry` where party_type = 'Customer'
-		and party = %s and company=%s {0}""".format(
+		and is_cancelled = 0 and party = %s
+		and company=%s {0}""".format(
 			cond
 		),
 		(customer, company),
@@ -629,8 +694,12 @@
 		"is_primary_contact": is_primary_contact,
 		"links": [{"link_doctype": args.get("doctype"), "link_name": args.get("name")}],
 	}
-	if args.customer_type == "Individual":
-		first, middle, last = parse_full_name(args.get("customer_name"))
+
+	party_type = args.customer_type if args.doctype == "Customer" else args.supplier_type
+	party_name_key = "customer_name" if args.doctype == "Customer" else "supplier_name"
+
+	if party_type == "Individual":
+		first, middle, last = parse_full_name(args.get(party_name_key))
 		values.update(
 			{
 				"first_name": first,
@@ -641,9 +710,10 @@
 	else:
 		values.update(
 			{
-				"company_name": args.get("customer_name"),
+				"company_name": args.get(party_name_key),
 			}
 		)
+
 	contact = frappe.get_doc(values)
 
 	if args.get("email_id"):
@@ -672,10 +742,12 @@
 			title=_("Missing Values Required"),
 		)
 
+	party_name_key = "customer_name" if args.doctype == "Customer" else "supplier_name"
+
 	address = frappe.get_doc(
 		{
 			"doctype": "Address",
-			"address_title": args.get("customer_name"),
+			"address_title": args.get(party_name_key),
 			"address_line1": args.get("address_line1"),
 			"address_line2": args.get("address_line2"),
 			"city": args.get("city"),
diff --git a/erpnext/selling/doctype/customer_credit_limit/customer_credit_limit.py b/erpnext/selling/doctype/customer_credit_limit/customer_credit_limit.py
index 193027b..fcc6c6e 100644
--- a/erpnext/selling/doctype/customer_credit_limit/customer_credit_limit.py
+++ b/erpnext/selling/doctype/customer_credit_limit/customer_credit_limit.py
@@ -7,4 +7,20 @@
 
 
 class CustomerCreditLimit(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
+
+		bypass_credit_limit_check: DF.Check
+		company: DF.Link | None
+		credit_limit: DF.Currency
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/selling/doctype/industry_type/industry_type.py b/erpnext/selling/doctype/industry_type/industry_type.py
index fbe0131..aedec5f 100644
--- a/erpnext/selling/doctype/industry_type/industry_type.py
+++ b/erpnext/selling/doctype/industry_type/industry_type.py
@@ -6,4 +6,15 @@
 
 
 class IndustryType(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
+
+		industry: DF.Data
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/selling/doctype/installation_note/installation_note.py b/erpnext/selling/doctype/installation_note/installation_note.py
index 0ef4754..d1bfd91 100644
--- a/erpnext/selling/doctype/installation_note/installation_note.py
+++ b/erpnext/selling/doctype/installation_note/installation_note.py
@@ -11,6 +11,38 @@
 
 
 class InstallationNote(TransactionBase):
+	# 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
+
+		from erpnext.selling.doctype.installation_note_item.installation_note_item import (
+			InstallationNoteItem,
+		)
+
+		address_display: DF.SmallText | None
+		amended_from: DF.Link | None
+		company: DF.Link
+		contact_display: DF.SmallText | None
+		contact_email: DF.Data | None
+		contact_mobile: DF.SmallText | None
+		contact_person: DF.Link | None
+		customer: DF.Link
+		customer_address: DF.Link | None
+		customer_group: DF.Link | None
+		customer_name: DF.Data | None
+		inst_date: DF.Date
+		inst_time: DF.Time | None
+		items: DF.Table[InstallationNoteItem]
+		naming_series: DF.Literal["MAT-INS-.YYYY.-"]
+		remarks: DF.SmallText | None
+		status: DF.Literal["Draft", "Submitted", "Cancelled"]
+		territory: DF.Link
+	# end: auto-generated types
+
 	def __init__(self, *args, **kwargs):
 		super(InstallationNote, self).__init__(*args, **kwargs)
 		self.status_updater = [
diff --git a/erpnext/selling/doctype/installation_note_item/installation_note_item.py b/erpnext/selling/doctype/installation_note_item/installation_note_item.py
index 2169a7b..8566ab0 100644
--- a/erpnext/selling/doctype/installation_note_item/installation_note_item.py
+++ b/erpnext/selling/doctype/installation_note_item/installation_note_item.py
@@ -6,4 +6,25 @@
 
 
 class InstallationNoteItem(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
+
+		description: DF.TextEditor | None
+		item_code: DF.Link
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		prevdoc_detail_docname: DF.Data | None
+		prevdoc_docname: DF.Data | None
+		prevdoc_doctype: DF.Data | None
+		qty: DF.Float
+		serial_and_batch_bundle: DF.Link | None
+		serial_no: DF.SmallText | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/selling/doctype/party_specific_item/party_specific_item.py b/erpnext/selling/doctype/party_specific_item/party_specific_item.py
index 0aef7d3..cce29f0 100644
--- a/erpnext/selling/doctype/party_specific_item/party_specific_item.py
+++ b/erpnext/selling/doctype/party_specific_item/party_specific_item.py
@@ -7,6 +7,20 @@
 
 
 class PartySpecificItem(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
+
+		based_on_value: DF.DynamicLink
+		party: DF.DynamicLink
+		party_type: DF.Literal["Customer", "Supplier"]
+		restrict_based_on: DF.Literal["Item", "Item Group", "Brand"]
+	# end: auto-generated types
+
 	def validate(self):
 		exists = frappe.db.exists(
 			{
diff --git a/erpnext/selling/doctype/product_bundle/product_bundle.json b/erpnext/selling/doctype/product_bundle/product_bundle.json
index 56155fb..c4f21b6 100644
--- a/erpnext/selling/doctype/product_bundle/product_bundle.json
+++ b/erpnext/selling/doctype/product_bundle/product_bundle.json
@@ -1,315 +1,119 @@
 {
- "allow_copy": 0, 
- "allow_guest_to_view": 0, 
- "allow_import": 1, 
- "allow_rename": 0, 
- "beta": 0, 
- "creation": "2013-06-20 11:53:21", 
- "custom": 0, 
- "description": "Aggregate group of **Items** into another **Item**. This is useful if you are bundling a certain **Items** into a package and you maintain stock of the packed **Items** and not the aggregate **Item**. \n\nThe package **Item** will have \"Is Stock Item\" as \"No\" and \"Is Sales Item\" as \"Yes\".\n\nFor Example: If you are selling Laptops and Backpacks separately and have a special price if the customer buys both, then the Laptop + Backpack will be a new Product Bundle Item.\n\nNote: BOM = Bill of Materials", 
- "docstatus": 0, 
- "doctype": "DocType", 
- "document_type": "", 
- "editable_grid": 0, 
+ "actions": [],
+ "allow_import": 1,
+ "creation": "2013-06-20 11:53:21",
+ "description": "Aggregate group of **Items** into another **Item**. This is useful if you are bundling a certain **Items** into a package and you maintain stock of the packed **Items** and not the aggregate **Item**. \n\nThe package **Item** will have \"Is Stock Item\" as \"No\" and \"Is Sales Item\" as \"Yes\".\n\nFor Example: If you are selling Laptops and Backpacks separately and have a special price if the customer buys both, then the Laptop + Backpack will be a new Product Bundle Item.\n\nNote: BOM = Bill of Materials",
+ "doctype": "DocType",
+ "engine": "InnoDB",
+ "field_order": [
+  "basic_section",
+  "new_item_code",
+  "description",
+  "column_break_eonk",
+  "disabled",
+  "item_section",
+  "items",
+  "section_break_4",
+  "about"
+ ],
  "fields": [
   {
-   "allow_bulk_edit": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "basic_section", 
-   "fieldtype": "Section Break", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "basic_section",
+   "fieldtype": "Section Break"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "description": "", 
-   "fieldname": "new_item_code", 
-   "fieldtype": "Link", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 1, 
-   "in_list_view": 1, 
-   "in_standard_filter": 0, 
-   "label": "Parent Item", 
-   "length": 0, 
-   "no_copy": 1, 
-   "oldfieldname": "new_item_code", 
-   "oldfieldtype": "Data", 
-   "options": "Item", 
-   "permlevel": 0, 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 1, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "new_item_code",
+   "fieldtype": "Link",
+   "in_global_search": 1,
+   "in_list_view": 1,
+   "label": "Parent Item",
+   "no_copy": 1,
+   "oldfieldname": "new_item_code",
+   "oldfieldtype": "Data",
+   "options": "Item",
+   "reqd": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "description", 
-   "fieldtype": "Data", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 1, 
-   "in_standard_filter": 0, 
-   "label": "Description", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "description",
+   "fieldtype": "Data",
+   "in_list_view": 1,
+   "label": "Description"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "description": "List items that form the package.", 
-   "fieldname": "item_section", 
-   "fieldtype": "Section Break", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Items", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0
-  }, 
+   "description": "List items that form the package.",
+   "fieldname": "item_section",
+   "fieldtype": "Section Break",
+   "label": "Items"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "items", 
-   "fieldtype": "Table", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Items", 
-   "length": 0, 
-   "no_copy": 0, 
-   "oldfieldname": "sales_bom_items", 
-   "oldfieldtype": "Table", 
-   "options": "Product Bundle Item", 
-   "permlevel": 0, 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 1, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "items",
+   "fieldtype": "Table",
+   "label": "Items",
+   "oldfieldname": "sales_bom_items",
+   "oldfieldtype": "Table",
+   "options": "Product Bundle Item",
+   "reqd": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "section_break_4", 
-   "fieldtype": "Section Break", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "section_break_4",
+   "fieldtype": "Section Break"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "about", 
-   "fieldtype": "HTML", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "<h3>About Product Bundle</h3>\n\n<p>Aggregate group of <b>Items</b> into another <b>Item</b>. This is useful if you are bundling a certain <b>Items</b> into a package and you maintain stock of the packed <b>Items</b> and not the aggregate <b>Item</b>.</p>\n<p>The package <b>Item</b> will have <code>Is Stock Item</code> as <b>No</b> and <code>Is Sales Item</code> as <b>Yes</b>.</p>\n<h4>Example:</h4>\n<p>If you are selling Laptops and Backpacks separately and have a special price if the customer buys both, then the Laptop + Backpack will be a new Product Bundle Item.</p>", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0
+   "fieldname": "about",
+   "fieldtype": "HTML",
+   "options": "<h3>About Product Bundle</h3>\n\n<p>Aggregate group of <b>Items</b> into another <b>Item</b>. This is useful if you are bundling a certain <b>Items</b> into a package and you maintain stock of the packed <b>Items</b> and not the aggregate <b>Item</b>.</p>\n<p>The package <b>Item</b> will have <code>Is Stock Item</code> as <b>No</b> and <code>Is Sales Item</code> as <b>Yes</b>.</p>\n<h4>Example:</h4>\n<p>If you are selling Laptops and Backpacks separately and have a special price if the customer buys both, then the Laptop + Backpack will be a new Product Bundle Item.</p>"
+  },
+  {
+   "default": "0",
+   "fieldname": "disabled",
+   "fieldtype": "Check",
+   "label": "Disabled"
+  },
+  {
+   "fieldname": "column_break_eonk",
+   "fieldtype": "Column Break"
   }
- ], 
- "has_web_view": 0, 
- "hide_heading": 0, 
- "hide_toolbar": 0, 
- "icon": "fa fa-sitemap", 
- "idx": 1, 
- "image_view": 0, 
- "in_create": 0, 
- "is_submittable": 0, 
- "issingle": 0, 
- "istable": 0, 
- "max_attachments": 0, 
- "modified": "2020-09-18 17:26:09.703215", 
- "modified_by": "Administrator", 
- "module": "Selling", 
- "name": "Product Bundle", 
- "owner": "Administrator", 
+ ],
+ "icon": "fa fa-sitemap",
+ "idx": 1,
+ "links": [],
+ "modified": "2023-11-22 15:20:46.805114",
+ "modified_by": "Administrator",
+ "module": "Selling",
+ "name": "Product Bundle",
+ "owner": "Administrator",
  "permissions": [
   {
-   "amend": 0, 
-   "apply_user_permissions": 0, 
-   "cancel": 0, 
-   "create": 1, 
-   "delete": 1, 
-   "email": 1, 
-   "export": 0, 
-   "if_owner": 0, 
-   "import": 0, 
-   "permlevel": 0, 
-   "print": 1, 
-   "read": 1, 
-   "report": 1, 
-   "role": "Stock Manager", 
-   "set_user_permissions": 0, 
-   "share": 1, 
-   "submit": 0, 
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "Stock Manager",
+   "share": 1,
    "write": 1
-  }, 
+  },
   {
-   "amend": 0, 
-   "apply_user_permissions": 0, 
-   "cancel": 0, 
-   "create": 0, 
-   "delete": 0, 
-   "email": 1, 
-   "export": 0, 
-   "if_owner": 0, 
-   "import": 0, 
-   "permlevel": 0, 
-   "print": 1, 
-   "read": 1, 
-   "report": 1, 
-   "role": "Stock User", 
-   "set_user_permissions": 0, 
-   "share": 0, 
-   "submit": 0, 
-   "write": 0
-  }, 
+   "email": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "Stock User"
+  },
   {
-   "amend": 0, 
-   "apply_user_permissions": 0, 
-   "cancel": 0, 
-   "create": 1, 
-   "delete": 1, 
-   "email": 1, 
-   "export": 0, 
-   "if_owner": 0, 
-   "import": 0, 
-   "permlevel": 0, 
-   "print": 1, 
-   "read": 1, 
-   "report": 1, 
-   "role": "Sales User", 
-   "set_user_permissions": 0, 
-   "share": 1, 
-   "submit": 0, 
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "Sales User",
+   "share": 1,
    "write": 1
   }
- ], 
- "quick_entry": 0, 
- "read_only": 0, 
- "read_only_onload": 0, 
- "show_name_in_global_search": 0, 
- "sort_order": "ASC", 
- "track_changes": 0, 
- "track_seen": 0
+ ],
+ "sort_field": "modified",
+ "sort_order": "ASC",
+ "states": []
 }
\ No newline at end of file
diff --git a/erpnext/selling/doctype/product_bundle/product_bundle.py b/erpnext/selling/doctype/product_bundle/product_bundle.py
index ac83c0f..6632742 100644
--- a/erpnext/selling/doctype/product_bundle/product_bundle.py
+++ b/erpnext/selling/doctype/product_bundle/product_bundle.py
@@ -9,6 +9,22 @@
 
 
 class ProductBundle(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
+
+		from erpnext.selling.doctype.product_bundle_item.product_bundle_item import ProductBundleItem
+
+		description: DF.Data | None
+		disabled: DF.Check
+		items: DF.Table[ProductBundleItem]
+		new_item_code: DF.Link
+	# end: auto-generated types
+
 	def autoname(self):
 		self.name = self.new_item_code
 
@@ -59,10 +75,12 @@
 		"""Validates, main Item is not a stock item"""
 		if frappe.db.get_value("Item", self.new_item_code, "is_stock_item"):
 			frappe.throw(_("Parent Item {0} must not be a Stock Item").format(self.new_item_code))
+		if frappe.db.get_value("Item", self.new_item_code, "is_fixed_asset"):
+			frappe.throw(_("Parent Item {0} must not be a Fixed Asset").format(self.new_item_code))
 
 	def validate_child_items(self):
 		for item in self.items:
-			if frappe.db.exists("Product Bundle", item.item_code):
+			if frappe.db.exists("Product Bundle", {"name": item.item_code, "disabled": 0}):
 				frappe.throw(
 					_(
 						"Row #{0}: Child Item should not be a Product Bundle. Please remove Item {1} and Save"
@@ -73,12 +91,20 @@
 @frappe.whitelist()
 @frappe.validate_and_sanitize_search_inputs
 def get_new_item_code(doctype, txt, searchfield, start, page_len, filters):
-	from erpnext.controllers.queries import get_match_cond
+	product_bundles = frappe.db.get_list("Product Bundle", {"disabled": 0}, pluck="name")
 
-	return frappe.db.sql(
-		"""select name, item_name, description from tabItem
-		where is_stock_item=0 and name not in (select name from `tabProduct Bundle`)
-		and %s like %s %s limit %s offset %s"""
-		% (searchfield, "%s", get_match_cond(doctype), "%s", "%s"),
-		("%%%s%%" % txt, page_len, start),
+	item = frappe.qb.DocType("Item")
+	query = (
+		frappe.qb.from_(item)
+		.select(item.item_code, item.item_name)
+		.where(
+			(item.is_stock_item == 0) & (item.is_fixed_asset == 0) & (item[searchfield].like(f"%{txt}%"))
+		)
+		.limit(page_len)
+		.offset(start)
 	)
+
+	if product_bundles:
+		query = query.where(item.name.notin(product_bundles))
+
+	return query.run()
diff --git a/erpnext/selling/doctype/product_bundle_item/product_bundle_item.py b/erpnext/selling/doctype/product_bundle_item/product_bundle_item.py
index 5c95a55..285ad5d 100644
--- a/erpnext/selling/doctype/product_bundle_item/product_bundle_item.py
+++ b/erpnext/selling/doctype/product_bundle_item/product_bundle_item.py
@@ -6,4 +6,22 @@
 
 
 class ProductBundleItem(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
+
+		description: DF.TextEditor | None
+		item_code: DF.Link
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		qty: DF.Float
+		rate: DF.Float
+		uom: DF.Link | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/selling/doctype/quotation/quotation.py b/erpnext/selling/doctype/quotation/quotation.py
index 95d2d2c..00b79e3 100644
--- a/erpnext/selling/doctype/quotation/quotation.py
+++ b/erpnext/selling/doctype/quotation/quotation.py
@@ -13,6 +13,109 @@
 
 
 class Quotation(SellingController):
+	# 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
+
+		from erpnext.accounts.doctype.payment_schedule.payment_schedule import PaymentSchedule
+		from erpnext.accounts.doctype.pricing_rule_detail.pricing_rule_detail import PricingRuleDetail
+		from erpnext.accounts.doctype.sales_taxes_and_charges.sales_taxes_and_charges import (
+			SalesTaxesandCharges,
+		)
+		from erpnext.crm.doctype.competitor_detail.competitor_detail import CompetitorDetail
+		from erpnext.selling.doctype.quotation_item.quotation_item import QuotationItem
+		from erpnext.setup.doctype.quotation_lost_reason_detail.quotation_lost_reason_detail import (
+			QuotationLostReasonDetail,
+		)
+		from erpnext.stock.doctype.packed_item.packed_item import PackedItem
+
+		additional_discount_percentage: DF.Float
+		address_display: DF.SmallText | None
+		amended_from: DF.Link | None
+		apply_discount_on: DF.Literal["", "Grand Total", "Net Total"]
+		auto_repeat: DF.Link | None
+		base_discount_amount: DF.Currency
+		base_grand_total: DF.Currency
+		base_in_words: DF.Data | None
+		base_net_total: DF.Currency
+		base_rounded_total: DF.Currency
+		base_rounding_adjustment: DF.Currency
+		base_total: DF.Currency
+		base_total_taxes_and_charges: DF.Currency
+		campaign: DF.Link | None
+		company: DF.Link
+		company_address: DF.Link | None
+		company_address_display: DF.SmallText | None
+		competitors: DF.TableMultiSelect[CompetitorDetail]
+		contact_display: DF.SmallText | None
+		contact_email: DF.Data | None
+		contact_mobile: DF.SmallText | None
+		contact_person: DF.Link | None
+		conversion_rate: DF.Float
+		coupon_code: DF.Link | None
+		currency: DF.Link
+		customer_address: DF.Link | None
+		customer_group: DF.Link | None
+		customer_name: DF.Data | None
+		discount_amount: DF.Currency
+		enq_det: DF.Text | None
+		grand_total: DF.Currency
+		group_same_items: DF.Check
+		ignore_pricing_rule: DF.Check
+		in_words: DF.Data | None
+		incoterm: DF.Link | None
+		items: DF.Table[QuotationItem]
+		language: DF.Data | None
+		letter_head: DF.Link | None
+		lost_reasons: DF.TableMultiSelect[QuotationLostReasonDetail]
+		named_place: DF.Data | None
+		naming_series: DF.Literal["SAL-QTN-.YYYY.-"]
+		net_total: DF.Currency
+		opportunity: DF.Link | None
+		order_lost_reason: DF.SmallText | None
+		order_type: DF.Literal["", "Sales", "Maintenance", "Shopping Cart"]
+		other_charges_calculation: DF.LongText | None
+		packed_items: DF.Table[PackedItem]
+		party_name: DF.DynamicLink | None
+		payment_schedule: DF.Table[PaymentSchedule]
+		payment_terms_template: DF.Link | None
+		plc_conversion_rate: DF.Float
+		price_list_currency: DF.Link
+		pricing_rules: DF.Table[PricingRuleDetail]
+		quotation_to: DF.Link
+		referral_sales_partner: DF.Link | None
+		rounded_total: DF.Currency
+		rounding_adjustment: DF.Currency
+		scan_barcode: DF.Data | None
+		select_print_heading: DF.Link | None
+		selling_price_list: DF.Link
+		shipping_address: DF.SmallText | None
+		shipping_address_name: DF.Link | None
+		shipping_rule: DF.Link | None
+		source: DF.Link | None
+		status: DF.Literal[
+			"Draft", "Open", "Replied", "Partially Ordered", "Ordered", "Lost", "Cancelled", "Expired"
+		]
+		supplier_quotation: DF.Link | None
+		tax_category: DF.Link | None
+		taxes: DF.Table[SalesTaxesandCharges]
+		taxes_and_charges: DF.Link | None
+		tc_name: DF.Link | None
+		terms: DF.TextEditor | None
+		territory: DF.Link | None
+		title: DF.Data | None
+		total: DF.Currency
+		total_net_weight: DF.Float
+		total_qty: DF.Float
+		total_taxes_and_charges: DF.Currency
+		transaction_date: DF.Date
+		valid_till: DF.Date | None
+	# end: auto-generated types
+
 	def set_indicator(self):
 		if self.docstatus == 1:
 			self.indicator_color = "blue"
@@ -331,9 +434,6 @@
 		ignore_permissions=ignore_permissions,
 	)
 
-	# postprocess: fetch shipping address, set missing values
-	doclist.set_onload("ignore_price_list", True)
-
 	return doclist
 
 
@@ -402,8 +502,6 @@
 		ignore_permissions=ignore_permissions,
 	)
 
-	doclist.set_onload("ignore_price_list", True)
-
 	return doclist
 
 
diff --git a/erpnext/selling/doctype/quotation_item/quotation_item.json b/erpnext/selling/doctype/quotation_item/quotation_item.json
index 5016f1f..0e25313 100644
--- a/erpnext/selling/doctype/quotation_item/quotation_item.json
+++ b/erpnext/selling/doctype/quotation_item/quotation_item.json
@@ -135,6 +135,7 @@
    "width": "300px"
   },
   {
+   "fetch_from": "item_code.image",
    "fieldname": "image",
    "fieldtype": "Attach",
    "hidden": 1,
@@ -666,7 +667,7 @@
  "idx": 1,
  "istable": 1,
  "links": [],
- "modified": "2023-09-26 13:42:11.410294",
+ "modified": "2023-11-14 18:24:24.619832",
  "modified_by": "Administrator",
  "module": "Selling",
  "name": "Quotation Item",
@@ -676,4 +677,4 @@
  "sort_order": "DESC",
  "states": [],
  "track_changes": 1
-}
+}
\ No newline at end of file
diff --git a/erpnext/selling/doctype/quotation_item/quotation_item.py b/erpnext/selling/doctype/quotation_item/quotation_item.py
index 8c2aabb..f209762 100644
--- a/erpnext/selling/doctype/quotation_item/quotation_item.py
+++ b/erpnext/selling/doctype/quotation_item/quotation_item.py
@@ -6,4 +6,67 @@
 
 
 class QuotationItem(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
+
+		actual_qty: DF.Float
+		additional_notes: DF.Text | None
+		against_blanket_order: DF.Check
+		amount: DF.Currency
+		base_amount: DF.Currency
+		base_net_amount: DF.Currency
+		base_net_rate: DF.Currency
+		base_price_list_rate: DF.Currency
+		base_rate: DF.Currency
+		base_rate_with_margin: DF.Currency
+		blanket_order: DF.Link | None
+		blanket_order_rate: DF.Currency
+		brand: DF.Link | None
+		conversion_factor: DF.Float
+		customer_item_code: DF.Data | None
+		description: DF.TextEditor | None
+		discount_amount: DF.Currency
+		discount_percentage: DF.Percent
+		gross_profit: DF.Currency
+		has_alternative_item: DF.Check
+		image: DF.Attach | None
+		is_alternative: DF.Check
+		is_free_item: DF.Check
+		item_code: DF.Link | None
+		item_group: DF.Link | None
+		item_name: DF.Data
+		item_tax_rate: DF.Code | None
+		item_tax_template: DF.Link | None
+		margin_rate_or_amount: DF.Float
+		margin_type: DF.Literal["", "Percentage", "Amount"]
+		net_amount: DF.Currency
+		net_rate: DF.Currency
+		page_break: DF.Check
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		prevdoc_docname: DF.DynamicLink | None
+		prevdoc_doctype: DF.Link | None
+		price_list_rate: DF.Currency
+		pricing_rules: DF.SmallText | None
+		projected_qty: DF.Float
+		qty: DF.Float
+		rate: DF.Currency
+		rate_with_margin: DF.Currency
+		stock_qty: DF.Float
+		stock_uom: DF.Link | None
+		stock_uom_rate: DF.Currency
+		total_weight: DF.Float
+		uom: DF.Link
+		valuation_rate: DF.Currency
+		warehouse: DF.Link | None
+		weight_per_unit: DF.Float
+		weight_uom: DF.Link | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/selling/doctype/sales_order/sales_order.js b/erpnext/selling/doctype/sales_order/sales_order.js
index 3ad18da..97b214e 100644
--- a/erpnext/selling/doctype/sales_order/sales_order.js
+++ b/erpnext/selling/doctype/sales_order/sales_order.js
@@ -214,13 +214,12 @@
 					label: __("Items to Reserve"),
 					allow_bulk_edit: false,
 					cannot_add_rows: true,
-					cannot_delete_rows: true,
 					data: [],
 					fields: [
 						{
-							fieldname: "name",
+							fieldname: "sales_order_item",
 							fieldtype: "Data",
-							label: __("Name"),
+							label: __("Sales Order Item"),
 							reqd: 1,
 							read_only: 1,
 						},
@@ -260,7 +259,7 @@
 			],
 			primary_action_label: __("Reserve Stock"),
 			primary_action: () => {
-				var data = {items: dialog.fields_dict.items.grid.get_selected_children()};
+				var data = {items: dialog.fields_dict.items.grid.data};
 
 				if (data.items && data.items.length > 0) {
 					frappe.call({
@@ -278,9 +277,6 @@
 						}
 					});
 				}
-				else {
-					frappe.msgprint(__("Please select items to reserve."));
-				}
 
 				dialog.hide();
 			},
@@ -292,7 +288,7 @@
 
 				if (unreserved_qty > 0) {
 					dialog.fields_dict.items.df.data.push({
-						'name': item.name,
+						'sales_order_item': item.name,
 						'item_code': item.item_code,
 						'warehouse': item.warehouse,
 						'qty_to_reserve': (unreserved_qty / flt(item.conversion_factor))
@@ -308,7 +304,7 @@
 	cancel_stock_reservation_entries(frm) {
 		const dialog = new frappe.ui.Dialog({
 			title: __("Stock Unreservation"),
-			size: "large",
+			size: "extra-large",
 			fields: [
 				{
 					fieldname: "sr_entries",
@@ -316,14 +312,13 @@
 					label: __("Reserved Stock"),
 					allow_bulk_edit: false,
 					cannot_add_rows: true,
-					cannot_delete_rows: true,
 					in_place_edit: true,
 					data: [],
 					fields: [
 						{
-							fieldname: "name",
+							fieldname: "sre",
 							fieldtype: "Link",
-							label: __("SRE"),
+							label: __("Stock Reservation Entry"),
 							options: "Stock Reservation Entry",
 							reqd: 1,
 							read_only: 1,
@@ -360,14 +355,14 @@
 			],
 			primary_action_label: __("Unreserve Stock"),
 			primary_action: () => {
-				var data = {sr_entries: dialog.fields_dict.sr_entries.grid.get_selected_children()};
+				var data = {sr_entries: dialog.fields_dict.sr_entries.grid.data};
 
 				if (data.sr_entries && data.sr_entries.length > 0) {
 					frappe.call({
 						doc: frm.doc,
 						method: "cancel_stock_reservation_entries",
 						args: {
-							sre_list: data.sr_entries,
+							sre_list: data.sr_entries.map(item => item.sre),
 						},
 						freeze: true,
 						freeze_message: __('Unreserving Stock...'),
@@ -377,9 +372,6 @@
 						}
 					});
 				}
-				else {
-					frappe.msgprint(__("Please select items to unreserve."));
-				}
 
 				dialog.hide();
 			},
@@ -396,7 +388,7 @@
 					r.message.forEach(sre => {
 						if (flt(sre.reserved_qty) > flt(sre.delivered_qty)) {
 							dialog.fields_dict.sr_entries.df.data.push({
-								'name': sre.name,
+								'sre': sre.name,
 								'item_code': sre.item_code,
 								'warehouse': sre.warehouse,
 								'qty': (flt(sre.reserved_qty) - flt(sre.delivered_qty))
diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py
index 56ae196..59853ff 100755
--- a/erpnext/selling/doctype/sales_order/sales_order.py
+++ b/erpnext/selling/doctype/sales_order/sales_order.py
@@ -46,6 +46,139 @@
 
 
 class SalesOrder(SellingController):
+	# 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
+
+		from erpnext.accounts.doctype.payment_schedule.payment_schedule import PaymentSchedule
+		from erpnext.accounts.doctype.pricing_rule_detail.pricing_rule_detail import PricingRuleDetail
+		from erpnext.accounts.doctype.sales_taxes_and_charges.sales_taxes_and_charges import (
+			SalesTaxesandCharges,
+		)
+		from erpnext.selling.doctype.sales_order_item.sales_order_item import SalesOrderItem
+		from erpnext.selling.doctype.sales_team.sales_team import SalesTeam
+		from erpnext.stock.doctype.packed_item.packed_item import PackedItem
+
+		additional_discount_percentage: DF.Float
+		address_display: DF.SmallText | None
+		advance_paid: DF.Currency
+		amended_from: DF.Link | None
+		amount_eligible_for_commission: DF.Currency
+		apply_discount_on: DF.Literal["", "Grand Total", "Net Total"]
+		auto_repeat: DF.Link | None
+		base_discount_amount: DF.Currency
+		base_grand_total: DF.Currency
+		base_in_words: DF.Data | None
+		base_net_total: DF.Currency
+		base_rounded_total: DF.Currency
+		base_rounding_adjustment: DF.Currency
+		base_total: DF.Currency
+		base_total_taxes_and_charges: DF.Currency
+		billing_status: DF.Literal["Not Billed", "Fully Billed", "Partly Billed", "Closed"]
+		campaign: DF.Link | None
+		commission_rate: DF.Float
+		company: DF.Link
+		company_address: DF.Link | None
+		company_address_display: DF.SmallText | None
+		contact_display: DF.SmallText | None
+		contact_email: DF.Data | None
+		contact_mobile: DF.SmallText | None
+		contact_person: DF.Link | None
+		contact_phone: DF.Data | None
+		conversion_rate: DF.Float
+		cost_center: DF.Link | None
+		coupon_code: DF.Link | None
+		currency: DF.Link
+		customer: DF.Link
+		customer_address: DF.Link | None
+		customer_group: DF.Link | None
+		customer_name: DF.Data | None
+		delivery_date: DF.Date | None
+		delivery_status: DF.Literal[
+			"Not Delivered", "Fully Delivered", "Partly Delivered", "Closed", "Not Applicable"
+		]
+		disable_rounded_total: DF.Check
+		discount_amount: DF.Currency
+		dispatch_address: DF.SmallText | None
+		dispatch_address_name: DF.Link | None
+		from_date: DF.Date | None
+		grand_total: DF.Currency
+		group_same_items: DF.Check
+		ignore_pricing_rule: DF.Check
+		in_words: DF.Data | None
+		incoterm: DF.Link | None
+		inter_company_order_reference: DF.Link | None
+		is_internal_customer: DF.Check
+		items: DF.Table[SalesOrderItem]
+		language: DF.Data | None
+		letter_head: DF.Link | None
+		loyalty_amount: DF.Currency
+		loyalty_points: DF.Int
+		named_place: DF.Data | None
+		naming_series: DF.Literal["SAL-ORD-.YYYY.-"]
+		net_total: DF.Currency
+		order_type: DF.Literal["", "Sales", "Maintenance", "Shopping Cart"]
+		other_charges_calculation: DF.LongText | None
+		packed_items: DF.Table[PackedItem]
+		party_account_currency: DF.Link | None
+		payment_schedule: DF.Table[PaymentSchedule]
+		payment_terms_template: DF.Link | None
+		per_billed: DF.Percent
+		per_delivered: DF.Percent
+		per_picked: DF.Percent
+		plc_conversion_rate: DF.Float
+		po_date: DF.Date | None
+		po_no: DF.Data | None
+		price_list_currency: DF.Link
+		pricing_rules: DF.Table[PricingRuleDetail]
+		project: DF.Link | None
+		represents_company: DF.Link | None
+		reserve_stock: DF.Check
+		rounded_total: DF.Currency
+		rounding_adjustment: DF.Currency
+		sales_partner: DF.Link | None
+		sales_team: DF.Table[SalesTeam]
+		scan_barcode: DF.Data | None
+		select_print_heading: DF.Link | None
+		selling_price_list: DF.Link
+		set_warehouse: DF.Link | None
+		shipping_address: DF.SmallText | None
+		shipping_address_name: DF.Link | None
+		shipping_rule: DF.Link | None
+		skip_delivery_note: DF.Check
+		source: DF.Link | None
+		status: DF.Literal[
+			"",
+			"Draft",
+			"On Hold",
+			"To Deliver and Bill",
+			"To Bill",
+			"To Deliver",
+			"Completed",
+			"Cancelled",
+			"Closed",
+		]
+		tax_category: DF.Link | None
+		tax_id: DF.Data | None
+		taxes: DF.Table[SalesTaxesandCharges]
+		taxes_and_charges: DF.Link | None
+		tc_name: DF.Link | None
+		terms: DF.TextEditor | None
+		territory: DF.Link | None
+		title: DF.Data | None
+		to_date: DF.Date | None
+		total: DF.Currency
+		total_commission: DF.Currency
+		total_net_weight: DF.Float
+		total_qty: DF.Float
+		total_taxes_and_charges: DF.Currency
+		transaction_date: DF.Date
+	# end: auto-generated types
+
 	def __init__(self, *args, **kwargs):
 		super(SalesOrder, self).__init__(*args, **kwargs)
 
@@ -690,7 +823,9 @@
 			"Sales Order Item": {
 				"doctype": "Material Request Item",
 				"field_map": {"name": "sales_order_item", "parent": "sales_order"},
-				"condition": lambda item: not frappe.db.exists("Product Bundle", item.item_code)
+				"condition": lambda item: not frappe.db.exists(
+					"Product Bundle", {"name": item.item_code, "disabled": 0}
+				)
 				and get_remaining_qty(item) > 0,
 				"postprocess": update_item,
 			},
@@ -769,8 +904,11 @@
 		if target.company_address:
 			target.update(get_fetch_values("Delivery Note", "company_address", target.company_address))
 
-		# set target items names to ensure proper linking with packed_items
-		target.set_new_name()
+		# if invoked in bulk creation, validations are ignored and thus this method is nerver invoked
+		if frappe.flags.bulk_transaction:
+			# set target items names to ensure proper linking with packed_items
+			target.set_new_name()
+
 		make_packing_list(target)
 
 	def condition(doc):
@@ -859,7 +997,6 @@
 
 	# Should be called after mapping items.
 	set_missing_values(so, target_doc)
-	target_doc.set_onload("ignore_price_list", True)
 
 	return target_doc
 
@@ -949,8 +1086,6 @@
 	if automatically_fetch_payment_terms:
 		doclist.set_payment_schedule()
 
-	doclist.set_onload("ignore_price_list", True)
-
 	return doclist
 
 
@@ -1308,7 +1443,7 @@
 
 
 def is_product_bundle(item_code):
-	return frappe.db.exists("Product Bundle", item_code)
+	return frappe.db.exists("Product Bundle", {"name": item_code, "disabled": 0})
 
 
 @frappe.whitelist()
@@ -1520,7 +1655,7 @@
 		product_bundle_parents = [
 			pb.new_item_code
 			for pb in frappe.get_all(
-				"Product Bundle", {"new_item_code": ["in", item_codes]}, ["new_item_code"]
+				"Product Bundle", {"new_item_code": ["in", item_codes], "disabled": 0}, ["new_item_code"]
 			)
 		]
 
diff --git a/erpnext/selling/doctype/sales_order/test_sales_order.py b/erpnext/selling/doctype/sales_order/test_sales_order.py
index d8b5878..a518597 100644
--- a/erpnext/selling/doctype/sales_order/test_sales_order.py
+++ b/erpnext/selling/doctype/sales_order/test_sales_order.py
@@ -51,6 +51,35 @@
 	def tearDown(self):
 		frappe.set_user("Administrator")
 
+	def test_sales_order_with_negative_rate(self):
+		"""
+		Test if negative rate is allowed in Sales Order via doc submission and update items
+		"""
+		so = make_sales_order(qty=1, rate=100, do_not_save=True)
+		so.append("items", {"item_code": "_Test Item", "qty": 1, "rate": -10})
+		so.save()
+		so.submit()
+
+		first_item = so.get("items")[0]
+		second_item = so.get("items")[1]
+		trans_item = json.dumps(
+			[
+				{
+					"item_code": first_item.item_code,
+					"rate": first_item.rate,
+					"qty": first_item.qty,
+					"docname": first_item.name,
+				},
+				{
+					"item_code": second_item.item_code,
+					"rate": -20,
+					"qty": second_item.qty,
+					"docname": second_item.name,
+				},
+			]
+		)
+		update_child_qty_rate("Sales Order", trans_item, so.name)
+
 	def test_make_material_request(self):
 		so = make_sales_order(do_not_submit=True)
 
diff --git a/erpnext/selling/doctype/sales_order_item/sales_order_item.json b/erpnext/selling/doctype/sales_order_item/sales_order_item.json
index f82047f..d4ccfc4 100644
--- a/erpnext/selling/doctype/sales_order_item/sales_order_item.json
+++ b/erpnext/selling/doctype/sales_order_item/sales_order_item.json
@@ -68,7 +68,6 @@
   "total_weight",
   "column_break_21",
   "weight_uom",
-  "accounting_dimensions_section",
   "warehouse_and_reference",
   "warehouse",
   "target_warehouse",
@@ -177,6 +176,7 @@
    "print_hide": 1
   },
   {
+   "fetch_from": "item_code.image",
    "fieldname": "image",
    "fieldtype": "Attach",
    "hidden": 1,
@@ -200,6 +200,7 @@
    "fieldtype": "Float",
    "in_list_view": 1,
    "label": "Quantity",
+   "non_negative": 1,
    "oldfieldname": "qty",
    "oldfieldtype": "Currency",
    "print_width": "100px",
@@ -890,18 +891,12 @@
    "label": "Production Plan Qty",
    "no_copy": 1,
    "read_only": 1
-  },
-  {
-   "collapsible": 1,
-   "fieldname": "accounting_dimensions_section",
-   "fieldtype": "Section Break",
-   "label": "Accounting Dimensions"
   }
  ],
  "idx": 1,
  "istable": 1,
  "links": [],
- "modified": "2023-10-17 18:18:26.475259",
+ "modified": "2023-11-24 13:24:55.756320",
  "modified_by": "Administrator",
  "module": "Selling",
  "name": "Sales Order Item",
diff --git a/erpnext/selling/doctype/sales_order_item/sales_order_item.py b/erpnext/selling/doctype/sales_order_item/sales_order_item.py
index 83d3f3b..25f5b4b 100644
--- a/erpnext/selling/doctype/sales_order_item/sales_order_item.py
+++ b/erpnext/selling/doctype/sales_order_item/sales_order_item.py
@@ -7,6 +7,90 @@
 
 
 class SalesOrderItem(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
+
+		actual_qty: DF.Float
+		additional_notes: DF.Text | None
+		against_blanket_order: DF.Check
+		amount: DF.Currency
+		base_amount: DF.Currency
+		base_net_amount: DF.Currency
+		base_net_rate: DF.Currency
+		base_price_list_rate: DF.Currency
+		base_rate: DF.Currency
+		base_rate_with_margin: DF.Currency
+		billed_amt: DF.Currency
+		blanket_order: DF.Link | None
+		blanket_order_rate: DF.Currency
+		bom_no: DF.Link | None
+		brand: DF.Link | None
+		conversion_factor: DF.Float
+		customer_item_code: DF.Data | None
+		delivered_by_supplier: DF.Check
+		delivered_qty: DF.Float
+		delivery_date: DF.Date | None
+		description: DF.TextEditor | None
+		discount_amount: DF.Currency
+		discount_percentage: DF.Percent
+		ensure_delivery_based_on_produced_serial_no: DF.Check
+		grant_commission: DF.Check
+		gross_profit: DF.Currency
+		image: DF.Attach | None
+		is_free_item: DF.Check
+		item_code: DF.Link | None
+		item_group: DF.Link | None
+		item_name: DF.Data
+		item_tax_rate: DF.Code | None
+		item_tax_template: DF.Link | None
+		margin_rate_or_amount: DF.Float
+		margin_type: DF.Literal["", "Percentage", "Amount"]
+		material_request: DF.Link | None
+		material_request_item: DF.Data | None
+		net_amount: DF.Currency
+		net_rate: DF.Currency
+		ordered_qty: DF.Float
+		page_break: DF.Check
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		picked_qty: DF.Float
+		planned_qty: DF.Float
+		prevdoc_docname: DF.Link | None
+		price_list_rate: DF.Currency
+		pricing_rules: DF.SmallText | None
+		produced_qty: DF.Float
+		production_plan_qty: DF.Float
+		projected_qty: DF.Float
+		purchase_order: DF.Link | None
+		purchase_order_item: DF.Data | None
+		qty: DF.Float
+		quotation_item: DF.Data | None
+		rate: DF.Currency
+		rate_with_margin: DF.Currency
+		reserve_stock: DF.Check
+		returned_qty: DF.Float
+		stock_qty: DF.Float
+		stock_reserved_qty: DF.Float
+		stock_uom: DF.Link | None
+		stock_uom_rate: DF.Currency
+		supplier: DF.Link | None
+		target_warehouse: DF.Link | None
+		total_weight: DF.Float
+		transaction_date: DF.Date | None
+		uom: DF.Link
+		valuation_rate: DF.Currency
+		warehouse: DF.Link | None
+		weight_per_unit: DF.Float
+		weight_uom: DF.Link | None
+		work_order_qty: DF.Float
+	# end: auto-generated types
+
 	pass
 
 
diff --git a/erpnext/selling/doctype/sales_partner_type/sales_partner_type.py b/erpnext/selling/doctype/sales_partner_type/sales_partner_type.py
index 0a07073..d156ccc 100644
--- a/erpnext/selling/doctype/sales_partner_type/sales_partner_type.py
+++ b/erpnext/selling/doctype/sales_partner_type/sales_partner_type.py
@@ -6,4 +6,15 @@
 
 
 class SalesPartnerType(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
+
+		sales_partner_type: DF.Data
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/selling/doctype/sales_team/sales_team.py b/erpnext/selling/doctype/sales_team/sales_team.py
index d3eae3a..6b4d6d5 100644
--- a/erpnext/selling/doctype/sales_team/sales_team.py
+++ b/erpnext/selling/doctype/sales_team/sales_team.py
@@ -6,4 +6,23 @@
 
 
 class SalesTeam(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
+
+		allocated_amount: DF.Currency
+		allocated_percentage: DF.Float
+		commission_rate: DF.Data | None
+		contact_no: DF.Data | None
+		incentives: DF.Currency
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		sales_person: DF.Link
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/selling/doctype/selling_settings/selling_settings.py b/erpnext/selling/doctype/selling_settings/selling_settings.py
index d977807..24fe909 100644
--- a/erpnext/selling/doctype/selling_settings/selling_settings.py
+++ b/erpnext/selling/doctype/selling_settings/selling_settings.py
@@ -11,6 +11,37 @@
 
 
 class SellingSettings(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
+
+		allow_against_multiple_purchase_orders: DF.Check
+		allow_multiple_items: DF.Check
+		allow_negative_rates_for_items: DF.Check
+		allow_sales_order_creation_for_expired_quotation: DF.Check
+		blanket_order_allowance: DF.Float
+		cust_master_name: DF.Literal["Customer Name", "Naming Series", "Auto Name"]
+		customer_group: DF.Link | None
+		dn_required: DF.Literal["No", "Yes"]
+		dont_reserve_sales_order_qty_on_sales_return: DF.Check
+		editable_bundle_item_rates: DF.Check
+		editable_price_list_rate: DF.Check
+		enable_discount_accounting: DF.Check
+		hide_tax_id: DF.Check
+		maintain_same_rate_action: DF.Literal["Stop", "Warn"]
+		maintain_same_sales_rate: DF.Check
+		role_to_override_stop_action: DF.Link | None
+		sales_update_frequency: DF.Literal["Monthly", "Each Transaction", "Daily"]
+		selling_price_list: DF.Link | None
+		so_required: DF.Literal["No", "Yes"]
+		territory: DF.Link | None
+		validate_selling_price: DF.Check
+	# end: auto-generated types
+
 	def on_update(self):
 		self.toggle_hide_tax_id()
 		self.toggle_editable_rate_for_bundle_items()
diff --git a/erpnext/selling/doctype/sms_center/sms_center.py b/erpnext/selling/doctype/sms_center/sms_center.py
index cdc7397..99f0351 100644
--- a/erpnext/selling/doctype/sms_center/sms_center.py
+++ b/erpnext/selling/doctype/sms_center/sms_center.py
@@ -10,6 +10,35 @@
 
 
 class SMSCenter(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
+
+		branch: DF.Link | None
+		customer: DF.Link | None
+		department: DF.Link | None
+		message: DF.Text
+		receiver_list: DF.Code | None
+		sales_partner: DF.Link | None
+		send_to: DF.Literal[
+			"",
+			"All Contact",
+			"All Customer Contact",
+			"All Supplier Contact",
+			"All Sales Partner Contact",
+			"All Lead (Open)",
+			"All Employee (Active)",
+			"All Sales Person",
+		]
+		supplier: DF.Link | None
+		total_characters: DF.Int
+		total_messages: DF.Int
+	# end: auto-generated types
+
 	@frappe.whitelist()
 	def create_receiver_list(self):
 		rec, where_clause = "", ""
diff --git a/erpnext/selling/page/point_of_sale/pos_controller.js b/erpnext/selling/page/point_of_sale/pos_controller.js
index 9bba4eb..feecd9c 100644
--- a/erpnext/selling/page/point_of_sale/pos_controller.js
+++ b/erpnext/selling/page/point_of_sale/pos_controller.js
@@ -609,11 +609,12 @@
 			// if item is clicked twice from item selector
 			// then "item_code, batch_no, uom, rate" will help in getting the exact item
 			// to increase the qty by one
-			const has_batch_no = batch_no;
+			const has_batch_no = (batch_no !== 'null' && batch_no !== null);
 			item_row = this.frm.doc.items.find(
 				i => i.item_code === item_code
 					&& (!has_batch_no || (has_batch_no && i.batch_no === batch_no))
 					&& (i.uom === uom)
+					&& (i.rate === flt(rate))
 			);
 		}
 
diff --git a/erpnext/accounts/doctype/unreconcile_payments/__init__.py b/erpnext/selling/report/lost_quotations/__init__.py
similarity index 100%
copy from erpnext/accounts/doctype/unreconcile_payments/__init__.py
copy to erpnext/selling/report/lost_quotations/__init__.py
diff --git a/erpnext/selling/report/lost_quotations/lost_quotations.js b/erpnext/selling/report/lost_quotations/lost_quotations.js
new file mode 100644
index 0000000..78e76cb
--- /dev/null
+++ b/erpnext/selling/report/lost_quotations/lost_quotations.js
@@ -0,0 +1,40 @@
+// Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.query_reports["Lost Quotations"] = {
+	filters: [
+		{
+			fieldname: "company",
+			label: __("Company"),
+			fieldtype: "Link",
+			options: "Company",
+			default: frappe.defaults.get_user_default("Company"),
+		},
+		{
+			label: "Timespan",
+			fieldtype: "Select",
+			fieldname: "timespan",
+			options: [
+				"Last Week",
+				"Last Month",
+				"Last Quarter",
+				"Last 6 months",
+				"Last Year",
+				"This Week",
+				"This Month",
+				"This Quarter",
+				"This Year",
+			],
+			default: "This Year",
+			reqd: 1,
+		},
+		{
+			fieldname: "group_by",
+			label: __("Group By"),
+			fieldtype: "Select",
+			options: ["Lost Reason", "Competitor"],
+			default: "Lost Reason",
+			reqd: 1,
+		},
+	],
+};
diff --git a/erpnext/selling/report/lost_quotations/lost_quotations.json b/erpnext/selling/report/lost_quotations/lost_quotations.json
new file mode 100644
index 0000000..8915bab
--- /dev/null
+++ b/erpnext/selling/report/lost_quotations/lost_quotations.json
@@ -0,0 +1,30 @@
+{
+ "add_total_row": 0,
+ "columns": [],
+ "creation": "2023-11-23 18:00:19.141922",
+ "disabled": 0,
+ "docstatus": 0,
+ "doctype": "Report",
+ "filters": [],
+ "idx": 0,
+ "is_standard": "Yes",
+ "letter_head": null,
+ "letterhead": null,
+ "modified": "2023-11-23 19:27:28.854108",
+ "modified_by": "Administrator",
+ "module": "Selling",
+ "name": "Lost Quotations",
+ "owner": "Administrator",
+ "prepared_report": 0,
+ "ref_doctype": "Quotation",
+ "report_name": "Lost Quotations",
+ "report_type": "Script Report",
+ "roles": [
+  {
+   "role": "Sales User"
+  },
+  {
+   "role": "Sales Manager"
+  }
+ ]
+}
\ No newline at end of file
diff --git a/erpnext/selling/report/lost_quotations/lost_quotations.py b/erpnext/selling/report/lost_quotations/lost_quotations.py
new file mode 100644
index 0000000..7c0bfbd
--- /dev/null
+++ b/erpnext/selling/report/lost_quotations/lost_quotations.py
@@ -0,0 +1,98 @@
+# Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from typing import Literal
+
+import frappe
+from frappe import _
+from frappe.model.docstatus import DocStatus
+from frappe.query_builder.functions import Coalesce, Count, Round, Sum
+from frappe.utils.data import get_timespan_date_range
+
+
+def execute(filters=None):
+	columns = get_columns(filters.get("group_by"))
+	from_date, to_date = get_timespan_date_range(filters.get("timespan").lower())
+	data = get_data(filters.get("company"), from_date, to_date, filters.get("group_by"))
+	return columns, data
+
+
+def get_columns(group_by: Literal["Lost Reason", "Competitor"]):
+	return [
+		{
+			"fieldname": "lost_reason" if group_by == "Lost Reason" else "competitor",
+			"label": _("Lost Reason") if group_by == "Lost Reason" else _("Competitor"),
+			"fieldtype": "Link",
+			"options": "Quotation Lost Reason" if group_by == "Lost Reason" else "Competitor",
+			"width": 200,
+		},
+		{
+			"filedname": "lost_quotations",
+			"label": _("Lost Quotations"),
+			"fieldtype": "Int",
+			"width": 150,
+		},
+		{
+			"filedname": "lost_quotations_pct",
+			"label": _("Lost Quotations %"),
+			"fieldtype": "Percent",
+			"width": 200,
+		},
+		{
+			"fieldname": "lost_value",
+			"label": _("Lost Value"),
+			"fieldtype": "Currency",
+			"width": 150,
+		},
+		{
+			"filedname": "lost_value_pct",
+			"label": _("Lost Value %"),
+			"fieldtype": "Percent",
+			"width": 200,
+		},
+	]
+
+
+def get_data(
+	company: str, from_date: str, to_date: str, group_by: Literal["Lost Reason", "Competitor"]
+):
+	"""Return quotation value grouped by lost reason or competitor"""
+	if group_by == "Lost Reason":
+		fieldname = "lost_reason"
+		dimension = frappe.qb.DocType("Quotation Lost Reason Detail")
+	elif group_by == "Competitor":
+		fieldname = "competitor"
+		dimension = frappe.qb.DocType("Competitor Detail")
+	else:
+		frappe.throw(_("Invalid Group By"))
+
+	q = frappe.qb.DocType("Quotation")
+
+	lost_quotation_condition = (
+		(q.status == "Lost")
+		& (q.docstatus == DocStatus.submitted())
+		& (q.transaction_date >= from_date)
+		& (q.transaction_date <= to_date)
+		& (q.company == company)
+	)
+
+	from_lost_quotations = frappe.qb.from_(q).where(lost_quotation_condition)
+	total_quotations = from_lost_quotations.select(Count(q.name))
+	total_value = from_lost_quotations.select(Sum(q.base_net_total))
+
+	query = (
+		frappe.qb.from_(q)
+		.select(
+			Coalesce(dimension[fieldname], _("Not Specified")),
+			Count(q.name).distinct(),
+			Round((Count(q.name).distinct() / total_quotations * 100), 2),
+			Sum(q.base_net_total),
+			Round((Sum(q.base_net_total) / total_value * 100), 2),
+		)
+		.left_join(dimension)
+		.on(dimension.parent == q.name)
+		.where(lost_quotation_condition)
+		.groupby(dimension[fieldname])
+	)
+
+	return query.run()
diff --git a/erpnext/selling/report/sales_person_wise_transaction_summary/sales_person_wise_transaction_summary.py b/erpnext/selling/report/sales_person_wise_transaction_summary/sales_person_wise_transaction_summary.py
index cb6e8a1..9f3ba0d 100644
--- a/erpnext/selling/report/sales_person_wise_transaction_summary/sales_person_wise_transaction_summary.py
+++ b/erpnext/selling/report/sales_person_wise_transaction_summary/sales_person_wise_transaction_summary.py
@@ -3,7 +3,8 @@
 
 
 import frappe
-from frappe import _, msgprint
+from frappe import _, msgprint, qb
+from frappe.query_builder import Criterion
 
 from erpnext import get_company_currency
 
@@ -214,24 +215,33 @@
 	if items:
 		conditions.append("dt_item.item_code in (%s)" % ", ".join(["%s"] * len(items)))
 		values += items
+	else:
+		# return empty result, if no items are fetched after filtering on 'item group' and 'brand'
+		conditions.append("dt_item.item_code = Null")
 
 	return " and ".join(conditions), values
 
 
 def get_items(filters):
+	item = qb.DocType("Item")
+
+	item_query_conditions = []
 	if filters.get("item_group"):
-		key = "item_group"
-	elif filters.get("brand"):
-		key = "brand"
-	else:
-		key = ""
-
-	items = []
-	if key:
-		items = frappe.db.sql_list(
-			"""select name from tabItem where %s = %s""" % (key, "%s"), (filters[key])
+		# Handle 'Parent' nodes as well.
+		item_group = qb.DocType("Item Group")
+		lft, rgt = frappe.db.get_all(
+			"Item Group", filters={"name": filters.get("item_group")}, fields=["lft", "rgt"], as_list=True
+		)[0]
+		item_group_query = (
+			qb.from_(item_group)
+			.select(item_group.name)
+			.where((item_group.lft >= lft) & (item_group.rgt <= rgt))
 		)
+		item_query_conditions.append(item.item_group.isin(item_group_query))
+	if filters.get("brand"):
+		item_query_conditions.append(item.brand == filters.get("brand"))
 
+	items = qb.from_(item).select(item.name).where(Criterion.all(item_query_conditions)).run()
 	return items
 
 
diff --git a/erpnext/setup/doctype/authorization_control/authorization_control.py b/erpnext/setup/doctype/authorization_control/authorization_control.py
index fd5a201..feb14a8 100644
--- a/erpnext/setup/doctype/authorization_control/authorization_control.py
+++ b/erpnext/setup/doctype/authorization_control/authorization_control.py
@@ -10,6 +10,16 @@
 
 
 class AuthorizationControl(TransactionBase):
+	# 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
+
+	# end: auto-generated types
+
 	def get_appr_user_role(self, det, doctype_name, total, based_on, condition, master_name, company):
 		amt_list, appr_users, appr_roles = [], [], []
 		users, roles = "", ""
diff --git a/erpnext/setup/doctype/authorization_rule/authorization_rule.py b/erpnext/setup/doctype/authorization_rule/authorization_rule.py
index 9e64e55..b65a327 100644
--- a/erpnext/setup/doctype/authorization_rule/authorization_rule.py
+++ b/erpnext/setup/doctype/authorization_rule/authorization_rule.py
@@ -9,6 +9,45 @@
 
 
 class AuthorizationRule(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
+
+		approving_role: DF.Link | None
+		approving_user: DF.Link | None
+		based_on: DF.Literal[
+			"",
+			"Grand Total",
+			"Average Discount",
+			"Customerwise Discount",
+			"Itemwise Discount",
+			"Item Group wise Discount",
+			"Not Applicable",
+		]
+		company: DF.Link | None
+		customer_or_item: DF.Literal["Customer", "Item", "Item Group"]
+		master_name: DF.DynamicLink | None
+		system_role: DF.Link | None
+		system_user: DF.Link | None
+		to_designation: DF.Link | None
+		to_emp: DF.Link | None
+		transaction: DF.Literal[
+			"",
+			"Sales Order",
+			"Purchase Order",
+			"Quotation",
+			"Delivery Note",
+			"Sales Invoice",
+			"Purchase Invoice",
+			"Purchase Receipt",
+		]
+		value: DF.Float
+	# end: auto-generated types
+
 	def check_duplicate_entry(self):
 		exists = frappe.db.sql(
 			"""select name, docstatus from `tabAuthorization Rule`
diff --git a/erpnext/setup/doctype/branch/branch.py b/erpnext/setup/doctype/branch/branch.py
index 133ada0..58d1782 100644
--- a/erpnext/setup/doctype/branch/branch.py
+++ b/erpnext/setup/doctype/branch/branch.py
@@ -6,4 +6,15 @@
 
 
 class Branch(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
+
+		branch: DF.Data
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/setup/doctype/brand/brand.py b/erpnext/setup/doctype/brand/brand.py
index 1bb6fc9..cf3f474 100644
--- a/erpnext/setup/doctype/brand/brand.py
+++ b/erpnext/setup/doctype/brand/brand.py
@@ -9,6 +9,22 @@
 
 
 class Brand(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
+
+		from erpnext.stock.doctype.item_default.item_default import ItemDefault
+
+		brand: DF.Data
+		brand_defaults: DF.Table[ItemDefault]
+		description: DF.Text | None
+		image: DF.AttachImage | None
+	# end: auto-generated types
+
 	pass
 
 
diff --git a/erpnext/setup/doctype/company/company.py b/erpnext/setup/doctype/company/company.py
index 3413702..0e8ee2d 100644
--- a/erpnext/setup/doctype/company/company.py
+++ b/erpnext/setup/doctype/company/company.py
@@ -19,6 +19,90 @@
 
 
 class Company(NestedSet):
+	# 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
+
+		abbr: DF.Data
+		accumulated_depreciation_account: DF.Link | None
+		allow_account_creation_against_child_company: DF.Check
+		asset_received_but_not_billed: DF.Link | None
+		auto_err_frequency: DF.Literal["Daily", "Weekly"]
+		auto_exchange_rate_revaluation: DF.Check
+		book_advance_payments_in_separate_party_account: DF.Check
+		capital_work_in_progress_account: DF.Link | None
+		chart_of_accounts: DF.Literal
+		company_description: DF.TextEditor | None
+		company_logo: DF.AttachImage | None
+		company_name: DF.Data
+		cost_center: DF.Link | None
+		country: DF.Link
+		create_chart_of_accounts_based_on: DF.Literal["", "Standard Template", "Existing Company"]
+		credit_limit: DF.Currency
+		date_of_commencement: DF.Date | None
+		date_of_establishment: DF.Date | None
+		date_of_incorporation: DF.Date | None
+		default_advance_paid_account: DF.Link | None
+		default_advance_received_account: DF.Link | None
+		default_bank_account: DF.Link | None
+		default_buying_terms: DF.Link | None
+		default_cash_account: DF.Link | None
+		default_currency: DF.Link
+		default_deferred_expense_account: DF.Link | None
+		default_deferred_revenue_account: DF.Link | None
+		default_discount_account: DF.Link | None
+		default_expense_account: DF.Link | None
+		default_finance_book: DF.Link | None
+		default_holiday_list: DF.Link | None
+		default_in_transit_warehouse: DF.Link | None
+		default_income_account: DF.Link | None
+		default_inventory_account: DF.Link | None
+		default_letter_head: DF.Link | None
+		default_payable_account: DF.Link | None
+		default_provisional_account: DF.Link | None
+		default_receivable_account: DF.Link | None
+		default_selling_terms: DF.Link | None
+		default_warehouse_for_sales_return: DF.Link | None
+		depreciation_cost_center: DF.Link | None
+		depreciation_expense_account: DF.Link | None
+		disposal_account: DF.Link | None
+		domain: DF.Data | None
+		email: DF.Data | None
+		enable_perpetual_inventory: DF.Check
+		enable_provisional_accounting_for_non_stock_items: DF.Check
+		exception_budget_approver_role: DF.Link | None
+		exchange_gain_loss_account: DF.Link | None
+		existing_company: DF.Link | None
+		fax: DF.Data | None
+		is_group: DF.Check
+		lft: DF.Int
+		monthly_sales_target: DF.Currency
+		old_parent: DF.Data | None
+		parent_company: DF.Link | None
+		payment_terms: DF.Link | None
+		phone_no: DF.Data | None
+		registration_details: DF.Code | None
+		rgt: DF.Int
+		round_off_account: DF.Link | None
+		round_off_cost_center: DF.Link | None
+		sales_monthly_history: DF.SmallText | None
+		series_for_depreciation_entry: DF.Data | None
+		stock_adjustment_account: DF.Link | None
+		stock_received_but_not_billed: DF.Link | None
+		submit_err_jv: DF.Check
+		tax_id: DF.Data | None
+		total_monthly_sales: DF.Currency
+		transactions_annual_history: DF.Code | None
+		unrealized_exchange_gain_loss_account: DF.Link | None
+		unrealized_profit_loss_account: DF.Link | None
+		website: DF.Data | None
+		write_off_account: DF.Link | None
+	# end: auto-generated types
+
 	nsm_parent_field = "parent_company"
 
 	def onload(self):
diff --git a/erpnext/setup/doctype/currency_exchange/currency_exchange.py b/erpnext/setup/doctype/currency_exchange/currency_exchange.py
index f9f3b3a..735734b 100644
--- a/erpnext/setup/doctype/currency_exchange/currency_exchange.py
+++ b/erpnext/setup/doctype/currency_exchange/currency_exchange.py
@@ -10,6 +10,22 @@
 
 
 class CurrencyExchange(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
+
+		date: DF.Date
+		exchange_rate: DF.Float
+		for_buying: DF.Check
+		for_selling: DF.Check
+		from_currency: DF.Link
+		to_currency: DF.Link
+	# end: auto-generated types
+
 	def autoname(self):
 		purpose = ""
 		if not self.date:
diff --git a/erpnext/setup/doctype/customer_group/customer_group.py b/erpnext/setup/doctype/customer_group/customer_group.py
index 246cc19..89b89ad 100644
--- a/erpnext/setup/doctype/customer_group/customer_group.py
+++ b/erpnext/setup/doctype/customer_group/customer_group.py
@@ -8,6 +8,31 @@
 
 
 class CustomerGroup(NestedSet):
+	# 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
+
+		from erpnext.accounts.doctype.party_account.party_account import PartyAccount
+		from erpnext.selling.doctype.customer_credit_limit.customer_credit_limit import (
+			CustomerCreditLimit,
+		)
+
+		accounts: DF.Table[PartyAccount]
+		credit_limits: DF.Table[CustomerCreditLimit]
+		customer_group_name: DF.Data
+		default_price_list: DF.Link | None
+		is_group: DF.Check
+		lft: DF.Int
+		old_parent: DF.Link | None
+		parent_customer_group: DF.Link | None
+		payment_terms: DF.Link | None
+		rgt: DF.Int
+	# end: auto-generated types
+
 	nsm_parent_field = "parent_customer_group"
 
 	def validate(self):
diff --git a/erpnext/setup/doctype/department/department.py b/erpnext/setup/doctype/department/department.py
index 1745178..6b090f8 100644
--- a/erpnext/setup/doctype/department/department.py
+++ b/erpnext/setup/doctype/department/department.py
@@ -9,6 +9,24 @@
 
 
 class Department(NestedSet):
+	# 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
+		department_name: DF.Data
+		disabled: DF.Check
+		is_group: DF.Check
+		lft: DF.Int
+		old_parent: DF.Data | None
+		parent_department: DF.Link | None
+		rgt: DF.Int
+	# end: auto-generated types
+
 	nsm_parent_field = "parent_department"
 
 	def autoname(self):
diff --git a/erpnext/setup/doctype/designation/designation.py b/erpnext/setup/doctype/designation/designation.py
index d7be55c..9ba9e80 100644
--- a/erpnext/setup/doctype/designation/designation.py
+++ b/erpnext/setup/doctype/designation/designation.py
@@ -6,4 +6,16 @@
 
 
 class Designation(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
+
+		description: DF.Text | None
+		designation_name: DF.Data
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/setup/doctype/driver/driver.py b/erpnext/setup/doctype/driver/driver.py
index 2698189..4faa8e3 100644
--- a/erpnext/setup/doctype/driver/driver.py
+++ b/erpnext/setup/doctype/driver/driver.py
@@ -6,4 +6,29 @@
 
 
 class Driver(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
+
+		from erpnext.setup.doctype.driving_license_category.driving_license_category import (
+			DrivingLicenseCategory,
+		)
+
+		address: DF.Link | None
+		cell_number: DF.Data | None
+		driving_license_category: DF.Table[DrivingLicenseCategory]
+		employee: DF.Link | None
+		expiry_date: DF.Date | None
+		full_name: DF.Data
+		issuing_date: DF.Date | None
+		license_number: DF.Data | None
+		naming_series: DF.Literal["HR-DRI-.YYYY.-"]
+		status: DF.Literal["Active", "Suspended", "Left"]
+		transporter: DF.Link | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/setup/doctype/driving_license_category/driving_license_category.py b/erpnext/setup/doctype/driving_license_category/driving_license_category.py
index a1a6d55..c06ce7d 100644
--- a/erpnext/setup/doctype/driving_license_category/driving_license_category.py
+++ b/erpnext/setup/doctype/driving_license_category/driving_license_category.py
@@ -6,4 +6,20 @@
 
 
 class DrivingLicenseCategory(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
+
+		description: DF.Data | None
+		expiry_date: DF.Date | None
+		issuing_date: DF.Date | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/setup/doctype/email_digest/email_digest.py b/erpnext/setup/doctype/email_digest/email_digest.py
index 4fc20e6..22bdf50 100644
--- a/erpnext/setup/doctype/email_digest/email_digest.py
+++ b/erpnext/setup/doctype/email_digest/email_digest.py
@@ -30,6 +30,50 @@
 
 
 class EmailDigest(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
+
+		from erpnext.setup.doctype.email_digest_recipient.email_digest_recipient import (
+			EmailDigestRecipient,
+		)
+
+		add_quote: DF.Check
+		bank_balance: DF.Check
+		calendar_events: DF.Check
+		company: DF.Link
+		credit_balance: DF.Check
+		enabled: DF.Check
+		expense_year_to_date: DF.Check
+		expenses_booked: DF.Check
+		frequency: DF.Literal["Daily", "Weekly", "Monthly"]
+		income: DF.Check
+		income_year_to_date: DF.Check
+		invoiced_amount: DF.Check
+		issue: DF.Check
+		new_quotations: DF.Check
+		next_send: DF.Data | None
+		notifications: DF.Check
+		payables: DF.Check
+		pending_quotations: DF.Check
+		project: DF.Check
+		purchase_invoice: DF.Check
+		purchase_order: DF.Check
+		purchase_orders_items_overdue: DF.Check
+		purchase_orders_to_bill: DF.Check
+		purchase_orders_to_receive: DF.Check
+		recipients: DF.TableMultiSelect[EmailDigestRecipient]
+		sales_invoice: DF.Check
+		sales_order: DF.Check
+		sales_orders_to_bill: DF.Check
+		sales_orders_to_deliver: DF.Check
+		todo_list: DF.Check
+	# end: auto-generated types
+
 	def __init__(self, *args, **kwargs):
 		super(EmailDigest, self).__init__(*args, **kwargs)
 
@@ -79,7 +123,7 @@
 				if msg_for_this_recipient and row.recipient in valid_users:
 					frappe.sendmail(
 						recipients=row.recipient,
-						subject=_("{0} Digest").format(self.frequency),
+						subject=_("{0} Digest").format(_(self.frequency)),
 						message=msg_for_this_recipient,
 						reference_doctype=self.doctype,
 						reference_name=self.name,
@@ -382,9 +426,10 @@
 		"""Get income to date"""
 		balance = 0.0
 		count = 0
+		fy_start_date = get_fiscal_year(self.future_to_date)[1]
 
 		for account in self.get_root_type_accounts(root_type):
-			balance += get_balance_on(account, date=self.future_to_date)
+			balance += get_balance_on(account, date=self.future_to_date, start_date=fy_start_date)
 			count += get_count_on(account, fieldname, date=self.future_to_date)
 
 		if fieldname == "income":
diff --git a/erpnext/setup/doctype/email_digest_recipient/email_digest_recipient.py b/erpnext/setup/doctype/email_digest_recipient/email_digest_recipient.py
index 06bf627..3316ca0 100644
--- a/erpnext/setup/doctype/email_digest_recipient/email_digest_recipient.py
+++ b/erpnext/setup/doctype/email_digest_recipient/email_digest_recipient.py
@@ -7,4 +7,18 @@
 
 
 class EmailDigestRecipient(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
+
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		recipient: DF.Link
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/setup/doctype/employee/employee.js b/erpnext/setup/doctype/employee/employee.js
index 39a215f..efc3fd1 100755
--- a/erpnext/setup/doctype/employee/employee.js
+++ b/erpnext/setup/doctype/employee/employee.js
@@ -81,8 +81,10 @@
 				employee: frm.doc.name,
 				email: frm.doc.prefered_email
 			},
+			freeze: true,
+			freeze_message: __("Creating User..."),
 			callback: function (r) {
-				frm.set_value("user_id", r.message);
+				frm.reload_doc();
 			}
 		});
 	}
diff --git a/erpnext/setup/doctype/employee/employee.py b/erpnext/setup/doctype/employee/employee.py
index 78fb4df..6f9176c 100755
--- a/erpnext/setup/doctype/employee/employee.py
+++ b/erpnext/setup/doctype/employee/employee.py
@@ -48,6 +48,9 @@
 		else:
 			existing_user_id = frappe.db.get_value("Employee", self.name, "user_id")
 			if existing_user_id:
+				user = frappe.get_doc("User", existing_user_id)
+				validate_employee_role(user, ignore_emp_check=True)
+				user.save(ignore_permissions=True)
 				remove_user_permission("Employee", self.name, existing_user_id)
 
 	def after_rename(self, old, new, merge):
@@ -230,12 +233,26 @@
 			frappe.cache().hdel("employees_with_number", prev_number)
 
 
-def validate_employee_role(doc, method):
+def validate_employee_role(doc, method=None, ignore_emp_check=False):
 	# called via User hook
-	if "Employee" in [d.role for d in doc.get("roles")]:
-		if not frappe.db.get_value("Employee", {"user_id": doc.name}):
-			frappe.msgprint(_("Please set User ID field in an Employee record to set Employee Role"))
-			doc.get("roles").remove(doc.get("roles", {"role": "Employee"})[0])
+	if not ignore_emp_check:
+		if frappe.db.get_value("Employee", {"user_id": doc.name}):
+			return
+
+	user_roles = [d.role for d in doc.get("roles")]
+	if "Employee" in user_roles:
+		frappe.msgprint(
+			_("User {0}: Removed Employee role as there is no mapped employee.").format(doc.name)
+		)
+		doc.get("roles").remove(doc.get("roles", {"role": "Employee"})[0])
+
+	if "Employee Self Service" in user_roles:
+		frappe.msgprint(
+			_("User {0}: Removed Employee Self Service role as there is no mapped employee.").format(
+				doc.name
+			)
+		)
+		doc.get("roles").remove(doc.get("roles", {"role": "Employee Self Service"})[0])
 
 
 def update_user_permissions(doc, method):
@@ -347,6 +364,8 @@
 		}
 	)
 	user.insert()
+	emp.user_id = user.name
+	emp.save()
 	return user.name
 
 
diff --git a/erpnext/setup/doctype/employee/test_employee.py b/erpnext/setup/doctype/employee/test_employee.py
index 5a693c5..9b70683 100644
--- a/erpnext/setup/doctype/employee/test_employee.py
+++ b/erpnext/setup/doctype/employee/test_employee.py
@@ -25,6 +25,15 @@
 		employee1_doc.status = "Left"
 		self.assertRaises(InactiveEmployeeStatusError, employee1_doc.save)
 
+	def test_user_has_employee(self):
+		employee = make_employee("test_emp_user_creation@company.com")
+		employee_doc = frappe.get_doc("Employee", employee)
+		user = employee_doc.user_id
+		self.assertTrue("Employee" in frappe.get_roles(user))
+		employee_doc.user_id = ""
+		employee_doc.save()
+		self.assertTrue("Employee" not in frappe.get_roles(user))
+
 	def tearDown(self):
 		frappe.db.rollback()
 
diff --git a/erpnext/setup/doctype/employee_education/employee_education.py b/erpnext/setup/doctype/employee_education/employee_education.py
index ded583b..8ef77f5 100644
--- a/erpnext/setup/doctype/employee_education/employee_education.py
+++ b/erpnext/setup/doctype/employee_education/employee_education.py
@@ -6,4 +6,23 @@
 
 
 class EmployeeEducation(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
+
+		class_per: DF.Data | None
+		level: DF.Literal["Graduate", "Post Graduate", "Under Graduate"]
+		maj_opt_subj: DF.Text | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		qualification: DF.Data | None
+		school_univ: DF.SmallText | None
+		year_of_passing: DF.Int
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/setup/doctype/employee_external_work_history/employee_external_work_history.py b/erpnext/setup/doctype/employee_external_work_history/employee_external_work_history.py
index d594fbf..96b9064 100644
--- a/erpnext/setup/doctype/employee_external_work_history/employee_external_work_history.py
+++ b/erpnext/setup/doctype/employee_external_work_history/employee_external_work_history.py
@@ -6,4 +6,23 @@
 
 
 class EmployeeExternalWorkHistory(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
+
+		address: DF.SmallText | None
+		company_name: DF.Data | None
+		contact: DF.Data | None
+		designation: DF.Data | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		salary: DF.Currency
+		total_experience: DF.Data | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/setup/doctype/employee_group/employee_group.py b/erpnext/setup/doctype/employee_group/employee_group.py
index c4ce083..1891328 100644
--- a/erpnext/setup/doctype/employee_group/employee_group.py
+++ b/erpnext/setup/doctype/employee_group/employee_group.py
@@ -6,4 +6,18 @@
 
 
 class EmployeeGroup(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
+
+		from erpnext.setup.doctype.employee_group_table.employee_group_table import EmployeeGroupTable
+
+		employee_group_name: DF.Data
+		employee_list: DF.Table[EmployeeGroupTable]
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/setup/doctype/employee_group_table/employee_group_table.py b/erpnext/setup/doctype/employee_group_table/employee_group_table.py
index adf6ca2..3775e0c 100644
--- a/erpnext/setup/doctype/employee_group_table/employee_group_table.py
+++ b/erpnext/setup/doctype/employee_group_table/employee_group_table.py
@@ -6,4 +6,20 @@
 
 
 class EmployeeGroupTable(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
+
+		employee: DF.Link | None
+		employee_name: DF.Data | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		user_id: DF.Data | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/setup/doctype/employee_internal_work_history/employee_internal_work_history.py b/erpnext/setup/doctype/employee_internal_work_history/employee_internal_work_history.py
index 6225de6..9f62684 100644
--- a/erpnext/setup/doctype/employee_internal_work_history/employee_internal_work_history.py
+++ b/erpnext/setup/doctype/employee_internal_work_history/employee_internal_work_history.py
@@ -6,4 +6,22 @@
 
 
 class EmployeeInternalWorkHistory(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
+
+		branch: DF.Link | None
+		department: DF.Link | None
+		designation: DF.Link | None
+		from_date: DF.Date | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		to_date: DF.Date | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/setup/doctype/global_defaults/global_defaults.py b/erpnext/setup/doctype/global_defaults/global_defaults.py
index fc80483..4b7f642 100644
--- a/erpnext/setup/doctype/global_defaults/global_defaults.py
+++ b/erpnext/setup/doctype/global_defaults/global_defaults.py
@@ -23,6 +23,24 @@
 
 
 class GlobalDefaults(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
+
+		country: DF.Link | None
+		default_company: DF.Link | None
+		default_currency: DF.Link
+		default_distance_unit: DF.Link | None
+		demo_company: DF.Link | None
+		disable_in_words: DF.Check
+		disable_rounded_total: DF.Check
+		hide_currency_symbol: DF.Literal["", "No", "Yes"]
+	# end: auto-generated types
+
 	def on_update(self):
 		"""update defaults"""
 		for key in keydict:
diff --git a/erpnext/setup/doctype/holiday/holiday.py b/erpnext/setup/doctype/holiday/holiday.py
index 85ca0b7..b226203 100644
--- a/erpnext/setup/doctype/holiday/holiday.py
+++ b/erpnext/setup/doctype/holiday/holiday.py
@@ -6,4 +6,20 @@
 
 
 class Holiday(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
+
+		description: DF.TextEditor
+		holiday_date: DF.Date
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		weekly_off: DF.Check
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/setup/doctype/holiday_list/holiday_list.py b/erpnext/setup/doctype/holiday_list/holiday_list.py
index df5b407..1afee41 100644
--- a/erpnext/setup/doctype/holiday_list/holiday_list.py
+++ b/erpnext/setup/doctype/holiday_list/holiday_list.py
@@ -16,6 +16,29 @@
 
 
 class HolidayList(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
+
+		from erpnext.setup.doctype.holiday.holiday import Holiday
+
+		color: DF.Color | None
+		country: DF.Autocomplete | None
+		from_date: DF.Date
+		holiday_list_name: DF.Data
+		holidays: DF.Table[Holiday]
+		subdivision: DF.Autocomplete | None
+		to_date: DF.Date
+		total_holidays: DF.Int
+		weekly_off: DF.Literal[
+			"", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"
+		]
+	# end: auto-generated types
+
 	def validate(self):
 		self.validate_days()
 		self.total_holidays = len(self.holidays)
diff --git a/erpnext/setup/doctype/incoterm/incoterm.py b/erpnext/setup/doctype/incoterm/incoterm.py
index 7e2e622..17305e9 100644
--- a/erpnext/setup/doctype/incoterm/incoterm.py
+++ b/erpnext/setup/doctype/incoterm/incoterm.py
@@ -6,6 +6,19 @@
 
 
 class Incoterm(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
+
+		code: DF.Data
+		description: DF.LongText | None
+		title: DF.Data
+	# end: auto-generated types
+
 	pass
 
 
diff --git a/erpnext/setup/doctype/item_group/item_group.py b/erpnext/setup/doctype/item_group/item_group.py
index fe7a241..fd65ab6 100644
--- a/erpnext/setup/doctype/item_group/item_group.py
+++ b/erpnext/setup/doctype/item_group/item_group.py
@@ -9,6 +9,28 @@
 
 
 class ItemGroup(NestedSet):
+	# 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
+
+		from erpnext.stock.doctype.item_default.item_default import ItemDefault
+		from erpnext.stock.doctype.item_tax.item_tax import ItemTax
+
+		image: DF.AttachImage | None
+		is_group: DF.Check
+		item_group_defaults: DF.Table[ItemDefault]
+		item_group_name: DF.Data
+		lft: DF.Int
+		old_parent: DF.Link | None
+		parent_item_group: DF.Link | None
+		rgt: DF.Int
+		taxes: DF.Table[ItemTax]
+	# end: auto-generated types
+
 	def validate(self):
 		if not self.parent_item_group and not frappe.flags.in_test:
 			if frappe.db.exists("Item Group", _("All Item Groups")):
diff --git a/erpnext/setup/doctype/party_type/party_type.py b/erpnext/setup/doctype/party_type/party_type.py
index cf7cba8..76b985b 100644
--- a/erpnext/setup/doctype/party_type/party_type.py
+++ b/erpnext/setup/doctype/party_type/party_type.py
@@ -7,6 +7,18 @@
 
 
 class PartyType(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_type: DF.Literal["Payable", "Receivable"]
+		party_type: DF.Link
+	# end: auto-generated types
+
 	pass
 
 
diff --git a/erpnext/setup/doctype/print_heading/print_heading.py b/erpnext/setup/doctype/print_heading/print_heading.py
index 3a2f15f..8e1a8fb 100644
--- a/erpnext/setup/doctype/print_heading/print_heading.py
+++ b/erpnext/setup/doctype/print_heading/print_heading.py
@@ -6,4 +6,16 @@
 
 
 class PrintHeading(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
+
+		description: DF.SmallText | None
+		print_heading: DF.Data
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/setup/doctype/quotation_lost_reason/quotation_lost_reason.json b/erpnext/setup/doctype/quotation_lost_reason/quotation_lost_reason.json
index 5d778ee..0eae08e 100644
--- a/erpnext/setup/doctype/quotation_lost_reason/quotation_lost_reason.json
+++ b/erpnext/setup/doctype/quotation_lost_reason/quotation_lost_reason.json
@@ -1,83 +1,58 @@
 {
- "allow_copy": 0, 
- "allow_import": 1, 
- "allow_rename": 0, 
- "autoname": "field:order_lost_reason", 
- "beta": 0, 
- "creation": "2013-01-10 16:34:24", 
- "custom": 0, 
- "docstatus": 0, 
- "doctype": "DocType", 
- "document_type": "Setup", 
- "editable_grid": 0, 
+ "actions": [],
+ "allow_import": 1,
+ "autoname": "field:order_lost_reason",
+ "creation": "2013-01-10 16:34:24",
+ "doctype": "DocType",
+ "document_type": "Setup",
+ "engine": "InnoDB",
+ "field_order": [
+  "order_lost_reason"
+ ],
  "fields": [
   {
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "fieldname": "order_lost_reason", 
-   "fieldtype": "Data", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_list_view": 1, 
-   "label": "Quotation Lost Reason", 
-   "length": 0, 
-   "no_copy": 0, 
-   "oldfieldname": "order_lost_reason", 
-   "oldfieldtype": "Data", 
-   "permlevel": 0, 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "report_hide": 0, 
-   "reqd": 1, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0
+   "fieldname": "order_lost_reason",
+   "fieldtype": "Data",
+   "in_list_view": 1,
+   "label": "Quotation Lost Reason",
+   "oldfieldname": "order_lost_reason",
+   "oldfieldtype": "Data",
+   "reqd": 1,
+   "unique": 1
   }
- ], 
- "hide_heading": 0, 
- "hide_toolbar": 0, 
- "icon": "fa fa-flag", 
- "idx": 1, 
- "image_view": 0, 
- "in_create": 0, 
-
- "is_submittable": 0, 
- "issingle": 0, 
- "istable": 0, 
- "max_attachments": 0, 
- "modified": "2016-07-25 05:24:25.533953", 
- "modified_by": "Administrator", 
- "module": "Setup", 
- "name": "Quotation Lost Reason", 
- "owner": "Administrator", 
+ ],
+ "icon": "fa fa-flag",
+ "idx": 1,
+ "links": [
+  {
+   "is_child_table": 1,
+   "link_doctype": "Quotation Lost Reason Detail",
+   "link_fieldname": "lost_reason",
+   "parent_doctype": "Quotation",
+   "table_fieldname": "lost_reasons"
+  }
+ ],
+ "modified": "2023-11-23 19:31:02.743353",
+ "modified_by": "Administrator",
+ "module": "Setup",
+ "name": "Quotation Lost Reason",
+ "naming_rule": "By fieldname",
+ "owner": "Administrator",
  "permissions": [
   {
-   "amend": 0, 
-   "apply_user_permissions": 0, 
-   "cancel": 0, 
-   "create": 1, 
-   "delete": 1, 
-   "email": 1, 
-   "export": 0, 
-   "if_owner": 0, 
-   "import": 0, 
-   "permlevel": 0, 
-   "print": 1, 
-   "read": 1, 
-   "report": 1, 
-   "role": "Sales Master Manager", 
-   "set_user_permissions": 0, 
-   "share": 1, 
-   "submit": 0, 
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "Sales Master Manager",
+   "share": 1,
    "write": 1
   }
- ], 
- "quick_entry": 1, 
- "read_only": 0, 
- "read_only_onload": 0, 
- "track_seen": 0
+ ],
+ "quick_entry": 1,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "states": []
 }
\ No newline at end of file
diff --git a/erpnext/setup/doctype/quotation_lost_reason/quotation_lost_reason.py b/erpnext/setup/doctype/quotation_lost_reason/quotation_lost_reason.py
index 651705c..fb9730e 100644
--- a/erpnext/setup/doctype/quotation_lost_reason/quotation_lost_reason.py
+++ b/erpnext/setup/doctype/quotation_lost_reason/quotation_lost_reason.py
@@ -6,4 +6,15 @@
 
 
 class QuotationLostReason(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
+
+		order_lost_reason: DF.Data
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/setup/doctype/quotation_lost_reason_detail/quotation_lost_reason_detail.py b/erpnext/setup/doctype/quotation_lost_reason_detail/quotation_lost_reason_detail.py
index dda64e9..87f700b 100644
--- a/erpnext/setup/doctype/quotation_lost_reason_detail/quotation_lost_reason_detail.py
+++ b/erpnext/setup/doctype/quotation_lost_reason_detail/quotation_lost_reason_detail.py
@@ -7,4 +7,18 @@
 
 
 class QuotationLostReasonDetail(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
+
+		lost_reason: DF.Link | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/setup/doctype/sales_partner/sales_partner.py b/erpnext/setup/doctype/sales_partner/sales_partner.py
index c313671..1047360 100644
--- a/erpnext/setup/doctype/sales_partner/sales_partner.py
+++ b/erpnext/setup/doctype/sales_partner/sales_partner.py
@@ -9,6 +9,30 @@
 
 
 class SalesPartner(WebsiteGenerator):
+	# 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
+
+		from erpnext.setup.doctype.target_detail.target_detail import TargetDetail
+
+		commission_rate: DF.Float
+		description: DF.TextEditor | None
+		introduction: DF.Text | None
+		logo: DF.Attach | None
+		partner_name: DF.Data
+		partner_type: DF.Link | None
+		partner_website: DF.Data | None
+		referral_code: DF.Data | None
+		route: DF.Data | None
+		show_in_website: DF.Check
+		targets: DF.Table[TargetDetail]
+		territory: DF.Link
+	# end: auto-generated types
+
 	website = frappe._dict(
 		page_title_field="partner_name",
 		condition_field="show_in_website",
diff --git a/erpnext/setup/doctype/sales_person/sales_person.py b/erpnext/setup/doctype/sales_person/sales_person.py
index beff7f5..c2615d3 100644
--- a/erpnext/setup/doctype/sales_person/sales_person.py
+++ b/erpnext/setup/doctype/sales_person/sales_person.py
@@ -16,6 +16,29 @@
 
 
 class SalesPerson(NestedSet):
+	# 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
+
+		from erpnext.setup.doctype.target_detail.target_detail import TargetDetail
+
+		commission_rate: DF.Data | None
+		department: DF.Link | None
+		employee: DF.Link | None
+		enabled: DF.Check
+		is_group: DF.Check
+		lft: DF.Int
+		old_parent: DF.Data | None
+		parent_sales_person: DF.Link | None
+		rgt: DF.Int
+		sales_person_name: DF.Data
+		targets: DF.Table[TargetDetail]
+	# end: auto-generated types
+
 	nsm_parent_field = "parent_sales_person"
 
 	def validate(self):
diff --git a/erpnext/setup/doctype/supplier_group/supplier_group.py b/erpnext/setup/doctype/supplier_group/supplier_group.py
index 9d2b733..b639b96 100644
--- a/erpnext/setup/doctype/supplier_group/supplier_group.py
+++ b/erpnext/setup/doctype/supplier_group/supplier_group.py
@@ -7,6 +7,26 @@
 
 
 class SupplierGroup(NestedSet):
+	# 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
+
+		from erpnext.accounts.doctype.party_account.party_account import PartyAccount
+
+		accounts: DF.Table[PartyAccount]
+		is_group: DF.Check
+		lft: DF.Int
+		old_parent: DF.Link | None
+		parent_supplier_group: DF.Link | None
+		payment_terms: DF.Link | None
+		rgt: DF.Int
+		supplier_group_name: DF.Data
+	# end: auto-generated types
+
 	nsm_parent_field = "parent_supplier_group"
 
 	def validate(self):
diff --git a/erpnext/setup/doctype/target_detail/target_detail.py b/erpnext/setup/doctype/target_detail/target_detail.py
index e27f5b6..86d94b2 100644
--- a/erpnext/setup/doctype/target_detail/target_detail.py
+++ b/erpnext/setup/doctype/target_detail/target_detail.py
@@ -6,4 +6,22 @@
 
 
 class TargetDetail(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
+
+		distribution_id: DF.Link
+		fiscal_year: DF.Link
+		item_group: DF.Link | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		target_amount: DF.Float
+		target_qty: DF.Float
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/setup/doctype/terms_and_conditions/terms_and_conditions.py b/erpnext/setup/doctype/terms_and_conditions/terms_and_conditions.py
index 344f6c6..73b5919 100644
--- a/erpnext/setup/doctype/terms_and_conditions/terms_and_conditions.py
+++ b/erpnext/setup/doctype/terms_and_conditions/terms_and_conditions.py
@@ -12,6 +12,21 @@
 
 
 class TermsandConditions(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
+
+		buying: DF.Check
+		disabled: DF.Check
+		selling: DF.Check
+		terms: DF.TextEditor | None
+		title: DF.Data
+	# end: auto-generated types
+
 	def validate(self):
 		if self.terms:
 			validate_template(self.terms)
diff --git a/erpnext/setup/doctype/territory/territory.py b/erpnext/setup/doctype/territory/territory.py
index 9bb5569..1cc3f62 100644
--- a/erpnext/setup/doctype/territory/territory.py
+++ b/erpnext/setup/doctype/territory/territory.py
@@ -9,6 +9,26 @@
 
 
 class Territory(NestedSet):
+	# 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
+
+		from erpnext.setup.doctype.target_detail.target_detail import TargetDetail
+
+		is_group: DF.Check
+		lft: DF.Int
+		old_parent: DF.Link | None
+		parent_territory: DF.Link | None
+		rgt: DF.Int
+		targets: DF.Table[TargetDetail]
+		territory_manager: DF.Link | None
+		territory_name: DF.Data
+	# end: auto-generated types
+
 	nsm_parent_field = "parent_territory"
 
 	def validate(self):
diff --git a/erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py b/erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py
index 481a3a5..7182201 100644
--- a/erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py
+++ b/erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py
@@ -10,6 +10,25 @@
 
 
 class TransactionDeletionRecord(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
+
+		from erpnext.setup.doctype.transaction_deletion_record_item.transaction_deletion_record_item import (
+			TransactionDeletionRecordItem,
+		)
+
+		amended_from: DF.Link | None
+		company: DF.Link
+		doctypes: DF.Table[TransactionDeletionRecordItem]
+		doctypes_to_be_ignored: DF.Table[TransactionDeletionRecordItem]
+		status: DF.Literal["Draft", "Completed"]
+	# end: auto-generated types
+
 	def __init__(self, *args, **kwargs):
 		super(TransactionDeletionRecord, self).__init__(*args, **kwargs)
 		self.batch_size = 5000
@@ -108,7 +127,16 @@
 
 				if no_of_docs > 0:
 					self.delete_version_log(docfield["parent"], docfield["fieldname"])
-					self.delete_communications(docfield["parent"], docfield["fieldname"])
+
+					reference_docs = frappe.get_all(
+						docfield["parent"], filters={docfield["fieldname"]: self.company}
+					)
+					reference_doc_names = [r.name for r in reference_docs]
+
+					self.delete_communications(docfield["parent"], reference_doc_names)
+					self.delete_comments(docfield["parent"], reference_doc_names)
+					self.unlink_attachments(docfield["parent"], reference_doc_names)
+
 					self.populate_doctypes_table(tables, docfield["parent"], no_of_docs)
 
 					self.delete_child_tables(docfield["parent"], docfield["fieldname"])
@@ -197,19 +225,49 @@
 					(versions.ref_doctype == doctype) & (versions.docname.isin(batch))
 				).run()
 
-	def delete_communications(self, doctype, company_fieldname):
-		reference_docs = frappe.get_all(doctype, filters={company_fieldname: self.company})
-		reference_doc_names = [r.name for r in reference_docs]
-
+	def delete_communications(self, doctype, reference_doc_names):
 		communications = frappe.get_all(
 			"Communication",
 			filters={"reference_doctype": doctype, "reference_name": ["in", reference_doc_names]},
 		)
 		communication_names = [c.name for c in communications]
 
+		if not communication_names:
+			return
+
 		for batch in create_batch(communication_names, self.batch_size):
 			frappe.delete_doc("Communication", batch, ignore_permissions=True)
 
+	def delete_comments(self, doctype, reference_doc_names):
+		comments = frappe.get_all(
+			"Comment",
+			filters={"reference_doctype": doctype, "reference_name": ["in", reference_doc_names]},
+		)
+		comment_names = [c.name for c in comments]
+
+		if not comment_names:
+			return
+
+		for batch in create_batch(comment_names, self.batch_size):
+			frappe.delete_doc("Comment", batch, ignore_permissions=True)
+
+	def unlink_attachments(self, doctype, reference_doc_names):
+		files = frappe.get_all(
+			"File",
+			filters={"attached_to_doctype": doctype, "attached_to_name": ["in", reference_doc_names]},
+		)
+		file_names = [c.name for c in files]
+
+		if not file_names:
+			return
+
+		file = qb.DocType("File")
+
+		for batch in create_batch(file_names, self.batch_size):
+			qb.update(file).set(file.attached_to_doctype, None).set(file.attached_to_name, None).where(
+				file.name.isin(batch)
+			).run()
+
 
 @frappe.whitelist()
 def get_doctypes_to_be_ignored():
diff --git a/erpnext/setup/doctype/transaction_deletion_record_item/transaction_deletion_record_item.py b/erpnext/setup/doctype/transaction_deletion_record_item/transaction_deletion_record_item.py
index 92ca8a2..f154cdb 100644
--- a/erpnext/setup/doctype/transaction_deletion_record_item/transaction_deletion_record_item.py
+++ b/erpnext/setup/doctype/transaction_deletion_record_item/transaction_deletion_record_item.py
@@ -7,4 +7,19 @@
 
 
 class TransactionDeletionRecordItem(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
+
+		doctype_name: DF.Link
+		no_of_docs: DF.Data | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/setup/doctype/uom/uom.py b/erpnext/setup/doctype/uom/uom.py
index ddb512a..0e674c1 100644
--- a/erpnext/setup/doctype/uom/uom.py
+++ b/erpnext/setup/doctype/uom/uom.py
@@ -6,4 +6,17 @@
 
 
 class UOM(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
+
+		enabled: DF.Check
+		must_be_whole_number: DF.Check
+		uom_name: DF.Data
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/setup/doctype/uom_conversion_factor/uom_conversion_factor.py b/erpnext/setup/doctype/uom_conversion_factor/uom_conversion_factor.py
index 12642fe..00d2000 100644
--- a/erpnext/setup/doctype/uom_conversion_factor/uom_conversion_factor.py
+++ b/erpnext/setup/doctype/uom_conversion_factor/uom_conversion_factor.py
@@ -6,4 +6,18 @@
 
 
 class UOMConversionFactor(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
+
+		category: DF.Link
+		from_uom: DF.Link
+		to_uom: DF.Link
+		value: DF.Float
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/setup/doctype/vehicle/vehicle.py b/erpnext/setup/doctype/vehicle/vehicle.py
index 6a1b75c..4a6146b 100644
--- a/erpnext/setup/doctype/vehicle/vehicle.py
+++ b/erpnext/setup/doctype/vehicle/vehicle.py
@@ -9,6 +9,36 @@
 
 
 class Vehicle(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
+
+		acquisition_date: DF.Date | None
+		amended_from: DF.Link | None
+		carbon_check_date: DF.Date | None
+		chassis_no: DF.Data | None
+		color: DF.Data | None
+		doors: DF.Int
+		employee: DF.Link | None
+		end_date: DF.Date | None
+		fuel_type: DF.Literal["Petrol", "Diesel", "Natural Gas", "Electric"]
+		insurance_company: DF.Data | None
+		last_odometer: DF.Int
+		license_plate: DF.Data
+		location: DF.Data | None
+		make: DF.Data
+		model: DF.Data
+		policy_no: DF.Data | None
+		start_date: DF.Date | None
+		uom: DF.Link
+		vehicle_value: DF.Currency
+		wheels: DF.Int
+	# end: auto-generated types
+
 	def validate(self):
 		if getdate(self.start_date) > getdate(self.end_date):
 			frappe.throw(_("Insurance Start date should be less than Insurance End date"))
diff --git a/erpnext/setup/doctype/website_item_group/website_item_group.py b/erpnext/setup/doctype/website_item_group/website_item_group.py
index 87fcb98..3d2b6e8 100644
--- a/erpnext/setup/doctype/website_item_group/website_item_group.py
+++ b/erpnext/setup/doctype/website_item_group/website_item_group.py
@@ -8,4 +8,18 @@
 
 
 class WebsiteItemGroup(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
+
+		item_group: DF.Link
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/setup/install.py b/erpnext/setup/install.py
index b106cfc..5b993fa 100644
--- a/erpnext/setup/install.py
+++ b/erpnext/setup/install.py
@@ -31,7 +31,6 @@
 	add_company_to_session_defaults()
 	add_standard_navbar_items()
 	add_app_name()
-	setup_log_settings()
 	hide_workspaces()
 	update_roles()
 	frappe.db.commit()
@@ -221,13 +220,6 @@
 	frappe.db.set_single_value("System Settings", "app_name", "ERPNext")
 
 
-def setup_log_settings():
-	log_settings = frappe.get_single("Log Settings")
-	log_settings.append("logs_to_clear", {"ref_doctype": "Repost Item Valuation", "days": 60})
-
-	log_settings.save(ignore_permissions=True)
-
-
 def hide_workspaces():
 	for ws in ["Integration", "Settings"]:
 		frappe.db.set_value("Workspace", ws, "public", 0)
diff --git a/erpnext/stock/doctype/batch/batch.py b/erpnext/stock/doctype/batch/batch.py
index 5919d7c..7b23f9e 100644
--- a/erpnext/stock/doctype/batch/batch.py
+++ b/erpnext/stock/doctype/batch/batch.py
@@ -87,6 +87,33 @@
 
 
 class Batch(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
+
+		batch_id: DF.Data
+		batch_qty: DF.Float
+		description: DF.SmallText | None
+		disabled: DF.Check
+		expiry_date: DF.Date | None
+		image: DF.AttachImage | None
+		item: DF.Link
+		item_name: DF.Data | None
+		manufacturing_date: DF.Date | None
+		parent_batch: DF.Link | None
+		produced_qty: DF.Float
+		qty_to_produce: DF.Float
+		reference_doctype: DF.Link | None
+		reference_name: DF.DynamicLink | None
+		stock_uom: DF.Link | None
+		supplier: DF.Link | None
+		use_batchwise_valuation: DF.Check
+	# end: auto-generated types
+
 	def autoname(self):
 		"""Generate random ID for batch if not specified"""
 
diff --git a/erpnext/stock/doctype/bin/bin.py b/erpnext/stock/doctype/bin/bin.py
index 8b2e5cf..9310985 100644
--- a/erpnext/stock/doctype/bin/bin.py
+++ b/erpnext/stock/doctype/bin/bin.py
@@ -10,6 +10,31 @@
 
 
 class Bin(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
+
+		actual_qty: DF.Float
+		indented_qty: DF.Float
+		item_code: DF.Link
+		ordered_qty: DF.Float
+		planned_qty: DF.Float
+		projected_qty: DF.Float
+		reserved_qty: DF.Float
+		reserved_qty_for_production: DF.Float
+		reserved_qty_for_production_plan: DF.Float
+		reserved_qty_for_sub_contract: DF.Float
+		reserved_stock: DF.Float
+		stock_uom: DF.Link | None
+		stock_value: DF.Float
+		valuation_rate: DF.Float
+		warehouse: DF.Link
+	# end: auto-generated types
+
 	def before_save(self):
 		if self.get("__islocal") or not self.stock_uom:
 			self.stock_uom = frappe.get_cached_value("Item", self.item_code, "stock_uom")
diff --git a/erpnext/stock/doctype/closing_stock_balance/closing_stock_balance.json b/erpnext/stock/doctype/closing_stock_balance/closing_stock_balance.json
index 225da6d..0c4757f 100644
--- a/erpnext/stock/doctype/closing_stock_balance/closing_stock_balance.json
+++ b/erpnext/stock/doctype/closing_stock_balance/closing_stock_balance.json
@@ -104,15 +104,6 @@
    "read_only": 1
   },
   {
-   "fieldname": "amended_from",
-   "fieldtype": "Link",
-   "label": "Amended From",
-   "no_copy": 1,
-   "options": "Closing Stock Balance",
-   "print_hide": 1,
-   "read_only": 1
-  },
-  {
    "fieldname": "include_uom",
    "fieldtype": "Link",
    "label": "Include UOM",
@@ -145,4 +136,4 @@
  "sort_field": "modified",
  "sort_order": "DESC",
  "states": []
-}
\ No newline at end of file
+}
diff --git a/erpnext/stock/doctype/closing_stock_balance/closing_stock_balance.py b/erpnext/stock/doctype/closing_stock_balance/closing_stock_balance.py
index b0499bf..7db8522 100644
--- a/erpnext/stock/doctype/closing_stock_balance/closing_stock_balance.py
+++ b/erpnext/stock/doctype/closing_stock_balance/closing_stock_balance.py
@@ -15,6 +15,27 @@
 
 
 class ClosingStockBalance(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
+
+		amended_from: DF.Link | None
+		company: DF.Link | None
+		from_date: DF.Date | None
+		include_uom: DF.Link | None
+		item_code: DF.Link | None
+		item_group: DF.Link | None
+		naming_series: DF.Literal["CBAL-.#####"]
+		status: DF.Literal["Draft", "Queued", "In Progress", "Completed", "Failed", "Canceled"]
+		to_date: DF.Date | None
+		warehouse: DF.Link | None
+		warehouse_type: DF.Link | None
+	# end: auto-generated types
+
 	def before_save(self):
 		self.set_status()
 
diff --git a/erpnext/stock/doctype/customs_tariff_number/customs_tariff_number.py b/erpnext/stock/doctype/customs_tariff_number/customs_tariff_number.py
index b52acb1..d032829 100644
--- a/erpnext/stock/doctype/customs_tariff_number/customs_tariff_number.py
+++ b/erpnext/stock/doctype/customs_tariff_number/customs_tariff_number.py
@@ -6,4 +6,16 @@
 
 
 class CustomsTariffNumber(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
+
+		description: DF.Data | None
+		tariff_number: DF.Data
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.py b/erpnext/stock/doctype/delivery_note/delivery_note.py
index 66dd33a..a101bdf 100644
--- a/erpnext/stock/doctype/delivery_note/delivery_note.py
+++ b/erpnext/stock/doctype/delivery_note/delivery_note.py
@@ -18,6 +18,128 @@
 
 
 class DeliveryNote(SellingController):
+	# 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
+
+		from erpnext.accounts.doctype.pricing_rule_detail.pricing_rule_detail import PricingRuleDetail
+		from erpnext.accounts.doctype.sales_taxes_and_charges.sales_taxes_and_charges import (
+			SalesTaxesandCharges,
+		)
+		from erpnext.selling.doctype.sales_team.sales_team import SalesTeam
+		from erpnext.stock.doctype.delivery_note_item.delivery_note_item import DeliveryNoteItem
+		from erpnext.stock.doctype.packed_item.packed_item import PackedItem
+
+		additional_discount_percentage: DF.Float
+		address_display: DF.SmallText | None
+		amended_from: DF.Link | None
+		amount_eligible_for_commission: DF.Currency
+		apply_discount_on: DF.Literal["", "Grand Total", "Net Total"]
+		auto_repeat: DF.Link | None
+		base_discount_amount: DF.Currency
+		base_grand_total: DF.Currency
+		base_in_words: DF.Data | None
+		base_net_total: DF.Currency
+		base_rounded_total: DF.Currency
+		base_rounding_adjustment: DF.Currency
+		base_total: DF.Currency
+		base_total_taxes_and_charges: DF.Currency
+		campaign: DF.Link | None
+		commission_rate: DF.Float
+		company: DF.Link
+		company_address: DF.Link | None
+		company_address_display: DF.SmallText | None
+		contact_display: DF.SmallText | None
+		contact_email: DF.Data | None
+		contact_mobile: DF.SmallText | None
+		contact_person: DF.Link | None
+		conversion_rate: DF.Float
+		cost_center: DF.Link | None
+		currency: DF.Link
+		customer: DF.Link
+		customer_address: DF.Link | None
+		customer_group: DF.Link | None
+		customer_name: DF.Data | None
+		disable_rounded_total: DF.Check
+		discount_amount: DF.Currency
+		dispatch_address: DF.SmallText | None
+		dispatch_address_name: DF.Link | None
+		driver: DF.Link | None
+		driver_name: DF.Data | None
+		excise_page: DF.Data | None
+		grand_total: DF.Currency
+		group_same_items: DF.Check
+		ignore_pricing_rule: DF.Check
+		in_words: DF.Data | None
+		incoterm: DF.Link | None
+		installation_status: DF.Literal
+		instructions: DF.Text | None
+		inter_company_reference: DF.Link | None
+		is_internal_customer: DF.Check
+		is_return: DF.Check
+		issue_credit_note: DF.Check
+		items: DF.Table[DeliveryNoteItem]
+		language: DF.Data | None
+		letter_head: DF.Link | None
+		lr_date: DF.Date | None
+		lr_no: DF.Data | None
+		named_place: DF.Data | None
+		naming_series: DF.Literal["MAT-DN-.YYYY.-", "MAT-DN-RET-.YYYY.-"]
+		net_total: DF.Currency
+		other_charges_calculation: DF.LongText | None
+		packed_items: DF.Table[PackedItem]
+		per_billed: DF.Percent
+		per_installed: DF.Percent
+		per_returned: DF.Percent
+		pick_list: DF.Link | None
+		plc_conversion_rate: DF.Float
+		po_date: DF.Date | None
+		po_no: DF.SmallText | None
+		posting_date: DF.Date
+		posting_time: DF.Time
+		price_list_currency: DF.Link
+		pricing_rules: DF.Table[PricingRuleDetail]
+		print_without_amount: DF.Check
+		project: DF.Link | None
+		represents_company: DF.Link | None
+		return_against: DF.Link | None
+		rounded_total: DF.Currency
+		rounding_adjustment: DF.Currency
+		sales_partner: DF.Link | None
+		sales_team: DF.Table[SalesTeam]
+		scan_barcode: DF.Data | None
+		select_print_heading: DF.Link | None
+		selling_price_list: DF.Link
+		set_posting_time: DF.Check
+		set_target_warehouse: DF.Link | None
+		set_warehouse: DF.Link | None
+		shipping_address: DF.SmallText | None
+		shipping_address_name: DF.Link | None
+		shipping_rule: DF.Link | None
+		source: DF.Link | None
+		status: DF.Literal["", "Draft", "To Bill", "Completed", "Return Issued", "Cancelled", "Closed"]
+		tax_category: DF.Link | None
+		tax_id: DF.Data | None
+		taxes: DF.Table[SalesTaxesandCharges]
+		taxes_and_charges: DF.Link | None
+		tc_name: DF.Link | None
+		terms: DF.TextEditor | None
+		territory: DF.Link | None
+		title: DF.Data | None
+		total: DF.Currency
+		total_commission: DF.Currency
+		total_net_weight: DF.Float
+		total_qty: DF.Float
+		total_taxes_and_charges: DF.Currency
+		transporter: DF.Link | None
+		transporter_name: DF.Data | None
+		vehicle_no: DF.Data | None
+	# end: auto-generated types
+
 	def __init__(self, *args, **kwargs):
 		super(DeliveryNote, self).__init__(*args, **kwargs)
 		self.status_updater = [
@@ -615,7 +737,7 @@
 		items_list = [item.item_code for item in self.items]
 		return frappe.db.get_all(
 			"Product Bundle",
-			filters={"new_item_code": ["in", items_list]},
+			filters={"new_item_code": ["in", items_list], "disabled": 0},
 			pluck="name",
 		)
 
@@ -842,8 +964,6 @@
 	if automatically_fetch_payment_terms:
 		doc.set_payment_schedule()
 
-	doc.set_onload("ignore_price_list", True)
-
 	return doc
 
 
@@ -938,7 +1058,7 @@
 				},
 				"postprocess": update_item,
 				"condition": lambda item: (
-					not frappe.db.exists("Product Bundle", {"new_item_code": item.item_code})
+					not frappe.db.exists("Product Bundle", {"new_item_code": item.item_code, "disabled": 0})
 					and flt(item.packed_qty) < flt(item.qty)
 				),
 			},
diff --git a/erpnext/stock/doctype/delivery_note/test_delivery_note.py b/erpnext/stock/doctype/delivery_note/test_delivery_note.py
index 137c352..9465574 100644
--- a/erpnext/stock/doctype/delivery_note/test_delivery_note.py
+++ b/erpnext/stock/doctype/delivery_note/test_delivery_note.py
@@ -1247,6 +1247,25 @@
 		dn.reload()
 		self.assertFalse(dn.items[0].target_warehouse)
 
+	def test_serial_no_status(self):
+		from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import make_purchase_receipt
+
+		item = make_item(
+			"Test Serial Item For Status",
+			{"has_serial_no": 1, "is_stock_item": 1, "serial_no_series": "TESTSERIAL.#####"},
+		)
+
+		item_code = item.name
+		pi = make_purchase_receipt(qty=1, item_code=item.name)
+		pi.reload()
+		serial_no = get_serial_nos_from_bundle(pi.items[0].serial_and_batch_bundle)
+
+		self.assertEqual(frappe.db.get_value("Serial No", serial_no, "status"), "Active")
+
+		dn = create_delivery_note(qty=1, item_code=item_code, serial_no=serial_no)
+		dn.reload()
+		self.assertEqual(frappe.db.get_value("Serial No", serial_no, "status"), "Delivered")
+
 
 def create_delivery_note(**args):
 	dn = frappe.new_doc("Delivery Note")
diff --git a/erpnext/stock/doctype/delivery_note_item/delivery_note_item.json b/erpnext/stock/doctype/delivery_note_item/delivery_note_item.json
index 6148950..a44b9ac 100644
--- a/erpnext/stock/doctype/delivery_note_item/delivery_note_item.json
+++ b/erpnext/stock/doctype/delivery_note_item/delivery_note_item.json
@@ -168,6 +168,7 @@
    "width": "300px"
   },
   {
+   "fetch_from": "item_code.image",
    "fieldname": "image",
    "fieldtype": "Attach",
    "hidden": 1,
@@ -893,7 +894,7 @@
  "index_web_pages_for_search": 1,
  "istable": 1,
  "links": [],
- "modified": "2023-10-16 16:18:18.013379",
+ "modified": "2023-11-14 18:37:38.638144",
  "modified_by": "Administrator",
  "module": "Stock",
  "name": "Delivery Note Item",
diff --git a/erpnext/stock/doctype/delivery_note_item/delivery_note_item.py b/erpnext/stock/doctype/delivery_note_item/delivery_note_item.py
index cd0d725..c11c410 100644
--- a/erpnext/stock/doctype/delivery_note_item/delivery_note_item.py
+++ b/erpnext/stock/doctype/delivery_note_item/delivery_note_item.py
@@ -6,4 +6,85 @@
 
 
 class DeliveryNoteItem(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
+
+		actual_batch_qty: DF.Float
+		actual_qty: DF.Float
+		against_sales_invoice: DF.Link | None
+		against_sales_order: DF.Link | None
+		allow_zero_valuation_rate: DF.Check
+		amount: DF.Currency
+		barcode: DF.Data | None
+		base_amount: DF.Currency
+		base_net_amount: DF.Currency
+		base_net_rate: DF.Currency
+		base_price_list_rate: DF.Currency
+		base_rate: DF.Currency
+		base_rate_with_margin: DF.Currency
+		batch_no: DF.Link | None
+		billed_amt: DF.Currency
+		brand: DF.Link | None
+		conversion_factor: DF.Float
+		cost_center: DF.Link | None
+		customer_item_code: DF.Data | None
+		description: DF.TextEditor | None
+		discount_amount: DF.Currency
+		discount_percentage: DF.Float
+		dn_detail: DF.Data | None
+		expense_account: DF.Link | None
+		grant_commission: DF.Check
+		has_item_scanned: DF.Check
+		image: DF.Attach | None
+		incoming_rate: DF.Currency
+		installed_qty: DF.Float
+		is_free_item: DF.Check
+		item_code: DF.Link
+		item_group: DF.Link | None
+		item_name: DF.Data
+		item_tax_rate: DF.SmallText | None
+		item_tax_template: DF.Link | None
+		margin_rate_or_amount: DF.Float
+		margin_type: DF.Literal["", "Percentage", "Amount"]
+		material_request: DF.Link | None
+		material_request_item: DF.Data | None
+		net_amount: DF.Currency
+		net_rate: DF.Currency
+		packed_qty: DF.Float
+		page_break: DF.Check
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		pick_list_item: DF.Data | None
+		price_list_rate: DF.Currency
+		pricing_rules: DF.SmallText | None
+		project: DF.Link | None
+		purchase_order: DF.Link | None
+		purchase_order_item: DF.Data | None
+		qty: DF.Float
+		quality_inspection: DF.Link | None
+		rate: DF.Currency
+		rate_with_margin: DF.Currency
+		received_qty: DF.Float
+		returned_qty: DF.Float
+		serial_and_batch_bundle: DF.Link | None
+		serial_no: DF.Text | None
+		si_detail: DF.Data | None
+		so_detail: DF.Data | None
+		stock_qty: DF.Float
+		stock_uom: DF.Link
+		stock_uom_rate: DF.Currency
+		target_warehouse: DF.Link | None
+		total_weight: DF.Float
+		uom: DF.Link
+		warehouse: DF.Link | None
+		weight_per_unit: DF.Float
+		weight_uom: DF.Link | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/stock/doctype/delivery_settings/delivery_settings.py b/erpnext/stock/doctype/delivery_settings/delivery_settings.py
index ab1ca80..776fbcb 100644
--- a/erpnext/stock/doctype/delivery_settings/delivery_settings.py
+++ b/erpnext/stock/doctype/delivery_settings/delivery_settings.py
@@ -6,4 +6,18 @@
 
 
 class DeliverySettings(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
+
+		dispatch_attachment: DF.Link | None
+		dispatch_template: DF.Link | None
+		send_with_attachment: DF.Check
+		stop_delay: DF.Int
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/stock/doctype/delivery_stop/delivery_stop.py b/erpnext/stock/doctype/delivery_stop/delivery_stop.py
index 9da8bfa..fbfbe94 100644
--- a/erpnext/stock/doctype/delivery_stop/delivery_stop.py
+++ b/erpnext/stock/doctype/delivery_stop/delivery_stop.py
@@ -6,4 +6,33 @@
 
 
 class DeliveryStop(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
+
+		address: DF.Link
+		contact: DF.Link | None
+		customer: DF.Link | None
+		customer_address: DF.SmallText | None
+		customer_contact: DF.SmallText | None
+		delivery_note: DF.Link | None
+		details: DF.TextEditor | None
+		distance: DF.Float
+		email_sent_to: DF.Data | None
+		estimated_arrival: DF.Datetime | None
+		grand_total: DF.Currency
+		lat: DF.Float
+		lng: DF.Float
+		locked: DF.Check
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		uom: DF.Link | None
+		visited: DF.Check
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/stock/doctype/delivery_trip/delivery_trip.py b/erpnext/stock/doctype/delivery_trip/delivery_trip.py
index c531a87..cb9fc5b 100644
--- a/erpnext/stock/doctype/delivery_trip/delivery_trip.py
+++ b/erpnext/stock/doctype/delivery_trip/delivery_trip.py
@@ -12,6 +12,33 @@
 
 
 class DeliveryTrip(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
+
+		from erpnext.stock.doctype.delivery_stop.delivery_stop import DeliveryStop
+
+		amended_from: DF.Link | None
+		company: DF.Link
+		delivery_stops: DF.Table[DeliveryStop]
+		departure_time: DF.Datetime
+		driver: DF.Link | None
+		driver_address: DF.Link | None
+		driver_email: DF.Data | None
+		driver_name: DF.Data | None
+		email_notification_sent: DF.Check
+		employee: DF.Link | None
+		naming_series: DF.Literal["MAT-DT-.YYYY.-"]
+		status: DF.Literal["Draft", "Scheduled", "In Transit", "Completed", "Cancelled"]
+		total_distance: DF.Float
+		uom: DF.Link | None
+		vehicle: DF.Link
+	# end: auto-generated types
+
 	def __init__(self, *args, **kwargs):
 		super(DeliveryTrip, self).__init__(*args, **kwargs)
 
diff --git a/erpnext/stock/doctype/inventory_dimension/inventory_dimension.py b/erpnext/stock/doctype/inventory_dimension/inventory_dimension.py
index 257d18f..60624d4 100644
--- a/erpnext/stock/doctype/inventory_dimension/inventory_dimension.py
+++ b/erpnext/stock/doctype/inventory_dimension/inventory_dimension.py
@@ -20,6 +20,30 @@
 
 
 class InventoryDimension(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
+
+		apply_to_all_doctypes: DF.Check
+		condition: DF.Code | None
+		dimension_name: DF.Data
+		disabled: DF.Check
+		document_type: DF.Link | None
+		fetch_from_parent: DF.Literal
+		istable: DF.Check
+		mandatory_depends_on: DF.SmallText | None
+		reference_document: DF.Link
+		reqd: DF.Check
+		source_fieldname: DF.Data | None
+		target_fieldname: DF.Data | None
+		type_of_transaction: DF.Literal["", "Inward", "Outward", "Both"]
+		validate_negative_stock: DF.Check
+	# end: auto-generated types
+
 	def onload(self):
 		if not self.is_new() and frappe.db.has_column("Stock Ledger Entry", self.target_fieldname):
 			self.set_onload("has_stock_ledger", self.has_stock_ledger())
diff --git a/erpnext/stock/doctype/item/item.json b/erpnext/stock/doctype/item/item.json
index c13d3eb..13f3be8 100644
--- a/erpnext/stock/doctype/item/item.json
+++ b/erpnext/stock/doctype/item/item.json
@@ -504,7 +504,7 @@
    "fieldtype": "Table",
    "hidden": 1,
    "label": "Variant Attributes",
-   "mandatory_depends_on": "has_variants",
+   "mandatory_depends_on": "eval:(doc.has_variants || doc.variant_of) && doc.variant_based_on==='Item Attribute'",
    "options": "Item Variant Attribute"
   },
   {
@@ -888,7 +888,7 @@
  "index_web_pages_for_search": 1,
  "links": [],
  "make_attachments_public": 1,
- "modified": "2023-09-11 13:46:32.688051",
+ "modified": "2023-09-18 15:41:32.688051",
  "modified_by": "Administrator",
  "module": "Stock",
  "name": "Item",
diff --git a/erpnext/stock/doctype/item/item.py b/erpnext/stock/doctype/item/item.py
index d8935fe..2d9e11a 100644
--- a/erpnext/stock/doctype/item/item.py
+++ b/erpnext/stock/doctype/item/item.py
@@ -52,6 +52,106 @@
 
 
 class Item(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
+
+		from erpnext.stock.doctype.item_barcode.item_barcode import ItemBarcode
+		from erpnext.stock.doctype.item_customer_detail.item_customer_detail import ItemCustomerDetail
+		from erpnext.stock.doctype.item_default.item_default import ItemDefault
+		from erpnext.stock.doctype.item_reorder.item_reorder import ItemReorder
+		from erpnext.stock.doctype.item_supplier.item_supplier import ItemSupplier
+		from erpnext.stock.doctype.item_tax.item_tax import ItemTax
+		from erpnext.stock.doctype.item_variant_attribute.item_variant_attribute import (
+			ItemVariantAttribute,
+		)
+		from erpnext.stock.doctype.uom_conversion_detail.uom_conversion_detail import UOMConversionDetail
+
+		allow_alternative_item: DF.Check
+		allow_negative_stock: DF.Check
+		asset_category: DF.Link | None
+		asset_naming_series: DF.Literal
+		attributes: DF.Table[ItemVariantAttribute]
+		auto_create_assets: DF.Check
+		barcodes: DF.Table[ItemBarcode]
+		batch_number_series: DF.Data | None
+		brand: DF.Link | None
+		country_of_origin: DF.Link | None
+		create_new_batch: DF.Check
+		customer: DF.Link | None
+		customer_code: DF.SmallText | None
+		customer_items: DF.Table[ItemCustomerDetail]
+		customs_tariff_number: DF.Link | None
+		default_bom: DF.Link | None
+		default_item_manufacturer: DF.Link | None
+		default_manufacturer_part_no: DF.Data | None
+		default_material_request_type: DF.Literal[
+			"Purchase", "Material Transfer", "Material Issue", "Manufacture", "Customer Provided"
+		]
+		delivered_by_supplier: DF.Check
+		description: DF.TextEditor | None
+		disabled: DF.Check
+		enable_deferred_expense: DF.Check
+		enable_deferred_revenue: DF.Check
+		end_of_life: DF.Date | None
+		grant_commission: DF.Check
+		has_batch_no: DF.Check
+		has_expiry_date: DF.Check
+		has_serial_no: DF.Check
+		has_variants: DF.Check
+		image: DF.AttachImage | None
+		include_item_in_manufacturing: DF.Check
+		inspection_required_before_delivery: DF.Check
+		inspection_required_before_purchase: DF.Check
+		is_customer_provided_item: DF.Check
+		is_fixed_asset: DF.Check
+		is_grouped_asset: DF.Check
+		is_purchase_item: DF.Check
+		is_sales_item: DF.Check
+		is_stock_item: DF.Check
+		is_sub_contracted_item: DF.Check
+		item_code: DF.Data
+		item_defaults: DF.Table[ItemDefault]
+		item_group: DF.Link
+		item_name: DF.Data | None
+		last_purchase_rate: DF.Float
+		lead_time_days: DF.Int
+		max_discount: DF.Float
+		min_order_qty: DF.Float
+		naming_series: DF.Literal["STO-ITEM-.YYYY.-"]
+		no_of_months: DF.Int
+		no_of_months_exp: DF.Int
+		opening_stock: DF.Float
+		over_billing_allowance: DF.Float
+		over_delivery_receipt_allowance: DF.Float
+		purchase_uom: DF.Link | None
+		quality_inspection_template: DF.Link | None
+		reorder_levels: DF.Table[ItemReorder]
+		retain_sample: DF.Check
+		safety_stock: DF.Float
+		sales_uom: DF.Link | None
+		sample_quantity: DF.Int
+		serial_no_series: DF.Data | None
+		shelf_life_in_days: DF.Int
+		standard_rate: DF.Currency
+		stock_uom: DF.Link
+		supplier_items: DF.Table[ItemSupplier]
+		taxes: DF.Table[ItemTax]
+		total_projected_qty: DF.Float
+		uoms: DF.Table[UOMConversionDetail]
+		valuation_method: DF.Literal["", "FIFO", "Moving Average", "LIFO"]
+		valuation_rate: DF.Currency
+		variant_based_on: DF.Literal["Item Attribute", "Manufacturer"]
+		variant_of: DF.Link | None
+		warranty_period: DF.Data | None
+		weight_per_unit: DF.Float
+		weight_uom: DF.Link | None
+	# end: auto-generated types
+
 	def onload(self):
 		self.set_onload("stock_exists", self.stock_ledger_created())
 		self.set_onload("asset_naming_series", get_asset_naming_series())
@@ -512,8 +612,12 @@
 
 	def validate_duplicate_product_bundles_before_merge(self, old_name, new_name):
 		"Block merge if both old and new items have product bundles."
-		old_bundle = frappe.get_value("Product Bundle", filters={"new_item_code": old_name})
-		new_bundle = frappe.get_value("Product Bundle", filters={"new_item_code": new_name})
+		old_bundle = frappe.get_value(
+			"Product Bundle", filters={"new_item_code": old_name, "disabled": 0}
+		)
+		new_bundle = frappe.get_value(
+			"Product Bundle", filters={"new_item_code": new_name, "disabled": 0}
+		)
 
 		if old_bundle and new_bundle:
 			bundle_link = get_link_to_form("Product Bundle", old_bundle)
diff --git a/erpnext/stock/doctype/item_alternative/item_alternative.py b/erpnext/stock/doctype/item_alternative/item_alternative.py
index 0c24d3c..83bee9c 100644
--- a/erpnext/stock/doctype/item_alternative/item_alternative.py
+++ b/erpnext/stock/doctype/item_alternative/item_alternative.py
@@ -8,6 +8,21 @@
 
 
 class ItemAlternative(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
+
+		alternative_item_code: DF.Link | None
+		alternative_item_name: DF.ReadOnly | None
+		item_code: DF.Link | None
+		item_name: DF.ReadOnly | None
+		two_way: DF.Check
+	# end: auto-generated types
+
 	def validate(self):
 		self.has_alternative_item()
 		self.validate_alternative_item()
diff --git a/erpnext/stock/doctype/item_attribute/item_attribute.py b/erpnext/stock/doctype/item_attribute/item_attribute.py
index ac4c313..7b341b2 100644
--- a/erpnext/stock/doctype/item_attribute/item_attribute.py
+++ b/erpnext/stock/doctype/item_attribute/item_attribute.py
@@ -19,6 +19,24 @@
 
 
 class ItemAttribute(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
+
+		from erpnext.stock.doctype.item_attribute_value.item_attribute_value import ItemAttributeValue
+
+		attribute_name: DF.Data
+		from_range: DF.Float
+		increment: DF.Float
+		item_attribute_values: DF.Table[ItemAttributeValue]
+		numeric_values: DF.Check
+		to_range: DF.Float
+	# end: auto-generated types
+
 	def __setup__(self):
 		self.flags.ignore_these_exceptions_in_test = [InvalidItemAttributeValueError]
 
diff --git a/erpnext/stock/doctype/item_attribute_value/item_attribute_value.py b/erpnext/stock/doctype/item_attribute_value/item_attribute_value.py
index bc6fb4f..0ddc867 100644
--- a/erpnext/stock/doctype/item_attribute_value/item_attribute_value.py
+++ b/erpnext/stock/doctype/item_attribute_value/item_attribute_value.py
@@ -6,4 +6,19 @@
 
 
 class ItemAttributeValue(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
+
+		abbr: DF.Data
+		attribute_value: DF.Data
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/stock/doctype/item_barcode/item_barcode.py b/erpnext/stock/doctype/item_barcode/item_barcode.py
index c2c0421..e38b95b 100644
--- a/erpnext/stock/doctype/item_barcode/item_barcode.py
+++ b/erpnext/stock/doctype/item_barcode/item_barcode.py
@@ -6,4 +6,36 @@
 
 
 class ItemBarcode(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
+
+		barcode: DF.Data
+		barcode_type: DF.Literal[
+			"",
+			"EAN",
+			"UPC-A",
+			"CODE-39",
+			"EAN-12",
+			"EAN-8",
+			"GS1",
+			"GTIN",
+			"ISBN",
+			"ISBN-10",
+			"ISBN-13",
+			"ISSN",
+			"JAN",
+			"PZN",
+			"UPC",
+		]
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		uom: DF.Link | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/stock/doctype/item_customer_detail/item_customer_detail.py b/erpnext/stock/doctype/item_customer_detail/item_customer_detail.py
index ba81b44..b0978e3 100644
--- a/erpnext/stock/doctype/item_customer_detail/item_customer_detail.py
+++ b/erpnext/stock/doctype/item_customer_detail/item_customer_detail.py
@@ -6,4 +6,20 @@
 
 
 class ItemCustomerDetail(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
+
+		customer_group: DF.Link | None
+		customer_name: DF.Link | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		ref_code: DF.Data
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/stock/doctype/item_default/item_default.py b/erpnext/stock/doctype/item_default/item_default.py
index 8a9693e..10dae2b 100644
--- a/erpnext/stock/doctype/item_default/item_default.py
+++ b/erpnext/stock/doctype/item_default/item_default.py
@@ -6,4 +6,29 @@
 
 
 class ItemDefault(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
+
+		buying_cost_center: DF.Link | None
+		company: DF.Link
+		default_discount_account: DF.Link | None
+		default_price_list: DF.Link | None
+		default_provisional_account: DF.Link | None
+		default_supplier: DF.Link | None
+		default_warehouse: DF.Link | None
+		deferred_expense_account: DF.Link | None
+		deferred_revenue_account: DF.Link | None
+		expense_account: DF.Link | None
+		income_account: DF.Link | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		selling_cost_center: DF.Link | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/stock/doctype/item_manufacturer/item_manufacturer.py b/erpnext/stock/doctype/item_manufacturer/item_manufacturer.py
index b65ba98..ed004d5 100644
--- a/erpnext/stock/doctype/item_manufacturer/item_manufacturer.py
+++ b/erpnext/stock/doctype/item_manufacturer/item_manufacturer.py
@@ -8,6 +8,22 @@
 
 
 class ItemManufacturer(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
+
+		description: DF.SmallText | None
+		is_default: DF.Check
+		item_code: DF.Link
+		item_name: DF.Data | None
+		manufacturer: DF.Link
+		manufacturer_part_no: DF.Data
+	# end: auto-generated types
+
 	def validate(self):
 		self.validate_duplicate_entry()
 		self.manage_default_item_manufacturer()
diff --git a/erpnext/stock/doctype/item_price/item_price.py b/erpnext/stock/doctype/item_price/item_price.py
index 54d1ae6..89a130a 100644
--- a/erpnext/stock/doctype/item_price/item_price.py
+++ b/erpnext/stock/doctype/item_price/item_price.py
@@ -15,6 +15,35 @@
 
 
 class ItemPrice(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
+
+		batch_no: DF.Link | None
+		brand: DF.Link | None
+		buying: DF.Check
+		currency: DF.Link | None
+		customer: DF.Link | None
+		item_code: DF.Link
+		item_description: DF.Text | None
+		item_name: DF.Data | None
+		lead_time_days: DF.Int
+		note: DF.Text | None
+		packing_unit: DF.Int
+		price_list: DF.Link
+		price_list_rate: DF.Currency
+		reference: DF.Data | None
+		selling: DF.Check
+		supplier: DF.Link | None
+		uom: DF.Link | None
+		valid_from: DF.Date | None
+		valid_upto: DF.Date | None
+	# end: auto-generated types
+
 	def validate(self):
 		self.validate_item()
 		self.validate_dates()
diff --git a/erpnext/stock/doctype/item_quality_inspection_parameter/item_quality_inspection_parameter.py b/erpnext/stock/doctype/item_quality_inspection_parameter/item_quality_inspection_parameter.py
index 6cadb99..b6ade8a 100644
--- a/erpnext/stock/doctype/item_quality_inspection_parameter/item_quality_inspection_parameter.py
+++ b/erpnext/stock/doctype/item_quality_inspection_parameter/item_quality_inspection_parameter.py
@@ -6,4 +6,25 @@
 
 
 class ItemQualityInspectionParameter(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
+
+		acceptance_formula: DF.Code | None
+		formula_based_criteria: DF.Check
+		max_value: DF.Float
+		min_value: DF.Float
+		numeric: DF.Check
+		parameter_group: DF.Link | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		specification: DF.Link
+		value: DF.Data | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/stock/doctype/item_reorder/item_reorder.py b/erpnext/stock/doctype/item_reorder/item_reorder.py
index c3cc69b..94f92f2 100644
--- a/erpnext/stock/doctype/item_reorder/item_reorder.py
+++ b/erpnext/stock/doctype/item_reorder/item_reorder.py
@@ -8,4 +8,22 @@
 
 
 class ItemReorder(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
+
+		material_request_type: DF.Literal["Purchase", "Transfer", "Material Issue", "Manufacture"]
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		warehouse: DF.Link
+		warehouse_group: DF.Link | None
+		warehouse_reorder_level: DF.Float
+		warehouse_reorder_qty: DF.Float
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/stock/doctype/item_supplier/item_supplier.py b/erpnext/stock/doctype/item_supplier/item_supplier.py
index 84f5556..955aea3 100644
--- a/erpnext/stock/doctype/item_supplier/item_supplier.py
+++ b/erpnext/stock/doctype/item_supplier/item_supplier.py
@@ -6,4 +6,19 @@
 
 
 class ItemSupplier(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
+
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		supplier: DF.Link
+		supplier_part_no: DF.Data | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/stock/doctype/item_tax/item_tax.py b/erpnext/stock/doctype/item_tax/item_tax.py
index aa82719..4b8adb9 100644
--- a/erpnext/stock/doctype/item_tax/item_tax.py
+++ b/erpnext/stock/doctype/item_tax/item_tax.py
@@ -6,4 +6,22 @@
 
 
 class ItemTax(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
+
+		item_tax_template: DF.Link
+		maximum_net_rate: DF.Float
+		minimum_net_rate: DF.Float
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		tax_category: DF.Link | None
+		valid_from: DF.Date | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/stock/doctype/item_variant/item_variant.py b/erpnext/stock/doctype/item_variant/item_variant.py
index f1580fc..94db29e 100644
--- a/erpnext/stock/doctype/item_variant/item_variant.py
+++ b/erpnext/stock/doctype/item_variant/item_variant.py
@@ -6,4 +6,19 @@
 
 
 class ItemVariant(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
+
+		item_attribute: DF.Link
+		item_attribute_value: DF.Data
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/stock/doctype/item_variant_attribute/item_variant_attribute.py b/erpnext/stock/doctype/item_variant_attribute/item_variant_attribute.py
index 76b88b8..756b742 100644
--- a/erpnext/stock/doctype/item_variant_attribute/item_variant_attribute.py
+++ b/erpnext/stock/doctype/item_variant_attribute/item_variant_attribute.py
@@ -6,4 +6,24 @@
 
 
 class ItemVariantAttribute(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
+
+		attribute: DF.Link
+		attribute_value: DF.Data | None
+		from_range: DF.Float
+		increment: DF.Float
+		numeric_values: DF.Check
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		to_range: DF.Float
+		variant_of: DF.Link | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/stock/doctype/item_variant_settings/item_variant_settings.py b/erpnext/stock/doctype/item_variant_settings/item_variant_settings.py
index c3edba3..a4bdc0b 100644
--- a/erpnext/stock/doctype/item_variant_settings/item_variant_settings.py
+++ b/erpnext/stock/doctype/item_variant_settings/item_variant_settings.py
@@ -8,6 +8,21 @@
 
 
 class ItemVariantSettings(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
+
+		from erpnext.stock.doctype.variant_field.variant_field import VariantField
+
+		allow_rename_attribute_value: DF.Check
+		do_not_update_variants: DF.Check
+		fields: DF.Table[VariantField]
+	# end: auto-generated types
+
 	invalid_fields_for_copy_fields_in_variants = ["barcodes"]
 
 	def set_default_fields(self):
diff --git a/erpnext/stock/doctype/item_website_specification/item_website_specification.py b/erpnext/stock/doctype/item_website_specification/item_website_specification.py
index af9612c..7ac02f6 100644
--- a/erpnext/stock/doctype/item_website_specification/item_website_specification.py
+++ b/erpnext/stock/doctype/item_website_specification/item_website_specification.py
@@ -8,4 +8,19 @@
 
 
 class ItemWebsiteSpecification(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
+
+		description: DF.TextEditor | None
+		label: DF.Data | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/stock/doctype/landed_cost_item/landed_cost_item.py b/erpnext/stock/doctype/landed_cost_item/landed_cost_item.py
index 35a3740..67f695a 100644
--- a/erpnext/stock/doctype/landed_cost_item/landed_cost_item.py
+++ b/erpnext/stock/doctype/landed_cost_item/landed_cost_item.py
@@ -6,4 +6,28 @@
 
 
 class LandedCostItem(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
+
+		amount: DF.Currency
+		applicable_charges: DF.Currency
+		cost_center: DF.Link | None
+		description: DF.TextEditor
+		is_fixed_asset: DF.Check
+		item_code: DF.Link
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		purchase_receipt_item: DF.Data | None
+		qty: DF.Float
+		rate: DF.Currency
+		receipt_document: DF.DynamicLink | None
+		receipt_document_type: DF.Literal["Purchase Invoice", "Purchase Receipt"]
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/stock/doctype/landed_cost_purchase_receipt/landed_cost_purchase_receipt.py b/erpnext/stock/doctype/landed_cost_purchase_receipt/landed_cost_purchase_receipt.py
index f5bbc4a..9f0ffb8 100644
--- a/erpnext/stock/doctype/landed_cost_purchase_receipt/landed_cost_purchase_receipt.py
+++ b/erpnext/stock/doctype/landed_cost_purchase_receipt/landed_cost_purchase_receipt.py
@@ -6,4 +6,22 @@
 
 
 class LandedCostPurchaseReceipt(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
+
+		grand_total: DF.Currency
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		posting_date: DF.Date | None
+		receipt_document: DF.DynamicLink
+		receipt_document_type: DF.Literal["", "Purchase Invoice", "Purchase Receipt"]
+		supplier: DF.Link | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/stock/doctype/landed_cost_taxes_and_charges/landed_cost_taxes_and_charges.py b/erpnext/stock/doctype/landed_cost_taxes_and_charges/landed_cost_taxes_and_charges.py
index a4a1c58..8509cb7 100644
--- a/erpnext/stock/doctype/landed_cost_taxes_and_charges/landed_cost_taxes_and_charges.py
+++ b/erpnext/stock/doctype/landed_cost_taxes_and_charges/landed_cost_taxes_and_charges.py
@@ -6,4 +6,23 @@
 
 
 class LandedCostTaxesandCharges(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_currency: DF.Link | None
+		amount: DF.Currency
+		base_amount: DF.Currency
+		description: DF.SmallText
+		exchange_rate: DF.Float
+		expense_account: DF.Link | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py b/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py
index 8bbc660..30b26a0 100644
--- a/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py
+++ b/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py
@@ -15,6 +15,33 @@
 
 
 class LandedCostVoucher(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
+
+		from erpnext.stock.doctype.landed_cost_item.landed_cost_item import LandedCostItem
+		from erpnext.stock.doctype.landed_cost_purchase_receipt.landed_cost_purchase_receipt import (
+			LandedCostPurchaseReceipt,
+		)
+		from erpnext.stock.doctype.landed_cost_taxes_and_charges.landed_cost_taxes_and_charges import (
+			LandedCostTaxesandCharges,
+		)
+
+		amended_from: DF.Link | None
+		company: DF.Link
+		distribute_charges_based_on: DF.Literal["Qty", "Amount", "Distribute Manually"]
+		items: DF.Table[LandedCostItem]
+		naming_series: DF.Literal["MAT-LCV-.YYYY.-"]
+		posting_date: DF.Date
+		purchase_receipts: DF.Table[LandedCostPurchaseReceipt]
+		taxes: DF.Table[LandedCostTaxesandCharges]
+		total_taxes_and_charges: DF.Currency
+	# end: auto-generated types
+
 	@frappe.whitelist()
 	def get_items_from_purchase_receipts(self):
 		self.set("items", [])
diff --git a/erpnext/stock/doctype/manufacturer/manufacturer.py b/erpnext/stock/doctype/manufacturer/manufacturer.py
index 426affc..5e559d0 100644
--- a/erpnext/stock/doctype/manufacturer/manufacturer.py
+++ b/erpnext/stock/doctype/manufacturer/manufacturer.py
@@ -7,6 +7,22 @@
 
 
 class Manufacturer(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
+
+		country: DF.Link | None
+		full_name: DF.Data | None
+		logo: DF.AttachImage | None
+		notes: DF.SmallText | None
+		short_name: DF.Data
+		website: DF.Data | None
+	# end: auto-generated types
+
 	def onload(self):
 		"""Load address and contacts in `__onload`"""
 		load_address_and_contact(self)
diff --git a/erpnext/stock/doctype/material_request/material_request.py b/erpnext/stock/doctype/material_request/material_request.py
index ecdec80..7df74f8 100644
--- a/erpnext/stock/doctype/material_request/material_request.py
+++ b/erpnext/stock/doctype/material_request/material_request.py
@@ -23,6 +23,55 @@
 
 
 class MaterialRequest(BuyingController):
+	# 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
+
+		from erpnext.stock.doctype.material_request_item.material_request_item import MaterialRequestItem
+
+		amended_from: DF.Link | None
+		company: DF.Link
+		customer: DF.Link | None
+		items: DF.Table[MaterialRequestItem]
+		job_card: DF.Link | None
+		letter_head: DF.Link | None
+		material_request_type: DF.Literal[
+			"Purchase", "Material Transfer", "Material Issue", "Manufacture", "Customer Provided"
+		]
+		naming_series: DF.Literal["MAT-MR-.YYYY.-"]
+		per_ordered: DF.Percent
+		per_received: DF.Percent
+		scan_barcode: DF.Data | None
+		schedule_date: DF.Date | None
+		select_print_heading: DF.Link | None
+		set_from_warehouse: DF.Link | None
+		set_warehouse: DF.Link | None
+		status: DF.Literal[
+			"",
+			"Draft",
+			"Submitted",
+			"Stopped",
+			"Cancelled",
+			"Pending",
+			"Partially Ordered",
+			"Partially Received",
+			"Ordered",
+			"Issued",
+			"Transferred",
+			"Received",
+		]
+		tc_name: DF.Link | None
+		terms: DF.TextEditor | None
+		title: DF.Data | None
+		transaction_date: DF.Date
+		transfer_status: DF.Literal["", "Not Started", "In Transit", "Completed"]
+		work_order: DF.Link | None
+	# end: auto-generated types
+
 	def check_if_already_pulled(self):
 		pass
 
diff --git a/erpnext/stock/doctype/material_request_item/material_request_item.json b/erpnext/stock/doctype/material_request_item/material_request_item.json
index 9912be1..5dc07c9 100644
--- a/erpnext/stock/doctype/material_request_item/material_request_item.json
+++ b/erpnext/stock/doctype/material_request_item/material_request_item.json
@@ -110,6 +110,7 @@
    "width": "250px"
   },
   {
+   "fetch_from": "item_code.image",
    "fieldname": "image",
    "fieldtype": "Attach Image",
    "label": "Image",
@@ -478,7 +479,7 @@
  "index_web_pages_for_search": 1,
  "istable": 1,
  "links": [],
- "modified": "2023-10-27 15:53:41.444236",
+ "modified": "2023-11-14 18:37:59.599115",
  "modified_by": "Administrator",
  "module": "Stock",
  "name": "Material Request Item",
diff --git a/erpnext/stock/doctype/material_request_item/material_request_item.py b/erpnext/stock/doctype/material_request_item/material_request_item.py
index 08c9ed2..2bed596 100644
--- a/erpnext/stock/doctype/material_request_item/material_request_item.py
+++ b/erpnext/stock/doctype/material_request_item/material_request_item.py
@@ -9,6 +9,54 @@
 
 
 class MaterialRequestItem(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
+
+		actual_qty: DF.Float
+		amount: DF.Currency
+		bom_no: DF.Link | None
+		brand: DF.Link | None
+		conversion_factor: DF.Float
+		cost_center: DF.Link | None
+		description: DF.TextEditor | None
+		expense_account: DF.Link | None
+		from_warehouse: DF.Link | None
+		image: DF.AttachImage | None
+		item_code: DF.Link
+		item_group: DF.Link | None
+		item_name: DF.Data | None
+		job_card_item: DF.Data | None
+		lead_time_date: DF.Date | None
+		manufacturer: DF.Link | None
+		manufacturer_part_no: DF.Data | None
+		material_request_plan_item: DF.Data | None
+		min_order_qty: DF.Float
+		ordered_qty: DF.Float
+		page_break: DF.Check
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		production_plan: DF.Link | None
+		project: DF.Link | None
+		projected_qty: DF.Float
+		qty: DF.Float
+		rate: DF.Currency
+		received_qty: DF.Float
+		sales_order: DF.Link | None
+		sales_order_item: DF.Data | None
+		schedule_date: DF.Date
+		stock_qty: DF.Float
+		stock_uom: DF.Link
+		uom: DF.Link
+		warehouse: DF.Link | None
+		wip_composite_asset: DF.Link | None
+	# end: auto-generated types
+
 	pass
 
 
diff --git a/erpnext/stock/doctype/packed_item/packed_item.py b/erpnext/stock/doctype/packed_item/packed_item.py
index a9e9ad1..ed667c2 100644
--- a/erpnext/stock/doctype/packed_item/packed_item.py
+++ b/erpnext/stock/doctype/packed_item/packed_item.py
@@ -14,6 +14,42 @@
 
 
 class PackedItem(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
+
+		actual_batch_qty: DF.Float
+		actual_qty: DF.Float
+		batch_no: DF.Link | None
+		conversion_factor: DF.Float
+		description: DF.TextEditor | None
+		incoming_rate: DF.Currency
+		item_code: DF.Link | None
+		item_name: DF.Data | None
+		ordered_qty: DF.Float
+		packed_qty: DF.Float
+		page_break: DF.Check
+		parent: DF.Data
+		parent_detail_docname: DF.Data | None
+		parent_item: DF.Link | None
+		parentfield: DF.Data
+		parenttype: DF.Data
+		picked_qty: DF.Float
+		prevdoc_doctype: DF.Data | None
+		projected_qty: DF.Float
+		qty: DF.Float
+		rate: DF.Currency
+		serial_and_batch_bundle: DF.Link | None
+		serial_no: DF.Text | None
+		target_warehouse: DF.Link | None
+		uom: DF.Link | None
+		warehouse: DF.Link | None
+	# end: auto-generated types
+
 	pass
 
 
@@ -55,7 +91,7 @@
 
 
 def is_product_bundle(item_code: str) -> bool:
-	return bool(frappe.db.exists("Product Bundle", {"new_item_code": item_code}))
+	return bool(frappe.db.exists("Product Bundle", {"new_item_code": item_code, "disabled": 0}))
 
 
 def get_indexed_packed_items_table(doc):
@@ -111,7 +147,7 @@
 			product_bundle_item.uom,
 			product_bundle_item.description,
 		)
-		.where(product_bundle.new_item_code == item_code)
+		.where((product_bundle.new_item_code == item_code) & (product_bundle.disabled == 0))
 		.orderby(product_bundle_item.idx)
 	)
 	return query.run(as_dict=True)
diff --git a/erpnext/stock/doctype/packing_slip/packing_slip.py b/erpnext/stock/doctype/packing_slip/packing_slip.py
index 6ea5938..88acfe8 100644
--- a/erpnext/stock/doctype/packing_slip/packing_slip.py
+++ b/erpnext/stock/doctype/packing_slip/packing_slip.py
@@ -10,6 +10,29 @@
 
 
 class PackingSlip(StatusUpdater):
+	# 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
+
+		from erpnext.stock.doctype.packing_slip_item.packing_slip_item import PackingSlipItem
+
+		amended_from: DF.Link | None
+		delivery_note: DF.Link
+		from_case_no: DF.Int
+		gross_weight_pkg: DF.Float
+		gross_weight_uom: DF.Link | None
+		items: DF.Table[PackingSlipItem]
+		letter_head: DF.Link | None
+		naming_series: DF.Literal["MAT-PAC-.YYYY.-"]
+		net_weight_pkg: DF.Float
+		net_weight_uom: DF.Link | None
+		to_case_no: DF.Int
+	# end: auto-generated types
+
 	def __init__(self, *args, **kwargs) -> None:
 		super(PackingSlip, self).__init__(*args, **kwargs)
 		self.status_updater = [
diff --git a/erpnext/stock/doctype/packing_slip_item/packing_slip_item.py b/erpnext/stock/doctype/packing_slip_item/packing_slip_item.py
index ec148aa..fa883c1 100644
--- a/erpnext/stock/doctype/packing_slip_item/packing_slip_item.py
+++ b/erpnext/stock/doctype/packing_slip_item/packing_slip_item.py
@@ -8,4 +8,28 @@
 
 
 class PackingSlipItem(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
+
+		batch_no: DF.Link | None
+		description: DF.TextEditor | None
+		dn_detail: DF.Data | None
+		item_code: DF.Link
+		item_name: DF.Data | None
+		net_weight: DF.Float
+		page_break: DF.Check
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		pi_detail: DF.Data | None
+		qty: DF.Float
+		stock_uom: DF.Link | None
+		weight_uom: DF.Link | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/stock/doctype/pick_list/pick_list.py b/erpnext/stock/doctype/pick_list/pick_list.py
index ed20209..545e45f 100644
--- a/erpnext/stock/doctype/pick_list/pick_list.py
+++ b/erpnext/stock/doctype/pick_list/pick_list.py
@@ -29,6 +29,34 @@
 
 
 class PickList(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
+
+		from erpnext.stock.doctype.pick_list_item.pick_list_item import PickListItem
+
+		amended_from: DF.Link | None
+		company: DF.Link
+		customer: DF.Link | None
+		customer_name: DF.Data | None
+		for_qty: DF.Float
+		group_same_items: DF.Check
+		locations: DF.Table[PickListItem]
+		material_request: DF.Link | None
+		naming_series: DF.Literal["STO-PICK-.YYYY.-"]
+		parent_warehouse: DF.Link | None
+		prompt_qty: DF.Check
+		purpose: DF.Literal["Material Transfer for Manufacture", "Material Transfer", "Delivery"]
+		scan_barcode: DF.Data | None
+		scan_mode: DF.Check
+		status: DF.Literal["Draft", "Open", "Completed", "Cancelled"]
+		work_order: DF.Link | None
+	# end: auto-generated types
+
 	def onload(self) -> None:
 		if frappe.get_cached_value("Stock Settings", None, "enable_stock_reservation"):
 			if self.has_unreserved_stock():
@@ -233,7 +261,7 @@
 		for location in self.locations:
 			if location.warehouse and location.sales_order and location.sales_order_item:
 				item_details = {
-					"name": location.sales_order_item,
+					"sales_order_item": location.sales_order_item,
 					"item_code": location.item_code,
 					"warehouse": location.warehouse,
 					"qty_to_reserve": (flt(location.picked_qty) - flt(location.stock_reserved_qty)),
@@ -368,7 +396,9 @@
 				frappe.throw("Row #{0}: Item Code is Mandatory".format(item.idx))
 			if not cint(
 				frappe.get_cached_value("Item", item.item_code, "is_stock_item")
-			) and not frappe.db.exists("Product Bundle", {"new_item_code": item.item_code}):
+			) and not frappe.db.exists(
+				"Product Bundle", {"new_item_code": item.item_code, "disabled": 0}
+			):
 				continue
 			item_code = item.item_code
 			reference = item.sales_order_item or item.material_request_item
@@ -507,7 +537,9 @@
 		# bundle_item_code: Dict[component, qty]
 		product_bundle_qty_map = {}
 		for bundle_item_code in bundles:
-			bundle = frappe.get_last_doc("Product Bundle", {"new_item_code": bundle_item_code})
+			bundle = frappe.get_last_doc(
+				"Product Bundle", {"new_item_code": bundle_item_code, "disabled": 0}
+			)
 			product_bundle_qty_map[bundle_item_code] = {item.item_code: item.qty for item in bundle.items}
 		return product_bundle_qty_map
 
diff --git a/erpnext/stock/doctype/pick_list_item/pick_list_item.py b/erpnext/stock/doctype/pick_list_item/pick_list_item.py
index 6ecccb1..6e5a94e 100644
--- a/erpnext/stock/doctype/pick_list_item/pick_list_item.py
+++ b/erpnext/stock/doctype/pick_list_item/pick_list_item.py
@@ -7,4 +7,37 @@
 
 
 class PickListItem(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
+
+		batch_no: DF.Link | None
+		conversion_factor: DF.Float
+		description: DF.Text | None
+		item_code: DF.Link
+		item_group: DF.Data | None
+		item_name: DF.Data | None
+		material_request: DF.Link | None
+		material_request_item: DF.Data | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		picked_qty: DF.Float
+		product_bundle_item: DF.Data | None
+		qty: DF.Float
+		sales_order: DF.Link | None
+		sales_order_item: DF.Data | None
+		serial_and_batch_bundle: DF.Link | None
+		serial_no: DF.SmallText | None
+		stock_qty: DF.Float
+		stock_reserved_qty: DF.Float
+		stock_uom: DF.Link | None
+		uom: DF.Link | None
+		warehouse: DF.Link | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/stock/doctype/price_list/price_list.py b/erpnext/stock/doctype/price_list/price_list.py
index 21c0f18..580c7c0 100644
--- a/erpnext/stock/doctype/price_list/price_list.py
+++ b/erpnext/stock/doctype/price_list/price_list.py
@@ -9,6 +9,25 @@
 
 
 class PriceList(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
+
+		from erpnext.stock.doctype.price_list_country.price_list_country import PriceListCountry
+
+		buying: DF.Check
+		countries: DF.Table[PriceListCountry]
+		currency: DF.Link
+		enabled: DF.Check
+		price_list_name: DF.Data
+		price_not_uom_dependent: DF.Check
+		selling: DF.Check
+	# end: auto-generated types
+
 	def validate(self):
 		if not cint(self.buying) and not cint(self.selling):
 			throw(_("Price List must be applicable for Buying or Selling"))
diff --git a/erpnext/stock/doctype/price_list_country/price_list_country.py b/erpnext/stock/doctype/price_list_country/price_list_country.py
index 94e1107..574d7e0 100644
--- a/erpnext/stock/doctype/price_list_country/price_list_country.py
+++ b/erpnext/stock/doctype/price_list_country/price_list_country.py
@@ -6,4 +6,18 @@
 
 
 class PriceListCountry(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
+
+		country: DF.Link
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js
index 6552cd7..6c9d339 100644
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js
@@ -49,6 +49,14 @@
 			}
 		});
 
+		frm.set_query("subcontracting_receipt", function() {
+			return {
+				filters: {
+					'docstatus': 1,
+					'supplier': frm.doc.supplier,
+				}
+			}
+		});
 	},
 	onload: function(frm) {
 		erpnext.queries.setup_queries(frm, "Warehouse", function() {
@@ -114,6 +122,20 @@
 		erpnext.accounts.dimensions.update_dimension(frm, frm.doctype);
 	},
 
+	subcontracting_receipt: (frm) => {
+		if (frm.doc.is_subcontracted === 1 && frm.doc.is_old_subcontracting_flow === 0 && frm.doc.subcontracting_receipt) {
+			frm.set_value('items', null);
+
+			erpnext.utils.map_current_doc({
+				method: 'erpnext.subcontracting.doctype.subcontracting_receipt.subcontracting_receipt.make_purchase_receipt',
+				source_name: frm.doc.subcontracting_receipt,
+				target_doc: frm,
+				freeze: true,
+				freeze_message: __('Mapping Purchase Receipt ...'),
+			});
+		}
+	},
+
 	toggle_display_account_head: function(frm) {
 		var enabled = erpnext.is_perpetual_inventory_enabled(frm.doc.company)
 		frm.fields_dict["items"].grid.set_column_disp(["cost_center"], enabled);
diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.json b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.json
index c8a9e3e..c7ad660 100755
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.json
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.json
@@ -16,6 +16,7 @@
   "supplier",
   "supplier_name",
   "supplier_delivery_note",
+  "subcontracting_receipt",
   "column_break1",
   "posting_date",
   "posting_time",
@@ -1236,13 +1237,21 @@
    "fieldname": "named_place",
    "fieldtype": "Data",
    "label": "Named Place"
+  },
+  {
+   "depends_on": "eval: (doc.is_subcontracted && !doc.is_old_subcontracting_flow)",
+   "fieldname": "subcontracting_receipt",
+   "fieldtype": "Link",
+   "label": "Subcontracting Receipt",
+   "options": "Subcontracting Receipt",
+   "search_index": 1
   }
  ],
  "icon": "fa fa-truck",
  "idx": 261,
  "is_submittable": 1,
  "links": [],
- "modified": "2023-10-01 21:00:44.556816",
+ "modified": "2023-11-28 13:14:15.243474",
  "modified_by": "Administrator",
  "module": "Stock",
  "name": "Purchase Receipt",
diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
index d905fe5..ab07271 100644
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
@@ -21,6 +21,118 @@
 
 
 class PurchaseReceipt(BuyingController):
+	# 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
+
+		from erpnext.accounts.doctype.pricing_rule_detail.pricing_rule_detail import PricingRuleDetail
+		from erpnext.accounts.doctype.purchase_taxes_and_charges.purchase_taxes_and_charges import (
+			PurchaseTaxesandCharges,
+		)
+		from erpnext.buying.doctype.purchase_receipt_item_supplied.purchase_receipt_item_supplied import (
+			PurchaseReceiptItemSupplied,
+		)
+		from erpnext.stock.doctype.purchase_receipt_item.purchase_receipt_item import PurchaseReceiptItem
+
+		additional_discount_percentage: DF.Float
+		address_display: DF.SmallText | None
+		amended_from: DF.Link | None
+		apply_discount_on: DF.Literal["", "Grand Total", "Net Total"]
+		apply_putaway_rule: DF.Check
+		auto_repeat: DF.Link | None
+		base_discount_amount: DF.Currency
+		base_grand_total: DF.Currency
+		base_in_words: DF.Data | None
+		base_net_total: DF.Currency
+		base_rounded_total: DF.Currency
+		base_rounding_adjustment: DF.Currency
+		base_taxes_and_charges_added: DF.Currency
+		base_taxes_and_charges_deducted: DF.Currency
+		base_total: DF.Currency
+		base_total_taxes_and_charges: DF.Currency
+		billing_address: DF.Link | None
+		billing_address_display: DF.SmallText | None
+		buying_price_list: DF.Link | None
+		company: DF.Link
+		contact_display: DF.SmallText | None
+		contact_email: DF.SmallText | None
+		contact_mobile: DF.SmallText | None
+		contact_person: DF.Link | None
+		conversion_rate: DF.Float
+		cost_center: DF.Link | None
+		currency: DF.Link
+		disable_rounded_total: DF.Check
+		discount_amount: DF.Currency
+		grand_total: DF.Currency
+		group_same_items: DF.Check
+		ignore_pricing_rule: DF.Check
+		in_words: DF.Data | None
+		incoterm: DF.Link | None
+		instructions: DF.SmallText | None
+		inter_company_reference: DF.Link | None
+		is_internal_supplier: DF.Check
+		is_old_subcontracting_flow: DF.Check
+		is_return: DF.Check
+		is_subcontracted: DF.Check
+		items: DF.Table[PurchaseReceiptItem]
+		language: DF.Data | None
+		letter_head: DF.Link | None
+		lr_date: DF.Date | None
+		lr_no: DF.Data | None
+		named_place: DF.Data | None
+		naming_series: DF.Literal["MAT-PRE-.YYYY.-", "MAT-PR-RET-.YYYY.-"]
+		net_total: DF.Currency
+		other_charges_calculation: DF.LongText | None
+		per_billed: DF.Percent
+		per_returned: DF.Percent
+		plc_conversion_rate: DF.Float
+		posting_date: DF.Date
+		posting_time: DF.Time
+		price_list_currency: DF.Link | None
+		pricing_rules: DF.Table[PricingRuleDetail]
+		project: DF.Link | None
+		range: DF.Data | None
+		rejected_warehouse: DF.Link | None
+		remarks: DF.SmallText | None
+		represents_company: DF.Link | None
+		return_against: DF.Link | None
+		rounded_total: DF.Currency
+		rounding_adjustment: DF.Currency
+		scan_barcode: DF.Data | None
+		select_print_heading: DF.Link | None
+		set_from_warehouse: DF.Link | None
+		set_posting_time: DF.Check
+		set_warehouse: DF.Link | None
+		shipping_address: DF.Link | None
+		shipping_address_display: DF.SmallText | None
+		shipping_rule: DF.Link | None
+		status: DF.Literal["", "Draft", "To Bill", "Completed", "Return Issued", "Cancelled", "Closed"]
+		subcontracting_receipt: DF.Link | None
+		supplied_items: DF.Table[PurchaseReceiptItemSupplied]
+		supplier: DF.Link
+		supplier_address: DF.Link | None
+		supplier_delivery_note: DF.Data | None
+		supplier_name: DF.Data | None
+		supplier_warehouse: DF.Link | None
+		tax_category: DF.Link | None
+		taxes: DF.Table[PurchaseTaxesandCharges]
+		taxes_and_charges: DF.Link | None
+		taxes_and_charges_added: DF.Currency
+		taxes_and_charges_deducted: DF.Currency
+		tc_name: DF.Link | None
+		terms: DF.TextEditor | None
+		title: DF.Data | None
+		total: DF.Currency
+		total_net_weight: DF.Float
+		total_qty: DF.Float
+		total_taxes_and_charges: DF.Currency
+		transporter_name: DF.Data | None
+	# end: auto-generated types
+
 	def __init__(self, *args, **kwargs):
 		super(PurchaseReceipt, self).__init__(*args, **kwargs)
 		self.status_updater = [
@@ -571,7 +683,7 @@
 					)
 
 					stock_value_diff = (
-						flt(d.net_amount)
+						flt(d.base_net_amount)
 						+ flt(d.item_tax_amount / self.conversion_rate)
 						+ flt(d.landed_cost_voucher_amount)
 					)
@@ -731,12 +843,18 @@
 
 	def update_assets(self, item, valuation_rate):
 		assets = frappe.db.get_all(
-			"Asset", filters={"purchase_receipt": self.name, "item_code": item.item_code}
+			"Asset",
+			filters={"purchase_receipt": self.name, "item_code": item.item_code},
+			fields=["name", "asset_quantity"],
 		)
 
 		for asset in assets:
-			frappe.db.set_value("Asset", asset.name, "gross_purchase_amount", flt(valuation_rate))
-			frappe.db.set_value("Asset", asset.name, "purchase_receipt_amount", flt(valuation_rate))
+			frappe.db.set_value(
+				"Asset", asset.name, "gross_purchase_amount", flt(valuation_rate) * asset.asset_quantity
+			)
+			frappe.db.set_value(
+				"Asset", asset.name, "purchase_receipt_amount", flt(valuation_rate) * asset.asset_quantity
+			)
 
 	def update_status(self, status):
 		self.set_status(update=True, status=status)
@@ -775,7 +893,7 @@
 		for item in self.items:
 			if item.sales_order and item.sales_order_item:
 				item_details = {
-					"name": item.sales_order_item,
+					"sales_order_item": item.sales_order_item,
 					"item_code": item.item_code,
 					"warehouse": item.warehouse,
 					"qty_to_reserve": item.stock_qty,
@@ -1090,7 +1208,6 @@
 		set_missing_values,
 	)
 
-	doclist.set_onload("ignore_price_list", True)
 	return doclist
 
 
diff --git a/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json b/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json
index 718f007..7344d2a 100644
--- a/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json
+++ b/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json
@@ -127,7 +127,8 @@
   "section_break_80",
   "page_break",
   "sales_order",
-  "sales_order_item"
+  "sales_order_item",
+  "subcontracting_receipt_item"
  ],
  "fields": [
   {
@@ -192,6 +193,7 @@
    "width": "300px"
   },
   {
+   "fetch_from": "item_code.image",
    "fieldname": "image",
    "fieldtype": "Attach",
    "hidden": 1,
@@ -357,6 +359,7 @@
    "oldfieldtype": "Currency",
    "options": "currency",
    "print_width": "100px",
+   "read_only_depends_on": "eval: (!parent.is_return && doc.purchase_order && doc.purchase_order_item)",
    "width": "100px"
   },
   {
@@ -1085,12 +1088,23 @@
    "print_hide": 1,
    "read_only": 1,
    "search_index": 1
+  },
+  {
+   "fieldname": "subcontracting_receipt_item",
+   "fieldtype": "Data",
+   "hidden": 1,
+   "label": "Subcontracting Receipt Item",
+   "no_copy": 1,
+   "print_hide": 1,
+   "read_only": 1,
+   "report_hide": 1,
+   "search_index": 1
   }
  ],
  "idx": 1,
  "istable": 1,
  "links": [],
- "modified": "2023-10-30 17:32:24.560337",
+ "modified": "2023-11-30 16:12:02.364608",
  "modified_by": "Administrator",
  "module": "Stock",
  "name": "Purchase Receipt Item",
diff --git a/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.py b/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.py
index b4b9fd3..aed8d21 100644
--- a/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.py
+++ b/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.py
@@ -6,4 +6,104 @@
 
 
 class PurchaseReceiptItem(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
+
+		allow_zero_valuation_rate: DF.Check
+		amount: DF.Currency
+		asset_category: DF.Link | None
+		asset_location: DF.Link | None
+		barcode: DF.Data | None
+		base_amount: DF.Currency
+		base_net_amount: DF.Currency
+		base_net_rate: DF.Currency
+		base_price_list_rate: DF.Currency
+		base_rate: DF.Currency
+		base_rate_with_margin: DF.Currency
+		batch_no: DF.Link | None
+		billed_amt: DF.Currency
+		bom: DF.Link | None
+		brand: DF.Link | None
+		conversion_factor: DF.Float
+		cost_center: DF.Link | None
+		delivery_note_item: DF.Data | None
+		description: DF.TextEditor | None
+		discount_amount: DF.Currency
+		discount_percentage: DF.Percent
+		expense_account: DF.Link | None
+		from_warehouse: DF.Link | None
+		has_item_scanned: DF.Check
+		image: DF.Attach | None
+		include_exploded_items: DF.Check
+		is_fixed_asset: DF.Check
+		is_free_item: DF.Check
+		item_code: DF.Link
+		item_group: DF.Link | None
+		item_name: DF.Data
+		item_tax_amount: DF.Currency
+		item_tax_rate: DF.Code | None
+		item_tax_template: DF.Link | None
+		landed_cost_voucher_amount: DF.Currency
+		manufacturer: DF.Link | None
+		manufacturer_part_no: DF.Data | None
+		margin_rate_or_amount: DF.Float
+		margin_type: DF.Literal["", "Percentage", "Amount"]
+		material_request: DF.Link | None
+		material_request_item: DF.Data | None
+		net_amount: DF.Currency
+		net_rate: DF.Currency
+		page_break: DF.Check
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		price_list_rate: DF.Currency
+		pricing_rules: DF.SmallText | None
+		product_bundle: DF.Link | None
+		project: DF.Link | None
+		provisional_expense_account: DF.Link | None
+		purchase_invoice: DF.Link | None
+		purchase_invoice_item: DF.Data | None
+		purchase_order: DF.Link | None
+		purchase_order_item: DF.Data | None
+		purchase_receipt_item: DF.Data | None
+		putaway_rule: DF.Link | None
+		qty: DF.Float
+		quality_inspection: DF.Link | None
+		rate: DF.Currency
+		rate_difference_with_purchase_invoice: DF.Currency
+		rate_with_margin: DF.Currency
+		received_qty: DF.Float
+		received_stock_qty: DF.Float
+		rejected_qty: DF.Float
+		rejected_serial_and_batch_bundle: DF.Link | None
+		rejected_serial_no: DF.Text | None
+		rejected_warehouse: DF.Link | None
+		retain_sample: DF.Check
+		returned_qty: DF.Float
+		rm_supp_cost: DF.Currency
+		sales_order: DF.Link | None
+		sales_order_item: DF.Data | None
+		sample_quantity: DF.Int
+		schedule_date: DF.Date | None
+		serial_and_batch_bundle: DF.Link | None
+		serial_no: DF.Text | None
+		stock_qty: DF.Float
+		stock_uom: DF.Link
+		stock_uom_rate: DF.Currency
+		subcontracting_receipt_item: DF.Data | None
+		supplier_part_no: DF.Data | None
+		total_weight: DF.Float
+		uom: DF.Link
+		valuation_rate: DF.Currency
+		warehouse: DF.Link | None
+		weight_per_unit: DF.Float
+		weight_uom: DF.Link | None
+		wip_composite_asset: DF.Link | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/stock/doctype/putaway_rule/putaway_rule.py b/erpnext/stock/doctype/putaway_rule/putaway_rule.py
index 0a04210..3fc4e01 100644
--- a/erpnext/stock/doctype/putaway_rule/putaway_rule.py
+++ b/erpnext/stock/doctype/putaway_rule/putaway_rule.py
@@ -15,6 +15,27 @@
 
 
 class PutawayRule(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
+
+		capacity: DF.Float
+		company: DF.Link
+		conversion_factor: DF.Float
+		disable: DF.Check
+		item_code: DF.Link
+		item_name: DF.Data | None
+		priority: DF.Int
+		stock_capacity: DF.Float
+		stock_uom: DF.Link | None
+		uom: DF.Link | None
+		warehouse: DF.Link
+	# end: auto-generated types
+
 	def validate(self):
 		self.validate_duplicate_rule()
 		self.validate_warehouse_and_company()
diff --git a/erpnext/stock/doctype/quality_inspection/quality_inspection.py b/erpnext/stock/doctype/quality_inspection/quality_inspection.py
index 9673c81..4464ea8 100644
--- a/erpnext/stock/doctype/quality_inspection/quality_inspection.py
+++ b/erpnext/stock/doctype/quality_inspection/quality_inspection.py
@@ -14,6 +14,49 @@
 
 
 class QualityInspection(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
+
+		from erpnext.stock.doctype.quality_inspection_reading.quality_inspection_reading import (
+			QualityInspectionReading,
+		)
+
+		amended_from: DF.Link | None
+		batch_no: DF.Link | None
+		bom_no: DF.Link | None
+		description: DF.SmallText | None
+		inspected_by: DF.Link
+		inspection_type: DF.Literal["", "Incoming", "Outgoing", "In Process"]
+		item_code: DF.Link
+		item_name: DF.Data | None
+		item_serial_no: DF.Link | None
+		manual_inspection: DF.Check
+		naming_series: DF.Literal["MAT-QA-.YYYY.-"]
+		quality_inspection_template: DF.Link | None
+		readings: DF.Table[QualityInspectionReading]
+		reference_name: DF.DynamicLink
+		reference_type: DF.Literal[
+			"",
+			"Purchase Receipt",
+			"Purchase Invoice",
+			"Subcontracting Receipt",
+			"Delivery Note",
+			"Sales Invoice",
+			"Stock Entry",
+			"Job Card",
+		]
+		remarks: DF.Text | None
+		report_date: DF.Date
+		sample_size: DF.Float
+		status: DF.Literal["", "Accepted", "Rejected"]
+		verified_by: DF.Data | None
+	# end: auto-generated types
+
 	def validate(self):
 		if not self.readings and self.item_code:
 			self.get_item_specification_details()
diff --git a/erpnext/stock/doctype/quality_inspection_parameter/quality_inspection_parameter.py b/erpnext/stock/doctype/quality_inspection_parameter/quality_inspection_parameter.py
index d5123c7..310915f 100644
--- a/erpnext/stock/doctype/quality_inspection_parameter/quality_inspection_parameter.py
+++ b/erpnext/stock/doctype/quality_inspection_parameter/quality_inspection_parameter.py
@@ -7,4 +7,17 @@
 
 
 class QualityInspectionParameter(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
+
+		description: DF.TextEditor | None
+		parameter: DF.Data
+		parameter_group: DF.Link | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/stock/doctype/quality_inspection_parameter_group/quality_inspection_parameter_group.py b/erpnext/stock/doctype/quality_inspection_parameter_group/quality_inspection_parameter_group.py
index 26e9361..0105376 100644
--- a/erpnext/stock/doctype/quality_inspection_parameter_group/quality_inspection_parameter_group.py
+++ b/erpnext/stock/doctype/quality_inspection_parameter_group/quality_inspection_parameter_group.py
@@ -7,4 +7,15 @@
 
 
 class QualityInspectionParameterGroup(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
+
+		group_name: DF.Data
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/stock/doctype/quality_inspection_reading/quality_inspection_reading.py b/erpnext/stock/doctype/quality_inspection_reading/quality_inspection_reading.py
index 81454f1..0ba9008 100644
--- a/erpnext/stock/doctype/quality_inspection_reading/quality_inspection_reading.py
+++ b/erpnext/stock/doctype/quality_inspection_reading/quality_inspection_reading.py
@@ -6,4 +6,38 @@
 
 
 class QualityInspectionReading(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
+
+		acceptance_formula: DF.Code | None
+		formula_based_criteria: DF.Check
+		manual_inspection: DF.Check
+		max_value: DF.Float
+		min_value: DF.Float
+		numeric: DF.Check
+		parameter_group: DF.Link | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		reading_10: DF.Data | None
+		reading_1: DF.Data | None
+		reading_2: DF.Data | None
+		reading_3: DF.Data | None
+		reading_4: DF.Data | None
+		reading_5: DF.Data | None
+		reading_6: DF.Data | None
+		reading_7: DF.Data | None
+		reading_8: DF.Data | None
+		reading_9: DF.Data | None
+		reading_value: DF.Data | None
+		specification: DF.Link
+		status: DF.Literal["", "Accepted", "Rejected"]
+		value: DF.Data | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/stock/doctype/quality_inspection_template/quality_inspection_template.py b/erpnext/stock/doctype/quality_inspection_template/quality_inspection_template.py
index 9b8f5d6..44b7735 100644
--- a/erpnext/stock/doctype/quality_inspection_template/quality_inspection_template.py
+++ b/erpnext/stock/doctype/quality_inspection_template/quality_inspection_template.py
@@ -7,6 +7,22 @@
 
 
 class QualityInspectionTemplate(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
+
+		from erpnext.stock.doctype.item_quality_inspection_parameter.item_quality_inspection_parameter import (
+			ItemQualityInspectionParameter,
+		)
+
+		item_quality_inspection_parameter: DF.Table[ItemQualityInspectionParameter]
+		quality_inspection_template_name: DF.Data
+	# end: auto-generated types
+
 	pass
 
 
diff --git a/erpnext/stock/doctype/quick_stock_balance/quick_stock_balance.py b/erpnext/stock/doctype/quick_stock_balance/quick_stock_balance.py
index 846be0b..34fb68c 100644
--- a/erpnext/stock/doctype/quick_stock_balance/quick_stock_balance.py
+++ b/erpnext/stock/doctype/quick_stock_balance/quick_stock_balance.py
@@ -10,6 +10,24 @@
 
 
 class QuickStockBalance(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
+
+		date: DF.Date
+		item: DF.Link
+		item_barcode: DF.Data | None
+		item_description: DF.SmallText | None
+		item_name: DF.Data | None
+		qty: DF.Float
+		value: DF.Currency
+		warehouse: DF.Link
+	# end: auto-generated types
+
 	pass
 
 
diff --git a/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py b/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py
index f128c8e..97ada06 100644
--- a/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py
+++ b/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py
@@ -25,6 +25,37 @@
 
 
 class RepostItemValuation(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
+
+		affected_transactions: DF.Code | None
+		allow_negative_stock: DF.Check
+		allow_zero_rate: DF.Check
+		amended_from: DF.Link | None
+		based_on: DF.Literal["Transaction", "Item and Warehouse"]
+		company: DF.Link | None
+		current_index: DF.Int
+		distinct_item_and_warehouse: DF.Code | None
+		error_log: DF.LongText | None
+		gl_reposting_index: DF.Int
+		item_code: DF.Link | None
+		items_to_be_repost: DF.Code | None
+		posting_date: DF.Date
+		posting_time: DF.Time | None
+		reposting_data_file: DF.Attach | None
+		status: DF.Literal["Queued", "In Progress", "Completed", "Skipped", "Failed"]
+		total_reposting_count: DF.Int
+		via_landed_cost_voucher: DF.Check
+		voucher_no: DF.DynamicLink | None
+		voucher_type: DF.Link | None
+		warehouse: DF.Link | None
+	# end: auto-generated types
+
 	@staticmethod
 	def clear_old_logs(days=None):
 		days = days or 90
diff --git a/erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py b/erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py
index f2bbf2b..108a2e0 100644
--- a/erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py
+++ b/erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py
@@ -44,6 +44,42 @@
 
 
 class SerialandBatchBundle(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
+
+		from erpnext.stock.doctype.serial_and_batch_entry.serial_and_batch_entry import (
+			SerialandBatchEntry,
+		)
+
+		amended_from: DF.Link | None
+		avg_rate: DF.Float
+		company: DF.Link
+		entries: DF.Table[SerialandBatchEntry]
+		has_batch_no: DF.Check
+		has_serial_no: DF.Check
+		is_cancelled: DF.Check
+		is_rejected: DF.Check
+		item_code: DF.Link
+		item_group: DF.Link | None
+		item_name: DF.Data | None
+		naming_series: DF.Literal["SABB-.########"]
+		posting_date: DF.Date | None
+		posting_time: DF.Time | None
+		returned_against: DF.Data | None
+		total_amount: DF.Float
+		total_qty: DF.Float
+		type_of_transaction: DF.Literal["", "Inward", "Outward", "Maintenance", "Asset Repair"]
+		voucher_detail_no: DF.Data | None
+		voucher_no: DF.DynamicLink | None
+		voucher_type: DF.Link
+		warehouse: DF.Link | None
+	# end: auto-generated types
+
 	def validate(self):
 		self.validate_serial_and_batch_no()
 		self.validate_duplicate_serial_and_batch_no()
@@ -216,6 +252,7 @@
 				"serial_nos": [row.serial_no for row in self.entries if row.serial_no],
 				"batch_nos": {row.batch_no: row for row in self.entries if row.batch_no},
 				"voucher_type": self.voucher_type,
+				"voucher_detail_no": self.voucher_detail_no,
 			}
 		)
 
@@ -246,7 +283,7 @@
 				valuation_field = "rate"
 				child_table = "Subcontracting Receipt Supplied Item"
 			else:
-				valuation_field = "rm_supp_cost"
+				valuation_field = "rate"
 				child_table = "Subcontracting Receipt Item"
 
 		precision = frappe.get_precision(child_table, valuation_field) or 2
@@ -406,7 +443,7 @@
 
 		if abs(abs(flt(self.total_qty, precision)) - abs(flt(row.get(qty_field), precision))) > 0.01:
 			self.throw_error_message(
-				f"Total quantity {abs(self.total_qty)} in the Serial and Batch Bundle {bold(self.name)} does not match with the quantity {abs(row.get(qty_field))} for the Item {bold(self.item_code)} in the {self.voucher_type} # {self.voucher_no}"
+				f"Total quantity {abs(flt(self.total_qty))} in the Serial and Batch Bundle {bold(self.name)} does not match with the quantity {abs(flt(row.get(qty_field)))} for the Item {bold(self.item_code)} in the {self.voucher_type} # {self.voucher_no}"
 			)
 
 	def set_is_outward(self):
@@ -1018,7 +1055,7 @@
 		doc.append(
 			"entries",
 			{
-				"qty": d.get("qty") * (1 if doc.type_of_transaction == "Inward" else -1),
+				"qty": (d.get("qty") or 1.0) * (1 if doc.type_of_transaction == "Inward" else -1),
 				"warehouse": warehouse or d.get("warehouse"),
 				"batch_no": d.get("batch_no"),
 				"serial_no": d.get("serial_no"),
@@ -1604,6 +1641,9 @@
 	)
 
 	for key, val in kwargs.items():
+		if not val:
+			continue
+
 		if key in ["get_subcontracted_item"]:
 			continue
 
@@ -1705,3 +1745,8 @@
 			batches[key].qty += d.qty
 
 	return batches
+
+
+@frappe.whitelist()
+def get_batch_no_from_serial_no(serial_no):
+	return frappe.get_cached_value("Serial No", serial_no, "batch_no")
diff --git a/erpnext/stock/doctype/serial_and_batch_entry/serial_and_batch_entry.py b/erpnext/stock/doctype/serial_and_batch_entry/serial_and_batch_entry.py
index 337403e..c849e68 100644
--- a/erpnext/stock/doctype/serial_and_batch_entry/serial_and_batch_entry.py
+++ b/erpnext/stock/doctype/serial_and_batch_entry/serial_and_batch_entry.py
@@ -6,4 +6,27 @@
 
 
 class SerialandBatchEntry(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
+
+		batch_no: DF.Link | None
+		delivered_qty: DF.Float
+		incoming_rate: DF.Float
+		is_outward: DF.Check
+		outgoing_rate: DF.Float
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		qty: DF.Float
+		serial_no: DF.Link | None
+		stock_queue: DF.SmallText | None
+		stock_value_difference: DF.Float
+		warehouse: DF.Link | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/stock/doctype/serial_no/serial_no.js b/erpnext/stock/doctype/serial_no/serial_no.js
index 9d5555e..1cb9fd1 100644
--- a/erpnext/stock/doctype/serial_no/serial_no.js
+++ b/erpnext/stock/doctype/serial_no/serial_no.js
@@ -18,3 +18,22 @@
 frappe.ui.form.on("Serial No", "refresh", function(frm) {
 	frm.toggle_enable("item_code", frm.doc.__islocal);
 });
+
+
+frappe.ui.form.on("Serial No", {
+	refresh(frm) {
+		frm.trigger("view_ledgers")
+	},
+
+	view_ledgers(frm) {
+		frm.add_custom_button(__("View Ledgers"), () => {
+			frappe.route_options = {
+				"item_code": frm.doc.item_code,
+				"serial_no": frm.doc.name,
+				"posting_date": frappe.datetime.now_date(),
+				"posting_time": frappe.datetime.now_time()
+			};
+			frappe.set_route("query-report", "Serial No Ledger");
+		}).addClass('btn-primary');
+	}
+})
\ No newline at end of file
diff --git a/erpnext/stock/doctype/serial_no/serial_no.json b/erpnext/stock/doctype/serial_no/serial_no.json
index ed1b0af..b4ece00 100644
--- a/erpnext/stock/doctype/serial_no/serial_no.json
+++ b/erpnext/stock/doctype/serial_no/serial_no.json
@@ -269,7 +269,7 @@
    "in_list_view": 1,
    "in_standard_filter": 1,
    "label": "Status",
-   "options": "\nActive\nInactive\nExpired",
+   "options": "\nActive\nInactive\nDelivered\nExpired",
    "read_only": 1
   },
   {
@@ -280,7 +280,7 @@
  "icon": "fa fa-barcode",
  "idx": 1,
  "links": [],
- "modified": "2023-04-16 15:58:46.139887",
+ "modified": "2023-11-28 15:37:59.489945",
  "modified_by": "Administrator",
  "module": "Stock",
  "name": "Serial No",
diff --git a/erpnext/stock/doctype/serial_no/serial_no.py b/erpnext/stock/doctype/serial_no/serial_no.py
index ba9482a..d562560 100644
--- a/erpnext/stock/doctype/serial_no/serial_no.py
+++ b/erpnext/stock/doctype/serial_no/serial_no.py
@@ -27,6 +27,39 @@
 
 
 class SerialNo(StockController):
+	# 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
+
+		amc_expiry_date: DF.Date | None
+		asset: DF.Link | None
+		asset_status: DF.Literal["", "Issue", "Receipt", "Transfer"]
+		batch_no: DF.Link | None
+		brand: DF.Link | None
+		company: DF.Link
+		delivery_document_type: DF.Link | None
+		description: DF.Text | None
+		employee: DF.Link | None
+		item_code: DF.Link
+		item_group: DF.Link | None
+		item_name: DF.Data | None
+		location: DF.Link | None
+		maintenance_status: DF.Literal[
+			"", "Under Warranty", "Out of Warranty", "Under AMC", "Out of AMC"
+		]
+		purchase_rate: DF.Float
+		serial_no: DF.Data
+		status: DF.Literal["", "Active", "Inactive", "Delivered", "Expired"]
+		warehouse: DF.Link | None
+		warranty_expiry_date: DF.Date | None
+		warranty_period: DF.Int
+		work_order: DF.Link | None
+	# end: auto-generated types
+
 	def __init__(self, *args, **kwargs):
 		super(SerialNo, self).__init__(*args, **kwargs)
 		self.via_stock_ledger = False
diff --git a/erpnext/stock/doctype/shipment/shipment.py b/erpnext/stock/doctype/shipment/shipment.py
index 42a67f4..346e70e 100644
--- a/erpnext/stock/doctype/shipment/shipment.py
+++ b/erpnext/stock/doctype/shipment/shipment.py
@@ -12,6 +12,65 @@
 
 
 class Shipment(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
+
+		from erpnext.stock.doctype.shipment_delivery_note.shipment_delivery_note import (
+			ShipmentDeliveryNote,
+		)
+		from erpnext.stock.doctype.shipment_parcel.shipment_parcel import ShipmentParcel
+
+		amended_from: DF.Link | None
+		awb_number: DF.Data | None
+		carrier: DF.Data | None
+		carrier_service: DF.Data | None
+		delivery_address: DF.SmallText | None
+		delivery_address_name: DF.Link
+		delivery_company: DF.Link | None
+		delivery_contact: DF.SmallText | None
+		delivery_contact_email: DF.Data | None
+		delivery_contact_name: DF.Link | None
+		delivery_customer: DF.Link | None
+		delivery_supplier: DF.Link | None
+		delivery_to: DF.Data | None
+		delivery_to_type: DF.Literal["Company", "Customer", "Supplier"]
+		description_of_content: DF.SmallText
+		incoterm: DF.Link | None
+		pallets: DF.Literal["No", "Yes"]
+		parcel_template: DF.Link | None
+		pickup: DF.Data | None
+		pickup_address: DF.SmallText | None
+		pickup_address_name: DF.Link
+		pickup_company: DF.Link | None
+		pickup_contact: DF.SmallText | None
+		pickup_contact_email: DF.Data | None
+		pickup_contact_name: DF.Link | None
+		pickup_contact_person: DF.Link | None
+		pickup_customer: DF.Link | None
+		pickup_date: DF.Date
+		pickup_from: DF.Time
+		pickup_from_type: DF.Literal["Company", "Customer", "Supplier"]
+		pickup_supplier: DF.Link | None
+		pickup_to: DF.Time
+		pickup_type: DF.Literal["Pickup", "Self delivery"]
+		service_provider: DF.Data | None
+		shipment_amount: DF.Currency
+		shipment_delivery_note: DF.Table[ShipmentDeliveryNote]
+		shipment_id: DF.Data | None
+		shipment_parcel: DF.Table[ShipmentParcel]
+		shipment_type: DF.Literal["Goods", "Documents"]
+		status: DF.Literal["Draft", "Submitted", "Booked", "Cancelled", "Completed"]
+		tracking_status: DF.Literal["", "In Progress", "Delivered", "Returned", "Lost"]
+		tracking_status_info: DF.Data | None
+		tracking_url: DF.SmallText | None
+		value_of_goods: DF.Currency
+	# end: auto-generated types
+
 	def validate(self):
 		self.validate_weight()
 		self.validate_pickup_time()
diff --git a/erpnext/stock/doctype/shipment_delivery_note/shipment_delivery_note.py b/erpnext/stock/doctype/shipment_delivery_note/shipment_delivery_note.py
index 2b58a39..fb5e616 100644
--- a/erpnext/stock/doctype/shipment_delivery_note/shipment_delivery_note.py
+++ b/erpnext/stock/doctype/shipment_delivery_note/shipment_delivery_note.py
@@ -7,4 +7,19 @@
 
 
 class ShipmentDeliveryNote(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
+
+		delivery_note: DF.Link
+		grand_total: DF.Currency
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/stock/doctype/shipment_parcel/shipment_parcel.py b/erpnext/stock/doctype/shipment_parcel/shipment_parcel.py
index a607021..f789f07 100644
--- a/erpnext/stock/doctype/shipment_parcel/shipment_parcel.py
+++ b/erpnext/stock/doctype/shipment_parcel/shipment_parcel.py
@@ -7,4 +7,22 @@
 
 
 class ShipmentParcel(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
+
+		count: DF.Int
+		height: DF.Int
+		length: DF.Int
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		weight: DF.Float
+		width: DF.Int
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/stock/doctype/shipment_parcel_template/shipment_parcel_template.py b/erpnext/stock/doctype/shipment_parcel_template/shipment_parcel_template.py
index a5de312..054c0f3 100644
--- a/erpnext/stock/doctype/shipment_parcel_template/shipment_parcel_template.py
+++ b/erpnext/stock/doctype/shipment_parcel_template/shipment_parcel_template.py
@@ -7,4 +7,19 @@
 
 
 class ShipmentParcelTemplate(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
+
+		height: DF.Int
+		length: DF.Int
+		parcel_template_name: DF.Data
+		weight: DF.Float
+		width: DF.Int
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.js b/erpnext/stock/doctype/stock_entry/stock_entry.js
index d37e8ee..7334b35 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.js
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.js
@@ -258,7 +258,7 @@
 			}
 		}
 
-		if (frm.doc.docstatus===0) {
+		if (frm.doc.docstatus === 0) {
 			frm.add_custom_button(__('Purchase Invoice'), function() {
 				erpnext.utils.map_current_doc({
 					method: "erpnext.accounts.doctype.purchase_invoice.purchase_invoice.make_stock_entry",
@@ -311,7 +311,8 @@
 				})
 			}, __("Get Items From"));
 		}
-		if (frm.doc.docstatus===0 && frm.doc.purpose == "Material Issue") {
+
+		if (frm.doc.docstatus === 0 && frm.doc.purpose == "Material Issue") {
 			frm.add_custom_button(__('Expired Batches'), function() {
 				frappe.call({
 					method: "erpnext.stock.doctype.stock_entry.stock_entry.get_expired_batch_items",
@@ -397,6 +398,10 @@
 		frm.remove_custom_button('Bill of Materials', "Get Items From");
 		frm.events.show_bom_custom_button(frm);
 		frm.trigger('add_to_transit');
+
+		frm.fields_dict.items.grid.update_docfield_property(
+			'basic_rate', 'read_only', frm.doc.purpose == "Material Receipt" ? 0 : 1
+		);
 	},
 
 	purpose: function(frm) {
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py
index b06de2e..3baafd7 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.py
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.py
@@ -74,6 +74,82 @@
 
 
 class StockEntry(StockController):
+	# 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
+
+		from erpnext.stock.doctype.landed_cost_taxes_and_charges.landed_cost_taxes_and_charges import (
+			LandedCostTaxesandCharges,
+		)
+		from erpnext.stock.doctype.stock_entry_detail.stock_entry_detail import StockEntryDetail
+
+		add_to_transit: DF.Check
+		additional_costs: DF.Table[LandedCostTaxesandCharges]
+		address_display: DF.SmallText | None
+		amended_from: DF.Link | None
+		apply_putaway_rule: DF.Check
+		bom_no: DF.Link | None
+		company: DF.Link
+		credit_note: DF.Link | None
+		delivery_note_no: DF.Link | None
+		fg_completed_qty: DF.Float
+		from_bom: DF.Check
+		from_warehouse: DF.Link | None
+		inspection_required: DF.Check
+		is_opening: DF.Literal["No", "Yes"]
+		is_return: DF.Check
+		items: DF.Table[StockEntryDetail]
+		job_card: DF.Link | None
+		letter_head: DF.Link | None
+		naming_series: DF.Literal["MAT-STE-.YYYY.-"]
+		outgoing_stock_entry: DF.Link | None
+		per_transferred: DF.Percent
+		pick_list: DF.Link | None
+		posting_date: DF.Date | None
+		posting_time: DF.Time | None
+		process_loss_percentage: DF.Percent
+		process_loss_qty: DF.Float
+		project: DF.Link | None
+		purchase_order: DF.Link | None
+		purchase_receipt_no: DF.Link | None
+		purpose: DF.Literal[
+			"Material Issue",
+			"Material Receipt",
+			"Material Transfer",
+			"Material Transfer for Manufacture",
+			"Material Consumption for Manufacture",
+			"Manufacture",
+			"Repack",
+			"Send to Subcontractor",
+		]
+		remarks: DF.Text | None
+		sales_invoice_no: DF.Link | None
+		scan_barcode: DF.Data | None
+		select_print_heading: DF.Link | None
+		set_posting_time: DF.Check
+		source_address_display: DF.SmallText | None
+		source_warehouse_address: DF.Link | None
+		stock_entry_type: DF.Link
+		subcontracting_order: DF.Link | None
+		supplier: DF.Link | None
+		supplier_address: DF.Link | None
+		supplier_name: DF.Data | None
+		target_address_display: DF.SmallText | None
+		target_warehouse_address: DF.Link | None
+		to_warehouse: DF.Link | None
+		total_additional_costs: DF.Currency
+		total_amount: DF.Currency
+		total_incoming_value: DF.Currency
+		total_outgoing_value: DF.Currency
+		use_multi_level_bom: DF.Check
+		value_difference: DF.Currency
+		work_order: DF.Link | None
+	# end: auto-generated types
+
 	def __init__(self, *args, **kwargs):
 		super(StockEntry, self).__init__(*args, **kwargs)
 		if self.purchase_order:
@@ -807,6 +883,7 @@
 				"company": self.company,
 				"allow_zero_valuation": item.allow_zero_valuation_rate,
 				"serial_and_batch_bundle": item.serial_and_batch_bundle,
+				"voucher_detail_no": item.name,
 			}
 		)
 
diff --git a/erpnext/stock/doctype/stock_entry/test_stock_entry.py b/erpnext/stock/doctype/stock_entry/test_stock_entry.py
index b640983..eb1c7a8 100644
--- a/erpnext/stock/doctype/stock_entry/test_stock_entry.py
+++ b/erpnext/stock/doctype/stock_entry/test_stock_entry.py
@@ -936,6 +936,42 @@
 		stock_entry.insert()
 		self.assertTrue("_Test Variant Item-S" in [d.item_code for d in stock_entry.items])
 
+	def test_nagative_stock_for_batch(self):
+		item = make_item(
+			"_Test Batch Negative Item",
+			{
+				"has_batch_no": 1,
+				"create_new_batch": 1,
+				"batch_number_series": "B-BATCH-.##",
+				"is_stock_item": 1,
+			},
+		)
+
+		make_stock_entry(item_code=item.name, target="_Test Warehouse - _TC", qty=50, basic_rate=100)
+
+		ste = frappe.new_doc("Stock Entry")
+		ste.purpose = "Material Issue"
+		ste.company = "_Test Company"
+		for qty in [50, 20, 30]:
+			ste.append(
+				"items",
+				{
+					"item_code": item.name,
+					"s_warehouse": "_Test Warehouse - _TC",
+					"qty": qty,
+					"uom": item.stock_uom,
+					"stock_uom": item.stock_uom,
+					"conversion_factor": 1,
+					"transfer_qty": qty,
+				},
+			)
+
+		ste.set_stock_entry_type()
+		ste.insert()
+		make_stock_entry(item_code=item.name, target="_Test Warehouse - _TC", qty=50, basic_rate=100)
+
+		self.assertRaises(frappe.ValidationError, ste.submit)
+
 	def test_same_serial_nos_in_repack_or_manufacture_entries(self):
 		s1 = make_serialized_item(target_warehouse="_Test Warehouse - _TC")
 		serial_nos = get_serial_nos_from_bundle(s1.get("items")[0].serial_and_batch_bundle)
diff --git a/erpnext/stock/doctype/stock_entry_detail/stock_entry_detail.py b/erpnext/stock/doctype/stock_entry_detail/stock_entry_detail.py
index 000ff2d..b2fc1f5 100644
--- a/erpnext/stock/doctype/stock_entry_detail/stock_entry_detail.py
+++ b/erpnext/stock/doctype/stock_entry_detail/stock_entry_detail.py
@@ -6,4 +6,65 @@
 
 
 class StockEntryDetail(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
+
+		actual_qty: DF.Float
+		additional_cost: DF.Currency
+		against_stock_entry: DF.Link | None
+		allow_alternative_item: DF.Check
+		allow_zero_valuation_rate: DF.Check
+		amount: DF.Currency
+		attach_something_here: DF.Attach | None
+		barcode: DF.Data | None
+		basic_amount: DF.Currency
+		basic_rate: DF.Currency
+		batch_no: DF.Link | None
+		bom_no: DF.Link | None
+		conversion_factor: DF.Float
+		cost_center: DF.Link | None
+		description: DF.TextEditor | None
+		expense_account: DF.Link | None
+		has_item_scanned: DF.Check
+		image: DF.Attach | None
+		is_finished_item: DF.Check
+		is_scrap_item: DF.Check
+		item_code: DF.Link
+		item_group: DF.Data | None
+		item_name: DF.Data | None
+		job_card_item: DF.Data | None
+		material_request: DF.Link | None
+		material_request_item: DF.Link | None
+		original_item: DF.Link | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		po_detail: DF.Data | None
+		project: DF.Link | None
+		putaway_rule: DF.Link | None
+		qty: DF.Float
+		quality_inspection: DF.Link | None
+		reference_purchase_receipt: DF.Link | None
+		retain_sample: DF.Check
+		s_warehouse: DF.Link | None
+		sample_quantity: DF.Int
+		sco_rm_detail: DF.Data | None
+		serial_and_batch_bundle: DF.Link | None
+		serial_no: DF.SmallText | None
+		set_basic_rate_manually: DF.Check
+		ste_detail: DF.Data | None
+		stock_uom: DF.Link
+		subcontracted_item: DF.Link | None
+		t_warehouse: DF.Link | None
+		transfer_qty: DF.Float
+		transferred_qty: DF.Float
+		uom: DF.Link
+		valuation_rate: DF.Currency
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/stock/doctype/stock_entry_type/stock_entry_type.py b/erpnext/stock/doctype/stock_entry_type/stock_entry_type.py
index 7258cfb..0342231 100644
--- a/erpnext/stock/doctype/stock_entry_type/stock_entry_type.py
+++ b/erpnext/stock/doctype/stock_entry_type/stock_entry_type.py
@@ -7,6 +7,28 @@
 
 
 class StockEntryType(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
+
+		add_to_transit: DF.Check
+		purpose: DF.Literal[
+			"",
+			"Material Issue",
+			"Material Receipt",
+			"Material Transfer",
+			"Material Transfer for Manufacture",
+			"Material Consumption for Manufacture",
+			"Manufacture",
+			"Repack",
+			"Send to Subcontractor",
+		]
+	# end: auto-generated types
+
 	def validate(self):
 		if self.add_to_transit and self.purpose != "Material Transfer":
 			self.add_to_transit = 0
diff --git a/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.json b/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.json
index dcbd9b2..be37994 100644
--- a/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.json
+++ b/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.json
@@ -12,6 +12,7 @@
   "posting_date",
   "posting_time",
   "is_adjustment_entry",
+  "auto_created_serial_and_batch_bundle",
   "column_break_6",
   "voucher_type",
   "voucher_no",
@@ -340,6 +341,13 @@
    "fieldname": "is_adjustment_entry",
    "fieldtype": "Check",
    "label": "Is Adjustment Entry"
+  },
+  {
+   "default": "0",
+   "depends_on": "serial_and_batch_bundle",
+   "fieldname": "auto_created_serial_and_batch_bundle",
+   "fieldtype": "Check",
+   "label": "Auto Created Serial and Batch Bundle"
   }
  ],
  "hide_toolbar": 1,
@@ -348,7 +356,7 @@
  "in_create": 1,
  "index_web_pages_for_search": 1,
  "links": [],
- "modified": "2023-10-23 18:07:42.063615",
+ "modified": "2023-11-14 16:47:39.791967",
  "modified_by": "Administrator",
  "module": "Stock",
  "name": "Stock Ledger Entry",
diff --git a/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py b/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py
index c1b2051..e62f0b2 100644
--- a/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py
+++ b/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py
@@ -29,6 +29,46 @@
 
 
 class StockLedgerEntry(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
+
+		actual_qty: DF.Float
+		auto_created_serial_and_batch_bundle: DF.Check
+		batch_no: DF.Data | None
+		company: DF.Link | None
+		dependant_sle_voucher_detail_no: DF.Data | None
+		fiscal_year: DF.Data | None
+		has_batch_no: DF.Check
+		has_serial_no: DF.Check
+		incoming_rate: DF.Currency
+		is_adjustment_entry: DF.Check
+		is_cancelled: DF.Check
+		item_code: DF.Link | None
+		outgoing_rate: DF.Currency
+		posting_date: DF.Date | None
+		posting_time: DF.Time | None
+		project: DF.Link | None
+		qty_after_transaction: DF.Float
+		recalculate_rate: DF.Check
+		serial_and_batch_bundle: DF.Link | None
+		serial_no: DF.LongText | None
+		stock_queue: DF.Text | None
+		stock_uom: DF.Link | None
+		stock_value: DF.Currency
+		stock_value_difference: DF.Currency
+		to_rename: DF.Check
+		valuation_rate: DF.Currency
+		voucher_detail_no: DF.Data | None
+		voucher_no: DF.DynamicLink | None
+		voucher_type: DF.Link | None
+		warehouse: DF.Link | None
+	# end: auto-generated types
+
 	def autoname(self):
 		"""
 		Temporarily name doc for fast insertion
diff --git a/erpnext/stock/doctype/stock_ledger_entry/test_stock_ledger_entry.py b/erpnext/stock/doctype/stock_ledger_entry/test_stock_ledger_entry.py
index f7c6ffe..d8a3f2e 100644
--- a/erpnext/stock/doctype/stock_ledger_entry/test_stock_ledger_entry.py
+++ b/erpnext/stock/doctype/stock_ledger_entry/test_stock_ledger_entry.py
@@ -485,9 +485,9 @@
 		dns = create_delivery_note_entries_for_batchwise_item_valuation_test(dn_entry_list)
 		sle_details = fetch_sle_details_for_doc_list(dns, ["stock_value_difference"])
 		svd_list = [-1 * d["stock_value_difference"] for d in sle_details]
-		expected_incoming_rates = expected_abs_svd = sorted([75.0, 125.0, 75.0, 125.0])
+		expected_incoming_rates = expected_abs_svd = [75.0, 125.0, 75.0, 125.0]
 
-		self.assertEqual(expected_abs_svd, sorted(svd_list), "Incorrect 'Stock Value Difference' values")
+		self.assertEqual(expected_abs_svd, svd_list, "Incorrect 'Stock Value Difference' values")
 		for dn, incoming_rate in zip(dns, expected_incoming_rates):
 			self.assertTrue(
 				dn.items[0].incoming_rate in expected_abs_svd,
diff --git a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py
index 1bf143b..e8d652e 100644
--- a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py
+++ b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py
@@ -29,6 +29,34 @@
 
 
 class StockReconciliation(StockController):
+	# 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
+
+		from erpnext.stock.doctype.stock_reconciliation_item.stock_reconciliation_item import (
+			StockReconciliationItem,
+		)
+
+		amended_from: DF.Link | None
+		company: DF.Link
+		cost_center: DF.Link | None
+		difference_amount: DF.Currency
+		expense_account: DF.Link | None
+		items: DF.Table[StockReconciliationItem]
+		naming_series: DF.Literal["MAT-RECO-.YYYY.-"]
+		posting_date: DF.Date
+		posting_time: DF.Time
+		purpose: DF.Literal["", "Opening Stock", "Stock Reconciliation"]
+		scan_barcode: DF.Data | None
+		scan_mode: DF.Check
+		set_posting_time: DF.Check
+		set_warehouse: DF.Link | None
+	# end: auto-generated types
+
 	def __init__(self, *args, **kwargs):
 		super(StockReconciliation, self).__init__(*args, **kwargs)
 		self.head_row = ["Item Code", "Warehouse", "Quantity", "Valuation Rate"]
diff --git a/erpnext/stock/doctype/stock_reconciliation_item/stock_reconciliation_item.py b/erpnext/stock/doctype/stock_reconciliation_item/stock_reconciliation_item.py
index b3b5d08..c82cdf5 100644
--- a/erpnext/stock/doctype/stock_reconciliation_item/stock_reconciliation_item.py
+++ b/erpnext/stock/doctype/stock_reconciliation_item/stock_reconciliation_item.py
@@ -6,4 +6,36 @@
 
 
 class StockReconciliationItem(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
+
+		allow_zero_valuation_rate: DF.Check
+		amount: DF.Currency
+		amount_difference: DF.Currency
+		barcode: DF.Data | None
+		batch_no: DF.Link | None
+		current_amount: DF.Currency
+		current_qty: DF.Float
+		current_serial_and_batch_bundle: DF.Link | None
+		current_serial_no: DF.LongText | None
+		current_valuation_rate: DF.Currency
+		has_item_scanned: DF.Data | None
+		item_code: DF.Link
+		item_name: DF.Data | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		qty: DF.Float
+		quantity_difference: DF.ReadOnly | None
+		serial_and_batch_bundle: DF.Link | None
+		serial_no: DF.LongText | None
+		valuation_rate: DF.Currency
+		warehouse: DF.Link
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/stock/doctype/stock_reposting_settings/stock_reposting_settings.py b/erpnext/stock/doctype/stock_reposting_settings/stock_reposting_settings.py
index 51fb5ac..50f3981 100644
--- a/erpnext/stock/doctype/stock_reposting_settings/stock_reposting_settings.py
+++ b/erpnext/stock/doctype/stock_reposting_settings/stock_reposting_settings.py
@@ -8,6 +8,24 @@
 
 
 class StockRepostingSettings(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
+
+		end_time: DF.Time | None
+		item_based_reposting: DF.Check
+		limit_reposting_timeslot: DF.Check
+		limits_dont_apply_on: DF.Literal[
+			"", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"
+		]
+		notify_reposting_error_to_role: DF.Link | None
+		start_time: DF.Time | None
+	# end: auto-generated types
+
 	def validate(self):
 		self.set_minimum_reposting_time_slot()
 
diff --git a/erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py b/erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py
index 0954282..85550c2 100644
--- a/erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py
+++ b/erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py
@@ -13,6 +13,43 @@
 
 
 class StockReservationEntry(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
+
+		from erpnext.stock.doctype.serial_and_batch_entry.serial_and_batch_entry import (
+			SerialandBatchEntry,
+		)
+
+		amended_from: DF.Link | None
+		available_qty: DF.Float
+		company: DF.Link | None
+		delivered_qty: DF.Float
+		from_voucher_detail_no: DF.Data | None
+		from_voucher_no: DF.DynamicLink | None
+		from_voucher_type: DF.Literal["", "Pick List", "Purchase Receipt"]
+		has_batch_no: DF.Check
+		has_serial_no: DF.Check
+		item_code: DF.Link | None
+		project: DF.Link | None
+		reservation_based_on: DF.Literal["Qty", "Serial and Batch"]
+		reserved_qty: DF.Float
+		sb_entries: DF.Table[SerialandBatchEntry]
+		status: DF.Literal[
+			"Draft", "Partially Reserved", "Reserved", "Partially Delivered", "Delivered", "Cancelled"
+		]
+		stock_uom: DF.Link | None
+		voucher_detail_no: DF.Data | None
+		voucher_no: DF.DynamicLink | None
+		voucher_qty: DF.Float
+		voucher_type: DF.Literal["", "Sales Order"]
+		warehouse: DF.Link | None
+	# end: auto-generated types
+
 	def validate(self) -> None:
 		from erpnext.stock.utils import validate_disabled_warehouse, validate_warehouse_company
 
@@ -869,7 +906,7 @@
 	items = []
 	if items_details:
 		for item in items_details:
-			so_item = frappe.get_doc("Sales Order Item", item.get("name"))
+			so_item = frappe.get_doc("Sales Order Item", item.get("sales_order_item"))
 			so_item.warehouse = item.get("warehouse")
 			so_item.qty_to_reserve = (
 				flt(item.get("qty_to_reserve"))
@@ -1053,12 +1090,14 @@
 	from_voucher_type: Literal["Pick List", "Purchase Receipt"] = None,
 	from_voucher_no: str = None,
 	from_voucher_detail_no: str = None,
-	sre_list: list[dict] = None,
+	sre_list: list = None,
 	notify: bool = True,
 ) -> None:
 	"""Cancel Stock Reservation Entries."""
 
 	if not sre_list:
+		sre_list = {}
+
 		if voucher_type and voucher_no:
 			sre_list = get_stock_reservation_entries_for_voucher(
 				voucher_type, voucher_no, voucher_detail_no, fields=["name"]
@@ -1082,9 +1121,11 @@
 
 			sre_list = query.run(as_dict=True)
 
+		sre_list = [d.name for d in sre_list]
+
 	if sre_list:
 		for sre in sre_list:
-			frappe.get_doc("Stock Reservation Entry", sre["name"]).cancel()
+			frappe.get_doc("Stock Reservation Entry", sre).cancel()
 
 		if notify:
 			msg = _("Stock Reservation Entries Cancelled")
diff --git a/erpnext/stock/doctype/stock_settings/stock_settings.py b/erpnext/stock/doctype/stock_settings/stock_settings.py
index c7afb10..088c7cd 100644
--- a/erpnext/stock/doctype/stock_settings/stock_settings.py
+++ b/erpnext/stock/doctype/stock_settings/stock_settings.py
@@ -15,6 +15,51 @@
 
 
 class StockSettings(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
+
+		action_if_quality_inspection_is_not_submitted: DF.Literal["Stop", "Warn"]
+		action_if_quality_inspection_is_rejected: DF.Literal["Stop", "Warn"]
+		allow_from_dn: DF.Check
+		allow_from_pr: DF.Check
+		allow_negative_stock: DF.Check
+		allow_partial_reservation: DF.Check
+		allow_to_edit_stock_uom_qty_for_purchase: DF.Check
+		allow_to_edit_stock_uom_qty_for_sales: DF.Check
+		auto_create_serial_and_batch_bundle_for_outward: DF.Check
+		auto_indent: DF.Check
+		auto_insert_price_list_rate_if_missing: DF.Check
+		auto_reserve_serial_and_batch: DF.Check
+		auto_reserve_stock_for_sales_order_on_purchase: DF.Check
+		clean_description_html: DF.Check
+		default_warehouse: DF.Link | None
+		disable_serial_no_and_batch_selector: DF.Check
+		enable_stock_reservation: DF.Check
+		item_group: DF.Link | None
+		item_naming_by: DF.Literal["Item Code", "Naming Series"]
+		mr_qty_allowance: DF.Float
+		naming_series_prefix: DF.Data | None
+		over_delivery_receipt_allowance: DF.Float
+		pick_serial_and_batch_based_on: DF.Literal["FIFO", "LIFO", "Expiry"]
+		reorder_email_notify: DF.Check
+		role_allowed_to_create_edit_back_dated_transactions: DF.Link | None
+		role_allowed_to_over_deliver_receive: DF.Link | None
+		sample_retention_warehouse: DF.Link | None
+		show_barcode_field: DF.Check
+		stock_auth_role: DF.Link | None
+		stock_frozen_upto: DF.Date | None
+		stock_frozen_upto_days: DF.Int
+		stock_uom: DF.Link | None
+		update_existing_price_list_rate: DF.Check
+		use_naming_series: DF.Check
+		valuation_method: DF.Literal["FIFO", "Moving Average", "LIFO"]
+	# end: auto-generated types
+
 	def validate(self):
 		for key in [
 			"item_naming_by",
diff --git a/erpnext/stock/doctype/uom_category/uom_category.py b/erpnext/stock/doctype/uom_category/uom_category.py
index 844f6e6..edbd1b9 100644
--- a/erpnext/stock/doctype/uom_category/uom_category.py
+++ b/erpnext/stock/doctype/uom_category/uom_category.py
@@ -6,4 +6,15 @@
 
 
 class UOMCategory(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
+
+		category_name: DF.Data
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/stock/doctype/uom_conversion_detail/uom_conversion_detail.py b/erpnext/stock/doctype/uom_conversion_detail/uom_conversion_detail.py
index e17a01e..d73ba65 100644
--- a/erpnext/stock/doctype/uom_conversion_detail/uom_conversion_detail.py
+++ b/erpnext/stock/doctype/uom_conversion_detail/uom_conversion_detail.py
@@ -6,4 +6,19 @@
 
 
 class UOMConversionDetail(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
+
+		conversion_factor: DF.Float
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		uom: DF.Link | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/stock/doctype/variant_field/variant_field.py b/erpnext/stock/doctype/variant_field/variant_field.py
index e8e02a0..65c9ee7 100644
--- a/erpnext/stock/doctype/variant_field/variant_field.py
+++ b/erpnext/stock/doctype/variant_field/variant_field.py
@@ -6,4 +6,18 @@
 
 
 class VariantField(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
+
+		field_name: DF.Autocomplete
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/stock/doctype/warehouse/warehouse.py b/erpnext/stock/doctype/warehouse/warehouse.py
index 430a8d1..ef9b12e 100644
--- a/erpnext/stock/doctype/warehouse/warehouse.py
+++ b/erpnext/stock/doctype/warehouse/warehouse.py
@@ -13,6 +13,35 @@
 
 
 class Warehouse(NestedSet):
+	# 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: DF.Link | None
+		address_line_1: DF.Data | None
+		address_line_2: DF.Data | None
+		city: DF.Data | None
+		company: DF.Link
+		default_in_transit_warehouse: DF.Link | None
+		disabled: DF.Check
+		email_id: DF.Data | None
+		is_group: DF.Check
+		lft: DF.Int
+		mobile_no: DF.Data | None
+		old_parent: DF.Link | None
+		parent_warehouse: DF.Link | None
+		phone_no: DF.Data | None
+		pin: DF.Data | None
+		rgt: DF.Int
+		state: DF.Data | None
+		warehouse_name: DF.Data
+		warehouse_type: DF.Link | None
+	# end: auto-generated types
+
 	nsm_parent_field = "parent_warehouse"
 
 	def autoname(self):
diff --git a/erpnext/stock/doctype/warehouse_type/warehouse_type.py b/erpnext/stock/doctype/warehouse_type/warehouse_type.py
index 3e07fe7..91c83ba 100644
--- a/erpnext/stock/doctype/warehouse_type/warehouse_type.py
+++ b/erpnext/stock/doctype/warehouse_type/warehouse_type.py
@@ -7,4 +7,15 @@
 
 
 class WarehouseType(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
+
+		description: DF.SmallText | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/stock/get_item_details.py b/erpnext/stock/get_item_details.py
index c766cab..dfeb1ee 100644
--- a/erpnext/stock/get_item_details.py
+++ b/erpnext/stock/get_item_details.py
@@ -8,6 +8,7 @@
 from frappe import _, throw
 from frappe.model import child_table_fields, default_fields
 from frappe.model.meta import get_field_precision
+from frappe.model.utils import get_fetch_values
 from frappe.query_builder.functions import IfNull, Sum
 from frappe.utils import add_days, add_months, cint, cstr, flt, getdate
 
@@ -149,7 +150,7 @@
 
 
 def set_valuation_rate(out, args):
-	if frappe.db.exists("Product Bundle", args.item_code, cache=True):
+	if frappe.db.exists("Product Bundle", {"name": args.item_code, "disabled": 0}, cache=True):
 		valuation_rate = 0.0
 		bundled_items = frappe.get_doc("Product Bundle", args.item_code)
 
@@ -571,6 +572,9 @@
 			item_tax_template = _get_item_tax_template(args, item_group_doc.taxes, out)
 			item_group = item_group_doc.parent_item_group
 
+	if args.child_doctype and item_tax_template:
+		out.update(get_fetch_values(args.child_doctype, "item_tax_template", item_tax_template))
+
 
 def _get_item_tax_template(args, taxes, out=None, for_validate=False):
 	if out is None:
diff --git a/erpnext/stock/report/item_prices/item_prices.py b/erpnext/stock/report/item_prices/item_prices.py
index ab47b4a..a53a9f2 100644
--- a/erpnext/stock/report/item_prices/item_prices.py
+++ b/erpnext/stock/report/item_prices/item_prices.py
@@ -202,7 +202,7 @@
 	bin_data = (
 		frappe.qb.from_(bin)
 		.select(
-			bin.item_code, Sum(bin.actual_qty * bin.valuation_rate) / Sum(bin.actual_qty).as_("val_rate")
+			bin.item_code, (Sum(bin.actual_qty * bin.valuation_rate) / Sum(bin.actual_qty)).as_("val_rate")
 		)
 		.where(bin.actual_qty > 0)
 		.groupby(bin.item_code)
diff --git a/erpnext/stock/report/serial_no_ledger/serial_no_ledger.py b/erpnext/stock/report/serial_no_ledger/serial_no_ledger.py
index 7212b92..ae12fbb 100644
--- a/erpnext/stock/report/serial_no_ledger/serial_no_ledger.py
+++ b/erpnext/stock/report/serial_no_ledger/serial_no_ledger.py
@@ -36,21 +36,27 @@
 			"fieldtype": "Link",
 			"fieldname": "company",
 			"options": "Company",
-			"width": 150,
+			"width": 120,
 		},
 		{
 			"label": _("Warehouse"),
 			"fieldtype": "Link",
 			"fieldname": "warehouse",
 			"options": "Warehouse",
-			"width": 150,
+			"width": 120,
+		},
+		{
+			"label": _("Status"),
+			"fieldtype": "Data",
+			"fieldname": "status",
+			"width": 120,
 		},
 		{
 			"label": _("Serial No"),
 			"fieldtype": "Link",
 			"fieldname": "serial_no",
 			"options": "Serial No",
-			"width": 150,
+			"width": 130,
 		},
 		{
 			"label": _("Valuation Rate"),
@@ -58,6 +64,12 @@
 			"fieldname": "valuation_rate",
 			"width": 150,
 		},
+		{
+			"label": _("Qty"),
+			"fieldtype": "Float",
+			"fieldname": "qty",
+			"width": 150,
+		},
 	]
 
 	return columns
@@ -83,12 +95,16 @@
 				"posting_time": row.posting_time,
 				"voucher_type": row.voucher_type,
 				"voucher_no": row.voucher_no,
+				"status": "Active" if row.actual_qty > 0 else "Delivered",
 				"company": row.company,
 				"warehouse": row.warehouse,
+				"qty": 1 if row.actual_qty > 0 else -1,
 			}
 		)
 
-		serial_nos = bundle_wise_serial_nos.get(row.serial_and_batch_bundle, [])
+		serial_nos = [{"serial_no": row.serial_no, "valuation_rate": row.valuation_rate}]
+		if row.serial_and_batch_bundle:
+			serial_nos = bundle_wise_serial_nos.get(row.serial_and_batch_bundle, [])
 
 		for index, bundle_data in enumerate(serial_nos):
 			if index == 0:
diff --git a/erpnext/stock/report/stock_analytics/stock_analytics.js b/erpnext/stock/report/stock_analytics/stock_analytics.js
index ea7bf56..e033fd9 100644
--- a/erpnext/stock/report/stock_analytics/stock_analytics.js
+++ b/erpnext/stock/report/stock_analytics/stock_analytics.js
@@ -17,6 +17,7 @@
 			fieldtype: "Link",
 			options:"Item",
 			default: "",
+			get_query: () => ({filters: { 'is_stock_item': 1 }}),
 		},
 		{
 			fieldname: "value_quantity",
diff --git a/erpnext/stock/report/stock_analytics/stock_analytics.py b/erpnext/stock/report/stock_analytics/stock_analytics.py
index 6c5b58c..ab48181 100644
--- a/erpnext/stock/report/stock_analytics/stock_analytics.py
+++ b/erpnext/stock/report/stock_analytics/stock_analytics.py
@@ -270,7 +270,7 @@
 	if item_code := filters.get("item_code"):
 		return [item_code]
 	else:
-		item_filters = {}
+		item_filters = {"is_stock_item": 1}
 		if item_group := filters.get("item_group"):
 			children = get_descendants_of("Item Group", item_group, ignore_permissions=True)
 			item_filters["item_group"] = ("in", children + [item_group])
diff --git a/erpnext/stock/report/stock_and_account_value_comparison/stock_and_account_value_comparison.py b/erpnext/stock/report/stock_and_account_value_comparison/stock_and_account_value_comparison.py
index b1da3ec..416cf48 100644
--- a/erpnext/stock/report/stock_and_account_value_comparison/stock_and_account_value_comparison.py
+++ b/erpnext/stock/report/stock_and_account_value_comparison/stock_and_account_value_comparison.py
@@ -166,4 +166,4 @@
 
 	if entries:
 		entries = ", ".join(entries)
-		frappe.msgprint(_(f"Reposting entries created: {entries}"))
+		frappe.msgprint(_("Reposting entries created: {0}").format(entries))
diff --git a/erpnext/stock/serial_batch_bundle.py b/erpnext/stock/serial_batch_bundle.py
index 5998274..0c18792 100644
--- a/erpnext/stock/serial_batch_bundle.py
+++ b/erpnext/stock/serial_batch_bundle.py
@@ -129,7 +129,9 @@
 			frappe.throw(_(error_msg))
 
 	def set_serial_and_batch_bundle(self, sn_doc):
-		self.sle.db_set("serial_and_batch_bundle", sn_doc.name)
+		self.sle.db_set(
+			{"serial_and_batch_bundle": sn_doc.name, "auto_created_serial_and_batch_bundle": 1}
+		)
 
 		if sn_doc.is_rejected:
 			frappe.db.set_value(
@@ -143,6 +145,12 @@
 	@property
 	def child_doctype(self):
 		child_doctype = self.sle.voucher_type + " Item"
+
+		if (
+			self.sle.voucher_type == "Subcontracting Receipt" and self.sle.dependant_sle_voucher_detail_no
+		):
+			child_doctype = "Subcontracting Receipt Supplied Item"
+
 		if self.sle.voucher_type == "Stock Entry":
 			child_doctype = "Stock Entry Detail"
 
@@ -247,11 +255,15 @@
 		if not serial_nos:
 			return
 
+		status = "Inactive"
+		if self.sle.actual_qty < 0:
+			status = "Delivered"
+
 		sn_table = frappe.qb.DocType("Serial No")
 		(
 			frappe.qb.update(sn_table)
 			.set(sn_table.warehouse, warehouse)
-			.set(sn_table.status, "Active" if warehouse else "Inactive")
+			.set(sn_table.status, "Active" if warehouse else status)
 			.where(sn_table.name.isin(serial_nos))
 		).run()
 
@@ -394,7 +406,7 @@
 			.orderby(bundle.posting_date, bundle.posting_time, bundle.creation)
 		)
 
-		# Important to exclude the current voucher
+		# Important to exclude the current voucher to calculate correct the stock value difference
 		if self.sle.voucher_no:
 			query = query.where(bundle.voucher_no != self.sle.voucher_no)
 
@@ -527,8 +539,10 @@
 			.groupby(child.batch_no)
 		)
 
-		# Important to exclude the current voucher
-		if self.sle.voucher_no:
+		# Important to exclude the current voucher detail no / voucher no to calculate the correct stock value difference
+		if self.sle.voucher_detail_no:
+			query = query.where(parent.voucher_detail_no != self.sle.voucher_detail_no)
+		elif self.sle.voucher_no:
 			query = query.where(parent.voucher_no != self.sle.voucher_no)
 
 		if timestamp_condition:
diff --git a/erpnext/stock/stock_ledger.py b/erpnext/stock/stock_ledger.py
index 6390894..9142a27 100644
--- a/erpnext/stock/stock_ledger.py
+++ b/erpnext/stock/stock_ledger.py
@@ -766,7 +766,9 @@
 		sle.doctype = "Stock Ledger Entry"
 		frappe.get_doc(sle).db_update()
 
-		if not self.args.get("sle_id"):
+		if not self.args.get("sle_id") or (
+			sle.serial_and_batch_bundle and sle.auto_created_serial_and_batch_bundle
+		):
 			self.update_outgoing_rate_on_transaction(sle)
 
 	def reset_actual_qty_for_stock_reco(self, sle):
diff --git a/erpnext/subcontracting/doctype/subcontracting_bom/subcontracting_bom.py b/erpnext/subcontracting/doctype/subcontracting_bom/subcontracting_bom.py
index 49ba986..6a889b1 100644
--- a/erpnext/subcontracting/doctype/subcontracting_bom/subcontracting_bom.py
+++ b/erpnext/subcontracting/doctype/subcontracting_bom/subcontracting_bom.py
@@ -8,6 +8,25 @@
 
 
 class SubcontractingBOM(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
+
+		conversion_factor: DF.Float
+		finished_good: DF.Link
+		finished_good_bom: DF.Link
+		finished_good_qty: DF.Float
+		finished_good_uom: DF.Link | None
+		is_active: DF.Check
+		service_item: DF.Link
+		service_item_qty: DF.Float
+		service_item_uom: DF.Link
+	# end: auto-generated types
+
 	def validate(self):
 		self.validate_finished_good()
 		self.validate_service_item()
diff --git a/erpnext/subcontracting/doctype/subcontracting_order/subcontracting_order.py b/erpnext/subcontracting/doctype/subcontracting_order/subcontracting_order.py
index faf0cad..6c187f8 100644
--- a/erpnext/subcontracting/doctype/subcontracting_order/subcontracting_order.py
+++ b/erpnext/subcontracting/doctype/subcontracting_order/subcontracting_order.py
@@ -8,11 +8,95 @@
 
 from erpnext.buying.doctype.purchase_order.purchase_order import is_subcontracting_order_created
 from erpnext.controllers.subcontracting_controller import SubcontractingController
-from erpnext.stock.stock_balance import get_ordered_qty, update_bin_qty
+from erpnext.stock.stock_balance import update_bin_qty
 from erpnext.stock.utils import get_bin
 
 
 class SubcontractingOrder(SubcontractingController):
+	# 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
+
+		from erpnext.stock.doctype.landed_cost_taxes_and_charges.landed_cost_taxes_and_charges import (
+			LandedCostTaxesandCharges,
+		)
+		from erpnext.subcontracting.doctype.subcontracting_order_item.subcontracting_order_item import (
+			SubcontractingOrderItem,
+		)
+		from erpnext.subcontracting.doctype.subcontracting_order_service_item.subcontracting_order_service_item import (
+			SubcontractingOrderServiceItem,
+		)
+		from erpnext.subcontracting.doctype.subcontracting_order_supplied_item.subcontracting_order_supplied_item import (
+			SubcontractingOrderSuppliedItem,
+		)
+
+		additional_costs: DF.Table[LandedCostTaxesandCharges]
+		address_display: DF.SmallText | None
+		amended_from: DF.Link | None
+		billing_address: DF.Link | None
+		billing_address_display: DF.SmallText | None
+		company: DF.Link
+		contact_display: DF.SmallText | None
+		contact_email: DF.SmallText | None
+		contact_mobile: DF.SmallText | None
+		contact_person: DF.Link | None
+		cost_center: DF.Link | None
+		distribute_additional_costs_based_on: DF.Literal["Qty", "Amount"]
+		items: DF.Table[SubcontractingOrderItem]
+		letter_head: DF.Link | None
+		naming_series: DF.Literal["SC-ORD-.YYYY.-"]
+		per_received: DF.Percent
+		project: DF.Link | None
+		purchase_order: DF.Link
+		schedule_date: DF.Date | None
+		select_print_heading: DF.Link | None
+		service_items: DF.Table[SubcontractingOrderServiceItem]
+		set_reserve_warehouse: DF.Link | None
+		set_warehouse: DF.Link | None
+		shipping_address: DF.Link | None
+		shipping_address_display: DF.SmallText | None
+		status: DF.Literal[
+			"Draft",
+			"Open",
+			"Partially Received",
+			"Completed",
+			"Material Transferred",
+			"Partial Material Transferred",
+			"Cancelled",
+		]
+		supplied_items: DF.Table[SubcontractingOrderSuppliedItem]
+		supplier: DF.Link
+		supplier_address: DF.Link | None
+		supplier_name: DF.Data
+		supplier_warehouse: DF.Link
+		title: DF.Data | None
+		total: DF.Currency
+		total_additional_costs: DF.Currency
+		total_qty: DF.Float
+		transaction_date: DF.Date
+	# end: auto-generated types
+
+	def __init__(self, *args, **kwargs):
+		super(SubcontractingOrder, self).__init__(*args, **kwargs)
+
+		self.status_updater = [
+			{
+				"source_dt": "Subcontracting Order Item",
+				"target_dt": "Material Request Item",
+				"join_field": "material_request_item",
+				"target_field": "ordered_qty",
+				"target_parent_dt": "Material Request",
+				"target_parent_field": "per_ordered",
+				"target_ref_field": "stock_qty",
+				"source_field": "qty",
+				"percent_join_field": "material_request",
+			}
+		]
+
 	def before_validate(self):
 		super(SubcontractingOrder, self).before_validate()
 
@@ -26,11 +110,15 @@
 		self.reset_default_field_value("set_warehouse", "items", "warehouse")
 
 	def on_submit(self):
+		self.update_prevdoc_status()
+		self.update_requested_qty()
 		self.update_ordered_qty_for_subcontracting()
 		self.update_reserved_qty_for_subcontracting()
 		self.update_status()
 
 	def on_cancel(self):
+		self.update_prevdoc_status()
+		self.update_requested_qty()
 		self.update_ordered_qty_for_subcontracting()
 		self.update_reserved_qty_for_subcontracting()
 		self.update_status()
@@ -114,7 +202,32 @@
 			):
 				item_wh_list.append([item.item_code, item.warehouse])
 		for item_code, warehouse in item_wh_list:
-			update_bin_qty(item_code, warehouse, {"ordered_qty": get_ordered_qty(item_code, warehouse)})
+			update_bin_qty(
+				item_code, warehouse, {"ordered_qty": self.get_ordered_qty(item_code, warehouse)}
+			)
+
+	@staticmethod
+	def get_ordered_qty(item_code, warehouse):
+		table = frappe.qb.DocType("Subcontracting Order")
+		child = frappe.qb.DocType("Subcontracting Order Item")
+
+		query = (
+			frappe.qb.from_(table)
+			.inner_join(child)
+			.on(table.name == child.parent)
+			.select((child.qty - child.received_qty) * child.conversion_factor)
+			.where(
+				(table.docstatus == 1)
+				& (child.item_code == item_code)
+				& (child.warehouse == warehouse)
+				& (child.qty > child.received_qty)
+				& (table.status != "Completed")
+			)
+		)
+
+		query = query.run()
+
+		return flt(query[0][0]) if query else 0
 
 	def update_reserved_qty_for_subcontracting(self):
 		for item in self.supplied_items:
@@ -134,6 +247,7 @@
 					)
 					or item.default_bom
 				)
+
 				items.append(
 					{
 						"item_code": item.item_code,
@@ -143,7 +257,10 @@
 						"qty": si.fg_item_qty,
 						"stock_uom": item.stock_uom,
 						"bom": bom,
-					},
+						"purchase_order_item": si.purchase_order_item,
+						"material_request": si.material_request,
+						"material_request_item": si.material_request_item,
+					}
 				)
 			else:
 				frappe.throw(
@@ -151,11 +268,12 @@
 						si.item_name or si.item_code
 					)
 				)
-		else:
+
+		if items:
 			for item in items:
 				self.append("items", item)
-			else:
-				self.set_missing_values()
+
+		self.set_missing_values()
 
 	def update_status(self, status=None, update_modified=True):
 		if self.docstatus >= 1 and not status:
@@ -197,9 +315,11 @@
 
 
 def get_mapped_subcontracting_receipt(source_name, target_doc=None):
-	def update_item(obj, target, source_parent):
-		target.qty = flt(obj.qty) - flt(obj.received_qty)
-		target.amount = (flt(obj.qty) - flt(obj.received_qty)) * flt(obj.rate)
+	def update_item(source, target, source_parent):
+		target.purchase_order = source_parent.purchase_order
+		target.purchase_order_item = source.purchase_order_item
+		target.qty = flt(source.qty) - flt(source.received_qty)
+		target.amount = (flt(source.qty) - flt(source.received_qty)) * flt(source.rate)
 
 	target_doc = get_mapped_doc(
 		"Subcontracting Order",
diff --git a/erpnext/subcontracting/doctype/subcontracting_order/test_subcontracting_order.py b/erpnext/subcontracting/doctype/subcontracting_order/test_subcontracting_order.py
index 22fdc13..37dabf1 100644
--- a/erpnext/subcontracting/doctype/subcontracting_order/test_subcontracting_order.py
+++ b/erpnext/subcontracting/doctype/subcontracting_order/test_subcontracting_order.py
@@ -6,6 +6,7 @@
 
 import frappe
 from frappe.tests.utils import FrappeTestCase
+from frappe.utils import flt
 
 from erpnext.buying.doctype.purchase_order.purchase_order import get_mapped_subcontracting_order
 from erpnext.controllers.subcontracting_controller import (
@@ -566,6 +567,123 @@
 		self.assertEqual(sco.status, "Closed")
 		self.assertEqual(sco.supplied_items[0].returned_qty, 5)
 
+	def test_ordered_qty_for_subcontracting_order(self):
+		service_items = [
+			{
+				"warehouse": "_Test Warehouse - _TC",
+				"item_code": "Subcontracted Service Item 8",
+				"qty": 10,
+				"rate": 100,
+				"fg_item": "Subcontracted Item SA8",
+				"fg_item_qty": 10,
+			},
+		]
+
+		ordered_qty = frappe.db.get_value(
+			"Bin",
+			filters={"warehouse": "_Test Warehouse - _TC", "item_code": "Subcontracted Item SA8"},
+			fieldname="ordered_qty",
+		)
+		ordered_qty = flt(ordered_qty)
+
+		sco = get_subcontracting_order(service_items=service_items)
+		sco.reload()
+
+		new_ordered_qty = frappe.db.get_value(
+			"Bin",
+			filters={"warehouse": "_Test Warehouse - _TC", "item_code": "Subcontracted Item SA8"},
+			fieldname="ordered_qty",
+		)
+		new_ordered_qty = flt(new_ordered_qty)
+
+		self.assertEqual(ordered_qty + 10, new_ordered_qty)
+
+		for row in sco.supplied_items:
+			make_stock_entry(
+				target="_Test Warehouse 1 - _TC",
+				item_code=row.rm_item_code,
+				qty=row.required_qty,
+				basic_rate=100,
+			)
+
+		scr = make_subcontracting_receipt(sco.name)
+		scr.submit()
+
+		new_ordered_qty = frappe.db.get_value(
+			"Bin",
+			filters={"warehouse": "_Test Warehouse - _TC", "item_code": "Subcontracted Item SA8"},
+			fieldname="ordered_qty",
+		)
+
+		self.assertEqual(ordered_qty, new_ordered_qty)
+
+		scr.reload()
+		scr.cancel()
+
+		new_ordered_qty = frappe.db.get_value(
+			"Bin",
+			filters={"warehouse": "_Test Warehouse - _TC", "item_code": "Subcontracted Item SA8"},
+			fieldname="ordered_qty",
+		)
+
+		self.assertEqual(ordered_qty + 10, new_ordered_qty)
+
+	def test_requested_qty_for_subcontracting_order(self):
+		from erpnext.stock.doctype.material_request.material_request import make_purchase_order
+		from erpnext.stock.doctype.material_request.test_material_request import make_material_request
+
+		requested_qty = frappe.db.get_value(
+			"Bin",
+			filters={"warehouse": "_Test Warehouse - _TC", "item_code": "Subcontracted Item SA8"},
+			fieldname="indented_qty",
+		)
+		requested_qty = flt(requested_qty)
+
+		mr = make_material_request(
+			item_code="Subcontracted Item SA8",
+			material_request_type="Purchase",
+			qty=10,
+		)
+
+		self.assertTrue(mr.docstatus == 1)
+
+		new_requested_qty = frappe.db.get_value(
+			"Bin",
+			filters={"warehouse": "_Test Warehouse - _TC", "item_code": "Subcontracted Item SA8"},
+			fieldname="indented_qty",
+		)
+		new_requested_qty = flt(new_requested_qty)
+
+		self.assertEqual(requested_qty + 10, new_requested_qty)
+
+		po = make_purchase_order(mr.name)
+		po.is_subcontracted = 1
+		po.supplier = "_Test Supplier"
+		po.items[0].fg_item = "Subcontracted Item SA8"
+		po.items[0].fg_item_qty = 10
+		po.items[0].item_code = "Subcontracted Service Item 8"
+		po.items[0].item_name = "Subcontracted Service Item 8"
+		po.items[0].qty = 10
+		po.supplier_warehouse = "_Test Warehouse 1 - _TC"
+		po.save()
+		po.submit()
+
+		self.assertTrue(po.items[0].material_request)
+		self.assertTrue(po.items[0].material_request_item)
+
+		sco = create_subcontracting_order(po_name=po.name)
+		self.assertTrue(sco.items[0].material_request)
+		self.assertTrue(sco.items[0].material_request_item)
+
+		new_requested_qty = frappe.db.get_value(
+			"Bin",
+			filters={"warehouse": "_Test Warehouse - _TC", "item_code": "Subcontracted Item SA8"},
+			fieldname="indented_qty",
+		)
+		new_requested_qty = flt(new_requested_qty)
+
+		self.assertEqual(requested_qty, new_requested_qty)
+
 
 def create_subcontracting_order(**args):
 	args = frappe._dict(args)
diff --git a/erpnext/subcontracting/doctype/subcontracting_order_item/subcontracting_order_item.json b/erpnext/subcontracting/doctype/subcontracting_order_item/subcontracting_order_item.json
index d77e774..1ca90c3 100644
--- a/erpnext/subcontracting/doctype/subcontracting_order_item/subcontracting_order_item.json
+++ b/erpnext/subcontracting/doctype/subcontracting_order_item/subcontracting_order_item.json
@@ -40,11 +40,17 @@
   "manufacture_section",
   "manufacturer",
   "manufacturer_part_no",
+  "column_break_impp",
+  "reference_section",
+  "material_request",
+  "column_break_fpyl",
+  "material_request_item",
   "accounting_dimensions_section",
   "cost_center",
   "dimension_col_break",
   "project",
   "section_break_34",
+  "purchase_order_item",
   "page_break"
  ],
  "fields": [
@@ -112,6 +118,7 @@
    "fieldtype": "Column Break"
   },
   {
+   "fetch_from": "item_code.image",
    "fieldname": "image",
    "fieldtype": "Attach",
    "hidden": 1,
@@ -331,13 +338,53 @@
    "fieldtype": "Link",
    "label": "Project",
    "options": "Project"
+  },
+  {
+   "fieldname": "column_break_impp",
+   "fieldtype": "Column Break"
+  },
+  {
+   "fieldname": "material_request",
+   "fieldtype": "Link",
+   "label": "Material Request",
+   "no_copy": 1,
+   "options": "Material Request",
+   "read_only": 1,
+   "search_index": 1
+  },
+  {
+   "fieldname": "material_request_item",
+   "fieldtype": "Data",
+   "label": "Material Request Item",
+   "no_copy": 1,
+   "read_only": 1,
+   "search_index": 1
+  },
+  {
+   "collapsible": 1,
+   "fieldname": "reference_section",
+   "fieldtype": "Section Break",
+   "label": "Reference"
+  },
+  {
+   "fieldname": "column_break_fpyl",
+   "fieldtype": "Column Break"
+  },
+  {
+   "fieldname": "purchase_order_item",
+   "fieldtype": "Data",
+   "hidden": 1,
+   "label": "Purchase Order Item",
+   "no_copy": 1,
+   "read_only": 1,
+   "search_index": 1
   }
  ],
  "idx": 1,
  "index_web_pages_for_search": 1,
  "istable": 1,
  "links": [],
- "modified": "2023-01-20 23:25:45.363281",
+ "modified": "2023-11-30 15:29:43.744618",
  "modified_by": "Administrator",
  "module": "Subcontracting",
  "name": "Subcontracting Order Item",
diff --git a/erpnext/subcontracting/doctype/subcontracting_order_item/subcontracting_order_item.py b/erpnext/subcontracting/doctype/subcontracting_order_item/subcontracting_order_item.py
index 174f5b2..fcd143c 100644
--- a/erpnext/subcontracting/doctype/subcontracting_order_item/subcontracting_order_item.py
+++ b/erpnext/subcontracting/doctype/subcontracting_order_item/subcontracting_order_item.py
@@ -6,4 +6,43 @@
 
 
 class SubcontractingOrderItem(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
+
+		additional_cost_per_qty: DF.Currency
+		amount: DF.Currency
+		bom: DF.Link
+		conversion_factor: DF.Float
+		cost_center: DF.Link | None
+		description: DF.TextEditor
+		expected_delivery_date: DF.Date | None
+		expense_account: DF.Link | None
+		image: DF.Attach | None
+		include_exploded_items: DF.Check
+		item_code: DF.Link
+		item_name: DF.Data
+		manufacturer: DF.Link | None
+		manufacturer_part_no: DF.Data | None
+		page_break: DF.Check
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		project: DF.Link | None
+		purchase_order_item: DF.Data | None
+		qty: DF.Float
+		rate: DF.Currency
+		received_qty: DF.Float
+		returned_qty: DF.Float
+		rm_cost_per_qty: DF.Currency
+		schedule_date: DF.Date | None
+		service_cost_per_qty: DF.Currency
+		stock_uom: DF.Link
+		warehouse: DF.Link
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/subcontracting/doctype/subcontracting_order_service_item/subcontracting_order_service_item.json b/erpnext/subcontracting/doctype/subcontracting_order_service_item/subcontracting_order_service_item.json
index f213313..f1e94e1 100644
--- a/erpnext/subcontracting/doctype/subcontracting_order_service_item/subcontracting_order_service_item.json
+++ b/erpnext/subcontracting/doctype/subcontracting_order_service_item/subcontracting_order_service_item.json
@@ -1,131 +1,170 @@
 {
-    "actions": [],
-    "autoname": "hash",
-    "creation": "2022-04-01 19:23:05.728354",
-    "doctype": "DocType",
-    "editable_grid": 1,
-    "engine": "InnoDB",
-    "field_order": [
-        "item_code",
-        "column_break_2",
-        "item_name",
-        "section_break_4",
-        "qty",
-        "column_break_6",
-        "rate",
-        "column_break_8",
-        "amount",
-        "section_break_10",
-        "fg_item",
-        "column_break_12",
-        "fg_item_qty"
-    ],
-    "fields": [
-        {
-            "bold": 1,
-            "columns": 2,
-            "fieldname": "item_code",
-            "fieldtype": "Link",
-            "in_list_view": 1,
-            "label": "Item Code",
-            "options": "Item",
-            "reqd": 1,
-            "search_index": 1
-        },
-        {
-            "fetch_from": "item_code.item_name",
-            "fieldname": "item_name",
-            "fieldtype": "Data",
-            "in_global_search": 1,
-            "in_list_view": 1,
-            "label": "Item Name",
-            "print_hide": 1,
-            "reqd": 1
-        },
-        {
-            "bold": 1,
-            "columns": 1,
-            "fieldname": "qty",
-            "fieldtype": "Float",
-            "in_list_view": 1,
-            "label": "Quantity",
-            "print_width": "60px",
-            "reqd": 1,
-            "width": "60px"
-        },
-        {
-            "bold": 1,
-            "columns": 2,
-            "fetch_from": "item_code.standard_rate",
-            "fetch_if_empty": 1,
-            "fieldname": "rate",
-            "fieldtype": "Currency",
-            "in_list_view": 1,
-            "label": "Rate",
-            "options": "currency",
-            "reqd": 1
-        },
-        {
-            "columns": 2,
-            "fieldname": "amount",
-            "fieldtype": "Currency",
-            "in_list_view": 1,
-            "label": "Amount",
-            "options": "currency",
-            "read_only": 1,
-            "reqd": 1
-        },
-        {
-            "fieldname": "fg_item",
-            "fieldtype": "Link",
-            "label": "Finished Good Item",
-            "options": "Item",
-            "reqd": 1
-        },
-        {
-            "default": "1",
-            "fieldname": "fg_item_qty",
-            "fieldtype": "Float",
-            "label": "Finished Good Item Quantity",
-            "reqd": 1
-        },
-        {
-            "fieldname": "column_break_2",
-            "fieldtype": "Column Break"
-        },
-        {
-            "fieldname": "section_break_4",
-            "fieldtype": "Section Break"
-        },
-        {
-            "fieldname": "column_break_6",
-            "fieldtype": "Column Break"
-        },
-        {
-            "fieldname": "column_break_8",
-            "fieldtype": "Column Break"
-        },
-        {
-            "fieldname": "section_break_10",
-            "fieldtype": "Section Break"
-        },
-        {
-            "fieldname": "column_break_12",
-            "fieldtype": "Column Break"
-        }
-    ],
-    "istable": 1,
-    "links": [],
-    "modified": "2022-04-07 11:43:43.094867",
-    "modified_by": "Administrator",
-    "module": "Subcontracting",
-    "name": "Subcontracting Order Service Item",
-    "naming_rule": "Random",
-    "owner": "Administrator",
-    "permissions": [],
-    "quick_entry": 1,
-    "search_fields": "item_name",
-    "sort_field": "modified",
-    "sort_order": "DESC",
-    "states": []
+ "actions": [],
+ "autoname": "hash",
+ "creation": "2022-04-01 19:23:05.728354",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "item_code",
+  "column_break_2",
+  "item_name",
+  "section_break_4",
+  "qty",
+  "column_break_6",
+  "rate",
+  "column_break_8",
+  "amount",
+  "section_break_10",
+  "fg_item",
+  "column_break_12",
+  "fg_item_qty",
+  "purchase_order_item",
+  "section_break_kphn",
+  "material_request",
+  "column_break_piqi",
+  "material_request_item"
+ ],
+ "fields": [
+  {
+   "bold": 1,
+   "columns": 2,
+   "fieldname": "item_code",
+   "fieldtype": "Link",
+   "in_list_view": 1,
+   "label": "Item Code",
+   "options": "Item",
+   "reqd": 1,
+   "search_index": 1
+  },
+  {
+   "fetch_from": "item_code.item_name",
+   "fieldname": "item_name",
+   "fieldtype": "Data",
+   "in_global_search": 1,
+   "in_list_view": 1,
+   "label": "Item Name",
+   "print_hide": 1,
+   "reqd": 1
+  },
+  {
+   "bold": 1,
+   "columns": 1,
+   "fieldname": "qty",
+   "fieldtype": "Float",
+   "in_list_view": 1,
+   "label": "Quantity",
+   "print_width": "60px",
+   "reqd": 1,
+   "width": "60px"
+  },
+  {
+   "bold": 1,
+   "columns": 2,
+   "fetch_from": "item_code.standard_rate",
+   "fetch_if_empty": 1,
+   "fieldname": "rate",
+   "fieldtype": "Currency",
+   "in_list_view": 1,
+   "label": "Rate",
+   "options": "currency",
+   "reqd": 1
+  },
+  {
+   "columns": 2,
+   "fieldname": "amount",
+   "fieldtype": "Currency",
+   "in_list_view": 1,
+   "label": "Amount",
+   "options": "currency",
+   "read_only": 1,
+   "reqd": 1
+  },
+  {
+   "fieldname": "fg_item",
+   "fieldtype": "Link",
+   "label": "Finished Good Item",
+   "options": "Item",
+   "reqd": 1
+  },
+  {
+   "default": "1",
+   "fieldname": "fg_item_qty",
+   "fieldtype": "Float",
+   "label": "Finished Good Item Quantity",
+   "reqd": 1
+  },
+  {
+   "fieldname": "column_break_2",
+   "fieldtype": "Column Break"
+  },
+  {
+   "fieldname": "section_break_4",
+   "fieldtype": "Section Break"
+  },
+  {
+   "fieldname": "column_break_6",
+   "fieldtype": "Column Break"
+  },
+  {
+   "fieldname": "column_break_8",
+   "fieldtype": "Column Break"
+  },
+  {
+   "fieldname": "section_break_10",
+   "fieldtype": "Section Break"
+  },
+  {
+   "fieldname": "column_break_12",
+   "fieldtype": "Column Break"
+  },
+  {
+   "fieldname": "purchase_order_item",
+   "fieldtype": "Data",
+   "hidden": 1,
+   "label": "Purchase Order Item",
+   "no_copy": 1,
+   "read_only": 1,
+   "search_index": 1
+  },
+  {
+   "collapsible": 1,
+   "fieldname": "section_break_kphn",
+   "fieldtype": "Section Break",
+   "label": "Reference"
+  },
+  {
+   "fieldname": "material_request",
+   "fieldtype": "Link",
+   "label": "Material Request",
+   "no_copy": 1,
+   "options": "Material Request",
+   "read_only": 1
+  },
+  {
+   "fieldname": "column_break_piqi",
+   "fieldtype": "Column Break"
+  },
+  {
+   "fieldname": "material_request_item",
+   "fieldtype": "Data",
+   "label": "Material Request Item",
+   "no_copy": 1,
+   "read_only": 1
+  }
+ ],
+ "istable": 1,
+ "links": [],
+ "modified": "2023-11-30 13:29:31.017440",
+ "modified_by": "Administrator",
+ "module": "Subcontracting",
+ "name": "Subcontracting Order Service Item",
+ "naming_rule": "Random",
+ "owner": "Administrator",
+ "permissions": [],
+ "quick_entry": 1,
+ "search_fields": "item_name",
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "states": []
 }
\ No newline at end of file
diff --git a/erpnext/subcontracting/doctype/subcontracting_order_service_item/subcontracting_order_service_item.py b/erpnext/subcontracting/doctype/subcontracting_order_service_item/subcontracting_order_service_item.py
index ad6289d..cc4901b 100644
--- a/erpnext/subcontracting/doctype/subcontracting_order_service_item/subcontracting_order_service_item.py
+++ b/erpnext/subcontracting/doctype/subcontracting_order_service_item/subcontracting_order_service_item.py
@@ -6,4 +6,25 @@
 
 
 class SubcontractingOrderServiceItem(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
+
+		amount: DF.Currency
+		fg_item: DF.Link
+		fg_item_qty: DF.Float
+		item_code: DF.Link
+		item_name: DF.Data
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		purchase_order_item: DF.Data | None
+		qty: DF.Float
+		rate: DF.Currency
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/subcontracting/doctype/subcontracting_order_supplied_item/subcontracting_order_supplied_item.py b/erpnext/subcontracting/doctype/subcontracting_order_supplied_item/subcontracting_order_supplied_item.py
index 5619e3b..4892601 100644
--- a/erpnext/subcontracting/doctype/subcontracting_order_supplied_item/subcontracting_order_supplied_item.py
+++ b/erpnext/subcontracting/doctype/subcontracting_order_supplied_item/subcontracting_order_supplied_item.py
@@ -6,4 +6,31 @@
 
 
 class SubcontractingOrderSuppliedItem(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
+
+		amount: DF.Currency
+		bom_detail_no: DF.Data | None
+		consumed_qty: DF.Float
+		conversion_factor: DF.Float
+		main_item_code: DF.Link | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		rate: DF.Currency
+		reference_name: DF.Data | None
+		required_qty: DF.Float
+		reserve_warehouse: DF.Link | None
+		returned_qty: DF.Float
+		rm_item_code: DF.Link | None
+		stock_uom: DF.Link | None
+		supplied_qty: DF.Float
+		total_supplied_qty: DF.Float
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.js b/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.js
index 19a1c93..575c4ed 100644
--- a/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.js
+++ b/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.js
@@ -11,67 +11,92 @@
 		frm.get_field('supplied_items').grid.cannot_add_rows = true;
 		frm.get_field('supplied_items').grid.only_sortable();
 		frm.trigger('set_queries');
+
+		frm.custom_make_buttons = {
+			'Purchase Receipt': 'Purchase Receipt',
+		}
+	},
+
+	on_submit(frm) {
+		frm.events.refresh_serial_batch_bundle_field(frm);
+	},
+
+	refresh_serial_batch_bundle_field(frm) {
+		frappe.route_hooks.after_submit = (frm_obj) => {
+			frm_obj.reload_doc();
+		}
 	},
 
 	refresh: (frm) => {
-		if (frm.doc.docstatus > 0) {
+		if (frm.doc.docstatus === 1) {
 			frm.add_custom_button(__('Stock Ledger'), () => {
-					frappe.route_options = {
-						voucher_no: frm.doc.name,
-						from_date: frm.doc.posting_date,
-						to_date: moment(frm.doc.modified).format('YYYY-MM-DD'),
-						company: frm.doc.company,
-						show_cancelled_entries: frm.doc.docstatus === 2
-					}
-					frappe.set_route('query-report', 'Stock Ledger');
-				}, __('View'));
+				frappe.route_options = {
+					voucher_no: frm.doc.name,
+					from_date: frm.doc.posting_date,
+					to_date: moment(frm.doc.modified).format('YYYY-MM-DD'),
+					company: frm.doc.company,
+					show_cancelled_entries: frm.doc.docstatus === 2
+				}
+				frappe.set_route('query-report', 'Stock Ledger');
+			}, __('View'));
 
 			frm.add_custom_button(__('Accounting Ledger'), () => {
-					frappe.route_options = {
-						voucher_no: frm.doc.name,
-						from_date: frm.doc.posting_date,
-						to_date: moment(frm.doc.modified).format('YYYY-MM-DD'),
-						company: frm.doc.company,
-						group_by: 'Group by Voucher (Consolidated)',
-						show_cancelled_entries: frm.doc.docstatus === 2
-					}
-					frappe.set_route('query-report', 'General Ledger');
-				}, __('View'));
+				frappe.route_options = {
+					voucher_no: frm.doc.name,
+					from_date: frm.doc.posting_date,
+					to_date: moment(frm.doc.modified).format('YYYY-MM-DD'),
+					company: frm.doc.company,
+					group_by: 'Group by Voucher (Consolidated)',
+					show_cancelled_entries: frm.doc.docstatus === 2
+				}
+				frappe.set_route('query-report', 'General Ledger');
+			}, __('View'));
+
+			if (frm.doc.is_return === 0) {
+				frm.add_custom_button(__('Purchase Receipt'), () => {
+					frappe.model.open_mapped_doc({
+						method: 'erpnext.subcontracting.doctype.subcontracting_receipt.subcontracting_receipt.make_purchase_receipt',
+						frm: frm,
+						freeze: true,
+						freeze_message: __('Creating Purchase Receipt ...')
+					});
+				}, __('Create'));
+			}
 		}
 
 		if (!frm.doc.is_return && frm.doc.docstatus === 1 && frm.doc.per_returned < 100) {
 			frm.add_custom_button(__('Subcontract Return'), () => {
-					frappe.model.open_mapped_doc({
-						method: 'erpnext.subcontracting.doctype.subcontracting_receipt.subcontracting_receipt.make_subcontract_return',
-						frm: frm
-					});
-				}, __('Create'));
+				frappe.model.open_mapped_doc({
+					method: 'erpnext.subcontracting.doctype.subcontracting_receipt.subcontracting_receipt.make_subcontract_return',
+					frm: frm
+				});
+			}, __('Create'));
 			frm.page.set_inner_btn_group_as_primary(__('Create'));
 		}
 
 		if (frm.doc.docstatus === 0) {
 			frm.add_custom_button(__('Subcontracting Order'), () => {
-					if (!frm.doc.supplier) {
-						frappe.throw({
-							title: __('Mandatory'),
-							message: __('Please Select a Supplier')
-						});
-					}
-
-					erpnext.utils.map_current_doc({
-						method: 'erpnext.subcontracting.doctype.subcontracting_order.subcontracting_order.make_subcontracting_receipt',
-						source_doctype: 'Subcontracting Order',
-						target: frm,
-						setters: {
-							supplier: frm.doc.supplier,
-						},
-						get_query_filters: {
-							docstatus: 1,
-							per_received: ['<', 100],
-							company: frm.doc.company
-						}
+				if (!frm.doc.supplier) {
+					frappe.throw({
+						title: __('Mandatory'),
+						message: __('Please Select a Supplier')
 					});
-				}, __('Get Items From'));
+				}
+
+				erpnext.utils.map_current_doc({
+					method: 'erpnext.subcontracting.doctype.subcontracting_order.subcontracting_order.make_subcontracting_receipt',
+					source_doctype: 'Subcontracting Order',
+					target: frm,
+					setters: {
+						supplier: frm.doc.supplier,
+					},
+					get_query_filters: {
+						docstatus: 1,
+						per_received: ['<', 100],
+						company: frm.doc.company
+					}
+				});
+			}, __('Get Items From'));
 
 			frm.fields_dict.supplied_items.grid.update_docfield_property('consumed_qty', 'read_only', frm.doc.__onload && frm.doc.__onload.backflush_based_on === 'BOM');
 		}
diff --git a/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.json b/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.json
index 8be1c1b..383a83b 100644
--- a/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.json
+++ b/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.json
@@ -11,6 +11,7 @@
   "naming_series",
   "supplier",
   "supplier_name",
+  "supplier_delivery_note",
   "column_break1",
   "company",
   "posting_date",
@@ -634,12 +635,17 @@
    "fieldtype": "Button",
    "label": "Get Scrap Items",
    "options": "get_scrap_items"
+  },
+  {
+   "fieldname": "supplier_delivery_note",
+   "fieldtype": "Data",
+   "label": "Supplier Delivery Note"
   }
  ],
  "in_create": 1,
  "is_submittable": 1,
  "links": [],
- "modified": "2023-08-26 10:52:04.050829",
+ "modified": "2023-11-16 13:04:00.710534",
  "modified_by": "Administrator",
  "module": "Subcontracting",
  "name": "Subcontracting Receipt",
diff --git a/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py b/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py
index 7e06444..1a5deb6 100644
--- a/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py
+++ b/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py
@@ -3,7 +3,8 @@
 
 import frappe
 from frappe import _
-from frappe.utils import cint, flt, getdate, nowdate
+from frappe.model.mapper import get_mapped_doc
+from frappe.utils import cint, flt, get_link_to_form, getdate, nowdate
 
 import erpnext
 from erpnext.accounts.utils import get_account_currency
@@ -12,6 +13,76 @@
 
 
 class SubcontractingReceipt(SubcontractingController):
+	# 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
+
+		from erpnext.stock.doctype.landed_cost_taxes_and_charges.landed_cost_taxes_and_charges import (
+			LandedCostTaxesandCharges,
+		)
+		from erpnext.subcontracting.doctype.subcontracting_receipt_item.subcontracting_receipt_item import (
+			SubcontractingReceiptItem,
+		)
+		from erpnext.subcontracting.doctype.subcontracting_receipt_supplied_item.subcontracting_receipt_supplied_item import (
+			SubcontractingReceiptSuppliedItem,
+		)
+
+		additional_costs: DF.Table[LandedCostTaxesandCharges]
+		address_display: DF.SmallText | None
+		amended_from: DF.Link | None
+		auto_repeat: DF.Link | None
+		bill_date: DF.Date | None
+		bill_no: DF.Data | None
+		billing_address: DF.Link | None
+		billing_address_display: DF.SmallText | None
+		company: DF.Link
+		contact_display: DF.SmallText | None
+		contact_email: DF.SmallText | None
+		contact_mobile: DF.SmallText | None
+		contact_person: DF.Link | None
+		cost_center: DF.Link | None
+		distribute_additional_costs_based_on: DF.Literal["Qty", "Amount"]
+		in_words: DF.Data | None
+		instructions: DF.SmallText | None
+		is_return: DF.Check
+		items: DF.Table[SubcontractingReceiptItem]
+		language: DF.Data | None
+		letter_head: DF.Link | None
+		lr_date: DF.Date | None
+		lr_no: DF.Data | None
+		naming_series: DF.Literal["MAT-SCR-.YYYY.-", "MAT-SCR-RET-.YYYY.-"]
+		per_returned: DF.Percent
+		posting_date: DF.Date
+		posting_time: DF.Time
+		project: DF.Link | None
+		range: DF.Data | None
+		rejected_warehouse: DF.Link | None
+		remarks: DF.SmallText | None
+		represents_company: DF.Link | None
+		return_against: DF.Link | None
+		select_print_heading: DF.Link | None
+		set_posting_time: DF.Check
+		set_warehouse: DF.Link | None
+		shipping_address: DF.Link | None
+		shipping_address_display: DF.SmallText | None
+		status: DF.Literal["", "Draft", "Completed", "Return", "Return Issued", "Cancelled", "Closed"]
+		supplied_items: DF.Table[SubcontractingReceiptSuppliedItem]
+		supplier: DF.Link
+		supplier_address: DF.Link | None
+		supplier_delivery_note: DF.Data | None
+		supplier_name: DF.Data | None
+		supplier_warehouse: DF.Link | None
+		title: DF.Data | None
+		total: DF.Currency
+		total_additional_costs: DF.Currency
+		total_qty: DF.Float
+		transporter_name: DF.Data | None
+	# end: auto-generated types
+
 	def __init__(self, *args, **kwargs):
 		super(SubcontractingReceipt, self).__init__(*args, **kwargs)
 		self.status_updater = [
@@ -80,6 +151,7 @@
 		self.make_gl_entries()
 		self.repost_future_sle_and_gle()
 		self.update_status()
+		self.auto_create_purchase_receipt()
 
 	def on_update(self):
 		for table_field in ["items", "supplied_items"]:
@@ -95,12 +167,12 @@
 		)
 		self.update_status_updater_args()
 		self.update_prevdoc_status()
-		self.update_stock_ledger()
-		self.make_gl_entries_on_cancel()
-		self.repost_future_sle_and_gle()
 		self.delete_auto_created_batches()
 		self.set_consumed_qty_in_subcontract_order()
 		self.set_subcontracting_order_status()
+		self.update_stock_ledger()
+		self.make_gl_entries_on_cancel()
+		self.repost_future_sle_and_gle()
 		self.update_status()
 
 	def validate_items_qty(self):
@@ -148,6 +220,8 @@
 		if (
 			frappe.db.get_single_value("Buying Settings", "backflush_raw_materials_of_subcontract_based_on")
 			== "BOM"
+			and self.supplied_items
+			and not any(item.serial_and_batch_bundle for item in self.supplied_items)
 		):
 			self.supplied_items = []
 
@@ -526,9 +600,102 @@
 				+ "\n".join(warehouse_with_no_account)
 			)
 
+	def auto_create_purchase_receipt(self):
+		if frappe.db.get_single_value("Buying Settings", "auto_create_purchase_receipt"):
+			make_purchase_receipt(self, save=True, notify=True)
+
 
 @frappe.whitelist()
 def make_subcontract_return(source_name, target_doc=None):
 	from erpnext.controllers.sales_and_purchase_return import make_return_doc
 
 	return make_return_doc("Subcontracting Receipt", source_name, target_doc)
+
+
+@frappe.whitelist()
+def make_purchase_receipt(source_name, target_doc=None, save=False, submit=False, notify=False):
+	if isinstance(source_name, str):
+		source_doc = frappe.get_doc("Subcontracting Receipt", source_name)
+	else:
+		source_doc = source_name
+
+	if not source_doc.is_return:
+		if not target_doc:
+			target_doc = frappe.new_doc("Purchase Receipt")
+			target_doc.is_subcontracted = 1
+			target_doc.is_old_subcontracting_flow = 0
+
+		target_doc = get_mapped_doc(
+			"Subcontracting Receipt",
+			source_doc.name,
+			{
+				"Subcontracting Receipt": {
+					"doctype": "Purchase Receipt",
+					"field_map": {
+						"posting_date": "posting_date",
+						"posting_time": "posting_time",
+						"name": "subcontracting_receipt",
+						"supplier_warehouse": "supplier_warehouse",
+					},
+					"field_no_map": ["total_qty", "total"],
+				},
+			},
+			target_doc,
+			ignore_child_tables=True,
+		)
+
+		target_doc.currency = frappe.get_cached_value("Company", target_doc.company, "default_currency")
+
+		po_items_details = {}
+		for item in source_doc.items:
+			if item.purchase_order and item.purchase_order_item:
+				if item.purchase_order not in po_items_details:
+					po_doc = frappe.get_doc("Purchase Order", item.purchase_order)
+					po_items_details[item.purchase_order] = {po_item.name: po_item for po_item in po_doc.items}
+
+				if po_item := po_items_details[item.purchase_order].get(item.purchase_order_item):
+					conversion_factor = flt(po_item.qty) / flt(po_item.fg_item_qty)
+					item_row = {
+						"item_code": po_item.item_code,
+						"item_name": po_item.item_name,
+						"conversion_factor": conversion_factor,
+						"qty": flt(item.qty) * conversion_factor,
+						"rejected_qty": flt(item.rejected_qty) * conversion_factor,
+						"uom": po_item.uom,
+						"rate": po_item.rate,
+						"warehouse": item.warehouse,
+						"rejected_warehouse": item.rejected_warehouse,
+						"purchase_order": item.purchase_order,
+						"purchase_order_item": item.purchase_order_item,
+						"subcontracting_receipt_item": item.name,
+					}
+					target_doc.append("items", item_row)
+
+		if not target_doc.items:
+			frappe.throw(
+				_("Purchase Order Item reference is missing in Subcontracting Receipt {0}").format(
+					source_doc.name
+				)
+			)
+
+		target_doc.set_missing_values()
+
+		if (save or submit) and frappe.has_permission(target_doc.doctype, "create"):
+			target_doc.save()
+
+			if submit and frappe.has_permission(target_doc.doctype, "submit", target_doc):
+				try:
+					target_doc.submit()
+				except Exception as e:
+					target_doc.add_comment("Comment", _("Submit Action Failed") + "<br><br>" + str(e))
+
+			if notify:
+				frappe.msgprint(
+					_("Purchase Receipt {0} created.").format(
+						get_link_to_form(target_doc.doctype, target_doc.name)
+					),
+					indicator="green",
+					alert=True,
+				)
+
+		return target_doc
diff --git a/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt_dashboard.py b/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt_dashboard.py
index deb8342..6b67a16 100644
--- a/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt_dashboard.py
+++ b/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt_dashboard.py
@@ -3,17 +3,27 @@
 
 def get_data():
 	return {
-		"fieldname": "subcontracting_receipt_no",
+		"fieldname": "subcontracting_receipt",
 		"non_standard_fieldnames": {
 			"Subcontracting Receipt": "return_against",
 		},
 		"internal_links": {
 			"Subcontracting Order": ["items", "subcontracting_order"],
+			"Purchase Order": ["items", "purchase_order"],
 			"Project": ["items", "project"],
 			"Quality Inspection": ["items", "quality_inspection"],
 		},
 		"transactions": [
-			{"label": _("Reference"), "items": ["Subcontracting Order", "Quality Inspection", "Project"]},
+			{
+				"label": _("Reference"),
+				"items": [
+					"Purchase Order",
+					"Purchase Receipt",
+					"Subcontracting Order",
+					"Quality Inspection",
+					"Project",
+				],
+			},
 			{"label": _("Returns"), "items": ["Subcontracting Receipt"]},
 		],
 	}
diff --git a/erpnext/subcontracting/doctype/subcontracting_receipt/test_subcontracting_receipt.py b/erpnext/subcontracting/doctype/subcontracting_receipt/test_subcontracting_receipt.py
index 1828f696..1d007fe 100644
--- a/erpnext/subcontracting/doctype/subcontracting_receipt/test_subcontracting_receipt.py
+++ b/erpnext/subcontracting/doctype/subcontracting_receipt/test_subcontracting_receipt.py
@@ -5,8 +5,8 @@
 import copy
 
 import frappe
-from frappe.tests.utils import FrappeTestCase
-from frappe.utils import add_days, cint, cstr, flt, today
+from frappe.tests.utils import FrappeTestCase, change_settings
+from frappe.utils import add_days, cint, cstr, flt, nowtime, today
 
 import erpnext
 from erpnext.accounts.doctype.account.test_account import get_inventory_account
@@ -26,6 +26,10 @@
 from erpnext.manufacturing.doctype.production_plan.test_production_plan import make_bom
 from erpnext.stock.doctype.item.test_item import make_item
 from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import get_gl_entries
+from erpnext.stock.doctype.serial_and_batch_bundle.test_serial_and_batch_bundle import (
+	get_batch_from_bundle,
+	make_serial_batch_bundle,
+)
 from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry
 from erpnext.stock.doctype.stock_reconciliation.test_stock_reconciliation import (
 	create_stock_reconciliation,
@@ -507,6 +511,260 @@
 		self.assertNotEqual(scr.supplied_items[0].rate, prev_cost)
 		self.assertEqual(scr.supplied_items[0].rate, sr.items[0].valuation_rate)
 
+	def test_subcontracting_receipt_for_batch_raw_materials_without_material_transfer(self):
+		set_backflush_based_on("BOM")
+
+		fg_item = make_item(properties={"is_stock_item": 1, "is_sub_contracted_item": 1}).name
+		rm_item1 = make_item(
+			properties={
+				"is_stock_item": 1,
+				"has_batch_no": 1,
+				"create_new_batch": 1,
+				"batch_number_series": "BNGS-.####",
+			}
+		).name
+
+		bom = make_bom(item=fg_item, raw_materials=[rm_item1])
+
+		rm_batch_no = None
+		for row in bom.items:
+			se = make_stock_entry(
+				item_code=row.item_code,
+				qty=1,
+				target="_Test Warehouse 1 - _TC",
+				rate=300,
+			)
+
+			se.reload()
+			rm_batch_no = get_batch_from_bundle(se.items[0].serial_and_batch_bundle)
+
+		service_items = [
+			{
+				"warehouse": "_Test Warehouse - _TC",
+				"item_code": "Subcontracted Service Item 1",
+				"qty": 1,
+				"rate": 100,
+				"fg_item": fg_item,
+				"fg_item_qty": 1,
+			},
+		]
+		sco = get_subcontracting_order(service_items=service_items)
+		scr = make_subcontracting_receipt(sco.name)
+		scr.save()
+		scr.reload()
+
+		bundle_doc = make_serial_batch_bundle(
+			{
+				"item_code": scr.supplied_items[0].rm_item_code,
+				"warehouse": "_Test Warehouse 1 - _TC",
+				"voucher_type": "Subcontracting Receipt",
+				"posting_date": today(),
+				"posting_time": nowtime(),
+				"qty": -1,
+				"batches": frappe._dict({rm_batch_no: 1}),
+				"type_of_transaction": "Outward",
+				"do_not_submit": True,
+			}
+		)
+
+		scr.supplied_items[0].serial_and_batch_bundle = bundle_doc.name
+		scr.submit()
+		scr.reload()
+
+		batch_no = get_batch_from_bundle(scr.supplied_items[0].serial_and_batch_bundle)
+		self.assertEqual(batch_no, rm_batch_no)
+		self.assertEqual(scr.items[0].rm_cost_per_qty, 300)
+		self.assertEqual(scr.items[0].service_cost_per_qty, 100)
+
+	def test_subcontracting_receipt_valuation_with_auto_created_serial_batch_bundle(self):
+		set_backflush_based_on("BOM")
+
+		fg_item = make_item(properties={"is_stock_item": 1, "is_sub_contracted_item": 1}).name
+		rm_item1 = make_item(
+			properties={
+				"is_stock_item": 1,
+				"has_batch_no": 1,
+				"create_new_batch": 1,
+				"batch_number_series": "BNGS-.####",
+			}
+		).name
+
+		rm_item2 = make_item(
+			properties={
+				"is_stock_item": 1,
+				"has_batch_no": 1,
+				"has_serial_no": 1,
+				"create_new_batch": 1,
+				"batch_number_series": "BNGS-.####",
+				"serial_no_series": "BNSS-.####",
+			}
+		).name
+
+		rm_item3 = make_item(
+			properties={
+				"is_stock_item": 1,
+				"has_serial_no": 1,
+				"serial_no_series": "BSSSS-.####",
+			}
+		).name
+
+		bom = make_bom(item=fg_item, raw_materials=[rm_item1, rm_item2, rm_item3])
+
+		rm_batch_no = None
+		for row in bom.items:
+			make_stock_entry(
+				item_code=row.item_code,
+				qty=1,
+				target="_Test Warehouse 1 - _TC",
+				rate=300,
+			)
+
+			make_stock_entry(
+				item_code=row.item_code,
+				qty=1,
+				target="_Test Warehouse 1 - _TC",
+				rate=400,
+			)
+
+		service_items = [
+			{
+				"warehouse": "_Test Warehouse - _TC",
+				"item_code": "Subcontracted Service Item 1",
+				"qty": 1,
+				"rate": 100,
+				"fg_item": fg_item,
+				"fg_item_qty": 1,
+			},
+		]
+		sco = get_subcontracting_order(service_items=service_items)
+
+		frappe.db.set_single_value(
+			"Stock Settings", "auto_create_serial_and_batch_bundle_for_outward", 1
+		)
+		scr = make_subcontracting_receipt(sco.name)
+		scr.save()
+		for row in scr.supplied_items:
+			self.assertNotEqual(row.rate, 300.00)
+			self.assertFalse(row.serial_and_batch_bundle)
+
+		scr.submit()
+		scr.reload()
+
+		for row in scr.supplied_items:
+			self.assertEqual(row.rate, 300.00)
+			self.assertTrue(row.serial_and_batch_bundle)
+			auto_created_serial_batch = frappe.db.get_value(
+				"Stock Ledger Entry",
+				{"voucher_no": scr.name, "voucher_detail_no": row.name},
+				"auto_created_serial_and_batch_bundle",
+			)
+
+			self.assertTrue(auto_created_serial_batch)
+
+		self.assertEqual(scr.items[0].rm_cost_per_qty, 900)
+		self.assertEqual(scr.items[0].service_cost_per_qty, 100)
+		frappe.db.set_single_value(
+			"Stock Settings", "auto_create_serial_and_batch_bundle_for_outward", 0
+		)
+
+	def test_subcontracting_receipt_valuation_for_fg_with_auto_created_serial_batch_bundle(self):
+		set_backflush_based_on("BOM")
+
+		fg_item = make_item(
+			properties={
+				"is_stock_item": 1,
+				"is_sub_contracted_item": 1,
+				"has_batch_no": 1,
+				"create_new_batch": 1,
+				"batch_number_series": "BSSNGS-.####",
+			}
+		).name
+
+		rm_item1 = make_item(
+			properties={
+				"is_stock_item": 1,
+				"has_batch_no": 1,
+				"create_new_batch": 1,
+				"batch_number_series": "BNGS-.####",
+			}
+		).name
+
+		rm_item2 = make_item(
+			properties={
+				"is_stock_item": 1,
+				"has_batch_no": 1,
+				"has_serial_no": 1,
+				"create_new_batch": 1,
+				"batch_number_series": "BNGS-.####",
+				"serial_no_series": "BNSS-.####",
+			}
+		).name
+
+		rm_item3 = make_item(
+			properties={
+				"is_stock_item": 1,
+				"has_serial_no": 1,
+				"serial_no_series": "BSSSS-.####",
+			}
+		).name
+
+		bom = make_bom(item=fg_item, raw_materials=[rm_item1, rm_item2, rm_item3])
+
+		rm_batch_no = None
+		for row in bom.items:
+			make_stock_entry(
+				item_code=row.item_code,
+				qty=1,
+				target="_Test Warehouse 1 - _TC",
+				rate=300,
+			)
+
+		service_items = [
+			{
+				"warehouse": "_Test Warehouse - _TC",
+				"item_code": "Subcontracted Service Item 1",
+				"qty": 1,
+				"rate": 100,
+				"fg_item": fg_item,
+				"fg_item_qty": 1,
+			},
+		]
+		sco = get_subcontracting_order(service_items=service_items)
+
+		frappe.db.set_single_value(
+			"Stock Settings", "auto_create_serial_and_batch_bundle_for_outward", 1
+		)
+		scr = make_subcontracting_receipt(sco.name)
+		scr.save()
+		scr.submit()
+		scr.reload()
+
+		for row in scr.supplied_items:
+			self.assertEqual(row.rate, 300.00)
+			self.assertTrue(row.serial_and_batch_bundle)
+			auto_created_serial_batch = frappe.db.get_value(
+				"Stock Ledger Entry",
+				{"voucher_no": scr.name, "voucher_detail_no": row.name},
+				"auto_created_serial_and_batch_bundle",
+			)
+
+			self.assertTrue(auto_created_serial_batch)
+
+		self.assertEqual(scr.items[0].rm_cost_per_qty, 900)
+		self.assertEqual(scr.items[0].service_cost_per_qty, 100)
+		self.assertEqual(scr.items[0].rate, 1000)
+		valuation_rate = frappe.db.get_value(
+			"Stock Ledger Entry",
+			{"voucher_no": scr.name, "voucher_detail_no": scr.items[0].name},
+			"valuation_rate",
+		)
+
+		self.assertEqual(flt(valuation_rate), flt(1000))
+
+		frappe.db.set_single_value(
+			"Stock Settings", "auto_create_serial_and_batch_bundle_for_outward", 0
+		)
+
 	def test_subcontracting_receipt_raw_material_rate(self):
 		# Step - 1: Set Backflush Based On as "BOM"
 		set_backflush_based_on("BOM")
@@ -695,6 +953,33 @@
 
 		scr.submit()
 
+	@change_settings("Buying Settings", {"auto_create_purchase_receipt": 1})
+	def test_auto_create_purchase_receipt(self):
+		fg_item = "Subcontracted Item SA1"
+		service_items = [
+			{
+				"warehouse": "_Test Warehouse - _TC",
+				"item_code": "Subcontracted Service Item 1",
+				"qty": 5,
+				"rate": 100,
+				"fg_item": fg_item,
+				"fg_item_qty": 5,
+			},
+		]
+		sco = get_subcontracting_order(service_items=service_items)
+		rm_items = get_rm_items(sco.supplied_items)
+		itemwise_details = make_stock_in_entry(rm_items=rm_items)
+		make_stock_transfer_entry(
+			sco_no=sco.name,
+			rm_items=rm_items,
+			itemwise_details=copy.deepcopy(itemwise_details),
+		)
+		scr = make_subcontracting_receipt(sco.name)
+		scr.save()
+		scr.submit()
+
+		self.assertTrue(frappe.db.get_value("Purchase Receipt", {"subcontracting_receipt": scr.name}))
+
 
 def make_return_subcontracting_receipt(**args):
 	args = frappe._dict(args)
diff --git a/erpnext/subcontracting/doctype/subcontracting_receipt_item/subcontracting_receipt_item.json b/erpnext/subcontracting/doctype/subcontracting_receipt_item/subcontracting_receipt_item.json
index 38432be..9bfc2fd 100644
--- a/erpnext/subcontracting/doctype/subcontracting_receipt_item/subcontracting_receipt_item.json
+++ b/erpnext/subcontracting/doctype/subcontracting_receipt_item/subcontracting_receipt_item.json
@@ -42,6 +42,7 @@
   "column_break_40",
   "rejected_warehouse",
   "bom",
+  "include_exploded_items",
   "quality_inspection",
   "schedule_date",
   "reference_name",
@@ -63,7 +64,9 @@
   "dimension_col_break",
   "project",
   "section_break_80",
-  "page_break"
+  "page_break",
+  "purchase_order",
+  "purchase_order_item"
  ],
  "fields": [
   {
@@ -109,6 +112,7 @@
    "width": "300px"
   },
   {
+   "fetch_from": "item_code.image",
    "fieldname": "image",
    "fieldtype": "Attach",
    "hidden": 1,
@@ -516,12 +520,38 @@
    "label": "Reference Name",
    "no_copy": 1,
    "read_only": 1
+  },
+  {
+   "fieldname": "purchase_order_item",
+   "fieldtype": "Data",
+   "hidden": 1,
+   "label": "Purchase Order Item",
+   "no_copy": 1,
+   "read_only": 1,
+   "search_index": 1
+  },
+  {
+   "fieldname": "purchase_order",
+   "fieldtype": "Link",
+   "hidden": 1,
+   "label": "Purchase Order",
+   "no_copy": 1,
+   "options": "Purchase Order",
+   "read_only": 1,
+   "search_index": 1
+  },
+  {
+   "default": "0",
+   "fieldname": "include_exploded_items",
+   "fieldtype": "Check",
+   "label": "Include Exploded Items",
+   "print_hide": 1
   }
  ],
  "idx": 1,
  "istable": 1,
  "links": [],
- "modified": "2023-09-03 17:04:21.214316",
+ "modified": "2023-11-30 12:05:51.920705",
  "modified_by": "Administrator",
  "module": "Subcontracting",
  "name": "Subcontracting Receipt Item",
diff --git a/erpnext/subcontracting/doctype/subcontracting_receipt_item/subcontracting_receipt_item.py b/erpnext/subcontracting/doctype/subcontracting_receipt_item/subcontracting_receipt_item.py
index 374f95b..d02160e 100644
--- a/erpnext/subcontracting/doctype/subcontracting_receipt_item/subcontracting_receipt_item.py
+++ b/erpnext/subcontracting/doctype/subcontracting_receipt_item/subcontracting_receipt_item.py
@@ -6,4 +6,59 @@
 
 
 class SubcontractingReceiptItem(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
+
+		additional_cost_per_qty: DF.Currency
+		amount: DF.Currency
+		batch_no: DF.Link | None
+		bom: DF.Link | None
+		brand: DF.Link | None
+		conversion_factor: DF.Float
+		cost_center: DF.Link | None
+		description: DF.TextEditor | None
+		expense_account: DF.Link | None
+		image: DF.Attach | None
+		include_exploded_items: DF.Check
+		is_scrap_item: DF.Check
+		item_code: DF.Link
+		item_name: DF.Data | None
+		manufacturer: DF.Link | None
+		manufacturer_part_no: DF.Data | None
+		page_break: DF.Check
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		project: DF.Link | None
+		purchase_order: DF.Link | None
+		purchase_order_item: DF.Data | None
+		qty: DF.Float
+		quality_inspection: DF.Link | None
+		rate: DF.Currency
+		received_qty: DF.Float
+		reference_name: DF.Data | None
+		rejected_qty: DF.Float
+		rejected_serial_and_batch_bundle: DF.Link | None
+		rejected_serial_no: DF.SmallText | None
+		rejected_warehouse: DF.Link | None
+		returned_qty: DF.Float
+		rm_cost_per_qty: DF.Currency
+		rm_supp_cost: DF.Currency
+		schedule_date: DF.Date | None
+		scrap_cost_per_qty: DF.Float
+		serial_and_batch_bundle: DF.Link | None
+		serial_no: DF.SmallText | None
+		service_cost_per_qty: DF.Currency
+		stock_uom: DF.Link
+		subcontracting_order: DF.Link | None
+		subcontracting_order_item: DF.Data | None
+		subcontracting_receipt_item: DF.Data | None
+		warehouse: DF.Link | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/subcontracting/doctype/subcontracting_receipt_supplied_item/subcontracting_receipt_supplied_item.py b/erpnext/subcontracting/doctype/subcontracting_receipt_supplied_item/subcontracting_receipt_supplied_item.py
index f4d2805..2ee5551 100644
--- a/erpnext/subcontracting/doctype/subcontracting_receipt_supplied_item/subcontracting_receipt_supplied_item.py
+++ b/erpnext/subcontracting/doctype/subcontracting_receipt_supplied_item/subcontracting_receipt_supplied_item.py
@@ -6,4 +6,35 @@
 
 
 class SubcontractingReceiptSuppliedItem(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
+
+		amount: DF.Currency
+		available_qty_for_consumption: DF.Float
+		batch_no: DF.Link | None
+		bom_detail_no: DF.Data | None
+		consumed_qty: DF.Float
+		conversion_factor: DF.Float
+		current_stock: DF.Float
+		description: DF.TextEditor | None
+		item_name: DF.Data | None
+		main_item_code: DF.Link | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		rate: DF.Currency
+		reference_name: DF.Data | None
+		required_qty: DF.Float
+		rm_item_code: DF.Link | None
+		serial_and_batch_bundle: DF.Link | None
+		serial_no: DF.Text | None
+		stock_uom: DF.Link | None
+		subcontracting_order: DF.Link | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/support/doctype/issue/issue.py b/erpnext/support/doctype/issue/issue.py
index f23419e..c03fb3e 100644
--- a/erpnext/support/doctype/issue/issue.py
+++ b/erpnext/support/doctype/issue/issue.py
@@ -18,6 +18,50 @@
 
 
 class Issue(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
+
+		agreement_status: DF.Literal["First Response Due", "Resolution Due", "Fulfilled", "Failed"]
+		attachment: DF.Attach | None
+		avg_response_time: DF.Duration | None
+		company: DF.Link | None
+		contact: DF.Link | None
+		content_type: DF.Data | None
+		customer: DF.Link | None
+		customer_name: DF.Data | None
+		description: DF.TextEditor | None
+		email_account: DF.Link | None
+		first_responded_on: DF.Datetime | None
+		first_response_time: DF.Duration | None
+		issue_split_from: DF.Link | None
+		issue_type: DF.Link | None
+		lead: DF.Link | None
+		naming_series: DF.Literal["ISS-.YYYY.-"]
+		on_hold_since: DF.Datetime | None
+		opening_date: DF.Date | None
+		opening_time: DF.Time | None
+		priority: DF.Link | None
+		project: DF.Link | None
+		raised_by: DF.Data | None
+		resolution_by: DF.Datetime | None
+		resolution_date: DF.Datetime | None
+		resolution_details: DF.TextEditor | None
+		resolution_time: DF.Duration | None
+		response_by: DF.Datetime | None
+		service_level_agreement: DF.Link | None
+		service_level_agreement_creation: DF.Datetime | None
+		status: DF.Literal["Open", "Replied", "On Hold", "Resolved", "Closed"]
+		subject: DF.Data
+		total_hold_time: DF.Duration | None
+		user_resolution_time: DF.Duration | None
+		via_customer_portal: DF.Check
+	# end: auto-generated types
+
 	def validate(self):
 		if self.is_new() and self.via_customer_portal:
 			self.flags.create_communication = True
diff --git a/erpnext/support/doctype/issue_priority/issue_priority.py b/erpnext/support/doctype/issue_priority/issue_priority.py
index f21a453..e2fbc70 100644
--- a/erpnext/support/doctype/issue_priority/issue_priority.py
+++ b/erpnext/support/doctype/issue_priority/issue_priority.py
@@ -6,4 +6,15 @@
 
 
 class IssuePriority(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
+
+		description: DF.SmallText | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/support/doctype/issue_type/issue_type.py b/erpnext/support/doctype/issue_type/issue_type.py
index c5adc8b..b33033b 100644
--- a/erpnext/support/doctype/issue_type/issue_type.py
+++ b/erpnext/support/doctype/issue_type/issue_type.py
@@ -6,4 +6,15 @@
 
 
 class IssueType(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
+
+		description: DF.SmallText | None
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/support/doctype/pause_sla_on_status/pause_sla_on_status.py b/erpnext/support/doctype/pause_sla_on_status/pause_sla_on_status.py
index 41d4f7f..59a5414 100644
--- a/erpnext/support/doctype/pause_sla_on_status/pause_sla_on_status.py
+++ b/erpnext/support/doctype/pause_sla_on_status/pause_sla_on_status.py
@@ -7,4 +7,18 @@
 
 
 class PauseSLAOnStatus(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
+
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		status: DF.Literal
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/support/doctype/service_day/service_day.py b/erpnext/support/doctype/service_day/service_day.py
index 4a3b1f0..b90a077 100644
--- a/erpnext/support/doctype/service_day/service_day.py
+++ b/erpnext/support/doctype/service_day/service_day.py
@@ -7,4 +7,20 @@
 
 
 class ServiceDay(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
+
+		end_time: DF.Time
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		start_time: DF.Time
+		workday: DF.Literal["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/support/doctype/service_level_agreement/service_level_agreement.py b/erpnext/support/doctype/service_level_agreement/service_level_agreement.py
index 6c9bc54..879381c 100644
--- a/erpnext/support/doctype/service_level_agreement/service_level_agreement.py
+++ b/erpnext/support/doctype/service_level_agreement/service_level_agreement.py
@@ -29,6 +29,41 @@
 
 
 class ServiceLevelAgreement(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
+
+		from erpnext.support.doctype.pause_sla_on_status.pause_sla_on_status import PauseSLAOnStatus
+		from erpnext.support.doctype.service_day.service_day import ServiceDay
+		from erpnext.support.doctype.service_level_priority.service_level_priority import (
+			ServiceLevelPriority,
+		)
+		from erpnext.support.doctype.sla_fulfilled_on_status.sla_fulfilled_on_status import (
+			SLAFulfilledOnStatus,
+		)
+
+		apply_sla_for_resolution: DF.Check
+		condition: DF.Code | None
+		default_priority: DF.Link | None
+		default_service_level_agreement: DF.Check
+		document_type: DF.Link
+		enabled: DF.Check
+		end_date: DF.Date | None
+		entity: DF.DynamicLink | None
+		entity_type: DF.Literal["", "Customer", "Customer Group", "Territory"]
+		holiday_list: DF.Link
+		pause_sla_on: DF.Table[PauseSLAOnStatus]
+		priorities: DF.Table[ServiceLevelPriority]
+		service_level: DF.Data
+		sla_fulfilled_on: DF.Table[SLAFulfilledOnStatus]
+		start_date: DF.Date | None
+		support_and_resolution: DF.Table[ServiceDay]
+	# end: auto-generated types
+
 	def validate(self):
 		self.validate_selected_doctype()
 		self.validate_doc()
diff --git a/erpnext/support/doctype/service_level_priority/service_level_priority.py b/erpnext/support/doctype/service_level_priority/service_level_priority.py
index adb153e..6ee6fdf 100644
--- a/erpnext/support/doctype/service_level_priority/service_level_priority.py
+++ b/erpnext/support/doctype/service_level_priority/service_level_priority.py
@@ -7,4 +7,21 @@
 
 
 class ServiceLevelPriority(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
+
+		default_priority: DF.Check
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		priority: DF.Link
+		resolution_time: DF.Duration | None
+		response_time: DF.Duration
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/support/doctype/sla_fulfilled_on_status/sla_fulfilled_on_status.py b/erpnext/support/doctype/sla_fulfilled_on_status/sla_fulfilled_on_status.py
index dbffcb8..b348bf1 100644
--- a/erpnext/support/doctype/sla_fulfilled_on_status/sla_fulfilled_on_status.py
+++ b/erpnext/support/doctype/sla_fulfilled_on_status/sla_fulfilled_on_status.py
@@ -6,4 +6,18 @@
 
 
 class SLAFulfilledOnStatus(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
+
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		status: DF.Literal
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/support/doctype/support_search_source/support_search_source.py b/erpnext/support/doctype/support_search_source/support_search_source.py
index 2270015..b4aa952 100644
--- a/erpnext/support/doctype/support_search_source/support_search_source.py
+++ b/erpnext/support/doctype/support_search_source/support_search_source.py
@@ -6,4 +6,31 @@
 
 
 class SupportSearchSource(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
+
+		base_url: DF.Data | None
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		post_description_key: DF.Data | None
+		post_route: DF.Data | None
+		post_route_key_list: DF.Data | None
+		post_title_key: DF.Data | None
+		query_route: DF.Data | None
+		response_result_key_path: DF.Data | None
+		result_preview_field: DF.Data | None
+		result_route_field: DF.Data | None
+		result_title_field: DF.Data | None
+		search_term_param_name: DF.Data | None
+		source_doctype: DF.Link | None
+		source_name: DF.Data | None
+		source_type: DF.Literal["API", "Link"]
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/support/doctype/support_settings/support_settings.py b/erpnext/support/doctype/support_settings/support_settings.py
index ee8a3f5..3bc1afe 100644
--- a/erpnext/support/doctype/support_settings/support_settings.py
+++ b/erpnext/support/doctype/support_settings/support_settings.py
@@ -6,4 +6,33 @@
 
 
 class SupportSettings(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
+
+		from erpnext.support.doctype.support_search_source.support_search_source import (
+			SupportSearchSource,
+		)
+
+		allow_resetting_service_level_agreement: DF.Check
+		close_issue_after_days: DF.Int
+		forum_url: DF.Data | None
+		get_latest_query: DF.Data | None
+		get_started_sections: DF.Code | None
+		greeting_subtitle: DF.Data | None
+		greeting_title: DF.Data | None
+		post_description_key: DF.Data | None
+		post_route_key: DF.Data | None
+		post_route_string: DF.Data | None
+		post_title_key: DF.Data | None
+		response_key_list: DF.Data | None
+		search_apis: DF.Table[SupportSearchSource]
+		show_latest_forum_posts: DF.Check
+		track_service_level_agreement: DF.Check
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/support/doctype/warranty_claim/warranty_claim.js b/erpnext/support/doctype/warranty_claim/warranty_claim.js
index 358768e..10cb37f 100644
--- a/erpnext/support/doctype/warranty_claim/warranty_claim.js
+++ b/erpnext/support/doctype/warranty_claim/warranty_claim.js
@@ -4,93 +4,67 @@
 frappe.provide("erpnext.support");
 
 frappe.ui.form.on("Warranty Claim", {
-	setup: function(frm) {
-		frm.set_query('contact_person', erpnext.queries.contact_query);
-		frm.set_query('customer_address', erpnext.queries.address_query);
-		frm.set_query('customer', erpnext.queries.customer);
+	setup: (frm) => {
+		frm.set_query("contact_person", erpnext.queries.contact_query);
+		frm.set_query("customer_address", erpnext.queries.address_query);
+		frm.set_query("customer", erpnext.queries.customer);
 
-		frm.add_fetch('serial_no', 'item_code', 'item_code');
-		frm.add_fetch('serial_no', 'item_name', 'item_name');
-		frm.add_fetch('serial_no', 'description', 'description');
-		frm.add_fetch('serial_no', 'maintenance_status', 'warranty_amc_status');
-		frm.add_fetch('serial_no', 'warranty_expiry_date', 'warranty_expiry_date');
-		frm.add_fetch('serial_no', 'amc_expiry_date', 'amc_expiry_date');
-		frm.add_fetch('serial_no', 'customer', 'customer');
-		frm.add_fetch('serial_no', 'customer_name', 'customer_name');
-		frm.add_fetch('item_code', 'item_name', 'item_name');
-		frm.add_fetch('item_code', 'description', 'description');
+		frm.set_query("serial_no", () => {
+			let filters = {
+				company: frm.doc.company,
+			};
+
+			if (frm.doc.item_code) {
+				filters["item_code"] = frm.doc.item_code;
+			}
+
+			return { filters: filters };
+		});
+
+		frm.set_query("item_code", () => {
+			return {
+				filters: {
+					disabled: 0,
+				},
+			};
+		});
 	},
-	onload: function(frm) {
-		if(!frm.doc.status) {
-			frm.set_value('status', 'Open');
+
+	onload: (frm) => {
+		if (!frm.doc.status) {
+			frm.set_value("status", "Open");
 		}
 	},
-	customer: function(frm) {
+
+	refresh: (frm) => {
+		frappe.dynamic_link = {
+			doc: frm.doc,
+			fieldname: "customer",
+			doctype: "Customer",
+		};
+
+		if (
+			!frm.doc.__islocal &&
+			["Open", "Work In Progress"].includes(frm.doc.status)
+		) {
+			frm.add_custom_button(__("Maintenance Visit"), () => {
+				frappe.model.open_mapped_doc({
+					method: "erpnext.support.doctype.warranty_claim.warranty_claim.make_maintenance_visit",
+					frm: frm,
+				});
+			});
+		}
+	},
+
+	customer: (frm) => {
 		erpnext.utils.get_party_details(frm);
 	},
-	customer_address: function(frm) {
+
+	customer_address: (frm) => {
 		erpnext.utils.get_address_display(frm);
 	},
-	contact_person: function(frm) {
+
+	contact_person: (frm) => {
 		erpnext.utils.get_contact_details(frm);
-	}
+	},
 });
-
-erpnext.support.WarrantyClaim = class WarrantyClaim extends frappe.ui.form.Controller {
-	refresh() {
-		frappe.dynamic_link = {doc: this.frm.doc, fieldname: 'customer', doctype: 'Customer'}
-
-		if(!cur_frm.doc.__islocal &&
-			(cur_frm.doc.status=='Open' || cur_frm.doc.status == 'Work In Progress')) {
-			cur_frm.add_custom_button(__('Maintenance Visit'),
-				this.make_maintenance_visit);
-		}
-	}
-
-	make_maintenance_visit() {
-		frappe.model.open_mapped_doc({
-			method: "erpnext.support.doctype.warranty_claim.warranty_claim.make_maintenance_visit",
-			frm: cur_frm
-		})
-	}
-};
-
-extend_cscript(cur_frm.cscript, new erpnext.support.WarrantyClaim({frm: cur_frm}));
-
-cur_frm.fields_dict['serial_no'].get_query = function(doc, cdt, cdn) {
-	var cond = [];
-	var filter = [
-		['Serial No', 'docstatus', '!=', 2]
-	];
-	if(doc.item_code) {
-		cond = ['Serial No', 'item_code', '=', doc.item_code];
-		filter.push(cond);
-	}
-	if(doc.customer) {
-		cond = ['Serial No', 'customer', '=', doc.customer];
-		filter.push(cond);
-	}
-	return{
-		filters:filter
-	}
-}
-
-cur_frm.fields_dict['item_code'].get_query = function(doc, cdt, cdn) {
-	if(doc.serial_no) {
-		return{
-			doctype: "Serial No",
-			fields: "item_code",
-			filters:{
-				name: doc.serial_no
-			}
-		}
-	}
-	else{
-		return{
-			filters:[
-				['Item', 'docstatus', '!=', 2],
-				['Item', 'disabled', '=', 0]
-			]
-		}
-	}
-};
diff --git a/erpnext/support/doctype/warranty_claim/warranty_claim.json b/erpnext/support/doctype/warranty_claim/warranty_claim.json
index 01d9b01..9af2b46 100644
--- a/erpnext/support/doctype/warranty_claim/warranty_claim.json
+++ b/erpnext/support/doctype/warranty_claim/warranty_claim.json
@@ -92,7 +92,8 @@
    "fieldname": "serial_no",
    "fieldtype": "Link",
    "label": "Serial No",
-   "options": "Serial No"
+   "options": "Serial No",
+   "search_index": 1
   },
   {
    "fieldname": "customer",
@@ -128,6 +129,8 @@
    "options": "fa fa-ticket"
   },
   {
+   "fetch_from": "serial_no.item_code",
+   "fetch_if_empty": 1,
    "fieldname": "item_code",
    "fieldtype": "Link",
    "in_list_view": 1,
@@ -140,6 +143,7 @@
   },
   {
    "depends_on": "eval:doc.item_code",
+   "fetch_from": "item_code.item_name",
    "fieldname": "item_name",
    "fieldtype": "Data",
    "label": "Item Name",
@@ -149,6 +153,7 @@
   },
   {
    "depends_on": "eval:doc.item_code",
+   "fetch_from": "item_code.description",
    "fieldname": "description",
    "fieldtype": "Small Text",
    "label": "Description",
@@ -164,17 +169,24 @@
    "width": "50%"
   },
   {
+   "fetch_from": "serial_no.maintenance_status",
+   "fetch_if_empty": 1,
    "fieldname": "warranty_amc_status",
    "fieldtype": "Select",
    "label": "Warranty / AMC Status",
-   "options": "\nUnder Warranty\nOut of Warranty\nUnder AMC\nOut of AMC"
+   "options": "\nUnder Warranty\nOut of Warranty\nUnder AMC\nOut of AMC",
+   "search_index": 1
   },
   {
+   "fetch_from": "serial_no.warranty_expiry_date",
+   "fetch_if_empty": 1,
    "fieldname": "warranty_expiry_date",
    "fieldtype": "Date",
    "label": "Warranty Expiry Date"
   },
   {
+   "fetch_from": "serial_no.amc_expiry_date",
+   "fetch_if_empty": 1,
    "fieldname": "amc_expiry_date",
    "fieldtype": "Date",
    "label": "AMC Expiry Date"
@@ -225,6 +237,7 @@
   {
    "bold": 1,
    "depends_on": "customer",
+   "fetch_from": "customer.customer_name",
    "fieldname": "customer_name",
    "fieldtype": "Data",
    "in_global_search": 1,
@@ -366,7 +379,7 @@
  "icon": "fa fa-bug",
  "idx": 1,
  "links": [],
- "modified": "2023-06-03 16:17:07.694449",
+ "modified": "2023-11-28 17:30:35.676410",
  "modified_by": "Administrator",
  "module": "Support",
  "name": "Warranty Claim",
diff --git a/erpnext/support/doctype/warranty_claim/warranty_claim.py b/erpnext/support/doctype/warranty_claim/warranty_claim.py
index ff63b77..e0eb5a3 100644
--- a/erpnext/support/doctype/warranty_claim/warranty_claim.py
+++ b/erpnext/support/doctype/warranty_claim/warranty_claim.py
@@ -10,6 +10,47 @@
 
 
 class WarrantyClaim(TransactionBase):
+	# 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
+
+		address_display: DF.SmallText | None
+		amc_expiry_date: DF.Date | None
+		amended_from: DF.Link | None
+		company: DF.Link
+		complaint: DF.TextEditor
+		complaint_date: DF.Date
+		complaint_raised_by: DF.Data | None
+		contact_display: DF.SmallText | None
+		contact_email: DF.Data | None
+		contact_mobile: DF.Data | None
+		contact_person: DF.Link | None
+		customer: DF.Link
+		customer_address: DF.Link | None
+		customer_group: DF.Link | None
+		customer_name: DF.Data | None
+		description: DF.SmallText | None
+		from_company: DF.Data | None
+		item_code: DF.Link | None
+		item_name: DF.Data | None
+		naming_series: DF.Literal["SER-WRN-.YYYY.-"]
+		resolution_date: DF.Datetime | None
+		resolution_details: DF.Text | None
+		resolved_by: DF.Link | None
+		serial_no: DF.Link | None
+		service_address: DF.SmallText | None
+		status: DF.Literal["", "Open", "Closed", "Work In Progress", "Cancelled"]
+		territory: DF.Link | None
+		warranty_amc_status: DF.Literal[
+			"", "Under Warranty", "Out of Warranty", "Under AMC", "Out of AMC"
+		]
+		warranty_expiry_date: DF.Date | None
+	# end: auto-generated types
+
 	def validate(self):
 		if session["user"] != "Guest" and not self.customer:
 			frappe.throw(_("Customer is required"))
diff --git a/erpnext/telephony/doctype/call_log/call_log.py b/erpnext/telephony/doctype/call_log/call_log.py
index 1d6839c..259f55b 100644
--- a/erpnext/telephony/doctype/call_log/call_log.py
+++ b/erpnext/telephony/doctype/call_log/call_log.py
@@ -16,6 +16,34 @@
 
 
 class CallLog(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.core.doctype.dynamic_link.dynamic_link import DynamicLink
+		from frappe.types import DF
+
+		call_received_by: DF.Link | None
+		customer: DF.Link | None
+		duration: DF.Duration | None
+		employee_user_id: DF.Link | None
+		end_time: DF.Datetime | None
+		id: DF.Data | None
+		links: DF.Table[DynamicLink]
+		medium: DF.Data | None
+		recording_url: DF.Data | None
+		start_time: DF.Datetime | None
+		status: DF.Literal[
+			"Ringing", "In Progress", "Completed", "Failed", "Busy", "No Answer", "Queued", "Canceled"
+		]
+		summary: DF.SmallText | None
+		to: DF.Data | None
+		type: DF.Literal["Incoming", "Outgoing"]
+		type_of_call: DF.Link | None
+	# end: auto-generated types
+
 	def validate(self):
 		deduplicate_dynamic_links(self)
 
diff --git a/erpnext/telephony/doctype/incoming_call_handling_schedule/incoming_call_handling_schedule.py b/erpnext/telephony/doctype/incoming_call_handling_schedule/incoming_call_handling_schedule.py
index b73f385..ddc86c4 100644
--- a/erpnext/telephony/doctype/incoming_call_handling_schedule/incoming_call_handling_schedule.py
+++ b/erpnext/telephony/doctype/incoming_call_handling_schedule/incoming_call_handling_schedule.py
@@ -7,4 +7,23 @@
 
 
 class IncomingCallHandlingSchedule(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
+
+		agent_group: DF.Link
+		day_of_week: DF.Literal[
+			"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"
+		]
+		from_time: DF.Time
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		to_time: DF.Time
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/telephony/doctype/incoming_call_settings/incoming_call_settings.py b/erpnext/telephony/doctype/incoming_call_settings/incoming_call_settings.py
index 5edf81d..f80c2d2 100644
--- a/erpnext/telephony/doctype/incoming_call_settings/incoming_call_settings.py
+++ b/erpnext/telephony/doctype/incoming_call_settings/incoming_call_settings.py
@@ -11,6 +11,25 @@
 
 
 class IncomingCallSettings(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
+
+		from erpnext.telephony.doctype.incoming_call_handling_schedule.incoming_call_handling_schedule import (
+			IncomingCallHandlingSchedule,
+		)
+
+		agent_busy_message: DF.Data | None
+		agent_unavailable_message: DF.Data | None
+		call_handling_schedule: DF.Table[IncomingCallHandlingSchedule]
+		call_routing: DF.Literal["Sequential", "Simultaneous"]
+		greeting_message: DF.Data | None
+	# end: auto-generated types
+
 	def validate(self):
 		"""List of validations
 		* Make sure that to time slot is ahead of from time slot in call schedule
diff --git a/erpnext/telephony/doctype/telephony_call_type/telephony_call_type.py b/erpnext/telephony/doctype/telephony_call_type/telephony_call_type.py
index 944ffef..ddb6f93 100644
--- a/erpnext/telephony/doctype/telephony_call_type/telephony_call_type.py
+++ b/erpnext/telephony/doctype/telephony_call_type/telephony_call_type.py
@@ -6,4 +6,16 @@
 
 
 class TelephonyCallType(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
+
+		amended_from: DF.Link | None
+		call_type: DF.Data
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/telephony/doctype/voice_call_settings/voice_call_settings.py b/erpnext/telephony/doctype/voice_call_settings/voice_call_settings.py
index 9f9486f..da3a83a 100644
--- a/erpnext/telephony/doctype/voice_call_settings/voice_call_settings.py
+++ b/erpnext/telephony/doctype/voice_call_settings/voice_call_settings.py
@@ -7,4 +7,19 @@
 
 
 class VoiceCallSettings(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
+
+		agent_busy_message: DF.Data | None
+		agent_unavailable_message: DF.Data | None
+		call_receiving_device: DF.Literal["Computer", "Phone"]
+		greeting_message: DF.Data | None
+		user: DF.Link
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/translations/de.csv b/erpnext/translations/de.csv
index 73755be..2745d4d 100644
--- a/erpnext/translations/de.csv
+++ b/erpnext/translations/de.csv
@@ -8856,3 +8856,7 @@
 Split Early Payment Discount Loss into Income and Tax Loss,"Skontobetrag in Aufwand und Umsatzsteuerkorrektur aufteilen",
 Approve,Genehmigen,
 Reject,Ablehnen,
+Lost Quotations,Verlorene Angebote,
+Lost Quotations %,Verlorene Angebote %,
+Lost Value,Verlorener Wert,
+Lost Value %,Verlorener Wert %,
diff --git a/erpnext/translations/fr.csv b/erpnext/translations/fr.csv
index 5c34759..a711123 100644
--- a/erpnext/translations/fr.csv
+++ b/erpnext/translations/fr.csv
@@ -134,7 +134,7 @@
 Advertising,Publicité,
 Aerospace,Aérospatial,
 Against,Contre,
-Against Account,Pour le Compte,
+Against Account,Contrepartie,
 Against Journal Entry {0} does not have any unmatched {1} entry,L'Écriture de Journal {0} n'a pas d'entrée non associée {1},
 Against Journal Entry {0} is already adjusted against some other voucher,L'Écriture de Journal {0} est déjà ajustée par un autre bon,
 Against Supplier Invoice {0} dated {1},Pour la Facture Fournisseur {0} datée {1},
@@ -2969,7 +2969,7 @@
 Please save first,S'il vous plaît enregistrer en premier,
 Price not found for item {0} in price list {1},Prix non trouvé pour l'article {0} dans la liste de prix {1},
 Warehouse Type,Type d'entrepôt,
-'Date' is required,'Date' est requis,
+'Date' is required,La 'date' est obligatoire,
 Budgets,Budgets,
 Bundle Qty,Quantité de paquet,
 Company GSTIN,GSTIN de la Société,
@@ -3002,7 +3002,7 @@
 Account: {0} is not permitted under Payment Entry,Compte: {0} n'est pas autorisé sous Saisie du paiement.,
 Accounting Dimension <b>{0}</b> is required for 'Balance Sheet' account {1}.,La dimension de comptabilité <b>{0}</b> est requise pour le compte &quot;Bilan&quot; {1}.,
 Accounting Dimension <b>{0}</b> is required for 'Profit and Loss' account {1}.,La dimension de comptabilité <b>{0}</b> est requise pour le compte 'Bénéfices et pertes' {1}.,
-Accounting Masters,Maîtres Comptables,
+Accounting Masters,Données de base,
 Accounting Period overlaps with {0},La période comptable chevauche avec {0},
 Add to Featured Item,Ajouter à l'article en vedette,
 Add your review,Ajouter votre avis,
@@ -3701,7 +3701,7 @@
 Accounting Period,Période comptable,
 Period Name,Nom de période,
 Closed Documents,Documents fermés,
-Accounts Settings,Paramètres des Comptes,
+Accounts Settings,Paramètres de comptabilité,
 Settings for Accounts,Paramètres des Comptes,
 Make Accounting Entry For Every Stock Movement,Faites une Écriture Comptable Pour Chaque Mouvement du Stock,
 Users with this role are allowed to set frozen accounts and create / modify accounting entries against frozen accounts,Les utilisateurs ayant ce rôle sont autorisés à définir les comptes gelés et à créer / modifier des écritures comptables sur des comptes gelés,
@@ -3718,7 +3718,7 @@
 Currency Exchange Settings,Paramètres d'échange de devises,
 Allow Stale Exchange Rates,Autoriser les Taux de Change Existants,
 Stale Days,Journées Passées,
-Report Settings,Paramètres de rapport,
+Report Settings,Paramètres des rapports,
 Use Custom Cash Flow Format,Utiliser le format de flux de trésorerie personnalisé,
 Allowed To Transact With,Autorisé à faire affaire avec,
 SWIFT number,Numéro rapide,
@@ -4321,7 +4321,7 @@
 Redemption Cost Center,Centre de coûts pour l'échange,
 In Words will be visible once you save the Sales Invoice.,En Toutes Lettres. Sera visible une fois que vous enregistrerez la Facture.,
 Allocate Advances Automatically (FIFO),Allouer automatiquement les avances (FIFO),
-Get Advances Received,Obtenir Acomptes Reçus,
+Get Advances Received,Obtenir les paiements des avances,
 Base Change Amount (Company Currency),Montant de Base à Rendre (Devise de la Société),
 Write Off Outstanding Amount,Encours de Reprise,
 Terms and Conditions Details,Détails des Termes et Conditions,
@@ -4329,7 +4329,7 @@
 Is Discounted,Est réduit,
 Unpaid and Discounted,Non payé et à prix réduit,
 Overdue and Discounted,En retard et à prix réduit,
-Accounting Details,Détails Comptabilité,
+Accounting Details,Détails Comptable,
 Debit To,Débit Pour,
 Is Opening Entry,Est Écriture Ouverte,
 C-Form Applicable,Formulaire-C Applicable,
@@ -8028,7 +8028,7 @@
 Completed Qty cannot be greater than 'Qty to Manufacture',La quantité terminée ne peut pas être supérieure à la `` quantité à fabriquer '',
 "Row {0}: For Supplier {1}, Email Address is Required to send an email","Ligne {0}: pour le fournisseur {1}, l'adresse e-mail est obligatoire pour envoyer un e-mail",
 "If enabled, the system will post accounting entries for inventory automatically","Si activé, le système enregistrera automatiquement les écritures comptables pour l'inventaire",
-Accounts Frozen Till Date,Comptes gelés jusqu'à la date,
+Accounts Frozen Till Date,Comptes gelés jusqu'au,
 Accounting entries are frozen up to this date. Nobody can create or modify entries except users with the role specified below,Les écritures comptables sont gelées jusqu'à cette date. Personne ne peut créer ou modifier des entrées sauf les utilisateurs avec le rôle spécifié ci-dessous,
 Role Allowed to Set Frozen Accounts and Edit Frozen Entries,Rôle autorisé à définir des comptes gelés et à modifier les entrées gelées,
 Address used to determine Tax Category in transactions,Adresse utilisée pour déterminer la catégorie de taxe dans les transactions,
@@ -8339,7 +8339,7 @@
 Unit Of Measure (UOM),Unité de mesure (UdM),
 CRM Settings,Paramètres CRM,
 Do Not Explode,Ne pas décomposer,
-Quick Access, Accés rapides,
+Quick Access, Accès rapides,
 {}  Available,{} Disponible.s,
 {} Pending,{} En attente.s,
 {} To Bill,{} à facturer,
@@ -8449,3 +8449,64 @@
 Allow Sales,Autoriser à la vente
 Approve,Approuver,
 Reject,Rejeter,
+'Account' in the Accounting section of Customer {0},'Compte' dans la section comptabilité du client {0},
+Accounting Entry Number,Numéro d'écriture comptable,
+Accounting Ledger,Grand livre,
+Accounts Closing,Clôture,
+Accounts Frozen Upto,Comptes gelés jusqu'au,
+Accounts Manager,Responsable comptable,
+Active Customers,Clients actifs,
+Against Account,Contrepartie,
+All the Comments and Emails will be copied from one document to another newly created document(Lead -> Opportunity -> Quotation) throughout the CRM documents.,Tous les commentaires et les courriels seront copiés d'un document à un autre document nouvellement créé (Lead -> Opportunité -> Devis) dans l'ensemble des documents CRM.,
+Allow multi-currency invoices against single party account ,Autoriser les factures multi-devises en contrepartie d'un seul compte de tiers,
+Allow Sales Order Creation For Expired Quotation,Autoriser la création de commandes client pour les devis expirés,
+Allow Continuous Material Consumption,Autoriser la consommation continue de matériel,
+Allow Lead Duplication based on Emails,Autoriser la duplication des pistes sur la base des courriels,
+Asset Settings,Paramètres des actifs,
+Auto close Opportunity Replied after the no. of days mentioned above,Fermeture automatique de l'opportunité de réponse après le nombre de jours mentionné ci-dessus.,
+Auto Creation of Contact,Création automatique d'un contact,
+Automatically Fetch Payment Terms from Order,Récupération automatique des conditions de paiement de la commande,
+Bill for Rejected Quantity in Purchase Invoice,Facturation de la quantité rejetée dans la facture d'achat,
+Credit Limit Settings,Paramètres de la limite de crédit,
+Create Ledger Entries for Change Amount,Créer des écritures de grand livre pour modifier le montant,
+Customer Defaults,Valeurs par défaut des clients,
+Calculate Product Bundle Price based on Child Items' Rates,Calculer le prix des ensembles de produits en fonction des tarifs des articles enfants,
+Configure the action to stop the transaction or just warn if the same rate is not maintained.,Configurez une action pour stopper la transaction ou alertez simplement su le prix unitaie n'est pas maintenu.,
+Close Replied Opportunity After Days,Fermer l'opportunité répliquée après des jours,
+Carry Forward Communication and Comments,Reprendre les communications et commentaires,
+Default Down Payment Payable Account,Compte d'acompte fournisseur par défaut,
+Default Down Payment Receivable Account,Compte d'acompte client par défaut,
+Disable Last Purchase Rate,Désactiver le dernier prix d'achat,
+'Default {0} Account' in Company {1},'Compte {0} par défaut' dans la société {1},
+Enable Custom Cash Flow Format,Activation du format de flux de trésorerie personnalisé,
+Enabling ensure each Purchase Invoice has a unique value in Supplier Invoice No. field,Garanti que chaque facture d'achat est associée à un numéro de facture fournisseur unique,
+Enable Common Party Accounting,Activer la comptabilité des tiers communs,
+Enabling this will allow creation of multi-currency invoices against single party account in company currency,L'activation de cette option va permettre la création de factures multi-devises en contrepartie d'un seul compte de tiers en devise de la société,
+Enable Discount Accounting for Selling,Activation de la comptabilité d'escompte pour la vente,
+'Expected Start Date' can not be greater than 'Expected End Date','Date de Début Prévue' ne peut pas être postérieure à 'Date de Fin Prévue',
+Get Advances Received, Obtenir les paiements des avances,
+"If enabled, ledger entries will be posted for change amount in POS transactions","Si cette option est activée, des écritures de grand livre seront enregistrées pour le montant de la modification dans les transactions POS.",
+"If enabled, additional ledger entries will be made for discounts in a separate Discount Account","Si cette option est activée, des écritures de grand livre supplémentaires seront effectuées pour les remises dans un compte de remise séparé.",
+Item Price Settings,Paramètres du prix de l'article,
+Invoice and Billing,Facturation,
+Invoice Cancellation,Annulation de facture,
+Invoicing Features,Caractéristiques de la facturation,
+Journals,Journaux,
+"Learn about <a href=""https://docs.erpnext.com/docs/v13/user/manual/en/accounts/articles/common_party_accounting#:~:text=Common%20Party%20Accounting%20in%20ERPNext,Invoice%20against%20a%20primary%20Supplier."">Common Party</a>","En savoir plus <a href=""https://docs.erpnext.com/docs/v13/user/manual/en/accounts/articles/common_party_accounting#:~:text=Common%20Party%20Accounting%20in%20ERPNext,Invoice%20against%20a%20primary%20Supplier."">Tiers communs</a>",
+Naming Series and Price Defaults,Nom de série et Tarifs,
+Over Order Allowance (%),Tolérance de sur-commande (%),
+Payment Terms from orders will be fetched into the invoices as is,Les termes de paiement des commandes seront récupérées dans les factures telles quelles,
+Percentage you are allowed to order more against the Blanket Order Quantity. For example: If you have a Blanket Order of Quantity 100 units. and your Allowance is 10% then you are allowed to order 110 units.,"Percentage de commande autorisée en plus de la quantité prévue dans la commande ouverte. Par exemple: Si vous avez une commande avec une quantité de 100 unités et une tolérance de 10%, alors vous pourrez commander jusqu'à 110 unités.",
+Period Closing Settings,Paramètres de clôture de la période,
+Quick Access,Accès rapide,
+Report Setting,Réglage des rapports,
+Record all transactions against an accounting journal,Comptabiliser toutes les transactions dans un journal comptable,
+Rows with Same Account heads will be merged on Ledger,Les lignes associées aux mêmes comptes comptables seront fusionnées dans le grand livre,
+Role Allowed to Over Bill ,Rôle autorisé à sur-facturer,
+Role allowed to bypass Credit Limit,Rôle autorisé à contourner la limite de crédit,
+Role Allowed to Override Stop Action,Rôle autorisé à outrepasser l'action Stop,
+Show Balances in Chart Of Accounts,Afficher les soldes dans le plan comptable,
+Sales Update Frequency in Company and Project,Fréquence de mise à jour des ventes dans la société et le projet,
+Transaction Settings,Paramètres des transactions,
+Subcontracting Settings,Paramètres de sous-traitance,
+Users with this role are allowed to over bill above the allowance percentage,Les utilisateurs avec ce rôle sont autorisés à sur-facturer au delà du pourcentage de tolérance,
diff --git a/erpnext/utilities/bulk_transaction.py b/erpnext/utilities/bulk_transaction.py
index fcee265..df21b61 100644
--- a/erpnext/utilities/bulk_transaction.py
+++ b/erpnext/utilities/bulk_transaction.py
@@ -3,6 +3,7 @@
 
 import frappe
 from frappe import _
+from frappe.utils import get_link_to_form, today
 
 
 @frappe.whitelist()
@@ -28,6 +29,51 @@
 		job(deserialized_data, from_doctype, to_doctype)
 
 
+@frappe.whitelist()
+def retry(date: str | None = None):
+	if not date:
+		date = today()
+
+	if date:
+		failed_docs = frappe.db.get_all(
+			"Bulk Transaction Log Detail",
+			filters={"date": date, "transaction_status": "Failed", "retried": 0},
+			fields=["name", "transaction_name", "from_doctype", "to_doctype"],
+		)
+		if not failed_docs:
+			frappe.msgprint(_("There are no Failed transactions"))
+		else:
+			job = frappe.enqueue(
+				retry_failed_transactions,
+				failed_docs=failed_docs,
+			)
+			frappe.msgprint(
+				_("Job: {0} has been triggered for processing failed transactions").format(
+					get_link_to_form("RQ Job", job.id)
+				)
+			)
+
+
+def retry_failed_transactions(failed_docs: list | None):
+	if failed_docs:
+		for log in failed_docs:
+			try:
+				frappe.db.savepoint("before_creation_state")
+				task(log.transaction_name, log.from_doctype, log.to_doctype)
+			except Exception as e:
+				frappe.db.rollback(save_point="before_creation_state")
+				update_log(log.name, "Failed", 1, str(frappe.get_traceback()))
+			else:
+				update_log(log.name, "Success", 1)
+
+
+def update_log(log_name, status, retried, err=None):
+	frappe.db.set_value("Bulk Transaction Log Detail", log_name, "transaction_status", status)
+	frappe.db.set_value("Bulk Transaction Log Detail", log_name, "retried", retried)
+	if err:
+		frappe.db.set_value("Bulk Transaction Log Detail", log_name, "error_description", err)
+
+
 def job(deserialized_data, from_doctype, to_doctype):
 	fail_count = 0
 	for d in deserialized_data:
@@ -38,7 +84,7 @@
 		except Exception as e:
 			frappe.db.rollback(save_point="before_creation_state")
 			fail_count += 1
-			update_logger(
+			create_log(
 				doc_name,
 				str(frappe.get_traceback()),
 				from_doctype,
@@ -47,7 +93,7 @@
 				log_date=str(date.today()),
 			)
 		else:
-			update_logger(
+			create_log(
 				doc_name, None, from_doctype, to_doctype, status="Success", log_date=str(date.today())
 			)
 
@@ -98,6 +144,7 @@
 		},
 		"Purchase Receipt": {"Purchase Invoice": purchase_receipt.make_purchase_invoice},
 	}
+	frappe.flags.bulk_transaction = True
 	if to_doctype in ["Payment Entry"]:
 		obj = mapper[from_doctype][to_doctype](from_doctype, doc_name)
 	else:
@@ -106,47 +153,21 @@
 	obj.flags.ignore_validate = True
 	obj.set_title_field()
 	obj.insert(ignore_mandatory=True)
+	del frappe.flags.bulk_transaction
 
 
-def check_logger_doc_exists(log_date):
-	return frappe.db.exists("Bulk Transaction Log", log_date)
-
-
-def get_logger_doc(log_date):
-	return frappe.get_doc("Bulk Transaction Log", log_date)
-
-
-def create_logger_doc():
-	log_doc = frappe.new_doc("Bulk Transaction Log")
-	log_doc.set_new_name(set_name=str(date.today()))
-	log_doc.log_date = date.today()
-
-	return log_doc
-
-
-def append_data_to_logger(log_doc, doc_name, error, from_doctype, to_doctype, status, restarted):
-	row = log_doc.append("logger_data", {})
-	row.transaction_name = doc_name
-	row.date = date.today()
+def create_log(doc_name, e, from_doctype, to_doctype, status, log_date=None, restarted=0):
+	transaction_log = frappe.new_doc("Bulk Transaction Log Detail")
+	transaction_log.transaction_name = doc_name
+	transaction_log.date = today()
 	now = datetime.now()
-	row.time = now.strftime("%H:%M:%S")
-	row.transaction_status = status
-	row.error_description = str(error)
-	row.from_doctype = from_doctype
-	row.to_doctype = to_doctype
-	row.retried = restarted
-
-
-def update_logger(doc_name, e, from_doctype, to_doctype, status, log_date=None, restarted=0):
-	if not check_logger_doc_exists(log_date):
-		log_doc = create_logger_doc()
-		append_data_to_logger(log_doc, doc_name, e, from_doctype, to_doctype, status, restarted)
-		log_doc.insert()
-	else:
-		log_doc = get_logger_doc(log_date)
-		if record_exists(log_doc, doc_name, status):
-			append_data_to_logger(log_doc, doc_name, e, from_doctype, to_doctype, status, restarted)
-			log_doc.save()
+	transaction_log.time = now.strftime("%H:%M:%S")
+	transaction_log.transaction_status = status
+	transaction_log.error_description = str(e)
+	transaction_log.from_doctype = from_doctype
+	transaction_log.to_doctype = to_doctype
+	transaction_log.retried = restarted
+	transaction_log.save()
 
 
 def show_job_status(fail_count, deserialized_data_count, to_doctype):
@@ -176,23 +197,3 @@
 			title="Failed",
 			indicator="red",
 		)
-
-
-def record_exists(log_doc, doc_name, status):
-	record = mark_retrired_transaction(log_doc, doc_name)
-	if record and status == "Failed":
-		return False
-	elif record and status == "Success":
-		return True
-	else:
-		return True
-
-
-def mark_retrired_transaction(log_doc, doc_name):
-	record = 0
-	for d in log_doc.get("logger_data"):
-		if d.transaction_name == doc_name and d.transaction_status == "Failed":
-			frappe.db.set_value("Bulk Transaction Log Detail", d.name, "retried", 1)
-			record = record + 1
-
-	return record
diff --git a/erpnext/utilities/doctype/portal_user/portal_user.py b/erpnext/utilities/doctype/portal_user/portal_user.py
index 2e0064d..176e32d 100644
--- a/erpnext/utilities/doctype/portal_user/portal_user.py
+++ b/erpnext/utilities/doctype/portal_user/portal_user.py
@@ -6,4 +6,18 @@
 
 
 class PortalUser(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
+
+		parent: DF.Data
+		parentfield: DF.Data
+		parenttype: DF.Data
+		user: DF.Link
+	# end: auto-generated types
+
 	pass
diff --git a/erpnext/utilities/doctype/rename_tool/rename_tool.py b/erpnext/utilities/doctype/rename_tool/rename_tool.py
index b31574c..19b29f7 100644
--- a/erpnext/utilities/doctype/rename_tool/rename_tool.py
+++ b/erpnext/utilities/doctype/rename_tool/rename_tool.py
@@ -10,6 +10,18 @@
 
 
 class RenameTool(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
+
+		file_to_rename: DF.Attach | None
+		select_doctype: DF.Literal
+	# end: auto-generated types
+
 	pass
 
 
diff --git a/erpnext/utilities/doctype/sms_log/README.md b/erpnext/utilities/doctype/sms_log/README.md
deleted file mode 100644
index 9ee2b79..0000000
--- a/erpnext/utilities/doctype/sms_log/README.md
+++ /dev/null
@@ -1 +0,0 @@
-Log of SMS sent via SMS Center.
\ No newline at end of file
diff --git a/erpnext/utilities/doctype/sms_log/sms_log.js b/erpnext/utilities/doctype/sms_log/sms_log.js
deleted file mode 100644
index f5358e8..0000000
--- a/erpnext/utilities/doctype/sms_log/sms_log.js
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
-// For license information, please see license.txt
-
-frappe.ui.form.on('SMS Log', {
-	refresh: function(frm) {
-
-	}
-});
diff --git a/erpnext/utilities/doctype/sms_log/sms_log.json b/erpnext/utilities/doctype/sms_log/sms_log.json
deleted file mode 100644
index 269094b..0000000
--- a/erpnext/utilities/doctype/sms_log/sms_log.json
+++ /dev/null
@@ -1,371 +0,0 @@
-{
- "allow_copy": 0, 
- "allow_guest_to_view": 0, 
- "allow_import": 0, 
- "allow_rename": 0, 
- "autoname": "SYS-SMS-.#####", 
- "beta": 0, 
- "creation": "2012-03-27 14:36:47", 
- "custom": 0, 
- "docstatus": 0, 
- "doctype": "DocType", 
- "editable_grid": 0, 
- "fields": [
-  {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "sender_name", 
-   "fieldtype": "Data", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Sender Name", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 1, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
-  {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "sent_on", 
-   "fieldtype": "Date", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Sent On", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 1, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
-  {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "column_break0", 
-   "fieldtype": "Column Break", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0, 
-   "width": "50%"
-  }, 
-  {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "message", 
-   "fieldtype": "Small Text", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Message", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 1, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
-  {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "sec_break1", 
-   "fieldtype": "Section Break", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Simple", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
-  {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "no_of_requested_sms", 
-   "fieldtype": "Int", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "No of Requested SMS", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 1, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
-  {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "requested_numbers", 
-   "fieldtype": "Code", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Requested Numbers", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 1, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
-  {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "column_break1", 
-   "fieldtype": "Column Break", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0, 
-   "width": "50%"
-  }, 
-  {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "no_of_sent_sms", 
-   "fieldtype": "Int", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "No of Sent SMS", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 1, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
-  {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "sent_to", 
-   "fieldtype": "Code", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Sent To", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 1, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }
- ], 
- "has_web_view": 0, 
- "hide_heading": 0, 
- "hide_toolbar": 0, 
- "icon": "fa fa-mobile-phone", 
- "idx": 1, 
- "image_view": 0, 
- "in_create": 0, 
- "is_submittable": 0, 
- "issingle": 0, 
- "istable": 0, 
- "max_attachments": 0, 
- "modified": "2018-08-21 16:15:40.898889", 
- "modified_by": "Administrator", 
- "module": "Utilities", 
- "name": "SMS Log", 
- "owner": "Administrator", 
- "permissions": [
-  {
-   "amend": 0, 
-   "cancel": 0, 
-   "create": 0, 
-   "delete": 0, 
-   "email": 1, 
-   "export": 0, 
-   "if_owner": 0, 
-   "import": 0, 
-   "permlevel": 0, 
-   "print": 1, 
-   "read": 1, 
-   "report": 1, 
-   "role": "System Manager", 
-   "set_user_permissions": 0, 
-   "share": 0, 
-   "submit": 0, 
-   "write": 0
-  }
- ], 
- "quick_entry": 0, 
- "read_only": 0, 
- "read_only_onload": 0, 
- "show_name_in_global_search": 0, 
- "track_changes": 1, 
- "track_seen": 0, 
- "track_views": 0
-}
\ No newline at end of file
diff --git a/erpnext/utilities/doctype/sms_log/sms_log.py b/erpnext/utilities/doctype/sms_log/sms_log.py
deleted file mode 100644
index 85140f3..0000000
--- a/erpnext/utilities/doctype/sms_log/sms_log.py
+++ /dev/null
@@ -1,9 +0,0 @@
-# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
-# License: GNU General Public License v3. See license.txt
-
-
-from frappe.model.document import Document
-
-
-class SMSLog(Document):
-	pass
diff --git a/erpnext/utilities/doctype/sms_log/test_sms_log.py b/erpnext/utilities/doctype/sms_log/test_sms_log.py
deleted file mode 100644
index 3ff0202..0000000
--- a/erpnext/utilities/doctype/sms_log/test_sms_log.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
-# See license.txt
-
-import unittest
-
-# test_records = frappe.get_test_records('SMS Log')
-
-
-class TestSMSLog(unittest.TestCase):
-	pass
diff --git a/erpnext/utilities/doctype/video/video.py b/erpnext/utilities/doctype/video/video.py
index 62033a5..1a9fe19 100644
--- a/erpnext/utilities/doctype/video/video.py
+++ b/erpnext/utilities/doctype/video/video.py
@@ -15,6 +15,28 @@
 
 
 class Video(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
+
+		comment_count: DF.Float
+		description: DF.TextEditor
+		dislike_count: DF.Float
+		duration: DF.Duration | None
+		image: DF.AttachImage | None
+		like_count: DF.Float
+		provider: DF.Literal["YouTube", "Vimeo"]
+		publish_date: DF.Date | None
+		title: DF.Data
+		url: DF.Data
+		view_count: DF.Float
+		youtube_video_id: DF.Data | None
+	# end: auto-generated types
+
 	def validate(self):
 		if self.provider == "YouTube" and is_tracking_enabled():
 			self.set_video_id()
diff --git a/erpnext/utilities/doctype/video_settings/video_settings.py b/erpnext/utilities/doctype/video_settings/video_settings.py
index 9bc7972..762a795 100644
--- a/erpnext/utilities/doctype/video_settings/video_settings.py
+++ b/erpnext/utilities/doctype/video_settings/video_settings.py
@@ -9,6 +9,19 @@
 
 
 class VideoSettings(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
+
+		api_key: DF.Data | None
+		enable_youtube_tracking: DF.Check
+		frequency: DF.Literal["30 mins", "1 hr", "6 hrs", "Daily"]
+	# end: auto-generated types
+
 	def validate(self):
 		self.validate_youtube_api_key()
 
diff --git a/erpnext/utilities/transaction_base.py b/erpnext/utilities/transaction_base.py
index 7eba35d..b083614 100644
--- a/erpnext/utilities/transaction_base.py
+++ b/erpnext/utilities/transaction_base.py
@@ -98,6 +98,7 @@
 				"Selling Settings", "None", ["maintain_same_rate_action", "role_to_override_stop_action"]
 			)
 
+		stop_actions = []
 		for ref_dt, ref_dn_field, ref_link_field in ref_details:
 			reference_names = [d.get(ref_link_field) for d in self.get("items") if d.get(ref_link_field)]
 			reference_details = self.get_reference_details(reference_names, ref_dt + " Item")
@@ -108,7 +109,7 @@
 					if abs(flt(d.rate - ref_rate, d.precision("rate"))) >= 0.01:
 						if action == "Stop":
 							if role_allowed_to_override not in frappe.get_roles():
-								frappe.throw(
+								stop_actions.append(
 									_("Row #{0}: Rate must be same as {1}: {2} ({3} / {4})").format(
 										d.idx, ref_dt, d.get(ref_dn_field), d.rate, ref_rate
 									)
@@ -121,6 +122,8 @@
 								title=_("Warning"),
 								indicator="orange",
 							)
+		if stop_actions:
+			frappe.throw(stop_actions, as_list=True)
 
 	def get_reference_details(self, reference_names, reference_doctype):
 		return frappe._dict(
diff --git a/erpnext/utilities/doctype/sms_log/__init__.py b/erpnext/www/all-products/__init__.py
similarity index 100%
rename from erpnext/utilities/doctype/sms_log/__init__.py
rename to erpnext/www/all-products/__init__.py
diff --git a/erpnext/utilities/doctype/sms_log/__init__.py b/erpnext/www/shop-by-category/__init__.py
similarity index 100%
copy from erpnext/utilities/doctype/sms_log/__init__.py
copy to erpnext/www/shop-by-category/__init__.py