Merge pull request #39457 from ruthra-kumar/background_job_transaction_deletion

refactor: delete transactions in background
diff --git a/.github/workflows/linters.yml b/.github/workflows/linters.yml
index 94b76b1..c7caa4c 100644
--- a/.github/workflows/linters.yml
+++ b/.github/workflows/linters.yml
@@ -20,6 +20,18 @@
       - name: Install and Run Pre-commit
         uses: pre-commit/action@v3.0.0
 
+  semgrep:
+    name: semgrep
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v3
+
+      - name: Set up Python 3.10
+        uses: actions/setup-python@v4
+        with:
+          python-version: '3.10'
+          cache: pip
+
       - name: Download Semgrep rules
         run: git clone --depth 1 https://github.com/frappe/semgrep-rules.git frappe-semgrep-rules
 
diff --git a/erpnext/accounts/deferred_revenue.py b/erpnext/accounts/deferred_revenue.py
index 6282e9a..367b017 100644
--- a/erpnext/accounts/deferred_revenue.py
+++ b/erpnext/accounts/deferred_revenue.py
@@ -358,11 +358,9 @@
 
 		account_currency = get_account_currency(item.expense_account or item.income_account)
 		if doc.doctype == "Sales Invoice":
-			against_type = "Customer"
 			against, project = doc.customer, doc.project
 			credit_account, debit_account = item.income_account, item.deferred_revenue_account
 		else:
-			against_type = "Supplier"
 			against, project = doc.supplier, item.project
 			credit_account, debit_account = item.deferred_expense_account, item.expense_account
 
@@ -415,7 +413,6 @@
 				doc,
 				credit_account,
 				debit_account,
-				against_type,
 				against,
 				amount,
 				base_amount,
@@ -497,7 +494,6 @@
 	doc,
 	credit_account,
 	debit_account,
-	against_type,
 	against,
 	amount,
 	base_amount,
@@ -519,9 +515,7 @@
 		doc.get_gl_dict(
 			{
 				"account": credit_account,
-				"against_type": against_type,
 				"against": against,
-				"against_link": against,
 				"credit": base_amount,
 				"credit_in_account_currency": amount,
 				"cost_center": cost_center,
@@ -540,9 +534,7 @@
 		doc.get_gl_dict(
 			{
 				"account": debit_account,
-				"against_type": against_type,
 				"against": against,
-				"against_link": against,
 				"debit": base_amount,
 				"debit_in_account_currency": amount,
 				"cost_center": cost_center,
diff --git a/erpnext/accounts/doctype/fiscal_year/fiscal_year.json b/erpnext/accounts/doctype/fiscal_year/fiscal_year.json
index 5ab91f2..bd2bfbd 100644
--- a/erpnext/accounts/doctype/fiscal_year/fiscal_year.json
+++ b/erpnext/accounts/doctype/fiscal_year/fiscal_year.json
@@ -82,11 +82,11 @@
  "icon": "fa fa-calendar",
  "idx": 1,
  "links": [],
- "modified": "2020-11-05 12:16:53.081573",
+ "modified": "2024-01-17 13:06:01.608953",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Fiscal Year",
- "owner": "Administrator",
+  "owner": "Administrator",
  "permissions": [
   {
    "create": 1,
@@ -118,6 +118,14 @@
   {
    "read": 1,
    "role": "Employee"
+  },
+  {
+   "read": 1,
+   "role": "Accounts Manager"
+  },
+  {
+   "read": 1,
+   "role": "Stock Manager"
   }
  ],
  "show_name_in_global_search": 1,
diff --git a/erpnext/accounts/doctype/fiscal_year/test_fiscal_year.py b/erpnext/accounts/doctype/fiscal_year/test_fiscal_year.py
index 181406b..8d43716 100644
--- a/erpnext/accounts/doctype/fiscal_year/test_fiscal_year.py
+++ b/erpnext/accounts/doctype/fiscal_year/test_fiscal_year.py
@@ -39,7 +39,7 @@
 	]
 
 	start = 2012
-	end = now_datetime().year + 5
+	end = now_datetime().year + 25
 	for year in range(start, end):
 		test_records.append(
 			{
diff --git a/erpnext/accounts/doctype/gl_entry/gl_entry.json b/erpnext/accounts/doctype/gl_entry/gl_entry.json
index 09912e9..c071193 100644
--- a/erpnext/accounts/doctype/gl_entry/gl_entry.json
+++ b/erpnext/accounts/doctype/gl_entry/gl_entry.json
@@ -17,9 +17,7 @@
   "account_currency",
   "debit_in_account_currency",
   "credit_in_account_currency",
-  "against_type",
   "against",
-  "against_link",
   "against_voucher_type",
   "against_voucher",
   "voucher_type",
@@ -132,13 +130,6 @@
    "options": "account_currency"
   },
   {
-   "fieldname": "against_type",
-   "fieldtype": "Link",
-   "in_filter": 1,
-   "label": "Against Type",
-   "options": "DocType"
-  },
-  {
    "fieldname": "against",
    "fieldtype": "Text",
    "in_filter": 1,
@@ -147,13 +138,6 @@
    "oldfieldtype": "Text"
   },
   {
-   "fieldname": "against_link",
-   "fieldtype": "Dynamic Link",
-   "in_filter": 1,
-   "label": "Against",
-   "options": "against_type"
-  },
-  {
    "fieldname": "against_voucher_type",
    "fieldtype": "Link",
    "label": "Against Voucher Type",
@@ -306,7 +290,7 @@
  "idx": 1,
  "in_create": 1,
  "links": [],
- "modified": "2023-12-18 15:38:14.006208",
+ "modified": "2023-09-26 12:03:23.031733",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "GL Entry",
diff --git a/erpnext/accounts/doctype/invoice_discounting/invoice_discounting.py b/erpnext/accounts/doctype/invoice_discounting/invoice_discounting.py
index 69b0860..76f4dad 100644
--- a/erpnext/accounts/doctype/invoice_discounting/invoice_discounting.py
+++ b/erpnext/accounts/doctype/invoice_discounting/invoice_discounting.py
@@ -153,9 +153,7 @@
 							"account": inv.debit_to,
 							"party_type": "Customer",
 							"party": d.customer,
-							"against_type": "Account",
 							"against": self.accounts_receivable_credit,
-							"against_link": self.accounts_receivable_credit,
 							"credit": outstanding_in_company_currency,
 							"credit_in_account_currency": outstanding_in_company_currency
 							if inv.party_account_currency == company_currency
@@ -175,9 +173,7 @@
 							"account": self.accounts_receivable_credit,
 							"party_type": "Customer",
 							"party": d.customer,
-							"against_type": "Account",
 							"against": inv.debit_to,
-							"against_link": inv.debit_to,
 							"debit": outstanding_in_company_currency,
 							"debit_in_account_currency": outstanding_in_company_currency
 							if ar_credit_account_currency == company_currency
diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.js b/erpnext/accounts/doctype/journal_entry/journal_entry.js
index abf8781..07fb5e8 100644
--- a/erpnext/accounts/doctype/journal_entry/journal_entry.js
+++ b/erpnext/accounts/doctype/journal_entry/journal_entry.js
@@ -220,16 +220,6 @@
 			return erpnext.journal_entry.account_query(me.frm);
 		});
 
-		me.frm.set_query("against_account_link", "accounts", function(doc, cdt, cdn) {
-			return erpnext.journal_entry.against_account_query(me.frm);
-		});
-
-		me.frm.set_query("against_type", "accounts", function(){
-			return {
-				query: "erpnext.accounts.doctype.journal_entry.journal_entry.get_against_type",
-			}
-		})
-
 		me.frm.set_query("party_type", "accounts", function(doc, cdt, cdn) {
 			const row = locals[cdt][cdn];
 
@@ -601,21 +591,6 @@
 		return { filters: filters };
 	},
 
-	against_account_query: function(frm) {
-		if (frm.doc.against_type != "Account"){
-			return { filters: {} };
-		}
-		else {
-			let filters = { company: frm.doc.company, is_group: 0 };
-			if(!frm.doc.multi_currency) {
-				$.extend(filters, {
-					account_currency: ['in', [frappe.get_doc(":Company", frm.doc.company).default_currency, null]]
-				});
-			}
-			return { filters: filters };
-		}
-	},
-
 	reverse_journal_entry: function() {
 		frappe.model.open_mapped_doc({
 			method: "erpnext.accounts.doctype.journal_entry.journal_entry.make_reverse_journal_entry",
diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.py b/erpnext/accounts/doctype/journal_entry/journal_entry.py
index 79f1ab0..40d552b 100644
--- a/erpnext/accounts/doctype/journal_entry/journal_entry.py
+++ b/erpnext/accounts/doctype/journal_entry/journal_entry.py
@@ -304,7 +304,6 @@
 					"account": tax_withholding_details.get("account_head"),
 					rev_debit_or_credit: tax_withholding_details.get("tax_amount"),
 					"against_account": parties[0],
-					"against_account_link": parties[0],
 				},
 			)
 
@@ -751,90 +750,27 @@
 					)
 
 	def set_against_account(self):
+		accounts_debited, accounts_credited = [], []
 		if self.voucher_type in ("Deferred Revenue", "Deferred Expense"):
 			for d in self.get("accounts"):
 				if d.reference_type == "Sales Invoice":
-					against_type = "Customer"
+					field = "customer"
 				else:
-					against_type = "Supplier"
+					field = "supplier"
 
-				against_account = frappe.db.get_value(d.reference_type, d.reference_name, against_type.lower())
-				d.against_type = against_type
-				d.against_account_link = against_account
+				d.against_account = frappe.db.get_value(d.reference_type, d.reference_name, field)
 		else:
-			self.get_debited_credited_accounts()
-			if len(self.accounts_credited) > 1 and len(self.accounts_debited) > 1:
-				self.auto_set_against_accounts()
-				return
-			self.get_against_accounts()
+			for d in self.get("accounts"):
+				if flt(d.debit) > 0:
+					accounts_debited.append(d.party or d.account)
+				if flt(d.credit) > 0:
+					accounts_credited.append(d.party or d.account)
 
-	def auto_set_against_accounts(self):
-		for i in range(0, len(self.accounts), 2):
-			acc = self.accounts[i]
-			against_acc = self.accounts[i + 1]
-			if acc.debit_in_account_currency > 0:
-				current_val = acc.debit_in_account_currency * flt(acc.exchange_rate)
-				against_val = against_acc.credit_in_account_currency * flt(against_acc.exchange_rate)
-			else:
-				current_val = acc.credit_in_account_currency * flt(acc.exchange_rate)
-				against_val = against_acc.debit_in_account_currency * flt(against_acc.exchange_rate)
-
-			if current_val == against_val:
-				acc.against_type = against_acc.party_type or "Account"
-				against_acc.against_type = acc.party_type or "Account"
-
-				acc.against_account_link = against_acc.party or against_acc.account
-				against_acc.against_account_link = acc.party or acc.account
-			else:
-				frappe.msgprint(
-					_(
-						"Unable to automatically determine {0} accounts. Set them up in the {1} table if needed."
-					).format(frappe.bold("against"), frappe.bold("Accounting Entries")),
-					alert=True,
-				)
-				break
-
-	def get_against_accounts(self):
-		self.against_accounts = []
-		self.split_account = {}
-		self.get_debited_credited_accounts()
-
-		if self.separate_against_account_entries:
-			no_of_credited_acc, no_of_debited_acc = len(self.accounts_credited), len(self.accounts_debited)
-			if no_of_credited_acc <= 1 and no_of_debited_acc <= 1:
-				self.set_against_accounts_for_single_dr_cr()
-				self.separate_against_account_entries = 0
-			elif no_of_credited_acc == 1:
-				self.against_accounts = self.accounts_debited
-				self.split_account = self.accounts_credited[0]
-			elif no_of_debited_acc == 1:
-				self.against_accounts = self.accounts_credited
-				self.split_account = self.accounts_debited[0]
-
-	def get_debited_credited_accounts(self):
-		self.accounts_debited, self.accounts_credited = [], []
-		self.separate_against_account_entries = 1
-		for d in self.get("accounts"):
-			if flt(d.debit) > 0:
-				self.accounts_debited.append(d)
-			elif flt(d.credit) > 0:
-				self.accounts_credited.append(d)
-
-			if d.against_account_link:
-				self.separate_against_account_entries = 0
-				break
-
-	def set_against_accounts_for_single_dr_cr(self):
-		against_account = None
-		for d in self.accounts:
-			if flt(d.debit) > 0:
-				against_account = self.accounts_credited[0]
-			elif flt(d.credit) > 0:
-				against_account = self.accounts_debited[0]
-			if against_account:
-				d.against_type = against_account.party_type or "Account"
-				d.against_account = against_account.party or against_account.account
-				d.against_account_link = against_account.party or against_account.account
+			for d in self.get("accounts"):
+				if flt(d.debit) > 0:
+					d.against_account = ", ".join(list(set(accounts_credited)))
+				if flt(d.credit) > 0:
+					d.against_account = ", ".join(list(set(accounts_debited)))
 
 	def validate_debit_credit_amount(self):
 		if not (self.voucher_type == "Exchange Gain Or Loss" and self.multi_currency):
@@ -1031,82 +967,40 @@
 
 	def build_gl_map(self):
 		gl_map = []
-		self.get_against_accounts()
 		for d in self.get("accounts"):
 			if d.debit or d.credit or (self.voucher_type == "Exchange Gain Or Loss"):
 				r = [d.user_remark, self.remark]
 				r = [x for x in r if x]
 				remarks = "\n".join(r)
 
-				gl_dict = self.get_gl_dict(
-					{
-						"account": d.account,
-						"party_type": d.party_type,
-						"due_date": self.due_date,
-						"party": d.party,
-						"debit": flt(d.debit, d.precision("debit")),
-						"credit": flt(d.credit, d.precision("credit")),
-						"account_currency": d.account_currency,
-						"debit_in_account_currency": flt(
-							d.debit_in_account_currency, d.precision("debit_in_account_currency")
-						),
-						"credit_in_account_currency": flt(
-							d.credit_in_account_currency, d.precision("credit_in_account_currency")
-						),
-						"against_voucher_type": d.reference_type,
-						"against_voucher": d.reference_name,
-						"remarks": remarks,
-						"voucher_detail_no": d.reference_detail_no,
-						"cost_center": d.cost_center,
-						"project": d.project,
-						"finance_book": self.finance_book,
-					},
-					item=d,
+				gl_map.append(
+					self.get_gl_dict(
+						{
+							"account": d.account,
+							"party_type": d.party_type,
+							"due_date": self.due_date,
+							"party": d.party,
+							"against": d.against_account,
+							"debit": flt(d.debit, d.precision("debit")),
+							"credit": flt(d.credit, d.precision("credit")),
+							"account_currency": d.account_currency,
+							"debit_in_account_currency": flt(
+								d.debit_in_account_currency, d.precision("debit_in_account_currency")
+							),
+							"credit_in_account_currency": flt(
+								d.credit_in_account_currency, d.precision("credit_in_account_currency")
+							),
+							"against_voucher_type": d.reference_type,
+							"against_voucher": d.reference_name,
+							"remarks": remarks,
+							"voucher_detail_no": d.reference_detail_no,
+							"cost_center": d.cost_center,
+							"project": d.project,
+							"finance_book": self.finance_book,
+						},
+						item=d,
+					)
 				)
-
-				if not self.separate_against_account_entries:
-					gl_dict.update(
-						{
-							"against_type": d.against_type,
-							"against_link": d.against_account_link,
-						}
-					)
-					gl_map.append(gl_dict)
-
-				elif d in self.against_accounts:
-					gl_dict.update(
-						{
-							"against_type": self.split_account.get("party_type") or "Account",
-							"against": self.split_account.get("party") or self.split_account.get("account"),
-							"against_link": self.split_account.get("party") or self.split_account.get("account"),
-						}
-					)
-					gl_map.append(gl_dict)
-
-				else:
-					for against_account in self.against_accounts:
-						against_account = against_account.as_dict()
-						debit = against_account.credit or against_account.credit_in_account_currency
-						credit = against_account.debit or against_account.debit_in_account_currency
-						gl_dict = gl_dict.copy()
-						gl_dict.update(
-							{
-								"against_type": against_account.party_type or "Account",
-								"against": against_account.party or against_account.account,
-								"against_link": against_account.party or against_account.account,
-								"debit": flt(debit, d.precision("debit")),
-								"credit": flt(credit, d.precision("credit")),
-								"account_currency": d.account_currency,
-								"debit_in_account_currency": flt(
-									debit / d.exchange_rate, d.precision("debit_in_account_currency")
-								),
-								"credit_in_account_currency": flt(
-									credit / d.exchange_rate, d.precision("credit_in_account_currency")
-								),
-							}
-						)
-						gl_map.append(gl_dict)
-
 		return gl_map
 
 	def make_gl_entries(self, cancel=0, adv_adj=0):
@@ -1731,10 +1625,3 @@
 	)
 
 	return doclist
-
-
-@frappe.whitelist()
-def get_against_type(doctype, txt, searchfield, start, page_len, filters):
-	against_types = frappe.db.get_list("Party Type", pluck="name") + ["Account"]
-	doctype = frappe.qb.DocType("DocType")
-	return frappe.qb.from_(doctype).select(doctype.name).where(doctype.name.isin(against_types)).run()
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 01006bd..99e66e6 100644
--- a/erpnext/accounts/doctype/journal_entry_account/journal_entry_account.json
+++ b/erpnext/accounts/doctype/journal_entry_account/journal_entry_account.json
@@ -37,9 +37,7 @@
   "col_break3",
   "is_advance",
   "user_remark",
-  "against_type",
-  "against_account",
-  "against_account_link"
+  "against_account"
  ],
  "fields": [
   {
@@ -252,21 +250,14 @@
    "print_hide": 1
   },
   {
-    "fieldname": "against_account",
-    "fieldtype": "Text",
-    "hidden": 1,
-    "label": "Against Account",
-    "no_copy": 1,
-    "oldfieldname": "against_account",
-    "oldfieldtype": "Text",
-    "print_hide": 1
-  },
-  {
-   "fieldname": "against_account_link",
-   "fieldtype": "Dynamic Link",
+   "fieldname": "against_account",
+   "fieldtype": "Text",
+   "hidden": 1,
    "label": "Against Account",
    "no_copy": 1,
-   "options": "against_type"
+   "oldfieldname": "against_account",
+   "oldfieldtype": "Text",
+   "print_hide": 1
   },
   {
    "collapsible": 1,
@@ -290,18 +281,12 @@
    "hidden": 1,
    "label": "Reference Detail No",
    "no_copy": 1
-  },
-  {
-   "fieldname": "against_type",
-   "fieldtype": "Link",
-   "label": "Against Type",
-   "options": "DocType"
   }
  ],
  "idx": 1,
  "istable": 1,
  "links": [],
- "modified": "2023-12-02 23:21:22.205409",
+ "modified": "2023-12-03 23:21:22.205409",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Journal Entry Account",
diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.js b/erpnext/accounts/doctype/payment_entry/payment_entry.js
index 9402e3d..2954d2f 100644
--- a/erpnext/accounts/doctype/payment_entry/payment_entry.js
+++ b/erpnext/accounts/doctype/payment_entry/payment_entry.js
@@ -933,7 +933,7 @@
 			if(frm.doc.payment_type == "Receive"
 				&& frm.doc.base_total_allocated_amount < frm.doc.base_received_amount + total_deductions
 				&& frm.doc.total_allocated_amount < frm.doc.paid_amount + (total_deductions / frm.doc.source_exchange_rate)) {
-					unallocated_amount = (frm.doc.base_received_amount + total_deductions + flt(frm.doc.base_total_taxes_and_charges)
+					unallocated_amount = (frm.doc.base_received_amount + total_deductions - flt(frm.doc.base_total_taxes_and_charges)
 						- frm.doc.base_total_allocated_amount) / frm.doc.source_exchange_rate;
 			} else if (frm.doc.payment_type == "Pay"
 				&& frm.doc.base_total_allocated_amount < frm.doc.base_paid_amount - total_deductions
diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.py b/erpnext/accounts/doctype/payment_entry/payment_entry.py
index 37bd8e6..dbebbb0 100644
--- a/erpnext/accounts/doctype/payment_entry/payment_entry.py
+++ b/erpnext/accounts/doctype/payment_entry/payment_entry.py
@@ -1144,9 +1144,7 @@
 					"account": self.party_account,
 					"party_type": self.party_type,
 					"party": self.party,
-					"against_type": "Account",
 					"against": against_account,
-					"against_link": against_account,
 					"account_currency": self.party_account_currency,
 					"cost_center": self.cost_center,
 				},
@@ -1311,9 +1309,7 @@
 					{
 						"account": self.paid_from,
 						"account_currency": self.paid_from_account_currency,
-						"against_type": self.party_type if self.payment_type == "Pay" else "Account",
 						"against": self.party if self.payment_type == "Pay" else self.paid_to,
-						"against_link": self.party if self.payment_type == "Pay" else self.paid_to,
 						"credit_in_account_currency": self.paid_amount,
 						"credit": self.base_paid_amount,
 						"cost_center": self.cost_center,
@@ -1328,9 +1324,7 @@
 					{
 						"account": self.paid_to,
 						"account_currency": self.paid_to_account_currency,
-						"against_type": self.party_type if self.payment_type == "Receive" else "Account",
 						"against": self.party if self.payment_type == "Receive" else self.paid_from,
-						"against_link": self.party if self.payment_type == "Receive" else self.paid_from,
 						"debit_in_account_currency": self.received_amount,
 						"debit": self.base_received_amount,
 						"cost_center": self.cost_center,
@@ -1354,7 +1348,6 @@
 				rev_dr_or_cr = "credit" if dr_or_cr == "debit" else "debit"
 				against = self.party or self.paid_to
 
-			against_type = self.party_type or "Account"
 			payment_account = self.get_party_account_for_taxes()
 			tax_amount = d.tax_amount
 			base_tax_amount = d.base_tax_amount
@@ -1363,9 +1356,7 @@
 				self.get_gl_dict(
 					{
 						"account": d.account_head,
-						"against_type": against_type,
 						"against": against,
-						"against_link": against,
 						dr_or_cr: tax_amount,
 						dr_or_cr + "_in_account_currency": base_tax_amount
 						if account_currency == self.company_currency
@@ -1390,9 +1381,7 @@
 					self.get_gl_dict(
 						{
 							"account": payment_account,
-							"against_type": against_type,
 							"against": against,
-							"against_link": against,
 							rev_dr_or_cr: tax_amount,
 							rev_dr_or_cr + "_in_account_currency": base_tax_amount
 							if account_currency == self.company_currency
@@ -1417,9 +1406,7 @@
 						{
 							"account": d.account,
 							"account_currency": account_currency,
-							"against_type": self.party_type or "Account",
 							"against": self.party or self.paid_from,
-							"against_link": self.party or self.paid_from,
 							"debit_in_account_currency": d.amount,
 							"debit": d.amount,
 							"cost_center": d.cost_center,
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
index b8ecf98..c4e09b4 100644
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
@@ -827,9 +827,7 @@
 						"party_type": "Supplier",
 						"party": self.supplier,
 						"due_date": self.due_date,
-						"against_type": "Account",
 						"against": self.against_expense_account,
-						"against_link": self.against_expense_account,
 						"credit": base_grand_total,
 						"credit_in_account_currency": base_grand_total
 						if self.party_account_currency == self.company_currency
@@ -902,9 +900,7 @@
 							self.get_gl_dict(
 								{
 									"account": warehouse_account[item.warehouse]["account"],
-									"against_type": "Account",
 									"against": warehouse_account[item.from_warehouse]["account"],
-									"against_link": warehouse_account[item.from_warehouse]["account"],
 									"cost_center": item.cost_center,
 									"project": item.project or self.project,
 									"remarks": self.get("remarks") or _("Accounting Entry for Stock"),
@@ -924,9 +920,7 @@
 							self.get_gl_dict(
 								{
 									"account": warehouse_account[item.from_warehouse]["account"],
-									"against_type": "Account",
 									"against": warehouse_account[item.warehouse]["account"],
-									"against_link": warehouse_account[item.warehouse]["account"],
 									"cost_center": item.cost_center,
 									"project": item.project or self.project,
 									"remarks": self.get("remarks") or _("Accounting Entry for Stock"),
@@ -943,9 +937,7 @@
 								self.get_gl_dict(
 									{
 										"account": item.expense_account,
-										"against_type": "Supplier",
 										"against": self.supplier,
-										"against_link": self.supplier,
 										"debit": flt(item.base_net_amount, item.precision("base_net_amount")),
 										"remarks": self.get("remarks") or _("Accounting Entry for Stock"),
 										"cost_center": item.cost_center,
@@ -962,9 +954,7 @@
 								self.get_gl_dict(
 									{
 										"account": item.expense_account,
-										"against_type": "Supplier",
 										"against": self.supplier,
-										"against_link": self.supplier,
 										"debit": warehouse_debit_amount,
 										"remarks": self.get("remarks") or _("Accounting Entry for Stock"),
 										"cost_center": item.cost_center,
@@ -983,9 +973,7 @@
 									self.get_gl_dict(
 										{
 											"account": account,
-											"against_type": "Account",
 											"against": item.expense_account,
-											"against_link": item.expense_account,
 											"cost_center": item.cost_center,
 											"remarks": self.get("remarks") or _("Accounting Entry for Stock"),
 											"credit": flt(amount["base_amount"]),
@@ -1005,9 +993,7 @@
 							self.get_gl_dict(
 								{
 									"account": supplier_warehouse_account,
-									"against_type": "Account",
 									"against": item.expense_account,
-									"against_link": item.expense_account,
 									"cost_center": item.cost_center,
 									"project": item.project or self.project,
 									"remarks": self.get("remarks") or _("Accounting Entry for Stock"),
@@ -1062,9 +1048,7 @@
 							self.get_gl_dict(
 								{
 									"account": expense_account,
-									"against_type": "Supplier",
 									"against": self.supplier,
-									"against_link": self.supplier,
 									"debit": amount,
 									"cost_center": item.cost_center,
 									"project": item.project or self.project,
@@ -1090,9 +1074,7 @@
 									self.get_gl_dict(
 										{
 											"account": expense_account,
-											"against_type": "Supplier",
 											"against": self.supplier,
-											"against_link": self.supplier,
 											"debit": discrepancy_caused_by_exchange_rate_difference,
 											"cost_center": item.cost_center,
 											"project": item.project or self.project,
@@ -1105,9 +1087,7 @@
 									self.get_gl_dict(
 										{
 											"account": self.get_company_default("exchange_gain_loss_account"),
-											"against_type": "Supplier",
 											"against": self.supplier,
-											"against_link": self.supplier,
 											"credit": discrepancy_caused_by_exchange_rate_difference,
 											"cost_center": item.cost_center,
 											"project": item.project or self.project,
@@ -1140,10 +1120,8 @@
 						gl_entries.append(
 							self.get_gl_dict(
 								{
-									"account": stock_rbnb,
-									"against_type": "Supplier",
+									"account": self.stock_received_but_not_billed,
 									"against": self.supplier,
-									"against_link": self.supplier,
 									"debit": flt(item.item_tax_amount, item.precision("item_tax_amount")),
 									"remarks": self.remarks or _("Accounting Entry for Stock"),
 									"cost_center": self.cost_center,
@@ -1204,9 +1182,7 @@
 				self.get_gl_dict(
 					{
 						"account": cost_of_goods_sold_account,
-						"against_type": "Account",
 						"against": item.expense_account,
-						"against_link": item.expense_account,
 						"debit": stock_adjustment_amt,
 						"remarks": self.get("remarks") or _("Stock Adjustment"),
 						"cost_center": item.cost_center,
@@ -1236,9 +1212,7 @@
 					self.get_gl_dict(
 						{
 							"account": tax.account_head,
-							"against_type": "Supplier",
 							"against": self.supplier,
-							"against_link": self.supplier,
 							dr_or_cr: base_amount,
 							dr_or_cr + "_in_account_currency": base_amount
 							if account_currency == self.company_currency
@@ -1286,10 +1260,8 @@
 						self.get_gl_dict(
 							{
 								"account": tax.account_head,
-								"against_type": "Supplier",
 								"cost_center": tax.cost_center,
 								"against": self.supplier,
-								"against_link": self.supplier,
 								"credit": applicable_amount,
 								"remarks": self.remarks or _("Accounting Entry for Stock"),
 							},
@@ -1307,9 +1279,7 @@
 							{
 								"account": tax.account_head,
 								"cost_center": tax.cost_center,
-								"against_type": "Supplier",
 								"against": self.supplier,
-								"against_link": self.supplier,
 								"credit": valuation_tax[tax.name],
 								"remarks": self.remarks or _("Accounting Entry for Stock"),
 							},
@@ -1324,9 +1294,7 @@
 				self.get_gl_dict(
 					{
 						"account": self.unrealized_profit_loss_account,
-						"against_type": "Supplier",
 						"against": self.supplier,
-						"against_link": self.supplier,
 						"credit": flt(self.total_taxes_and_charges),
 						"credit_in_account_currency": flt(self.base_total_taxes_and_charges),
 						"cost_center": self.cost_center,
@@ -1347,9 +1315,7 @@
 						"account": self.credit_to,
 						"party_type": "Supplier",
 						"party": self.supplier,
-						"against_type": "Account",
 						"against": self.cash_bank_account,
-						"against_link": self.cash_bank_account,
 						"debit": self.base_paid_amount,
 						"debit_in_account_currency": self.base_paid_amount
 						if self.party_account_currency == self.company_currency
@@ -1370,9 +1336,7 @@
 				self.get_gl_dict(
 					{
 						"account": self.cash_bank_account,
-						"against_type": "Supplier",
 						"against": self.supplier,
-						"against_link": self.supplier,
 						"credit": self.base_paid_amount,
 						"credit_in_account_currency": self.base_paid_amount
 						if bank_account_currency == self.company_currency
@@ -1396,9 +1360,7 @@
 						"account": self.credit_to,
 						"party_type": "Supplier",
 						"party": self.supplier,
-						"against_type": "Account",
 						"against": self.write_off_account,
-						"against_link": self.write_off_account,
 						"debit": self.base_write_off_amount,
 						"debit_in_account_currency": self.base_write_off_amount
 						if self.party_account_currency == self.company_currency
@@ -1418,9 +1380,7 @@
 				self.get_gl_dict(
 					{
 						"account": self.write_off_account,
-						"against_type": "Supplier",
 						"against": self.supplier,
-						"against_link": self.supplier,
 						"credit": flt(self.base_write_off_amount),
 						"credit_in_account_currency": self.base_write_off_amount
 						if write_off_account_currency == self.company_currency
@@ -1447,9 +1407,7 @@
 				self.get_gl_dict(
 					{
 						"account": round_off_account,
-						"against_type": "Supplier",
 						"against": self.supplier,
-						"against_link": self.supplier,
 						"debit_in_account_currency": self.rounding_adjustment,
 						"debit": self.base_rounding_adjustment,
 						"cost_center": round_off_cost_center
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 9cf4e4f..26984d9 100644
--- a/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json
+++ b/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json
@@ -64,6 +64,7 @@
   "warehouse",
   "from_warehouse",
   "quality_inspection",
+  "add_serial_batch_bundle",
   "serial_and_batch_bundle",
   "serial_no",
   "col_br_wh",
@@ -913,12 +914,18 @@
    "fieldtype": "Link",
    "label": "WIP Composite Asset",
    "options": "Asset"
+  },
+  {
+   "depends_on": "eval:parent.update_stock === 1",
+   "fieldname": "add_serial_batch_bundle",
+   "fieldtype": "Button",
+   "label": "Add Serial / Batch No"
   }
  ],
  "idx": 1,
  "istable": 1,
  "links": [],
- "modified": "2023-12-25 22:00:28.043555",
+ "modified": "2024-01-21 19:46:25.537861",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Purchase Invoice Item",
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
index 8da4505..cc19650 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
@@ -7,7 +7,7 @@
 from frappe.contacts.doctype.address.address import get_address_display
 from frappe.model.mapper import get_mapped_doc
 from frappe.model.utils import get_fetch_values
-from frappe.utils import add_days, cint, flt, formatdate, get_link_to_form, getdate, nowdate
+from frappe.utils import add_days, cint, cstr, flt, formatdate, get_link_to_form, getdate, nowdate
 
 import erpnext
 from erpnext.accounts.deferred_revenue import validate_service_stop_date
@@ -1233,9 +1233,7 @@
 						"party_type": "Customer",
 						"party": self.customer,
 						"due_date": self.due_date,
-						"against_type": "Account",
 						"against": self.against_income_account,
-						"against_link": self.against_income_account,
 						"debit": base_grand_total,
 						"debit_in_account_currency": base_grand_total
 						if self.party_account_currency == self.company_currency
@@ -1264,9 +1262,7 @@
 					self.get_gl_dict(
 						{
 							"account": tax.account_head,
-							"against_type": "Customer",
 							"against": self.customer,
-							"against_link": self.customer,
 							"credit": flt(base_amount, tax.precision("tax_amount_after_discount_amount")),
 							"credit_in_account_currency": (
 								flt(base_amount, tax.precision("base_tax_amount_after_discount_amount"))
@@ -1287,9 +1283,7 @@
 				self.get_gl_dict(
 					{
 						"account": self.unrealized_profit_loss_account,
-						"against_type": "Customer",
 						"against": self.customer,
-						"against_link": self.customer,
 						"debit": flt(self.total_taxes_and_charges),
 						"debit_in_account_currency": flt(self.base_total_taxes_and_charges),
 						"cost_center": self.cost_center,
@@ -1357,9 +1351,7 @@
 						add_asset_activity(asset.name, _("Asset sold"))
 
 					for gle in fixed_asset_gl_entries:
-						gle["against_type"] = "Customer"
 						gle["against"] = self.customer
-						gle["against_link"] = self.customer
 						gl_entries.append(self.get_gl_dict(gle, item=item))
 
 					self.set_asset_status(asset)
@@ -1380,9 +1372,7 @@
 							self.get_gl_dict(
 								{
 									"account": income_account,
-									"against_type": "Customer",
 									"against": self.customer,
-									"against_link": self.customer,
 									"credit": flt(base_amount, item.precision("base_net_amount")),
 									"credit_in_account_currency": (
 										flt(base_amount, item.precision("base_net_amount"))
@@ -1436,9 +1426,9 @@
 						"account": self.debit_to,
 						"party_type": "Customer",
 						"party": self.customer,
-						"against_type": "Account",
-						"against": self.loyalty_redemption_account,
-						"against_link": self.loyalty_redemption_account,
+						"against": "Expense account - "
+						+ cstr(self.loyalty_redemption_account)
+						+ " for the Loyalty Program",
 						"credit": self.loyalty_amount,
 						"against_voucher": self.return_against if cint(self.is_return) else self.name,
 						"against_voucher_type": self.doctype,
@@ -1452,9 +1442,7 @@
 					{
 						"account": self.loyalty_redemption_account,
 						"cost_center": self.cost_center or self.loyalty_redemption_cost_center,
-						"against_type": "Customer",
 						"against": self.customer,
-						"against_link": self.customer,
 						"debit": self.loyalty_amount,
 						"remark": "Loyalty Points redeemed by the customer",
 					},
@@ -1481,9 +1469,7 @@
 								"account": self.debit_to,
 								"party_type": "Customer",
 								"party": self.customer,
-								"against_type": "Account",
 								"against": payment_mode.account,
-								"against_link": payment_mode.account,
 								"credit": payment_mode.base_amount,
 								"credit_in_account_currency": payment_mode.base_amount
 								if self.party_account_currency == self.company_currency
@@ -1504,9 +1490,7 @@
 						self.get_gl_dict(
 							{
 								"account": payment_mode.account,
-								"against_type": "Customer",
 								"against": self.customer,
-								"against_link": self.customer,
 								"debit": payment_mode.base_amount,
 								"debit_in_account_currency": payment_mode.base_amount
 								if payment_mode_account_currency == self.company_currency
@@ -1530,9 +1514,7 @@
 							"account": self.debit_to,
 							"party_type": "Customer",
 							"party": self.customer,
-							"against_type": "Account",
 							"against": self.account_for_change_amount,
-							"against_link": self.account_for_change_amount,
 							"debit": flt(self.base_change_amount),
 							"debit_in_account_currency": flt(self.base_change_amount)
 							if self.party_account_currency == self.company_currency
@@ -1553,9 +1535,7 @@
 					self.get_gl_dict(
 						{
 							"account": self.account_for_change_amount,
-							"against_type": "Customer",
 							"against": self.customer,
-							"against_link": self.customer,
 							"credit": self.base_change_amount,
 							"cost_center": self.cost_center,
 						},
@@ -1581,9 +1561,7 @@
 						"account": self.debit_to,
 						"party_type": "Customer",
 						"party": self.customer,
-						"against_type": "Account",
 						"against": self.write_off_account,
-						"against_link": self.write_off_account,
 						"credit": flt(self.base_write_off_amount, self.precision("base_write_off_amount")),
 						"credit_in_account_currency": (
 							flt(self.base_write_off_amount, self.precision("base_write_off_amount"))
@@ -1603,9 +1581,7 @@
 				self.get_gl_dict(
 					{
 						"account": self.write_off_account,
-						"against_type": "Customer",
 						"against": self.customer,
-						"against_link": self.customer,
 						"debit": flt(self.base_write_off_amount, self.precision("base_write_off_amount")),
 						"debit_in_account_currency": (
 							flt(self.base_write_off_amount, self.precision("base_write_off_amount"))
@@ -1633,9 +1609,7 @@
 				self.get_gl_dict(
 					{
 						"account": round_off_account,
-						"against_type": "Customer",
 						"against": self.customer,
-						"against_link": self.customer,
 						"credit_in_account_currency": flt(
 							self.rounding_adjustment, self.precision("rounding_adjustment")
 						),
diff --git a/erpnext/accounts/doctype/subscription/subscription.py b/erpnext/accounts/doctype/subscription/subscription.py
index ce56a7b..6d27806 100644
--- a/erpnext/accounts/doctype/subscription/subscription.py
+++ b/erpnext/accounts/doctype/subscription/subscription.py
@@ -595,6 +595,8 @@
 		) and self.can_generate_new_invoice(posting_date):
 			self.generate_invoice(posting_date=posting_date)
 			self.update_subscription_period(add_days(self.current_invoice_end, 1))
+		elif posting_date and getdate(posting_date) > getdate(self.current_invoice_end):
+			self.update_subscription_period()
 
 		if self.cancel_at_period_end and (
 			getdate(posting_date) >= getdate(self.current_invoice_end)
diff --git a/erpnext/accounts/doctype/subscription/test_subscription.py b/erpnext/accounts/doctype/subscription/test_subscription.py
index 37326fd..a46642a 100644
--- a/erpnext/accounts/doctype/subscription/test_subscription.py
+++ b/erpnext/accounts/doctype/subscription/test_subscription.py
@@ -460,11 +460,13 @@
 		self.assertEqual(len(subscription.invoices), 1)
 
 	def test_multi_currency_subscription(self):
+		party = "_Test Subscription Customer"
+		frappe.db.set_value("Customer", party, "default_currency", "USD")
 		subscription = create_subscription(
 			start_date="2018-01-01",
 			generate_invoice_at="Beginning of the current subscription period",
 			plans=[{"plan": "_Test Plan Multicurrency", "qty": 1, "currency": "USD"}],
-			party="_Test Subscription Customer",
+			party=party,
 		)
 
 		subscription.process()
diff --git a/erpnext/accounts/general_ledger.py b/erpnext/accounts/general_ledger.py
index b48a8e6..1c8ac2f 100644
--- a/erpnext/accounts/general_ledger.py
+++ b/erpnext/accounts/general_ledger.py
@@ -280,7 +280,6 @@
 		"project",
 		"finance_book",
 		"voucher_no",
-		"against_link",
 	]
 
 	if dimensions:
diff --git a/erpnext/accounts/report/accounts_receivable/accounts_receivable.html b/erpnext/accounts/report/accounts_receivable/accounts_receivable.html
index ed3b991..7d8d33c 100644
--- a/erpnext/accounts/report/accounts_receivable/accounts_receivable.html
+++ b/erpnext/accounts/report/accounts_receivable/accounts_receivable.html
@@ -10,10 +10,8 @@
 
 	<h2 class="text-center" style="margin-top:0">{%= __(report.report_name) %}</h2>
 	<h4 class="text-center">
-		{% if (filters.customer_name) { %}
-			{%= filters.customer_name %}
-		{% } else { %}
-			{%= filters.customer || filters.supplier %}
+		{% if (filters.party) { %}
+			{%= __(filters.party) %}
 		{% } %}
 	</h4>
 	<h6 class="text-center">
@@ -141,7 +139,7 @@
 						<th style="width: 24%">{%= __("Reference") %}</th>
 					{% } %}
 					{% if(!filters.show_future_payments) { %}
-						<th style="width: 20%">{%= (filters.customer || filters.supplier) ? __("Remarks"): __("Party") %}</th>
+						<th style="width: 20%">{%= (filters.party) ? __("Remarks"): __("Party") %}</th>
 					{% } %}
 					<th style="width: 10%; text-align: right">{%= __("Invoiced Amount") %}</th>
 					{% if(!filters.show_future_payments) { %}
@@ -158,7 +156,7 @@
 						<th style="width: 10%">{%= __("Remaining Balance") %}</th>
 					{% } %}
 				{% } else { %}
-					<th style="width: 40%">{%= (filters.customer || filters.supplier) ? __("Remarks"): __("Party") %}</th>
+					<th style="width: 40%">{%= (filters.party) ? __("Remarks"): __("Party") %}</th>
 					<th style="width: 15%">{%= __("Total Invoiced Amount") %}</th>
 					<th style="width: 15%">{%= __("Total Paid Amount") %}</th>
 					<th style="width: 15%">{%= report.report_name === "Accounts Receivable Summary" ? __('Credit Note Amount') : __('Debit Note Amount') %}</th>
@@ -187,7 +185,7 @@
 
 						{% if(!filters.show_future_payments) { %}
 						<td>
-							{% if(!(filters.customer || filters.supplier)) { %}
+							{% if(!(filters.party)) { %}
 								{%= data[i]["party"] %}
 								{% if(data[i]["customer_name"] && data[i]["customer_name"] != data[i]["party"]) { %}
 									<br> {%= data[i]["customer_name"] %}
@@ -260,7 +258,7 @@
 					{% if(data[i]["party"]|| "&nbsp;") { %}
 						{% if(!data[i]["is_total_row"]) { %}
 							<td>
-								{% if(!(filters.customer || filters.supplier)) { %}
+								{% if(!(filters.party)) { %}
 									{%= data[i]["party"] %}
 									{% if(data[i]["customer_name"] && data[i]["customer_name"] != data[i]["party"]) { %}
 										<br> {%= data[i]["customer_name"] %}
diff --git a/erpnext/accounts/report/financial_statements.py b/erpnext/accounts/report/financial_statements.py
index 004a929..aadd873 100644
--- a/erpnext/accounts/report/financial_statements.py
+++ b/erpnext/accounts/report/financial_statements.py
@@ -8,17 +8,7 @@
 
 import frappe
 from frappe import _
-from frappe.utils import (
-	add_days,
-	add_months,
-	cint,
-	cstr,
-	flt,
-	formatdate,
-	get_first_day,
-	getdate,
-	today,
-)
+from frappe.utils import add_days, add_months, cint, cstr, flt, formatdate, get_first_day, getdate
 
 from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import (
 	get_accounting_dimensions,
@@ -53,8 +43,6 @@
 		year_start_date = getdate(period_start_date)
 		year_end_date = getdate(period_end_date)
 
-	year_end_date = getdate(today()) if year_end_date > getdate(today()) else year_end_date
-
 	months_to_add = {"Yearly": 12, "Half-Yearly": 6, "Quarterly": 3, "Monthly": 1}[periodicity]
 
 	period_list = []
diff --git a/erpnext/accounts/report/general_ledger/general_ledger.py b/erpnext/accounts/report/general_ledger/general_ledger.py
index f5b034a..110ec75 100644
--- a/erpnext/accounts/report/general_ledger/general_ledger.py
+++ b/erpnext/accounts/report/general_ledger/general_ledger.py
@@ -203,7 +203,7 @@
 			voucher_type, voucher_subtype, voucher_no, {dimension_fields}
 			cost_center, project, {transaction_currency_fields}
 			against_voucher_type, against_voucher, account_currency,
-			against_link, against, is_opening, creation {select_fields}
+			against, is_opening, creation {select_fields}
 		from `tabGL Entry`
 		where company=%(company)s {conditions}
 		{order_by_statement}
@@ -398,7 +398,6 @@
 	group_by = group_by_field(filters.get("group_by"))
 
 	for gle in gl_entries:
-		gle.against = gle.get("against_link") or gle.get("against")
 		gle_map.setdefault(gle.get(group_by), _dict(totals=get_totals_dict(), entries=[]))
 	return gle_map
 
diff --git a/erpnext/accounts/report/gross_and_net_profit_report/gross_and_net_profit_report.py b/erpnext/accounts/report/gross_and_net_profit_report/gross_and_net_profit_report.py
index 604bc01..a52aaff 100644
--- a/erpnext/accounts/report/gross_and_net_profit_report/gross_and_net_profit_report.py
+++ b/erpnext/accounts/report/gross_and_net_profit_report/gross_and_net_profit_report.py
@@ -134,7 +134,7 @@
 
 def remove_parent_with_no_child(data):
 	data_to_be_removed = False
-	for parent in data:
+	for parent in list(data):
 		if "is_group" in parent and parent.get("is_group") == 1:
 			have_child = False
 			for child in data:
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 d045d91..4a80dd0 100644
--- a/erpnext/accounts/report/tax_withholding_details/tax_withholding_details.py
+++ b/erpnext/accounts/report/tax_withholding_details/tax_withholding_details.py
@@ -46,12 +46,10 @@
 
 	out = []
 	for name, details in gle_map.items():
-		tax_amount, total_amount, grand_total, base_total = 0, 0, 0, 0
-		bill_no, bill_date = "", ""
-		tax_withholding_category = tax_category_map.get(name)
-		rate = tax_rate_map.get(tax_withholding_category)
-
 		for entry in details:
+			tax_amount, total_amount, grand_total, base_total = 0, 0, 0, 0
+			tax_withholding_category, rate = None, None
+			bill_no, bill_date = "", ""
 			party = entry.party or entry.against
 			posting_date = entry.posting_date
 			voucher_type = entry.voucher_type
@@ -61,12 +59,19 @@
 				if party_list:
 					party = party_list[0]
 
-			if not tax_withholding_category:
-				tax_withholding_category = party_map.get(party, {}).get("tax_withholding_category")
-				rate = tax_rate_map.get(tax_withholding_category)
-
-			if entry.account in tds_accounts:
+			if entry.account in tds_accounts.keys():
 				tax_amount += entry.credit - entry.debit
+				# infer tax withholding category from the account if it's the single account for this category
+				tax_withholding_category = tds_accounts.get(entry.account)
+				rate = tax_rate_map.get(tax_withholding_category)
+				# or else the consolidated value from the voucher document
+				if not tax_withholding_category:
+					# or else from the party default
+					tax_withholding_category = tax_category_map.get(name)
+					rate = tax_rate_map.get(tax_withholding_category)
+				if not tax_withholding_category:
+					tax_withholding_category = party_map.get(party, {}).get("tax_withholding_category")
+					rate = tax_rate_map.get(tax_withholding_category)
 
 			if net_total_map.get(name):
 				if voucher_type == "Journal Entry" and tax_amount and rate:
@@ -80,41 +85,41 @@
 			else:
 				total_amount += entry.credit
 
-		if tax_amount:
-			if party_map.get(party, {}).get("party_type") == "Supplier":
-				party_name = "supplier_name"
-				party_type = "supplier_type"
-			else:
-				party_name = "customer_name"
-				party_type = "customer_type"
+			if tax_amount:
+				if party_map.get(party, {}).get("party_type") == "Supplier":
+					party_name = "supplier_name"
+					party_type = "supplier_type"
+				else:
+					party_name = "customer_name"
+					party_type = "customer_type"
 
-			row = {
-				"pan"
-				if frappe.db.has_column(filters.party_type, "pan")
-				else "tax_id": party_map.get(party, {}).get("pan"),
-				"party": party_map.get(party, {}).get("name"),
-			}
-
-			if filters.naming_series == "Naming Series":
-				row.update({"party_name": party_map.get(party, {}).get(party_name)})
-
-			row.update(
-				{
-					"section_code": tax_withholding_category or "",
-					"entity_type": party_map.get(party, {}).get(party_type),
-					"rate": rate,
-					"total_amount": total_amount,
-					"grand_total": grand_total,
-					"base_total": base_total,
-					"tax_amount": tax_amount,
-					"transaction_date": posting_date,
-					"transaction_type": voucher_type,
-					"ref_no": name,
-					"supplier_invoice_no": bill_no,
-					"supplier_invoice_date": bill_date,
+				row = {
+					"pan"
+					if frappe.db.has_column(filters.party_type, "pan")
+					else "tax_id": party_map.get(party, {}).get("pan"),
+					"party": party_map.get(party, {}).get("name"),
 				}
-			)
-			out.append(row)
+
+				if filters.naming_series == "Naming Series":
+					row.update({"party_name": party_map.get(party, {}).get(party_name)})
+
+				row.update(
+					{
+						"section_code": tax_withholding_category or "",
+						"entity_type": party_map.get(party, {}).get(party_type),
+						"rate": rate,
+						"total_amount": total_amount,
+						"grand_total": grand_total,
+						"base_total": base_total,
+						"tax_amount": tax_amount,
+						"transaction_date": posting_date,
+						"transaction_type": voucher_type,
+						"ref_no": name,
+						"supplier_invoice_no": bill_no,
+						"supplier_invoice_date": bill_date,
+					}
+				)
+				out.append(row)
 
 	out.sort(key=lambda x: x["section_code"])
 
@@ -282,11 +287,20 @@
 	journal_entry_party_map = frappe._dict()
 	bank_accounts = frappe.get_all("Account", {"is_group": 0, "account_type": "Bank"}, pluck="name")
 
-	tds_accounts = frappe.get_all(
-		"Tax Withholding Account", {"company": filters.get("company")}, pluck="account"
+	_tds_accounts = frappe.get_all(
+		"Tax Withholding Account",
+		{"company": filters.get("company")},
+		["account", "parent"],
 	)
+	tds_accounts = {}
+	for tds_acc in _tds_accounts:
+		# if it turns out not to be the only tax withholding category, then don't include in the map
+		if tds_accounts.get(tds_acc["account"]):
+			tds_accounts[tds_acc["account"]] = None
+		else:
+			tds_accounts[tds_acc["account"]] = tds_acc["parent"]
 
-	tds_docs = get_tds_docs_query(filters, bank_accounts, tds_accounts).run(as_dict=True)
+	tds_docs = get_tds_docs_query(filters, bank_accounts, list(tds_accounts.keys())).run(as_dict=True)
 
 	for d in tds_docs:
 		if d.voucher_type == "Purchase Invoice":
diff --git a/erpnext/accounts/utils.py b/erpnext/accounts/utils.py
index f933209..19095bc 100644
--- a/erpnext/accounts/utils.py
+++ b/erpnext/accounts/utils.py
@@ -642,7 +642,6 @@
 	new_row.set("reference_name", d["against_voucher"])
 
 	new_row.against_account = cstr(jv_detail.against_account)
-	new_row.against_account_link = cstr(jv_detail.against_account)
 	new_row.is_advance = cstr(jv_detail.is_advance)
 	new_row.docstatus = 1
 
diff --git a/erpnext/accounts/workspace/accounting/accounting.json b/erpnext/accounts/workspace/accounting/accounting.json
index f4aced2..45ab92e 100644
--- a/erpnext/accounts/workspace/accounting/accounting.json
+++ b/erpnext/accounts/workspace/accounting/accounting.json
@@ -5,7 +5,7 @@
    "label": "Profit and Loss"
   }
  ],
- "content": "[{\"id\":\"MmUf9abwxg\",\"type\":\"onboarding\",\"data\":{\"onboarding_name\":\"Accounts\",\"col\":12}},{\"id\":\"VVvJ1lUcfc\",\"type\":\"number_card\",\"data\":{\"number_card_name\":\"Total Outgoing Bills\",\"col\":3}},{\"id\":\"Vlj2FZtlHV\",\"type\":\"number_card\",\"data\":{\"number_card_name\":\"Total Incoming Bills\",\"col\":3}},{\"id\":\"VVVjQVAhPf\",\"type\":\"number_card\",\"data\":{\"number_card_name\":\"Total Incoming Payment\",\"col\":3}},{\"id\":\"DySNdlysIW\",\"type\":\"number_card\",\"data\":{\"number_card_name\":\"Total Outgoing Payment\",\"col\":3}},{\"id\":\"i0EtSjDAXq\",\"type\":\"chart\",\"data\":{\"chart_name\":\"Profit and Loss\",\"col\":12}},{\"id\":\"X78jcbq1u3\",\"type\":\"spacer\",\"data\":{\"col\":12}},{\"id\":\"vikWSkNm6_\",\"type\":\"header\",\"data\":{\"text\":\"<span class=\\\"h4\\\"><b>Your Shortcuts</b></span>\",\"col\":12}},{\"id\":\"pMywM0nhlj\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Chart of Accounts\",\"col\":3}},{\"id\":\"_pRdD6kqUG\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Sales Invoice\",\"col\":3}},{\"id\":\"G984SgVRJN\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Purchase Invoice\",\"col\":3}},{\"id\":\"1ArNvt9qhz\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Journal Entry\",\"col\":3}},{\"id\":\"F9f4I1viNr\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Payment Entry\",\"col\":3}},{\"id\":\"4IBBOIxfqW\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Accounts Receivable\",\"col\":3}},{\"id\":\"El2anpPaFY\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"General Ledger\",\"col\":3}},{\"id\":\"1nwcM9upJo\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Trial Balance\",\"col\":3}},{\"id\":\"OF9WOi1Ppc\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Dashboard\",\"col\":3}},{\"id\":\"iAwpe-Chra\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Learn Accounting\",\"col\":3}},{\"id\":\"B7-uxs8tkU\",\"type\":\"spacer\",\"data\":{\"col\":12}},{\"id\":\"tHb3yxthkR\",\"type\":\"header\",\"data\":{\"text\":\"<span class=\\\"h4\\\"><b>Reports &amp; Masters</b></span>\",\"col\":12}},{\"id\":\"DnNtsmxpty\",\"type\":\"card\",\"data\":{\"card_name\":\"Accounting Masters\",\"col\":4}},{\"id\":\"nKKr6fjgjb\",\"type\":\"card\",\"data\":{\"card_name\":\"General Ledger\",\"col\":4}},{\"id\":\"xOHTyD8b5l\",\"type\":\"card\",\"data\":{\"card_name\":\"Accounts Receivable\",\"col\":4}},{\"id\":\"_Cb7C8XdJJ\",\"type\":\"card\",\"data\":{\"card_name\":\"Accounts Payable\",\"col\":4}},{\"id\":\"p7NY6MHe2Y\",\"type\":\"card\",\"data\":{\"card_name\":\"Financial Statements\",\"col\":4}},{\"id\":\"KlqilF5R_V\",\"type\":\"card\",\"data\":{\"card_name\":\"Taxes\",\"col\":4}},{\"id\":\"jTUy8LB0uw\",\"type\":\"card\",\"data\":{\"card_name\":\"Cost Center and Budgeting\",\"col\":4}},{\"id\":\"Wn2lhs7WLn\",\"type\":\"card\",\"data\":{\"card_name\":\"Multi Currency\",\"col\":4}},{\"id\":\"PAQMqqNkBM\",\"type\":\"card\",\"data\":{\"card_name\":\"Banking\",\"col\":4}},{\"id\":\"Q_hBCnSeJY\",\"type\":\"card\",\"data\":{\"card_name\":\"Reports\",\"col\":4}},{\"id\":\"3AK1Zf0oew\",\"type\":\"card\",\"data\":{\"card_name\":\"Profitability\",\"col\":4}},{\"id\":\"kxhoaiqdLq\",\"type\":\"card\",\"data\":{\"card_name\":\"Opening and Closing\",\"col\":4}},{\"id\":\"q0MAlU2j_Z\",\"type\":\"card\",\"data\":{\"card_name\":\"Subscription Management\",\"col\":4}},{\"id\":\"ptm7T6Hwu-\",\"type\":\"card\",\"data\":{\"card_name\":\"Share Management\",\"col\":4}},{\"id\":\"OX7lZHbiTr\",\"type\":\"card\",\"data\":{\"card_name\":\"Settings\",\"col\":4}}]",
+ "content": "[{\"id\":\"MmUf9abwxg\",\"type\":\"onboarding\",\"data\":{\"onboarding_name\":\"Accounts\",\"col\":12}},{\"id\":\"nDhfcJYbKH\",\"type\":\"chart\",\"data\":{\"chart_name\":\"Profit and Loss\",\"col\":12}},{\"id\":\"VVvJ1lUcfc\",\"type\":\"number_card\",\"data\":{\"number_card_name\":\"Total Outgoing Bills\",\"col\":3}},{\"id\":\"Vlj2FZtlHV\",\"type\":\"number_card\",\"data\":{\"number_card_name\":\"Total Incoming Bills\",\"col\":3}},{\"id\":\"VVVjQVAhPf\",\"type\":\"number_card\",\"data\":{\"number_card_name\":\"Total Incoming Payment\",\"col\":3}},{\"id\":\"DySNdlysIW\",\"type\":\"number_card\",\"data\":{\"number_card_name\":\"Total Outgoing Payment\",\"col\":3}},{\"id\":\"9k1rDm2C0l\",\"type\":\"spacer\",\"data\":{\"col\":12}},{\"id\":\"vikWSkNm6_\",\"type\":\"header\",\"data\":{\"text\":\"<span class=\\\"h4\\\"><b>Shortcuts</b></span>\",\"col\":12}},{\"id\":\"pMywM0nhlj\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Chart of Accounts\",\"col\":3}},{\"id\":\"_pRdD6kqUG\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Sales Invoice\",\"col\":3}},{\"id\":\"G984SgVRJN\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Purchase Invoice\",\"col\":3}},{\"id\":\"1ArNvt9qhz\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Journal Entry\",\"col\":3}},{\"id\":\"F9f4I1viNr\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Payment Entry\",\"col\":3}},{\"id\":\"4IBBOIxfqW\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Accounts Receivable\",\"col\":3}},{\"id\":\"El2anpPaFY\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"General Ledger\",\"col\":3}},{\"id\":\"1nwcM9upJo\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Trial Balance\",\"col\":3}},{\"id\":\"OF9WOi1Ppc\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Dashboard\",\"col\":3}},{\"id\":\"iAwpe-Chra\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Learn Accounting\",\"col\":3}},{\"id\":\"B7-uxs8tkU\",\"type\":\"spacer\",\"data\":{\"col\":12}},{\"id\":\"tHb3yxthkR\",\"type\":\"header\",\"data\":{\"text\":\"<span class=\\\"h4\\\"><b>Reports &amp; Masters</b></span>\",\"col\":12}},{\"id\":\"DnNtsmxpty\",\"type\":\"card\",\"data\":{\"card_name\":\"Accounting Masters\",\"col\":4}},{\"id\":\"nKKr6fjgjb\",\"type\":\"card\",\"data\":{\"card_name\":\"Payments\",\"col\":4}},{\"id\":\"KlqilF5R_V\",\"type\":\"card\",\"data\":{\"card_name\":\"Tax Masters\",\"col\":4}},{\"id\":\"jTUy8LB0uw\",\"type\":\"card\",\"data\":{\"card_name\":\"Cost Center and Budgeting\",\"col\":4}},{\"id\":\"Wn2lhs7WLn\",\"type\":\"card\",\"data\":{\"card_name\":\"Multi Currency\",\"col\":4}},{\"id\":\"PAQMqqNkBM\",\"type\":\"card\",\"data\":{\"card_name\":\"Banking\",\"col\":4}},{\"id\":\"kxhoaiqdLq\",\"type\":\"card\",\"data\":{\"card_name\":\"Opening and Closing\",\"col\":4}},{\"id\":\"q0MAlU2j_Z\",\"type\":\"card\",\"data\":{\"card_name\":\"Subscription Management\",\"col\":4}},{\"id\":\"ptm7T6Hwu-\",\"type\":\"card\",\"data\":{\"card_name\":\"Share Management\",\"col\":4}}]",
  "creation": "2020-03-02 15:41:59.515192",
  "custom_blocks": [],
  "docstatus": 0,
@@ -14,565 +14,13 @@
  "hide_custom": 0,
  "icon": "accounting",
  "idx": 0,
+ "indicator_color": "",
  "is_hidden": 0,
  "label": "Accounting",
  "links": [
   {
    "hidden": 0,
    "is_query_report": 0,
-   "label": "Accounting Masters",
-   "link_count": 0,
-   "onboard": 0,
-   "type": "Card Break"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Company",
-   "link_count": 0,
-   "link_to": "Company",
-   "link_type": "DocType",
-   "onboard": 1,
-   "type": "Link"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Chart of Accounts",
-   "link_count": 0,
-   "link_to": "Account",
-   "link_type": "DocType",
-   "onboard": 1,
-   "type": "Link"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Accounts Settings",
-   "link_count": 0,
-   "link_to": "Accounts Settings",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Fiscal Year",
-   "link_count": 0,
-   "link_to": "Fiscal Year",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Accounting Dimension",
-   "link_count": 0,
-   "link_to": "Accounting Dimension",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Finance Book",
-   "link_count": 0,
-   "link_to": "Finance Book",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Accounting Period",
-   "link_count": 0,
-   "link_to": "Accounting Period",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Payment Term",
-   "link_count": 0,
-   "link_to": "Payment Term",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "General Ledger",
-   "link_count": 0,
-   "onboard": 0,
-   "type": "Card Break"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Journal Entry",
-   "link_count": 0,
-   "link_to": "Journal Entry",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Journal Entry Template",
-   "link_count": 0,
-   "link_to": "Journal Entry Template",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "GL Entry",
-   "hidden": 0,
-   "is_query_report": 1,
-   "label": "General Ledger",
-   "link_count": 0,
-   "link_to": "General Ledger",
-   "link_type": "Report",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "Sales Invoice",
-   "hidden": 0,
-   "is_query_report": 1,
-   "label": "Customer Ledger Summary",
-   "link_count": 0,
-   "link_to": "Customer Ledger Summary",
-   "link_type": "Report",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "Sales Invoice",
-   "hidden": 0,
-   "is_query_report": 1,
-   "label": "Supplier Ledger Summary",
-   "link_count": 0,
-   "link_to": "Supplier Ledger Summary",
-   "link_type": "Report",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Accounts Receivable",
-   "link_count": 0,
-   "onboard": 0,
-   "type": "Card Break"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Sales Invoice",
-   "link_count": 0,
-   "link_to": "Sales Invoice",
-   "link_type": "DocType",
-   "onboard": 1,
-   "type": "Link"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Customer",
-   "link_count": 0,
-   "link_to": "Customer",
-   "link_type": "DocType",
-   "onboard": 1,
-   "type": "Link"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Payment Entry",
-   "link_count": 0,
-   "link_to": "Payment Entry",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Payment Request",
-   "link_count": 0,
-   "link_to": "Payment Request",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Payment Reconciliation",
-   "link_count": 0,
-   "link_to": "Payment Reconciliation",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "Sales Invoice",
-   "hidden": 0,
-   "is_query_report": 1,
-   "label": "Accounts Receivable",
-   "link_count": 0,
-   "link_to": "Accounts Receivable",
-   "link_type": "Report",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "Sales Invoice",
-   "hidden": 0,
-   "is_query_report": 1,
-   "label": "Accounts Receivable Summary",
-   "link_count": 0,
-   "link_to": "Accounts Receivable Summary",
-   "link_type": "Report",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "Sales Invoice",
-   "hidden": 0,
-   "is_query_report": 1,
-   "label": "Sales Register",
-   "link_count": 0,
-   "link_to": "Sales Register",
-   "link_type": "Report",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "Sales Invoice",
-   "hidden": 0,
-   "is_query_report": 1,
-   "label": "Item-wise Sales Register",
-   "link_count": 0,
-   "link_to": "Item-wise Sales Register",
-   "link_type": "Report",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "Sales Invoice",
-   "hidden": 0,
-   "is_query_report": 1,
-   "label": "Sales Order Analysis",
-   "link_count": 0,
-   "link_to": "Sales Order Analysis",
-   "link_type": "Report",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "Sales Invoice",
-   "hidden": 0,
-   "is_query_report": 1,
-   "label": "Delivered Items To Be Billed",
-   "link_count": 0,
-   "link_to": "Delivered Items To Be Billed",
-   "link_type": "Report",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Accounts Payable",
-   "link_count": 0,
-   "onboard": 0,
-   "type": "Card Break"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Purchase Invoice",
-   "link_count": 0,
-   "link_to": "Purchase Invoice",
-   "link_type": "DocType",
-   "onboard": 1,
-   "type": "Link"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Supplier",
-   "link_count": 0,
-   "link_to": "Supplier",
-   "link_type": "DocType",
-   "onboard": 1,
-   "type": "Link"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Payment Entry",
-   "link_count": 0,
-   "link_to": "Payment Entry",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Payment Reconciliation",
-   "link_count": 0,
-   "link_to": "Payment Reconciliation",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "Purchase Invoice",
-   "hidden": 0,
-   "is_query_report": 1,
-   "label": "Accounts Payable",
-   "link_count": 0,
-   "link_to": "Accounts Payable",
-   "link_type": "Report",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "Purchase Invoice",
-   "hidden": 0,
-   "is_query_report": 1,
-   "label": "Accounts Payable Summary",
-   "link_count": 0,
-   "link_to": "Accounts Payable Summary",
-   "link_type": "Report",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "Purchase Invoice",
-   "hidden": 0,
-   "is_query_report": 1,
-   "label": "Purchase Register",
-   "link_count": 0,
-   "link_to": "Purchase Register",
-   "link_type": "Report",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "Purchase Invoice",
-   "hidden": 0,
-   "is_query_report": 1,
-   "label": "Item-wise Purchase Register",
-   "link_count": 0,
-   "link_to": "Item-wise Purchase Register",
-   "link_type": "Report",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "Purchase Order",
-   "hidden": 0,
-   "is_query_report": 1,
-   "label": "Purchase Order Analysis",
-   "link_count": 0,
-   "link_to": "Purchase Order Analysis",
-   "link_type": "Report",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "Purchase Invoice",
-   "hidden": 0,
-   "is_query_report": 1,
-   "label": "Received Items To Be Billed",
-   "link_count": 0,
-   "link_to": "Received Items To Be Billed",
-   "link_type": "Report",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Reports",
-   "link_count": 0,
-   "onboard": 0,
-   "type": "Card Break"
-  },
-  {
-   "dependencies": "GL Entry",
-   "hidden": 0,
-   "is_query_report": 1,
-   "label": "Trial Balance for Party",
-   "link_count": 0,
-   "link_to": "Trial Balance for Party",
-   "link_type": "Report",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "Journal Entry",
-   "hidden": 0,
-   "is_query_report": 1,
-   "label": "Payment Period Based On Invoice Date",
-   "link_count": 0,
-   "link_to": "Payment Period Based On Invoice Date",
-   "link_type": "Report",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "Sales Invoice",
-   "hidden": 0,
-   "is_query_report": 1,
-   "label": "Sales Partners Commission",
-   "link_count": 0,
-   "link_to": "Sales Partners Commission",
-   "link_type": "Report",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "Customer",
-   "hidden": 0,
-   "is_query_report": 1,
-   "label": "Customer Credit Balance",
-   "link_count": 0,
-   "link_to": "Customer Credit Balance",
-   "link_type": "Report",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "Sales Invoice",
-   "hidden": 0,
-   "is_query_report": 1,
-   "label": "Sales Payment Summary",
-   "link_count": 0,
-   "link_to": "Sales Payment Summary",
-   "link_type": "Report",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "Address",
-   "hidden": 0,
-   "is_query_report": 1,
-   "label": "Address And Contacts",
-   "link_count": 0,
-   "link_to": "Address And Contacts",
-   "link_type": "Report",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "GL Entry",
-   "hidden": 0,
-   "is_query_report": 1,
-   "label": "UAE VAT 201",
-   "link_count": 0,
-   "link_to": "UAE VAT 201",
-   "link_type": "Report",
-   "onboard": 0,
-   "only_for": "United Arab Emirates",
-   "type": "Link"
-  },
-  {
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Financial Statements",
-   "link_count": 0,
-   "onboard": 0,
-   "type": "Card Break"
-  },
-  {
-   "dependencies": "GL Entry",
-   "hidden": 0,
-   "is_query_report": 1,
-   "label": "Trial Balance",
-   "link_count": 0,
-   "link_to": "Trial Balance",
-   "link_type": "Report",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "GL Entry",
-   "hidden": 0,
-   "is_query_report": 1,
-   "label": "Profit and Loss Statement",
-   "link_count": 0,
-   "link_to": "Profit and Loss Statement",
-   "link_type": "Report",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "GL Entry",
-   "hidden": 0,
-   "is_query_report": 1,
-   "label": "Balance Sheet",
-   "link_count": 0,
-   "link_to": "Balance Sheet",
-   "link_type": "Report",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "GL Entry",
-   "hidden": 0,
-   "is_query_report": 1,
-   "label": "Cash Flow",
-   "link_count": 0,
-   "link_to": "Cash Flow",
-   "link_type": "Report",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "GL Entry",
-   "hidden": 0,
-   "is_query_report": 1,
-   "label": "Consolidated Financial Statement",
-   "link_count": 0,
-   "link_to": "Consolidated Financial Statement",
-   "link_type": "Report",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "hidden": 0,
-   "is_query_report": 0,
    "label": "Multi Currency",
    "link_count": 0,
    "onboard": 0,
@@ -614,102 +62,6 @@
   {
    "hidden": 0,
    "is_query_report": 0,
-   "label": "Settings",
-   "link_count": 0,
-   "onboard": 0,
-   "type": "Card Break"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Payment Gateway Account",
-   "link_count": 0,
-   "link_to": "Payment Gateway Account",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Terms and Conditions Template",
-   "link_count": 0,
-   "link_to": "Terms and Conditions",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Mode of Payment",
-   "link_count": 0,
-   "link_to": "Mode of Payment",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Bank",
-   "link_count": 0,
-   "link_to": "Bank",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Bank Account",
-   "link_count": 0,
-   "link_to": "Bank Account",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Bank Clearance",
-   "link_count": 0,
-   "link_to": "Bank Clearance",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Bank Reconciliation Tool",
-   "link_count": 0,
-   "link_to": "Bank Reconciliation Tool",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "GL Entry",
-   "hidden": 0,
-   "is_query_report": 1,
-   "label": "Bank Reconciliation Statement",
-   "link_count": 0,
-   "link_to": "Bank Reconciliation Statement",
-   "link_type": "Report",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "hidden": 0,
-   "is_query_report": 0,
    "label": "Subscription Management",
    "link_count": 0,
    "onboard": 0,
@@ -918,8 +270,83 @@
   {
    "hidden": 0,
    "is_query_report": 0,
-   "label": "Taxes",
+   "label": "Banking",
+   "link_count": 6,
+   "link_type": "DocType",
+   "onboard": 0,
+   "type": "Card Break"
+  },
+  {
+   "dependencies": "",
+   "hidden": 0,
+   "is_query_report": 0,
+   "label": "Bank",
    "link_count": 0,
+   "link_to": "Bank",
+   "link_type": "DocType",
+   "onboard": 0,
+   "type": "Link"
+  },
+  {
+   "dependencies": "",
+   "hidden": 0,
+   "is_query_report": 0,
+   "label": "Bank Account",
+   "link_count": 0,
+   "link_to": "Bank Account",
+   "link_type": "DocType",
+   "onboard": 0,
+   "type": "Link"
+  },
+  {
+   "dependencies": "",
+   "hidden": 0,
+   "is_query_report": 0,
+   "label": "Bank Clearance",
+   "link_count": 0,
+   "link_to": "Bank Clearance",
+   "link_type": "DocType",
+   "onboard": 0,
+   "type": "Link"
+  },
+  {
+   "dependencies": "",
+   "hidden": 0,
+   "is_query_report": 0,
+   "label": "Bank Reconciliation Tool",
+   "link_count": 0,
+   "link_to": "Bank Reconciliation Tool",
+   "link_type": "DocType",
+   "onboard": 0,
+   "type": "Link"
+  },
+  {
+   "dependencies": "GL Entry",
+   "hidden": 0,
+   "is_query_report": 1,
+   "label": "Bank Reconciliation Statement",
+   "link_count": 0,
+   "link_to": "Bank Reconciliation Statement",
+   "link_type": "Report",
+   "onboard": 0,
+   "type": "Link"
+  },
+  {
+   "hidden": 0,
+   "is_query_report": 0,
+   "label": "Plaid Settings",
+   "link_count": 0,
+   "link_to": "Plaid Settings",
+   "link_type": "DocType",
+   "onboard": 0,
+   "type": "Link"
+  },
+  {
+   "hidden": 0,
+   "is_query_report": 0,
+   "label": "Tax Masters",
+   "link_count": 7,
+   "link_type": "DocType",
    "onboard": 0,
    "type": "Card Break"
   },
@@ -1003,60 +430,8 @@
   {
    "hidden": 0,
    "is_query_report": 0,
-   "label": "Profitability",
-   "link_count": 0,
-   "onboard": 0,
-   "type": "Card Break"
-  },
-  {
-   "dependencies": "Sales Invoice",
-   "hidden": 0,
-   "is_query_report": 1,
-   "label": "Gross Profit",
-   "link_count": 0,
-   "link_to": "Gross Profit",
-   "link_type": "Report",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "GL Entry",
-   "hidden": 0,
-   "is_query_report": 1,
-   "label": "Profitability Analysis",
-   "link_count": 0,
-   "link_to": "Profitability Analysis",
-   "link_type": "Report",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "Sales Invoice",
-   "hidden": 0,
-   "is_query_report": 1,
-   "label": "Sales Invoice Trends",
-   "link_count": 0,
-   "link_to": "Sales Invoice Trends",
-   "link_type": "Report",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "Purchase Invoice",
-   "hidden": 0,
-   "is_query_report": 1,
-   "label": "Purchase Invoice Trends",
-   "link_count": 0,
-   "link_to": "Purchase Invoice Trends",
-   "link_type": "Report",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Banking",
-   "link_count": 6,
+   "label": "Accounting Masters",
+   "link_count": 8,
    "link_type": "DocType",
    "onboard": 0,
    "type": "Card Break"
@@ -1065,9 +440,31 @@
    "dependencies": "",
    "hidden": 0,
    "is_query_report": 0,
-   "label": "Bank",
+   "label": "Company",
    "link_count": 0,
-   "link_to": "Bank",
+   "link_to": "Company",
+   "link_type": "DocType",
+   "onboard": 1,
+   "type": "Link"
+  },
+  {
+   "dependencies": "",
+   "hidden": 0,
+   "is_query_report": 0,
+   "label": "Chart of Accounts",
+   "link_count": 0,
+   "link_to": "Account",
+   "link_type": "DocType",
+   "onboard": 1,
+   "type": "Link"
+  },
+  {
+   "dependencies": "",
+   "hidden": 0,
+   "is_query_report": 0,
+   "label": "Accounts Settings",
+   "link_count": 0,
+   "link_to": "Accounts Settings",
    "link_type": "DocType",
    "onboard": 0,
    "type": "Link"
@@ -1076,9 +473,9 @@
    "dependencies": "",
    "hidden": 0,
    "is_query_report": 0,
-   "label": "Bank Account",
+   "label": "Fiscal Year",
    "link_count": 0,
-   "link_to": "Bank Account",
+   "link_to": "Fiscal Year",
    "link_type": "DocType",
    "onboard": 0,
    "type": "Link"
@@ -1087,9 +484,9 @@
    "dependencies": "",
    "hidden": 0,
    "is_query_report": 0,
-   "label": "Bank Clearance",
+   "label": "Accounting Dimension",
    "link_count": 0,
-   "link_to": "Bank Clearance",
+   "link_to": "Accounting Dimension",
    "link_type": "DocType",
    "onboard": 0,
    "type": "Link"
@@ -1098,36 +495,98 @@
    "dependencies": "",
    "hidden": 0,
    "is_query_report": 0,
-   "label": "Bank Reconciliation Tool",
+   "label": "Finance Book",
    "link_count": 0,
-   "link_to": "Bank Reconciliation Tool",
+   "link_to": "Finance Book",
    "link_type": "DocType",
    "onboard": 0,
    "type": "Link"
   },
   {
-   "dependencies": "GL Entry",
+   "dependencies": "",
    "hidden": 0,
-   "is_query_report": 1,
-   "label": "Bank Reconciliation Statement",
+   "is_query_report": 0,
+   "label": "Accounting Period",
    "link_count": 0,
-   "link_to": "Bank Reconciliation Statement",
-   "link_type": "Report",
+   "link_to": "Accounting Period",
+   "link_type": "DocType",
+   "onboard": 0,
+   "type": "Link"
+  },
+  {
+   "dependencies": "",
+   "hidden": 0,
+   "is_query_report": 0,
+   "label": "Payment Term",
+   "link_count": 0,
+   "link_to": "Payment Term",
+   "link_type": "DocType",
    "onboard": 0,
    "type": "Link"
   },
   {
    "hidden": 0,
    "is_query_report": 0,
-   "label": "Plaid Settings",
+   "label": "Payments",
+   "link_count": 5,
+   "link_type": "DocType",
+   "onboard": 0,
+   "type": "Card Break"
+  },
+  {
+   "hidden": 0,
+   "is_query_report": 0,
+   "label": "Payment Entry",
    "link_count": 0,
-   "link_to": "Plaid Settings",
+   "link_to": "Payment Entry",
+   "link_type": "DocType",
+   "onboard": 0,
+   "type": "Link"
+  },
+  {
+   "dependencies": "",
+   "hidden": 0,
+   "is_query_report": 0,
+   "label": "Journal Entry",
+   "link_count": 0,
+   "link_to": "Journal Entry",
+   "link_type": "DocType",
+   "onboard": 0,
+   "type": "Link"
+  },
+  {
+   "dependencies": "",
+   "hidden": 0,
+   "is_query_report": 0,
+   "label": "Journal Entry Template",
+   "link_count": 0,
+   "link_to": "Journal Entry Template",
+   "link_type": "DocType",
+   "onboard": 0,
+   "type": "Link"
+  },
+  {
+   "hidden": 0,
+   "is_query_report": 0,
+   "label": "Terms and Conditions",
+   "link_count": 0,
+   "link_to": "Terms and Conditions",
+   "link_type": "DocType",
+   "onboard": 0,
+   "type": "Link"
+  },
+  {
+   "hidden": 0,
+   "is_query_report": 0,
+   "label": "Mode of Payment",
+   "link_count": 0,
+   "link_to": "Mode of Payment",
    "link_type": "DocType",
    "onboard": 0,
    "type": "Link"
   }
  ],
- "modified": "2024-01-02 15:21:09.895531",
+ "modified": "2024-01-18 22:15:40.941711",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Accounting",
diff --git a/erpnext/accounts/workspace/financial_reports/financial_reports.json b/erpnext/accounts/workspace/financial_reports/financial_reports.json
new file mode 100644
index 0000000..3ab4a3e
--- /dev/null
+++ b/erpnext/accounts/workspace/financial_reports/financial_reports.json
@@ -0,0 +1,277 @@
+{
+ "charts": [],
+ "content": "[{\"id\":\"nKKr6fjgjb\",\"type\":\"card\",\"data\":{\"card_name\":\"Ledgers\",\"col\":4}},{\"id\":\"p7NY6MHe2Y\",\"type\":\"card\",\"data\":{\"card_name\":\"Financial Statements\",\"col\":4}},{\"id\":\"3AK1Zf0oew\",\"type\":\"card\",\"data\":{\"card_name\":\"Profitability\",\"col\":4}},{\"id\":\"Q_hBCnSeJY\",\"type\":\"card\",\"data\":{\"card_name\":\"Other Reports\",\"col\":4}}]",
+ "creation": "2024-01-05 16:09:16.766939",
+ "custom_blocks": [],
+ "docstatus": 0,
+ "doctype": "Workspace",
+ "for_user": "",
+ "hide_custom": 0,
+ "icon": "file",
+ "idx": 0,
+ "indicator_color": "",
+ "is_hidden": 0,
+ "label": "Financial Reports",
+ "links": [
+  {
+   "hidden": 0,
+   "is_query_report": 0,
+   "label": "Profitability",
+   "link_count": 0,
+   "link_type": "DocType",
+   "onboard": 0,
+   "type": "Card Break"
+  },
+  {
+   "dependencies": "Sales Invoice",
+   "hidden": 0,
+   "is_query_report": 1,
+   "label": "Gross Profit",
+   "link_count": 0,
+   "link_to": "Gross Profit",
+   "link_type": "Report",
+   "onboard": 0,
+   "type": "Link"
+  },
+  {
+   "dependencies": "GL Entry",
+   "hidden": 0,
+   "is_query_report": 1,
+   "label": "Profitability Analysis",
+   "link_count": 0,
+   "link_to": "Profitability Analysis",
+   "link_type": "Report",
+   "onboard": 0,
+   "type": "Link"
+  },
+  {
+   "dependencies": "Sales Invoice",
+   "hidden": 0,
+   "is_query_report": 1,
+   "label": "Sales Invoice Trends",
+   "link_count": 0,
+   "link_to": "Sales Invoice Trends",
+   "link_type": "Report",
+   "onboard": 0,
+   "type": "Link"
+  },
+  {
+   "dependencies": "Purchase Invoice",
+   "hidden": 0,
+   "is_query_report": 1,
+   "label": "Purchase Invoice Trends",
+   "link_count": 0,
+   "link_to": "Purchase Invoice Trends",
+   "link_type": "Report",
+   "onboard": 0,
+   "type": "Link"
+  },
+  {
+   "hidden": 0,
+   "is_query_report": 0,
+   "label": "Financial Statements",
+   "link_count": 5,
+   "link_type": "DocType",
+   "onboard": 0,
+   "type": "Card Break"
+  },
+  {
+   "dependencies": "GL Entry",
+   "hidden": 0,
+   "is_query_report": 1,
+   "label": "Trial Balance",
+   "link_count": 0,
+   "link_to": "Trial Balance",
+   "link_type": "Report",
+   "onboard": 0,
+   "type": "Link"
+  },
+  {
+   "dependencies": "GL Entry",
+   "hidden": 0,
+   "is_query_report": 1,
+   "label": "Profit and Loss Statement",
+   "link_count": 0,
+   "link_to": "Profit and Loss Statement",
+   "link_type": "Report",
+   "onboard": 0,
+   "type": "Link"
+  },
+  {
+   "dependencies": "GL Entry",
+   "hidden": 0,
+   "is_query_report": 1,
+   "label": "Balance Sheet",
+   "link_count": 0,
+   "link_to": "Balance Sheet",
+   "link_type": "Report",
+   "onboard": 0,
+   "type": "Link"
+  },
+  {
+   "dependencies": "GL Entry",
+   "hidden": 0,
+   "is_query_report": 1,
+   "label": "Cash Flow",
+   "link_count": 0,
+   "link_to": "Cash Flow",
+   "link_type": "Report",
+   "onboard": 0,
+   "type": "Link"
+  },
+  {
+   "dependencies": "GL Entry",
+   "hidden": 0,
+   "is_query_report": 1,
+   "label": "Consolidated Financial Statement",
+   "link_count": 0,
+   "link_to": "Consolidated Financial Statement",
+   "link_type": "Report",
+   "onboard": 0,
+   "type": "Link"
+  },
+  {
+   "hidden": 0,
+   "is_query_report": 0,
+   "label": "Ledgers",
+   "link_count": 3,
+   "link_type": "DocType",
+   "onboard": 0,
+   "type": "Card Break"
+  },
+  {
+   "dependencies": "GL Entry",
+   "hidden": 0,
+   "is_query_report": 1,
+   "label": "General Ledger",
+   "link_count": 0,
+   "link_to": "General Ledger",
+   "link_type": "Report",
+   "onboard": 0,
+   "type": "Link"
+  },
+  {
+   "dependencies": "Sales Invoice",
+   "hidden": 0,
+   "is_query_report": 1,
+   "label": "Customer Ledger Summary",
+   "link_count": 0,
+   "link_to": "Customer Ledger Summary",
+   "link_type": "Report",
+   "onboard": 0,
+   "type": "Link"
+  },
+  {
+   "dependencies": "Sales Invoice",
+   "hidden": 0,
+   "is_query_report": 1,
+   "label": "Supplier Ledger Summary",
+   "link_count": 0,
+   "link_to": "Supplier Ledger Summary",
+   "link_type": "Report",
+   "onboard": 0,
+   "type": "Link"
+  },
+  {
+   "hidden": 0,
+   "is_query_report": 0,
+   "label": "Other Reports",
+   "link_count": 7,
+   "link_type": "DocType",
+   "onboard": 0,
+   "type": "Card Break"
+  },
+  {
+   "dependencies": "GL Entry",
+   "hidden": 0,
+   "is_query_report": 1,
+   "label": "Trial Balance for Party",
+   "link_count": 0,
+   "link_to": "Trial Balance for Party",
+   "link_type": "Report",
+   "onboard": 0,
+   "type": "Link"
+  },
+  {
+   "dependencies": "Journal Entry",
+   "hidden": 0,
+   "is_query_report": 1,
+   "label": "Payment Period Based On Invoice Date",
+   "link_count": 0,
+   "link_to": "Payment Period Based On Invoice Date",
+   "link_type": "Report",
+   "onboard": 0,
+   "type": "Link"
+  },
+  {
+   "dependencies": "Sales Invoice",
+   "hidden": 0,
+   "is_query_report": 1,
+   "label": "Sales Partners Commission",
+   "link_count": 0,
+   "link_to": "Sales Partners Commission",
+   "link_type": "Report",
+   "onboard": 0,
+   "type": "Link"
+  },
+  {
+   "dependencies": "Customer",
+   "hidden": 0,
+   "is_query_report": 1,
+   "label": "Customer Credit Balance",
+   "link_count": 0,
+   "link_to": "Customer Credit Balance",
+   "link_type": "Report",
+   "onboard": 0,
+   "type": "Link"
+  },
+  {
+   "dependencies": "Sales Invoice",
+   "hidden": 0,
+   "is_query_report": 1,
+   "label": "Sales Payment Summary",
+   "link_count": 0,
+   "link_to": "Sales Payment Summary",
+   "link_type": "Report",
+   "onboard": 0,
+   "type": "Link"
+  },
+  {
+   "dependencies": "Address",
+   "hidden": 0,
+   "is_query_report": 1,
+   "label": "Address And Contacts",
+   "link_count": 0,
+   "link_to": "Address And Contacts",
+   "link_type": "Report",
+   "onboard": 0,
+   "type": "Link"
+  },
+  {
+   "dependencies": "GL Entry",
+   "hidden": 0,
+   "is_query_report": 1,
+   "label": "UAE VAT 201",
+   "link_count": 0,
+   "link_to": "UAE VAT 201",
+   "link_type": "Report",
+   "onboard": 0,
+   "only_for": "United Arab Emirates",
+   "type": "Link"
+  }
+ ],
+ "modified": "2024-01-18 22:13:07.596844",
+ "modified_by": "Administrator",
+ "module": "Accounts",
+ "name": "Financial Reports",
+ "number_cards": [],
+ "owner": "Administrator",
+ "parent_page": "Accounting",
+ "public": 1,
+ "quick_lists": [],
+ "restrict_to_domain": "",
+ "roles": [],
+ "sequence_id": 5.0,
+ "shortcuts": [],
+ "title": "Financial Reports"
+}
\ No newline at end of file
diff --git a/erpnext/accounts/workspace/payables/payables.json b/erpnext/accounts/workspace/payables/payables.json
new file mode 100644
index 0000000..f8c8564
--- /dev/null
+++ b/erpnext/accounts/workspace/payables/payables.json
@@ -0,0 +1,204 @@
+{
+ "charts": [],
+ "content": "[{\"id\":\"rMMsfn2eB4\",\"type\":\"header\",\"data\":{\"text\":\"<span class=\\\"h4\\\"><b>Shortcuts</b></span>\",\"col\":12}},{\"id\":\"G984SgVRJN\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Purchase Invoice\",\"col\":3}},{\"id\":\"F9f4I1viNr\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Payment Entry\",\"col\":3}},{\"id\":\"1ArNvt9qhz\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Journal Entry\",\"col\":3}},{\"id\":\"4IBBOIxfqW\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Accounts Payable\",\"col\":3}},{\"id\":\"B7-uxs8tkU\",\"type\":\"spacer\",\"data\":{\"col\":12}},{\"id\":\"jAcOH-cC-Q\",\"type\":\"header\",\"data\":{\"text\":\"<span class=\\\"h4\\\"><b>Reports &amp; Masters</b></span>\",\"col\":12}},{\"id\":\"7dj93PEUjW\",\"type\":\"card\",\"data\":{\"card_name\":\"Invoicing\",\"col\":4}},{\"id\":\"_Cb7C8XdJJ\",\"type\":\"card\",\"data\":{\"card_name\":\"Payments\",\"col\":4}},{\"id\":\"9yseIkdG50\",\"type\":\"card\",\"data\":{\"card_name\":\"Reports\",\"col\":4}}]",
+ "creation": "2024-01-05 15:29:11.144373",
+ "custom_blocks": [],
+ "docstatus": 0,
+ "doctype": "Workspace",
+ "for_user": "",
+ "hide_custom": 0,
+ "icon": "arrow-left",
+ "idx": 0,
+ "indicator_color": "",
+ "is_hidden": 0,
+ "label": "Payables",
+ "links": [
+  {
+   "hidden": 0,
+   "is_query_report": 0,
+   "label": "Invoicing",
+   "link_count": 2,
+   "link_type": "DocType",
+   "onboard": 0,
+   "type": "Card Break"
+  },
+  {
+   "hidden": 0,
+   "is_query_report": 0,
+   "label": "Purchase Invoice",
+   "link_count": 0,
+   "link_to": "Purchase Invoice",
+   "link_type": "DocType",
+   "onboard": 0,
+   "type": "Link"
+  },
+  {
+   "hidden": 0,
+   "is_query_report": 0,
+   "label": "Supplier",
+   "link_count": 0,
+   "link_to": "Supplier",
+   "link_type": "DocType",
+   "onboard": 0,
+   "type": "Link"
+  },
+  {
+   "hidden": 0,
+   "is_query_report": 0,
+   "label": "Payments",
+   "link_count": 3,
+   "link_type": "DocType",
+   "onboard": 0,
+   "type": "Card Break"
+  },
+  {
+   "dependencies": "",
+   "hidden": 0,
+   "is_query_report": 0,
+   "label": "Payment Entry",
+   "link_count": 0,
+   "link_to": "Payment Entry",
+   "link_type": "DocType",
+   "onboard": 0,
+   "type": "Link"
+  },
+  {
+   "hidden": 0,
+   "is_query_report": 0,
+   "label": "Journal Entry",
+   "link_count": 0,
+   "link_to": "Journal Entry",
+   "link_type": "DocType",
+   "onboard": 0,
+   "type": "Link"
+  },
+  {
+   "hidden": 0,
+   "is_query_report": 0,
+   "label": "Payment Reconciliation",
+   "link_count": 0,
+   "link_to": "Payment Reconciliation",
+   "link_type": "DocType",
+   "onboard": 0,
+   "type": "Link"
+  },
+  {
+   "hidden": 0,
+   "is_query_report": 0,
+   "label": "Reports",
+   "link_count": 7,
+   "link_type": "DocType",
+   "onboard": 0,
+   "type": "Card Break"
+  },
+  {
+   "hidden": 0,
+   "is_query_report": 0,
+   "label": "Accounts Payable",
+   "link_count": 0,
+   "link_to": "Accounts Payable",
+   "link_type": "Report",
+   "onboard": 0,
+   "type": "Link"
+  },
+  {
+   "hidden": 0,
+   "is_query_report": 0,
+   "label": "Accounts Payable Summary",
+   "link_count": 0,
+   "link_to": "Accounts Payable Summary",
+   "link_type": "Report",
+   "onboard": 0,
+   "type": "Link"
+  },
+  {
+   "hidden": 0,
+   "is_query_report": 0,
+   "label": "Purchase Register",
+   "link_count": 0,
+   "link_to": "Purchase Register",
+   "link_type": "Report",
+   "onboard": 0,
+   "type": "Link"
+  },
+  {
+   "hidden": 0,
+   "is_query_report": 0,
+   "label": "Item-wise Purchase Register",
+   "link_count": 0,
+   "link_to": "Item-wise Purchase Register",
+   "link_type": "Report",
+   "onboard": 0,
+   "type": "Link"
+  },
+  {
+   "hidden": 0,
+   "is_query_report": 0,
+   "label": "Purchase Order Analysis",
+   "link_count": 0,
+   "link_to": "Purchase Order Analysis",
+   "link_type": "Report",
+   "onboard": 0,
+   "type": "Link"
+  },
+  {
+   "hidden": 0,
+   "is_query_report": 0,
+   "label": "Received Items To Be Billed",
+   "link_count": 0,
+   "link_to": "Received Items To Be Billed",
+   "link_type": "Report",
+   "onboard": 0,
+   "type": "Link"
+  },
+  {
+   "hidden": 0,
+   "is_query_report": 0,
+   "label": "Supplier Ledger Summary",
+   "link_count": 0,
+   "link_to": "Supplier Ledger Summary",
+   "link_type": "Report",
+   "onboard": 0,
+   "type": "Link"
+  }
+ ],
+ "modified": "2024-01-18 22:09:46.221549",
+ "modified_by": "Administrator",
+ "module": "Accounts",
+ "name": "Payables",
+ "number_cards": [],
+ "owner": "Administrator",
+ "parent_page": "Accounting",
+ "public": 1,
+ "quick_lists": [],
+ "restrict_to_domain": "",
+ "roles": [],
+ "sequence_id": 3.0,
+ "shortcuts": [
+  {
+   "doc_view": "",
+   "label": "Accounts Payable",
+   "link_to": "Accounts Payable",
+   "type": "Report"
+  },
+  {
+   "doc_view": "",
+   "label": "Purchase Invoice",
+   "link_to": "Purchase Invoice",
+   "type": "DocType"
+  },
+  {
+   "doc_view": "",
+   "label": "Journal Entry",
+   "link_to": "Journal Entry",
+   "type": "DocType"
+  },
+  {
+   "doc_view": "",
+   "label": "Payment Entry",
+   "link_to": "Payment Entry",
+   "type": "DocType"
+  }
+ ],
+ "title": "Payables"
+}
\ No newline at end of file
diff --git a/erpnext/accounts/workspace/receivables/receivables.json b/erpnext/accounts/workspace/receivables/receivables.json
new file mode 100644
index 0000000..6fa8c09
--- /dev/null
+++ b/erpnext/accounts/workspace/receivables/receivables.json
@@ -0,0 +1,254 @@
+{
+ "charts": [],
+ "content": "[{\"id\":\"vikWSkNm6_\",\"type\":\"header\",\"data\":{\"text\":\"<span class=\\\"h4\\\"><b>Shortcuts</b></span>\",\"col\":12}},{\"id\":\"G984SgVRJN\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Sales Invoice\",\"col\":3}},{\"id\":\"5yHldR0JNk\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"POS Invoice\",\"col\":3}},{\"id\":\"F9f4I1viNr\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Payment Entry\",\"col\":3}},{\"id\":\"1ArNvt9qhz\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Journal Entry\",\"col\":3}},{\"id\":\"4IBBOIxfqW\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Accounts Receivable\",\"col\":3}},{\"id\":\"ILlIxJuexy\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Cost Center\",\"col\":3}},{\"id\":\"B7-uxs8tkU\",\"type\":\"spacer\",\"data\":{\"col\":12}},{\"id\":\"tHb3yxthkR\",\"type\":\"header\",\"data\":{\"text\":\"<span class=\\\"h4\\\"><b>Reports &amp; Masters</b></span>\",\"col\":12}},{\"id\":\"jLgv00c6ek\",\"type\":\"card\",\"data\":{\"card_name\":\"Invoicing\",\"col\":4}},{\"id\":\"npwfXlz0u1\",\"type\":\"card\",\"data\":{\"card_name\":\"Payments\",\"col\":4}},{\"id\":\"am70C27Jrb\",\"type\":\"card\",\"data\":{\"card_name\":\"Dunning\",\"col\":4}},{\"id\":\"xOHTyD8b5l\",\"type\":\"card\",\"data\":{\"card_name\":\"Reports\",\"col\":4}}]",
+ "creation": "2024-01-05 15:29:21.084241",
+ "custom_blocks": [],
+ "docstatus": 0,
+ "doctype": "Workspace",
+ "for_user": "",
+ "hide_custom": 0,
+ "icon": "arrow-right",
+ "idx": 0,
+ "indicator_color": "",
+ "is_hidden": 0,
+ "label": "Receivables",
+ "links": [
+  {
+   "hidden": 0,
+   "is_query_report": 0,
+   "label": "Invoicing",
+   "link_count": 2,
+   "link_type": "DocType",
+   "onboard": 0,
+   "type": "Card Break"
+  },
+  {
+   "hidden": 0,
+   "is_query_report": 0,
+   "label": "Sales Invoice",
+   "link_count": 0,
+   "link_to": "Sales Invoice",
+   "link_type": "DocType",
+   "onboard": 0,
+   "type": "Link"
+  },
+  {
+   "hidden": 0,
+   "is_query_report": 0,
+   "label": "Customer",
+   "link_count": 0,
+   "link_to": "Customer",
+   "link_type": "DocType",
+   "onboard": 0,
+   "type": "Link"
+  },
+  {
+   "hidden": 0,
+   "is_query_report": 0,
+   "label": "Payments",
+   "link_count": 4,
+   "link_type": "DocType",
+   "onboard": 0,
+   "type": "Card Break"
+  },
+  {
+   "hidden": 0,
+   "is_query_report": 0,
+   "label": "Payment Entry",
+   "link_count": 0,
+   "link_to": "Payment Entry",
+   "link_type": "DocType",
+   "onboard": 0,
+   "type": "Link"
+  },
+  {
+   "hidden": 0,
+   "is_query_report": 0,
+   "label": "Payment Request",
+   "link_count": 0,
+   "link_to": "Payment Request",
+   "link_type": "DocType",
+   "onboard": 0,
+   "type": "Link"
+  },
+  {
+   "hidden": 0,
+   "is_query_report": 0,
+   "label": "Payment Reconciliation",
+   "link_count": 0,
+   "link_to": "Payment Reconciliation",
+   "link_type": "DocType",
+   "onboard": 0,
+   "type": "Link"
+  },
+  {
+   "hidden": 0,
+   "is_query_report": 0,
+   "label": "Payment Gateway Account",
+   "link_count": 0,
+   "link_to": "Payment Gateway Account",
+   "link_type": "DocType",
+   "onboard": 0,
+   "type": "Link"
+  },
+  {
+   "hidden": 0,
+   "is_query_report": 0,
+   "label": "Dunning",
+   "link_count": 2,
+   "link_type": "DocType",
+   "onboard": 0,
+   "type": "Card Break"
+  },
+  {
+   "hidden": 0,
+   "is_query_report": 0,
+   "label": "Dunning",
+   "link_count": 0,
+   "link_to": "Dunning",
+   "link_type": "DocType",
+   "onboard": 0,
+   "type": "Link"
+  },
+  {
+   "hidden": 0,
+   "is_query_report": 0,
+   "label": "Dunning Type",
+   "link_count": 0,
+   "link_to": "Dunning Type",
+   "link_type": "DocType",
+   "onboard": 0,
+   "type": "Link"
+  },
+  {
+   "hidden": 0,
+   "is_query_report": 0,
+   "label": "Reports",
+   "link_count": 6,
+   "link_type": "DocType",
+   "onboard": 0,
+   "type": "Card Break"
+  },
+  {
+   "dependencies": "Sales Invoice",
+   "hidden": 0,
+   "is_query_report": 1,
+   "label": "Accounts Receivable",
+   "link_count": 0,
+   "link_to": "Accounts Receivable",
+   "link_type": "Report",
+   "onboard": 0,
+   "type": "Link"
+  },
+  {
+   "dependencies": "Sales Invoice",
+   "hidden": 0,
+   "is_query_report": 1,
+   "label": "Accounts Receivable Summary",
+   "link_count": 0,
+   "link_to": "Accounts Receivable Summary",
+   "link_type": "Report",
+   "onboard": 0,
+   "type": "Link"
+  },
+  {
+   "dependencies": "Sales Invoice",
+   "hidden": 0,
+   "is_query_report": 1,
+   "label": "Sales Register",
+   "link_count": 0,
+   "link_to": "Sales Register",
+   "link_type": "Report",
+   "onboard": 0,
+   "type": "Link"
+  },
+  {
+   "dependencies": "Sales Invoice",
+   "hidden": 0,
+   "is_query_report": 1,
+   "label": "Item-wise Sales Register",
+   "link_count": 0,
+   "link_to": "Item-wise Sales Register",
+   "link_type": "Report",
+   "onboard": 0,
+   "type": "Link"
+  },
+  {
+   "dependencies": "Sales Invoice",
+   "hidden": 0,
+   "is_query_report": 1,
+   "label": "Sales Order Analysis",
+   "link_count": 0,
+   "link_to": "Sales Order Analysis",
+   "link_type": "Report",
+   "onboard": 0,
+   "type": "Link"
+  },
+  {
+   "dependencies": "Sales Invoice",
+   "hidden": 0,
+   "is_query_report": 1,
+   "label": "Delivered Items To Be Billed",
+   "link_count": 0,
+   "link_to": "Delivered Items To Be Billed",
+   "link_type": "Report",
+   "onboard": 0,
+   "type": "Link"
+  }
+ ],
+ "modified": "2024-01-18 22:11:51.474477",
+ "modified_by": "Administrator",
+ "module": "Accounts",
+ "name": "Receivables",
+ "number_cards": [],
+ "owner": "Administrator",
+ "parent_page": "Accounting",
+ "public": 1,
+ "quick_lists": [],
+ "restrict_to_domain": "",
+ "roles": [],
+ "sequence_id": 4.0,
+ "shortcuts": [
+  {
+   "color": "Grey",
+   "doc_view": "List",
+   "label": "POS Invoice",
+   "link_to": "POS Invoice",
+   "stats_filter": "[]",
+   "type": "DocType"
+  },
+  {
+   "color": "Grey",
+   "doc_view": "List",
+   "label": "Cost Center",
+   "link_to": "Cost Center",
+   "type": "DocType"
+  },
+  {
+   "doc_view": "",
+   "label": "Sales Invoice",
+   "link_to": "Sales Invoice",
+   "stats_filter": "[]",
+   "type": "DocType"
+  },
+  {
+   "doc_view": "",
+   "label": "Journal Entry",
+   "link_to": "Journal Entry",
+   "type": "DocType"
+  },
+  {
+   "doc_view": "",
+   "label": "Payment Entry",
+   "link_to": "Payment Entry",
+   "type": "DocType"
+  },
+  {
+   "doc_view": "",
+   "label": "Accounts Receivable",
+   "link_to": "Accounts Receivable",
+   "type": "Report"
+  }
+ ],
+ "title": "Receivables"
+}
\ No newline at end of file
diff --git a/erpnext/assets/doctype/asset/asset.json b/erpnext/assets/doctype/asset/asset.json
index d0c9350..39a0867 100644
--- a/erpnext/assets/doctype/asset/asset.json
+++ b/erpnext/assets/doctype/asset/asset.json
@@ -202,8 +202,7 @@
    "fieldname": "purchase_date",
    "fieldtype": "Date",
    "label": "Purchase Date",
-   "mandatory_depends_on": "eval:!doc.is_existing_asset",
-   "read_only": 1,
+   "mandatory_depends_on": "eval:!doc.is_existing_asset && !doc.is_composite_asset",
    "read_only_depends_on": "eval:!doc.is_existing_asset && !doc.is_composite_asset"
   },
   {
@@ -590,7 +589,7 @@
    "link_fieldname": "target_asset"
   }
  ],
- "modified": "2024-01-05 17:36:53.131512",
+ "modified": "2024-01-15 17:35:49.226603",
  "modified_by": "Administrator",
  "module": "Assets",
  "name": "Asset",
diff --git a/erpnext/assets/doctype/asset/asset.py b/erpnext/assets/doctype/asset/asset.py
index 5f44898..7357249 100644
--- a/erpnext/assets/doctype/asset/asset.py
+++ b/erpnext/assets/doctype/asset/asset.py
@@ -162,6 +162,7 @@
 	def on_cancel(self):
 		self.validate_cancellation()
 		self.cancel_movement_entries()
+		self.cancel_capitalization()
 		self.delete_depreciation_entries()
 		cancel_asset_depr_schedules(self)
 		self.set_status()
@@ -517,6 +518,16 @@
 			movement = frappe.get_doc("Asset Movement", movement.get("name"))
 			movement.cancel()
 
+	def cancel_capitalization(self):
+		asset_capitalization = frappe.db.get_value(
+			"Asset Capitalization",
+			{"target_asset": self.name, "docstatus": 1, "entry_type": "Capitalization"},
+		)
+
+		if asset_capitalization:
+			asset_capitalization = frappe.get_doc("Asset Capitalization", asset_capitalization)
+			asset_capitalization.cancel()
+
 	def delete_depreciation_entries(self):
 		if self.calculate_depreciation:
 			for row in self.get("finance_books"):
@@ -697,9 +708,7 @@
 				self.get_gl_dict(
 					{
 						"account": cwip_account,
-						"against_type": "Account",
 						"against": fixed_asset_account,
-						"against_link": fixed_asset_account,
 						"remarks": self.get("remarks") or _("Accounting Entry for Asset"),
 						"posting_date": self.available_for_use_date,
 						"credit": self.purchase_receipt_amount,
@@ -714,9 +723,7 @@
 				self.get_gl_dict(
 					{
 						"account": fixed_asset_account,
-						"against_type": "Account",
 						"against": cwip_account,
-						"against_link": cwip_account,
 						"remarks": self.get("remarks") or _("Accounting Entry for Asset"),
 						"posting_date": self.available_for_use_date,
 						"debit": self.purchase_receipt_amount,
@@ -1031,6 +1038,8 @@
 @frappe.whitelist()
 def get_asset_value_after_depreciation(asset_name, finance_book=None):
 	asset = frappe.get_doc("Asset", asset_name)
+	if not asset.calculate_depreciation:
+		return flt(asset.value_after_depreciation)
 
 	return asset.get_value_after_depreciation(finance_book)
 
diff --git a/erpnext/assets/doctype/asset/test_asset.py b/erpnext/assets/doctype/asset/test_asset.py
index 0773698..25d0105 100644
--- a/erpnext/assets/doctype/asset/test_asset.py
+++ b/erpnext/assets/doctype/asset/test_asset.py
@@ -251,16 +251,7 @@
 				flt(18000.0 + pro_rata_amount, asset.precision("gross_purchase_amount")),
 				0.0,
 			),
-			(
-				"_Test Fixed Asset - _TC",
-				0.0,
-				flt(18000.0 + pro_rata_amount, asset.precision("gross_purchase_amount")),
-			),
-			(
-				"_Test Fixed Asset - _TC",
-				0.0,
-				flt(82000.0 - pro_rata_amount, asset.precision("gross_purchase_amount")),
-			),
+			("_Test Fixed Asset - _TC", 0.0, 100000.0),
 			(
 				"_Test Gain/Loss on Asset Disposal - _TC",
 				flt(82000.0 - pro_rata_amount, asset.precision("gross_purchase_amount")),
@@ -900,7 +891,7 @@
 			["2030-12-31", 28630.14, 28630.14],
 			["2031-12-31", 35684.93, 64315.07],
 			["2032-12-31", 17842.46, 82157.53],
-			["2033-06-06", 5342.47, 87500.0],
+			["2033-06-06", 5342.46, 87499.99],
 		]
 
 		schedules = [
@@ -1012,7 +1003,7 @@
 		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]
+			asset_depr_schedule_doc, asset, 100000, 100000, asset.finance_books[0]
 		)
 		self.assertEqual(depreciation_amount, 30000)
 
diff --git a/erpnext/assets/doctype/asset_capitalization/asset_capitalization.js b/erpnext/assets/doctype/asset_capitalization/asset_capitalization.js
index be78d9e..2f0de97 100644
--- a/erpnext/assets/doctype/asset_capitalization/asset_capitalization.js
+++ b/erpnext/assets/doctype/asset_capitalization/asset_capitalization.js
@@ -21,10 +21,10 @@
 			this.show_stock_ledger();
 		}
 
-		if (this.frm.doc.stock_items && !this.frm.doc.stock_items.length && this.frm.doc.target_asset && this.frm.doc.capitalization_method === "Choose a WIP composite asset") {
-			this.set_consumed_stock_items_tagged_to_wip_composite_asset(this.frm.doc.target_asset);
-			this.get_target_asset_details();
-		}
+		// if (this.frm.doc.stock_items && !this.frm.doc.stock_items.length && this.frm.doc.target_asset && this.frm.doc.capitalization_method === "Choose a WIP composite asset") {
+		// 	this.set_consumed_stock_items_tagged_to_wip_composite_asset(this.frm.doc.target_asset);
+		// 	this.get_target_asset_details();
+		// }
 	}
 
 	setup_queries() {
@@ -143,13 +143,20 @@
 				},
 				callback: function (r) {
 					if (!r.exc && r.message) {
-						me.frm.clear_table("stock_items");
-
-						for (let item of r.message) {
-							me.frm.add_child("stock_items", item);
+						if(r.message[0] && r.message[0].length) {
+							me.frm.clear_table("stock_items");
+							for (let item of r.message[0]) {
+								me.frm.add_child("stock_items", item);
+							}
+							refresh_field("stock_items");
 						}
-
-						refresh_field("stock_items");
+						if (r.message[1] && r.message[1].length) {
+							me.frm.clear_table("asset_items");
+							for (let item of r.message[1]) {
+								me.frm.add_child("asset_items", item);
+							}
+							me.frm.refresh_field("asset_items");
+						}
 
 						me.calculate_totals();
 					}
diff --git a/erpnext/assets/doctype/asset_capitalization/asset_capitalization.py b/erpnext/assets/doctype/asset_capitalization/asset_capitalization.py
index de75841..cad74df 100644
--- a/erpnext/assets/doctype/asset_capitalization/asset_capitalization.py
+++ b/erpnext/assets/doctype/asset_capitalization/asset_capitalization.py
@@ -136,11 +136,19 @@
 			"Stock Ledger Entry",
 			"Repost Item Valuation",
 			"Serial and Batch Bundle",
+			"Asset",
 		)
+		self.cancel_target_asset()
 		self.update_stock_ledger()
 		self.make_gl_entries()
 		self.restore_consumed_asset_items()
 
+	def cancel_target_asset(self):
+		if self.entry_type == "Capitalization" and self.target_asset:
+			asset_doc = frappe.get_doc("Asset", self.target_asset)
+			if asset_doc.docstatus == 1:
+				asset_doc.cancel()
+
 	def set_title(self):
 		self.title = self.target_asset_name or self.target_item_name or self.target_item_code
 
@@ -485,9 +493,7 @@
 						self.get_gl_dict(
 							{
 								"account": account,
-								"against_type": "Account",
 								"against": target_account,
-								"against_link": target_account,
 								"cost_center": item_row.cost_center,
 								"project": item_row.get("project") or self.get("project"),
 								"remarks": self.get("remarks") or "Accounting Entry for Stock",
@@ -528,9 +534,7 @@
 			self.set_consumed_asset_status(asset)
 
 			for gle in fixed_asset_gl_entries:
-				gle["against_type"] = "Account"
 				gle["against"] = target_account
-				gle["against_link"] = target_account
 				gl_entries.append(self.get_gl_dict(gle, item=item))
 				target_against.add(gle["account"])
 
@@ -546,9 +550,7 @@
 				self.get_gl_dict(
 					{
 						"account": item_row.expense_account,
-						"against_type": "Account",
 						"against": target_account,
-						"against_link": target_account,
 						"cost_center": item_row.cost_center,
 						"project": item_row.get("project") or self.get("project"),
 						"remarks": self.get("remarks") or "Accounting Entry for Stock",
@@ -559,46 +561,41 @@
 			)
 
 	def get_gl_entries_for_target_item(self, gl_entries, target_against, precision):
-		for target_account in target_against:
-			if self.target_is_fixed_asset:
-				# Capitalization
+		if self.target_is_fixed_asset:
+			# Capitalization
+			gl_entries.append(
+				self.get_gl_dict(
+					{
+						"account": self.target_fixed_asset_account,
+						"against": ", ".join(target_against),
+						"remarks": self.get("remarks") or _("Accounting Entry for Asset"),
+						"debit": flt(self.total_value, precision),
+						"cost_center": self.get("cost_center"),
+					},
+					item=self,
+				)
+			)
+		else:
+			# Target Stock Item
+			sle_list = self.sle_map.get(self.name)
+			for sle in sle_list:
+				stock_value_difference = flt(sle.stock_value_difference, precision)
+				account = self.warehouse_account[sle.warehouse]["account"]
+
 				gl_entries.append(
 					self.get_gl_dict(
 						{
-							"account": self.target_fixed_asset_account,
-							"against_type": "Account",
-							"against": target_account,
-							"against_link": target_account,
-							"remarks": self.get("remarks") or _("Accounting Entry for Asset"),
-							"debit": flt(self.total_value, precision) / len(target_against),
-							"cost_center": self.get("cost_center"),
+							"account": account,
+							"against": ", ".join(target_against),
+							"cost_center": self.cost_center,
+							"project": self.get("project"),
+							"remarks": self.get("remarks") or "Accounting Entry for Stock",
+							"debit": stock_value_difference,
 						},
+						self.warehouse_account[sle.warehouse]["account_currency"],
 						item=self,
 					)
 				)
-			else:
-				# Target Stock Item
-				sle_list = self.sle_map.get(self.name)
-				for sle in sle_list:
-					stock_value_difference = flt(sle.stock_value_difference, precision)
-					account = self.warehouse_account[sle.warehouse]["account"]
-
-					gl_entries.append(
-						self.get_gl_dict(
-							{
-								"account": account,
-								"against_type": "Account",
-								"against": target_account,
-								"against_link": target_account,
-								"cost_center": self.cost_center,
-								"project": self.get("project"),
-								"remarks": self.get("remarks") or "Accounting Entry for Stock",
-								"debit": stock_value_difference / len(target_against),
-							},
-							self.warehouse_account[sle.warehouse]["account_currency"],
-							item=self,
-						)
-					)
 
 	def create_target_asset(self):
 		if (
@@ -892,7 +889,6 @@
 		out.cost_center = get_default_cost_center(
 			args, item_defaults, item_group_defaults, brand_defaults
 		)
-
 	return out
 
 
@@ -940,10 +936,27 @@
 		"qty",
 		"valuation_rate",
 		"amount",
+		"is_fixed_asset",
+		"parent",
 	]
 
 	pr_items = frappe.get_all(
-		"Purchase Receipt Item", filters={"wip_composite_asset": asset}, fields=fields
+		"Purchase Receipt Item", filters={"wip_composite_asset": asset, "docstatus": 1}, fields=fields
 	)
 
-	return pr_items
+	stock_items = []
+	asset_items = []
+	for d in pr_items:
+		if not d.is_fixed_asset:
+			stock_items.append(frappe._dict(d))
+		else:
+			asset_details = frappe.db.get_value(
+				"Asset",
+				{"item_code": d.item_code, "purchase_receipt": d.parent},
+				["name as asset", "asset_name"],
+				as_dict=1,
+			)
+			d.update(asset_details)
+			asset_items.append(frappe._dict(d))
+
+	return stock_items, asset_items
diff --git a/erpnext/assets/doctype/asset_capitalization/test_asset_capitalization.py b/erpnext/assets/doctype/asset_capitalization/test_asset_capitalization.py
index 7a7a10d..ac7c90d 100644
--- a/erpnext/assets/doctype/asset_capitalization/test_asset_capitalization.py
+++ b/erpnext/assets/doctype/asset_capitalization/test_asset_capitalization.py
@@ -98,12 +98,12 @@
 
 		# Test General Ledger Entries
 		expected_gle = {
-			"_Test Fixed Asset - TCP1": 2999.99,
+			"_Test Fixed Asset - TCP1": 3000,
 			"Expenses Included In Asset Valuation - TCP1": -1000,
 			"_Test Warehouse - TCP1": -2000,
-			"Round Off - TCP1": 0.01,
 		}
 		actual_gle = get_actual_gle_dict(asset_capitalization.name)
+
 		self.assertEqual(actual_gle, expected_gle)
 
 		# Test Stock Ledger Entries
@@ -189,10 +189,9 @@
 		# Test General Ledger Entries
 		default_expense_account = frappe.db.get_value("Company", company, "default_expense_account")
 		expected_gle = {
-			"_Test Fixed Asset - _TC": 2999.99,
+			"_Test Fixed Asset - _TC": 3000,
 			"Expenses Included In Asset Valuation - _TC": -1000,
 			default_expense_account: -2000,
-			"Round Off - _TC": 0.01,
 		}
 		actual_gle = get_actual_gle_dict(asset_capitalization.name)
 
@@ -377,10 +376,9 @@
 
 		# Test General Ledger Entries
 		expected_gle = {
+			"_Test Warehouse - TCP1": consumed_asset_value_before_disposal,
 			"_Test Accumulated Depreciations - TCP1": accumulated_depreciation,
 			"_Test Fixed Asset - TCP1": -consumed_asset_purchase_value,
-			"_Test Warehouse - TCP1": consumed_asset_value_before_disposal - 0.01,
-			"Round Off - TCP1": 0.01,
 		}
 		actual_gle = get_actual_gle_dict(asset_capitalization.name)
 		self.assertEqual(actual_gle, expected_gle)
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 74d2aa7..146c03e 100644
--- a/erpnext/assets/doctype/asset_depreciation_schedule/asset_depreciation_schedule.py
+++ b/erpnext/assets/doctype/asset_depreciation_schedule/asset_depreciation_schedule.py
@@ -7,6 +7,7 @@
 from frappe.utils import (
 	add_days,
 	add_months,
+	add_years,
 	cint,
 	date_diff,
 	flt,
@@ -18,6 +19,7 @@
 )
 
 import erpnext
+from erpnext.accounts.utils import get_fiscal_year
 
 
 class AssetDepreciationSchedule(Document):
@@ -283,12 +285,20 @@
 		depreciation_amount = 0
 
 		number_of_pending_depreciations = final_number_of_depreciations - start
-
+		yearly_opening_wdv = value_after_depreciation
+		current_fiscal_year_end_date = None
 		for n in range(start, final_number_of_depreciations):
 			# If depreciation is already completed (for double declining balance)
 			if skip_row:
 				continue
 
+			schedule_date = add_months(row.depreciation_start_date, n * cint(row.frequency_of_depreciation))
+			if not current_fiscal_year_end_date:
+				current_fiscal_year_end_date = get_fiscal_year(row.depreciation_start_date)[2]
+			elif getdate(schedule_date) > getdate(current_fiscal_year_end_date):
+				current_fiscal_year_end_date = add_years(current_fiscal_year_end_date, 1)
+				yearly_opening_wdv = value_after_depreciation
+
 			if n > 0 and len(self.get("depreciation_schedule")) > n - 1:
 				prev_depreciation_amount = self.get("depreciation_schedule")[n - 1].depreciation_amount
 			else:
@@ -298,6 +308,7 @@
 				self,
 				asset_doc,
 				value_after_depreciation,
+				yearly_opening_wdv,
 				row,
 				n,
 				prev_depreciation_amount,
@@ -401,8 +412,9 @@
 
 			if not depreciation_amount:
 				continue
-			value_after_depreciation -= flt(
-				depreciation_amount, asset_doc.precision("gross_purchase_amount")
+			value_after_depreciation = flt(
+				value_after_depreciation - flt(depreciation_amount),
+				asset_doc.precision("gross_purchase_amount"),
 			)
 
 			# Adjust depreciation amount in the last period based on the expected value after useful life
@@ -582,6 +594,7 @@
 	asset_depr_schedule,
 	asset,
 	depreciable_value,
+	yearly_opening_wdv,
 	fb_row,
 	schedule_idx=0,
 	prev_depreciation_amount=0,
@@ -597,6 +610,7 @@
 			asset,
 			fb_row,
 			depreciable_value,
+			yearly_opening_wdv,
 			schedule_idx,
 			prev_depreciation_amount,
 			has_wdv_or_dd_non_yearly_pro_rata,
@@ -744,6 +758,7 @@
 	asset,
 	fb_row,
 	depreciable_value,
+	yearly_opening_wdv,
 	schedule_idx,
 	prev_depreciation_amount,
 	has_wdv_or_dd_non_yearly_pro_rata,
diff --git a/erpnext/assets/doctype/asset_repair/asset_repair.py b/erpnext/assets/doctype/asset_repair/asset_repair.py
index bb627d4..10d36e6 100644
--- a/erpnext/assets/doctype/asset_repair/asset_repair.py
+++ b/erpnext/assets/doctype/asset_repair/asset_repair.py
@@ -285,9 +285,7 @@
 					"account": fixed_asset_account,
 					"debit": self.repair_cost,
 					"debit_in_account_currency": self.repair_cost,
-					"against_type": "Account",
 					"against": pi_expense_account,
-					"against_link": pi_expense_account,
 					"voucher_type": self.doctype,
 					"voucher_no": self.name,
 					"cost_center": self.cost_center,
@@ -306,9 +304,7 @@
 					"account": pi_expense_account,
 					"credit": self.repair_cost,
 					"credit_in_account_currency": self.repair_cost,
-					"against_type": "Account",
 					"against": fixed_asset_account,
-					"against_link": fixed_asset_account,
 					"voucher_type": self.doctype,
 					"voucher_no": self.name,
 					"cost_center": self.cost_center,
@@ -342,9 +338,7 @@
 							"account": item.expense_account or default_expense_account,
 							"credit": item.amount,
 							"credit_in_account_currency": item.amount,
-							"against_type": "Account",
 							"against": fixed_asset_account,
-							"against_link": fixed_asset_account,
 							"voucher_type": self.doctype,
 							"voucher_no": self.name,
 							"cost_center": self.cost_center,
@@ -361,9 +355,7 @@
 							"account": fixed_asset_account,
 							"debit": item.amount,
 							"debit_in_account_currency": item.amount,
-							"against_type": "Account",
 							"against": item.expense_account or default_expense_account,
-							"against_link": item.expense_account or default_expense_account,
 							"voucher_type": self.doctype,
 							"voucher_no": self.name,
 							"cost_center": self.cost_center,
diff --git a/erpnext/assets/workspace/assets/assets.json b/erpnext/assets/workspace/assets/assets.json
index c6b321e..26e8d8a 100644
--- a/erpnext/assets/workspace/assets/assets.json
+++ b/erpnext/assets/workspace/assets/assets.json
@@ -196,18 +196,18 @@
    "type": "Link"
   }
  ],
- "modified": "2023-05-24 14:47:20.243146",
+ "modified": "2024-01-05 17:40:34.570041",
  "modified_by": "Administrator",
  "module": "Assets",
  "name": "Assets",
  "number_cards": [],
  "owner": "Administrator",
- "parent_page": "Accounting",
+ "parent_page": "",
  "public": 1,
  "quick_lists": [],
  "restrict_to_domain": "",
  "roles": [],
- "sequence_id": 4.0,
+ "sequence_id": 7.0,
  "shortcuts": [
   {
    "label": "Asset",
diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py
index aef3d31..0c554f2 100644
--- a/erpnext/controllers/accounts_controller.py
+++ b/erpnext/controllers/accounts_controller.py
@@ -1161,7 +1161,6 @@
 		)
 
 		credit_or_debit = "credit" if self.doctype == "Purchase Invoice" else "debit"
-		against_type = "Supplier" if self.doctype == "Purchase Invoice" else "Customer"
 		against = self.supplier if self.doctype == "Purchase Invoice" else self.customer
 
 		if precision_loss:
@@ -1169,9 +1168,7 @@
 				self.get_gl_dict(
 					{
 						"account": round_off_account,
-						"against_type": against_type,
 						"against": against,
-						"against_link": against,
 						credit_or_debit: precision_loss,
 						"cost_center": round_off_cost_center
 						if self.use_company_roundoff_cost_center
@@ -1525,13 +1522,11 @@
 		if self.doctype == "Purchase Invoice":
 			dr_or_cr = "credit"
 			rev_dr_cr = "debit"
-			against_type = "Supplier"
 			supplier_or_customer = self.supplier
 
 		else:
 			dr_or_cr = "debit"
 			rev_dr_cr = "credit"
-			against_type = "Customer"
 			supplier_or_customer = self.customer
 
 		if enable_discount_accounting:
@@ -1556,9 +1551,7 @@
 						self.get_gl_dict(
 							{
 								"account": item.discount_account,
-								"against_type": against_type,
 								"against": supplier_or_customer,
-								"against_link": supplier_or_customer,
 								dr_or_cr: flt(
 									discount_amount * self.get("conversion_rate"), item.precision("discount_amount")
 								),
@@ -1576,9 +1569,7 @@
 						self.get_gl_dict(
 							{
 								"account": income_or_expense_account,
-								"against_type": against_type,
 								"against": supplier_or_customer,
-								"against_link": supplier_or_customer,
 								rev_dr_cr: flt(
 									discount_amount * self.get("conversion_rate"), item.precision("discount_amount")
 								),
@@ -1601,9 +1592,7 @@
 				self.get_gl_dict(
 					{
 						"account": self.additional_discount_account,
-						"against_type": against_type,
 						"against": supplier_or_customer,
-						"against_link": supplier_or_customer,
 						dr_or_cr: self.base_discount_amount,
 						"cost_center": self.cost_center or erpnext.get_default_cost_center(self.company),
 					},
diff --git a/erpnext/controllers/item_variant.py b/erpnext/controllers/item_variant.py
index ea7fb23..1eee9ea 100644
--- a/erpnext/controllers/item_variant.py
+++ b/erpnext/controllers/item_variant.py
@@ -56,7 +56,11 @@
 
 	copy_attributes_to_variant(template, variant)
 
-	variant.item_code = append_number_if_name_exists("Item", template.name)
+	variant_name = f"{template.name} - {manufacturer}"
+	if manufacturer_part_no:
+		variant_name += f" - {manufacturer_part_no}"
+
+	variant.item_code = append_number_if_name_exists("Item", variant_name)
 	variant.flags.ignore_mandatory = True
 	variant.save()
 
diff --git a/erpnext/controllers/queries.py b/erpnext/controllers/queries.py
index 8ebdcc5..e234eec 100644
--- a/erpnext/controllers/queries.py
+++ b/erpnext/controllers/queries.py
@@ -6,10 +6,12 @@
 from collections import OrderedDict, defaultdict
 
 import frappe
-from frappe import scrub
+from frappe import qb, scrub
 from frappe.desk.reportview import get_filters_cond, get_match_cond
-from frappe.query_builder.functions import Concat, Sum
+from frappe.query_builder import Criterion, CustomFunction
+from frappe.query_builder.functions import Concat, Locate, Sum
 from frappe.utils import nowdate, today, unique
+from pypika import Order
 
 import erpnext
 from erpnext.stock.get_item_details import _get_item_tax_template
@@ -344,37 +346,46 @@
 @frappe.whitelist()
 @frappe.validate_and_sanitize_search_inputs
 def get_project_name(doctype, txt, searchfield, start, page_len, filters):
-	doctype = "Project"
-	cond = ""
+	proj = qb.DocType("Project")
+	qb_filter_and_conditions = []
+	qb_filter_or_conditions = []
+	ifelse = CustomFunction("IF", ["condition", "then", "else"])
+
 	if filters and filters.get("customer"):
-		cond = """(`tabProject`.customer = %s or
-			ifnull(`tabProject`.customer,"")="") and""" % (
-			frappe.db.escape(filters.get("customer"))
-		)
+		qb_filter_and_conditions.append(proj.customer == filters.get("customer"))
+
+	qb_filter_and_conditions.append(proj.status.notin(["Completed", "Cancelled"]))
+
+	q = qb.from_(proj)
 
 	fields = get_fields(doctype, ["name", "project_name"])
-	searchfields = frappe.get_meta(doctype).get_search_fields()
-	searchfields = " or ".join(["`tabProject`." + field + " like %(txt)s" for field in searchfields])
+	for x in fields:
+		q = q.select(proj[x])
 
-	return frappe.db.sql(
-		"""select {fields} from `tabProject`
-		where
-			`tabProject`.status not in ('Completed', 'Cancelled')
-			and {cond} {scond} {match_cond}
-		order by
-			(case when locate(%(_txt)s, `tabProject`.name) > 0 then locate(%(_txt)s, `tabProject`.name) else 99999 end),
-			`tabProject`.idx desc,
-			`tabProject`.name asc
-		limit {page_len} offset {start}""".format(
-			fields=", ".join(["`tabProject`.{0}".format(f) for f in fields]),
-			cond=cond,
-			scond=searchfields,
-			match_cond=get_match_cond(doctype),
-			start=start,
-			page_len=page_len,
-		),
-		{"txt": "%{0}%".format(txt), "_txt": txt.replace("%", "")},
-	)
+	# don't consider 'customer' and 'status' fields for pattern search, as they must be exactly matched
+	searchfields = [
+		x for x in frappe.get_meta(doctype).get_search_fields() if x not in ["customer", "status"]
+	]
+
+	# pattern search
+	if txt:
+		for x in searchfields:
+			qb_filter_or_conditions.append(proj[x].like(f"%{txt}%"))
+
+	q = q.where(Criterion.all(qb_filter_and_conditions)).where(Criterion.any(qb_filter_or_conditions))
+
+	# ordering
+	if txt:
+		# project_name containing search string 'txt' will be given higher precedence
+		q = q.orderby(ifelse(Locate(txt, proj.project_name) > 0, Locate(txt, proj.project_name), 99999))
+	q = q.orderby(proj.idx, order=Order.desc).orderby(proj.name)
+
+	if page_len:
+		q = q.limit(page_len)
+
+	if start:
+		q = q.offset(start)
+	return q.run()
 
 
 @frappe.whitelist()
diff --git a/erpnext/controllers/stock_controller.py b/erpnext/controllers/stock_controller.py
index de86846..7c63518 100644
--- a/erpnext/controllers/stock_controller.py
+++ b/erpnext/controllers/stock_controller.py
@@ -162,9 +162,7 @@
 							self.get_gl_dict(
 								{
 									"account": warehouse_account[sle.warehouse]["account"],
-									"against_type": "Account",
 									"against": expense_account,
-									"against_link": expense_account,
 									"cost_center": item_row.cost_center,
 									"project": item_row.project or self.get("project"),
 									"remarks": self.get("remarks") or _("Accounting Entry for Stock"),
@@ -180,9 +178,7 @@
 							self.get_gl_dict(
 								{
 									"account": expense_account,
-									"against_type": "Account",
 									"against": warehouse_account[sle.warehouse]["account"],
-									"against_link": warehouse_account[sle.warehouse]["account"],
 									"cost_center": item_row.cost_center,
 									"remarks": self.get("remarks") or _("Accounting Entry for Stock"),
 									"debit": -1 * flt(sle.stock_value_difference, precision),
@@ -214,9 +210,7 @@
 					self.get_gl_dict(
 						{
 							"account": expense_account,
-							"against_type": "Account",
 							"against": warehouse_asset_account,
-							"against_link": warehouse_asset_account,
 							"cost_center": item_row.cost_center,
 							"project": item_row.project or self.get("project"),
 							"remarks": _("Rounding gain/loss Entry for Stock Transfer"),
@@ -232,9 +226,7 @@
 					self.get_gl_dict(
 						{
 							"account": warehouse_asset_account,
-							"against_type": "Account",
 							"against": expense_account,
-							"against_link": expense_account,
 							"cost_center": item_row.cost_center,
 							"remarks": _("Rounding gain/loss Entry for Stock Transfer"),
 							"credit": sle_rounding_diff,
@@ -836,7 +828,6 @@
 		credit,
 		remarks,
 		against_account,
-		against_type="Account",
 		debit_in_account_currency=None,
 		credit_in_account_currency=None,
 		account_currency=None,
@@ -851,9 +842,7 @@
 			"cost_center": cost_center,
 			"debit": debit,
 			"credit": credit,
-			"against_type": against_type,
 			"against": against_account,
-			"against_link": against_account,
 			"remarks": remarks,
 		}
 
diff --git a/erpnext/controllers/tests/test_queries.py b/erpnext/controllers/tests/test_queries.py
index 60d1733..3a3bc1c 100644
--- a/erpnext/controllers/tests/test_queries.py
+++ b/erpnext/controllers/tests/test_queries.py
@@ -68,7 +68,7 @@
 		self.assertGreaterEqual(len(query(txt="_Test Item Home Desktop Manufactured")), 1)
 
 	def test_project_query(self):
-		query = add_default_params(queries.get_project_name, "BOM")
+		query = add_default_params(queries.get_project_name, "Project")
 
 		self.assertGreaterEqual(len(query(txt="_Test Project")), 1)
 
diff --git a/erpnext/manufacturing/doctype/bom_creator/bom_creator.js b/erpnext/manufacturing/doctype/bom_creator/bom_creator.js
index 243e52d..3bd2021 100644
--- a/erpnext/manufacturing/doctype/bom_creator/bom_creator.js
+++ b/erpnext/manufacturing/doctype/bom_creator/bom_creator.js
@@ -101,6 +101,7 @@
 			}
 		})
 
+		dialog.fields_dict.item_code.get_query = "erpnext.controllers.queries.item_query";
 		dialog.show();
 	},
 
@@ -113,6 +114,16 @@
 				}
 			}
 		});
+		frm.set_query("item_code", "items", function() {
+			return {
+				query: "erpnext.controllers.queries.item_query",
+			}
+		});
+		frm.set_query("fg_item", "items", function() {
+			return {
+				query: "erpnext.controllers.queries.item_query",
+			}
+		});
 	},
 
 	refresh(frm) {
@@ -211,4 +222,4 @@
 	}
 };
 
-extend_cscript(cur_frm.cscript, new erpnext.bom.BomConfigurator({frm: cur_frm}));
\ No newline at end of file
+extend_cscript(cur_frm.cscript, new erpnext.bom.BomConfigurator({frm: cur_frm}));
diff --git a/erpnext/manufacturing/doctype/work_order/test_work_order.py b/erpnext/manufacturing/doctype/work_order/test_work_order.py
index aa5db57..f6e9a07 100644
--- a/erpnext/manufacturing/doctype/work_order/test_work_order.py
+++ b/erpnext/manufacturing/doctype/work_order/test_work_order.py
@@ -998,12 +998,6 @@
 
 		make_job_card(wo_order.name, operations)
 		job_card = frappe.db.get_value("Job Card", {"work_order": wo_order.name, "docstatus": 0}, "name")
-		update_job_card(job_card, 10, 2)
-
-		stock_entry = frappe.get_doc(make_stock_entry(wo_order.name, "Manufacture", 10))
-		for row in stock_entry.items:
-			if row.is_scrap_item:
-				self.assertEqual(row.qty, 2)
 
 	def test_close_work_order(self):
 		items = [
diff --git a/erpnext/regional/united_arab_emirates/utils.py b/erpnext/regional/united_arab_emirates/utils.py
index 3e9f761..634a152 100644
--- a/erpnext/regional/united_arab_emirates/utils.py
+++ b/erpnext/regional/united_arab_emirates/utils.py
@@ -153,9 +153,7 @@
 					"account": tax.account_head,
 					"cost_center": tax.cost_center,
 					"posting_date": doc.posting_date,
-					"against_type": "Supplier",
 					"against": doc.supplier,
-					"against_link": doc.supplier,
 					dr_or_cr: tax.base_tax_amount_after_discount_amount,
 					dr_or_cr + "_in_account_currency": tax.base_tax_amount_after_discount_amount
 					if account_currency == doc.company_currency
diff --git a/erpnext/selling/doctype/sales_order/sales_order.js b/erpnext/selling/doctype/sales_order/sales_order.js
index b206e3f..56c745c 100644
--- a/erpnext/selling/doctype/sales_order/sales_order.js
+++ b/erpnext/selling/doctype/sales_order/sales_order.js
@@ -94,6 +94,9 @@
 						frm.set_value("reserve_stock", 0);
 						frm.set_df_property("reserve_stock", "read_only", 1);
 						frm.set_df_property("reserve_stock", "hidden", 1);
+						frm.fields_dict.items.grid.update_docfield_property('reserve_stock', 'hidden', 1);
+						frm.fields_dict.items.grid.update_docfield_property('reserve_stock', 'default', 0);
+						frm.fields_dict.items.grid.update_docfield_property('reserve_stock', 'read_only', 1);
 					}
 				})
 			}
diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py
index 9542361..5ef2c50 100755
--- a/erpnext/selling/doctype/sales_order/sales_order.py
+++ b/erpnext/selling/doctype/sales_order/sales_order.py
@@ -200,6 +200,7 @@
 		self.validate_for_items()
 		self.validate_warehouse()
 		self.validate_drop_ship()
+		self.validate_reserved_stock()
 		self.validate_serial_no_based_delivery()
 		validate_against_blanket_order(self)
 		validate_inter_company_party(
@@ -660,6 +661,17 @@
 					).format(item.item_code)
 				)
 
+	def validate_reserved_stock(self):
+		"""Clean reserved stock flag for non-stock Item"""
+
+		enable_stock_reservation = frappe.db.get_single_value(
+			"Stock Settings", "enable_stock_reservation"
+		)
+
+		for item in self.items:
+			if item.reserve_stock and (not enable_stock_reservation or not cint(item.is_stock_item)):
+				item.reserve_stock = 0
+
 	def has_unreserved_stock(self) -> bool:
 		"""Returns True if there is any unreserved item in the Sales Order."""
 
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 d4ccfc4..87aeeac 100644
--- a/erpnext/selling/doctype/sales_order_item/sales_order_item.json
+++ b/erpnext/selling/doctype/sales_order_item/sales_order_item.json
@@ -10,6 +10,7 @@
   "item_code",
   "customer_item_code",
   "ensure_delivery_based_on_produced_serial_no",
+  "is_stock_item",
   "reserve_stock",
   "col_break1",
   "delivery_date",
@@ -867,6 +868,7 @@
   {
    "allow_on_submit": 1,
    "default": "1",
+   "depends_on": "eval:doc.is_stock_item",
    "fieldname": "reserve_stock",
    "fieldtype": "Check",
    "label": "Reserve Stock",
@@ -891,6 +893,16 @@
    "label": "Production Plan Qty",
    "no_copy": 1,
    "read_only": 1
+  },
+  {
+   "default": "0",
+   "fetch_from": "item_code.is_stock_item",
+   "fieldname": "is_stock_item",
+   "fieldtype": "Check",
+   "hidden": 1,
+   "label": "Is Stock Item",
+   "print_hide": 1,
+   "report_hide": 1
   }
  ],
  "idx": 1,
diff --git a/erpnext/stock/doctype/bin/bin.json b/erpnext/stock/doctype/bin/bin.json
index 10d9511..39e0917 100644
--- a/erpnext/stock/doctype/bin/bin.json
+++ b/erpnext/stock/doctype/bin/bin.json
@@ -186,7 +186,7 @@
  "idx": 1,
  "in_create": 1,
  "links": [],
- "modified": "2023-11-01 16:51:17.079107",
+ "modified": "2024-01-16 15:11:46.140323",
  "modified_by": "Administrator",
  "module": "Stock",
  "name": "Bin",
@@ -213,6 +213,21 @@
    "read": 1,
    "report": 1,
    "role": "Stock User"
+  },
+  {
+   "read": 1,
+   "report": 1,
+   "role": "Stock Manager"
+  },
+  {
+   "read": 1,
+   "report": 1,
+   "role": "Purchase Manager"
+  },
+  {
+   "read": 1,
+   "report": 1,
+   "role": "Sales Manager"
   }
  ],
  "quick_entry": 1,
diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
index 326ef9b..fcb7a6d 100644
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
@@ -519,7 +519,6 @@
 							debit=0.0,
 							credit=discrepancy_caused_by_exchange_rate_difference,
 							remarks=remarks,
-							against_type="Supplier",
 							against_account=self.supplier,
 							debit_in_account_currency=-1 * discrepancy_caused_by_exchange_rate_difference,
 							account_currency=account_currency,
@@ -533,7 +532,6 @@
 							debit=discrepancy_caused_by_exchange_rate_difference,
 							credit=0.0,
 							remarks=remarks,
-							against_type="Supplier",
 							against_account=self.supplier,
 							debit_in_account_currency=-1 * discrepancy_caused_by_exchange_rate_difference,
 							account_currency=account_currency,
@@ -800,7 +798,7 @@
 			# Backward compatibility:
 			# and charges added via Landed Cost Voucher,
 			# post valuation related charges on "Stock Received But Not Billed"
-			against_accounts = [d.account for d in gl_entries if flt(d.debit) > 0]
+			against_accounts = ", ".join([d.account for d in gl_entries if flt(d.debit) > 0])
 			total_valuation_amount = sum(valuation_tax.values())
 			amount_including_divisional_loss = negative_expense_to_be_booked
 			stock_rbnb = (
@@ -832,17 +830,16 @@
 						)
 						amount_including_divisional_loss -= applicable_amount
 
-					for against in against_accounts:
-						self.add_gl_entry(
-							gl_entries=gl_entries,
-							account=account,
-							cost_center=tax.cost_center,
-							debit=0.0,
-							credit=flt(applicable_amount) / len(against_accounts),
-							remarks=self.remarks or _("Accounting Entry for Stock"),
-							against_account=against,
-							item=tax,
-						)
+					self.add_gl_entry(
+						gl_entries=gl_entries,
+						account=account,
+						cost_center=tax.cost_center,
+						debit=0.0,
+						credit=applicable_amount,
+						remarks=self.remarks or _("Accounting Entry for Stock"),
+						against_account=against_accounts,
+						item=tax,
+					)
 
 					i += 1
 
diff --git a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
index 497530f..57ba5bb 100644
--- a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
+++ b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
@@ -4,7 +4,6 @@
 import frappe
 from frappe.tests.utils import FrappeTestCase, change_settings
 from frappe.utils import add_days, cint, cstr, flt, nowtime, today
-from pypika import Order
 from pypika import functions as fn
 
 import erpnext
@@ -1009,7 +1008,7 @@
 		gl_entries = get_gl_entries("Purchase Receipt", pr.name)
 		sl_entries = get_sl_entries("Purchase Receipt", pr.name)
 
-		self.assertEqual(len(gl_entries), 2)
+		self.assertFalse(gl_entries)
 
 		expected_sle = {"Work In Progress - TCP1": -5, "Stores - TCP1": 5}
 
@@ -2254,13 +2253,13 @@
 
 
 def get_gl_entries(voucher_type, voucher_no):
-	gle = frappe.qb.DocType("GL Entry")
-	return (
-		frappe.qb.from_(gle)
-		.select(gle.account, gle.debit, gle.credit, gle.cost_center, gle.is_cancelled)
-		.where((gle.voucher_type == voucher_type) & (gle.voucher_no == voucher_no))
-		.orderby(gle.account, gle.debit, order=Order.desc)
-	).run(as_dict=True)
+	return frappe.db.sql(
+		"""select account, debit, credit, cost_center, is_cancelled
+		from `tabGL Entry` where voucher_type=%s and voucher_no=%s
+		order by account desc""",
+		(voucher_type, voucher_no),
+		as_dict=1,
+	)
 
 
 def get_taxes(**args):
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py
index bc5f428..96c249f 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.py
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.py
@@ -1459,9 +1459,7 @@
 						self.get_gl_dict(
 							{
 								"account": account,
-								"against_type": "Account",
 								"against": d.expense_account,
-								"against_link": d.expense_account,
 								"cost_center": d.cost_center,
 								"remarks": self.get("remarks") or _("Accounting Entry for Stock"),
 								"credit_in_account_currency": flt(amount["amount"]),
@@ -1475,9 +1473,7 @@
 						self.get_gl_dict(
 							{
 								"account": d.expense_account,
-								"against_type": "Account",
 								"against": account,
-								"against_link": account,
 								"cost_center": d.cost_center,
 								"remarks": self.get("remarks") or _("Accounting Entry for Stock"),
 								"credit": -1
diff --git a/erpnext/stock/doctype/stock_entry/test_stock_entry.py b/erpnext/stock/doctype/stock_entry/test_stock_entry.py
index 085d215..23dacc8 100644
--- a/erpnext/stock/doctype/stock_entry/test_stock_entry.py
+++ b/erpnext/stock/doctype/stock_entry/test_stock_entry.py
@@ -517,14 +517,7 @@
 		self.check_gl_entries(
 			"Stock Entry",
 			repack.name,
-			sorted(
-				[
-					["Cost of Goods Sold - TCP1", 0.0, 1200.0],
-					["Stock Adjustment - TCP1", 0.0, 1200.0],
-					["Stock Adjustment - TCP1", 1200.0, 0.0],
-					[stock_in_hand_account, 1200.0, 0.0],
-				]
-			),
+			sorted([[stock_in_hand_account, 1200, 0.0], ["Cost of Goods Sold - TCP1", 0.0, 1200.0]]),
 		)
 
 	def check_stock_ledger_entries(self, voucher_type, voucher_no, expected_sle):
diff --git a/erpnext/stock/report/stock_ageing/stock_ageing.py b/erpnext/stock/report/stock_ageing/stock_ageing.py
index f055c6c..02ac8c6 100644
--- a/erpnext/stock/report/stock_ageing/stock_ageing.py
+++ b/erpnext/stock/report/stock_ageing/stock_ageing.py
@@ -233,28 +233,30 @@
 		"""
 
 		stock_ledger_entries = self.sle
-		if stock_ledger_entries is None:
-			stock_ledger_entries = self.__get_stock_ledger_entries()
 
-		for d in stock_ledger_entries:
-			key, fifo_queue, transferred_item_key = self.__init_key_stores(d)
+		with frappe.db.unbuffered_cursor():
+			if stock_ledger_entries is None:
+				stock_ledger_entries = self.__get_stock_ledger_entries()
 
-			if d.voucher_type == "Stock Reconciliation":
-				# get difference in qty shift as actual qty
-				prev_balance_qty = self.item_details[key].get("qty_after_transaction", 0)
-				d.actual_qty = flt(d.qty_after_transaction) - flt(prev_balance_qty)
+			for d in stock_ledger_entries:
+				key, fifo_queue, transferred_item_key = self.__init_key_stores(d)
 
-			serial_nos = get_serial_nos(d.serial_no) if d.serial_no else []
+				if d.voucher_type == "Stock Reconciliation":
+					# get difference in qty shift as actual qty
+					prev_balance_qty = self.item_details[key].get("qty_after_transaction", 0)
+					d.actual_qty = flt(d.qty_after_transaction) - flt(prev_balance_qty)
 
-			if d.actual_qty > 0:
-				self.__compute_incoming_stock(d, fifo_queue, transferred_item_key, serial_nos)
-			else:
-				self.__compute_outgoing_stock(d, fifo_queue, transferred_item_key, serial_nos)
+				serial_nos = get_serial_nos(d.serial_no) if d.serial_no else []
 
-			self.__update_balances(d, key)
+				if d.actual_qty > 0:
+					self.__compute_incoming_stock(d, fifo_queue, transferred_item_key, serial_nos)
+				else:
+					self.__compute_outgoing_stock(d, fifo_queue, transferred_item_key, serial_nos)
 
-		# Note that stock_ledger_entries is an iterator, you can not reuse it  like a list
-		del stock_ledger_entries
+				self.__update_balances(d, key)
+
+			# Note that stock_ledger_entries is an iterator, you can not reuse it  like a list
+			del stock_ledger_entries
 
 		if not self.filters.get("show_warehouse_wise_stock"):
 			# (Item 1, WH 1), (Item 1, WH 2) => (Item 1)
diff --git a/erpnext/stock/stock_ledger.py b/erpnext/stock/stock_ledger.py
index a6206ac..0370666 100644
--- a/erpnext/stock/stock_ledger.py
+++ b/erpnext/stock/stock_ledger.py
@@ -439,7 +439,7 @@
 		reposting_data = get_reposting_data(doc.reposting_data_file)
 
 	if reposting_data and reposting_data.distinct_item_and_warehouse:
-		return reposting_data.distinct_item_and_warehouse
+		return parse_distinct_items_and_warehouses(reposting_data.distinct_item_and_warehouse)
 
 	distinct_item_warehouses = {}
 
@@ -457,6 +457,16 @@
 	return distinct_item_warehouses
 
 
+def parse_distinct_items_and_warehouses(distinct_items_and_warehouses):
+	new_dict = frappe._dict({})
+
+	# convert string keys to tuple
+	for k, v in distinct_items_and_warehouses.items():
+		new_dict[frappe.safe_eval(k)] = frappe._dict(v)
+
+	return new_dict
+
+
 def get_affected_transactions(doc, reposting_data=None) -> Set[Tuple[str, str]]:
 	if not reposting_data and doc and doc.reposting_data_file:
 		reposting_data = get_reposting_data(doc.reposting_data_file)
diff --git a/erpnext/subcontracting/doctype/subcontracting_receipt/test_subcontracting_receipt.py b/erpnext/subcontracting/doctype/subcontracting_receipt/test_subcontracting_receipt.py
index 9d7be36..5523c31 100644
--- a/erpnext/subcontracting/doctype/subcontracting_receipt/test_subcontracting_receipt.py
+++ b/erpnext/subcontracting/doctype/subcontracting_receipt/test_subcontracting_receipt.py
@@ -365,17 +365,24 @@
 		fg_warehouse_ac = get_inventory_account(scr.company, scr.items[0].warehouse)
 		supplier_warehouse_ac = get_inventory_account(scr.company, scr.supplier_warehouse)
 		expense_account = scr.items[0].expense_account
-		expected_values = [
-			[fg_warehouse_ac, 2100.0, 0.0],  # FG Amount (D)
-			[supplier_warehouse_ac, 0.0, 1000.0],  # RM Cost (C)
-			[additional_costs_expense_account, 0.0, 100.0],  # Additional Cost (C)
-			[expense_account, 0.0, 1000.0],  # Service Cost (C)
-		]
 
-		for i in range(len(expected_values)):
-			self.assertEqual(expected_values[i][0], gl_entries[i]["account"])
-			self.assertEqual(expected_values[i][1], gl_entries[i]["debit"])
-			self.assertEqual(expected_values[i][2], gl_entries[i]["credit"])
+		if fg_warehouse_ac == supplier_warehouse_ac:
+			expected_values = {
+				fg_warehouse_ac: [2100.0, 1000.0],  # FG Amount (D), RM Cost (C)
+				expense_account: [0.0, 1000.0],  # Service Cost (C)
+				additional_costs_expense_account: [0.0, 100.0],  # Additional Cost (C)
+			}
+		else:
+			expected_values = {
+				fg_warehouse_ac: [2100.0, 0.0],  # FG Amount (D)
+				supplier_warehouse_ac: [0.0, 1000.0],  # RM Cost (C)
+				expense_account: [0.0, 1000.0],  # Service Cost (C)
+				additional_costs_expense_account: [0.0, 100.0],  # Additional Cost (C)
+			}
+
+		for gle in gl_entries:
+			self.assertEqual(expected_values[gle.account][0], gle.debit)
+			self.assertEqual(expected_values[gle.account][1], gle.credit)
 
 		scr.reload()
 		scr.cancel()