Merge pull request #37031 from HarryPaulo/fix-auth-rule-based-on

fix: "Based on" field always has the value "Not applicable"
diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.py b/erpnext/accounts/doctype/payment_entry/payment_entry.py
index 2c2efc0..8a894e2 100644
--- a/erpnext/accounts/doctype/payment_entry/payment_entry.py
+++ b/erpnext/accounts/doctype/payment_entry/payment_entry.py
@@ -98,7 +98,6 @@
 		if self.difference_amount:
 			frappe.throw(_("Difference Amount must be zero"))
 		self.make_gl_entries()
-		self.make_advance_gl_entries()
 		self.update_outstanding_amounts()
 		self.update_advance_paid()
 		self.update_payment_schedule()
@@ -152,7 +151,6 @@
 		)
 		super(PaymentEntry, self).on_cancel()
 		self.make_gl_entries(cancel=1)
-		self.make_advance_gl_entries(cancel=1)
 		self.update_outstanding_amounts()
 		self.update_advance_paid()
 		self.delink_advance_entry_references()
@@ -1060,6 +1058,8 @@
 		else:
 			self.make_exchange_gain_loss_journal()
 
+		self.make_advance_gl_entries(cancel=cancel)
+
 	def add_party_gl_entries(self, gl_entries):
 		if self.party_account:
 			if self.payment_type == "Receive":
@@ -1128,7 +1128,7 @@
 		if self.book_advance_payments_in_separate_party_account:
 			gl_entries = []
 			for d in self.get("references"):
-				if d.reference_doctype in ("Sales Invoice", "Purchase Invoice"):
+				if d.reference_doctype in ("Sales Invoice", "Purchase Invoice", "Journal Entry"):
 					if not (against_voucher_type and against_voucher) or (
 						d.reference_doctype == against_voucher_type and d.reference_name == against_voucher
 					):
@@ -1164,6 +1164,13 @@
 			"voucher_detail_no": invoice.name,
 		}
 
+		posting_date = frappe.db.get_value(
+			invoice.reference_doctype, invoice.reference_name, "posting_date"
+		)
+
+		if getdate(posting_date) < getdate(self.posting_date):
+			posting_date = self.posting_date
+
 		dr_or_cr = "credit" if invoice.reference_doctype == "Sales Invoice" else "debit"
 		args_dict["account"] = invoice.account
 		args_dict[dr_or_cr] = invoice.allocated_amount
@@ -1172,6 +1179,7 @@
 			{
 				"against_voucher_type": invoice.reference_doctype,
 				"against_voucher": invoice.reference_name,
+				"posting_date": posting_date,
 			}
 		)
 		gle = self.get_gl_dict(
diff --git a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.js b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.js
index 7b7ce7a..d9f00be 100644
--- a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.js
+++ b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.js
@@ -24,7 +24,8 @@
 				filters: {
 					"company": this.frm.doc.company,
 					"is_group": 0,
-					"account_type": frappe.boot.party_account_types[this.frm.doc.party_type]
+					"account_type": frappe.boot.party_account_types[this.frm.doc.party_type],
+					"root_type": this.frm.doc.party_type == 'Customer' ? "Asset" : "Liability"
 				}
 			};
 		});
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice_dashboard.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice_dashboard.py
index 6fdcf26..fd95c1f 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice_dashboard.py
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice_dashboard.py
@@ -15,9 +15,11 @@
 		},
 		"internal_links": {
 			"Sales Order": ["items", "sales_order"],
-			"Delivery Note": ["items", "delivery_note"],
 			"Timesheet": ["timesheets", "time_sheet"],
 		},
+		"internal_and_external_links": {
+			"Delivery Note": ["items", "delivery_note"],
+		},
 		"transactions": [
 			{
 				"label": _("Payment"),
diff --git a/erpnext/accounts/report/general_ledger/general_ledger.py b/erpnext/accounts/report/general_ledger/general_ledger.py
index e05a4e7..ae24675 100644
--- a/erpnext/accounts/report/general_ledger/general_ledger.py
+++ b/erpnext/accounts/report/general_ledger/general_ledger.py
@@ -279,20 +279,19 @@
 	if match_conditions:
 		conditions.append(match_conditions)
 
-	if filters.get("include_dimensions"):
-		accounting_dimensions = get_accounting_dimensions(as_list=False)
+	accounting_dimensions = get_accounting_dimensions(as_list=False)
 
-		if accounting_dimensions:
-			for dimension in accounting_dimensions:
-				if not dimension.disabled:
-					if filters.get(dimension.fieldname):
-						if frappe.get_cached_value("DocType", dimension.document_type, "is_tree"):
-							filters[dimension.fieldname] = get_dimension_with_children(
-								dimension.document_type, filters.get(dimension.fieldname)
-							)
-							conditions.append("{0} in %({0})s".format(dimension.fieldname))
-						else:
-							conditions.append("{0} in %({0})s".format(dimension.fieldname))
+	if accounting_dimensions:
+		for dimension in accounting_dimensions:
+			if not dimension.disabled:
+				if filters.get(dimension.fieldname):
+					if frappe.get_cached_value("DocType", dimension.document_type, "is_tree"):
+						filters[dimension.fieldname] = get_dimension_with_children(
+							dimension.document_type, filters.get(dimension.fieldname)
+						)
+						conditions.append("{0} in %({0})s".format(dimension.fieldname))
+					else:
+						conditions.append("{0} in %({0})s".format(dimension.fieldname))
 
 	return "and {}".format(" and ".join(conditions)) if conditions else ""
 
diff --git a/erpnext/accounts/utils.py b/erpnext/accounts/utils.py
index eed74a5..6a80f20 100644
--- a/erpnext/accounts/utils.py
+++ b/erpnext/accounts/utils.py
@@ -491,14 +491,13 @@
 		gl_map = doc.build_gl_map()
 		create_payment_ledger_entry(gl_map, update_outstanding="No", cancel=0, adv_adj=1)
 
-		if voucher_type == "Payment Entry":
-			doc.make_advance_gl_entries()
-
 		# Only update outstanding for newly linked vouchers
 		for entry in entries:
 			update_voucher_outstanding(
 				entry.against_voucher_type, entry.against_voucher, entry.account, entry.party_type, entry.party
 			)
+			if voucher_type == "Payment Entry":
+				doc.make_advance_gl_entries(entry.against_voucher_type, entry.against_voucher)
 
 		frappe.flags.ignore_party_validation = False
 
@@ -1163,8 +1162,13 @@
 
 def parse_naming_series_variable(doc, variable):
 	if variable == "FY":
-		date = doc.get("posting_date") or doc.get("transaction_date") or getdate()
-		return get_fiscal_year(date=date, company=doc.get("company"))[0]
+		if doc:
+			date = doc.get("posting_date") or doc.get("transaction_date")
+			company = doc.get("company")
+		else:
+			date = getdate()
+			company = None
+		return get_fiscal_year(date=date, company=company)[0]
 
 
 @frappe.whitelist()
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.json b/erpnext/buying/doctype/purchase_order/purchase_order.json
index b242108..5b5cc2b 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.json
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.json
@@ -1173,6 +1173,7 @@
    "depends_on": "is_internal_supplier",
    "fieldname": "set_from_warehouse",
    "fieldtype": "Link",
+   "ignore_user_permissions": 1,
    "label": "Set From Warehouse",
    "options": "Warehouse"
   },
@@ -1273,7 +1274,7 @@
  "idx": 105,
  "is_submittable": 1,
  "links": [],
- "modified": "2023-06-03 16:19:45.710444",
+ "modified": "2023-09-13 16:21:07.361700",
  "modified_by": "Administrator",
  "module": "Buying",
  "name": "Purchase Order",
diff --git a/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json b/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json
index 414f086..f79b622 100644
--- a/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json
+++ b/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json
@@ -878,6 +878,7 @@
    "depends_on": "eval:parent.is_internal_supplier",
    "fieldname": "from_warehouse",
    "fieldtype": "Link",
+   "ignore_user_permissions": 1,
    "label": "From Warehouse",
    "options": "Warehouse"
   },
@@ -902,7 +903,7 @@
  "index_web_pages_for_search": 1,
  "istable": 1,
  "links": [],
- "modified": "2023-08-17 10:17:40.893393",
+ "modified": "2023-09-13 16:22:40.825092",
  "modified_by": "Administrator",
  "module": "Buying",
  "name": "Purchase Order Item",
diff --git a/erpnext/buying/doctype/supplier/supplier.js b/erpnext/buying/doctype/supplier/supplier.js
index 372ca56..08dc44c 100644
--- a/erpnext/buying/doctype/supplier/supplier.js
+++ b/erpnext/buying/doctype/supplier/supplier.js
@@ -12,6 +12,7 @@
 			return {
 				filters: {
 					'account_type': 'Payable',
+					'root_type': 'Liability',
 					'company': d.company,
 					"is_group": 0
 				}
diff --git a/erpnext/buying/doctype/supplier/test_supplier.py b/erpnext/buying/doctype/supplier/test_supplier.py
index 7be1d83..ee2ada3 100644
--- a/erpnext/buying/doctype/supplier/test_supplier.py
+++ b/erpnext/buying/doctype/supplier/test_supplier.py
@@ -206,6 +206,7 @@
 		{
 			"doctype": "Supplier",
 			"supplier_name": args.supplier_name,
+			"default_currency": args.default_currency,
 			"supplier_group": args.supplier_group or "Services",
 			"supplier_type": args.supplier_type or "Company",
 			"tax_withholding_category": args.tax_withholding_category,
diff --git a/erpnext/manufacturing/doctype/bom_creator/bom_creator.js b/erpnext/manufacturing/doctype/bom_creator/bom_creator.js
index 01dc89b..0cf2b51 100644
--- a/erpnext/manufacturing/doctype/bom_creator/bom_creator.js
+++ b/erpnext/manufacturing/doctype/bom_creator/bom_creator.js
@@ -134,6 +134,19 @@
 				frm.trigger("build_tree");
 			});
 		}
+
+		if (frm.doc.docstatus === 1 && frm.doc.status !== "Completed") {
+			frm.add_custom_button(__("Create Multi-level BOM"), () => {
+				frm.trigger("create_multi_level_bom");
+			});
+		}
+	},
+
+	create_multi_level_bom(frm) {
+		frm.call({
+			method: "enqueue_create_boms",
+			doc: frm.doc,
+		})
 	}
 });
 
diff --git a/erpnext/manufacturing/doctype/bom_creator/bom_creator.py b/erpnext/manufacturing/doctype/bom_creator/bom_creator.py
index 999d610..058caa3 100644
--- a/erpnext/manufacturing/doctype/bom_creator/bom_creator.py
+++ b/erpnext/manufacturing/doctype/bom_creator/bom_creator.py
@@ -161,6 +161,7 @@
 	def on_submit(self):
 		self.enqueue_create_boms()
 
+	@frappe.whitelist()
 	def enqueue_create_boms(self):
 		frappe.enqueue(
 			self.create_boms,
@@ -220,6 +221,18 @@
 			frappe.msgprint(_("BOMs creation failed"))
 
 	def create_bom(self, row, production_item_wise_rm):
+		bom_creator_item = row.name if row.name != self.name else ""
+		if frappe.db.exists(
+			"BOM",
+			{
+				"bom_creator": self.name,
+				"item": row.item_code,
+				"bom_creator_item": bom_creator_item,
+				"docstatus": 1,
+			},
+		):
+			return
+
 		bom = frappe.new_doc("BOM")
 		bom.update(
 			{
@@ -228,7 +241,7 @@
 				"quantity": row.qty,
 				"allow_alternative_item": 1,
 				"bom_creator": self.name,
-				"bom_creator_item": row.name if row.name != self.name else "",
+				"bom_creator_item": bom_creator_item,
 				"rm_cost_as_per": "Manual",
 			}
 		)
diff --git a/erpnext/manufacturing/doctype/bom_creator/test_bom_creator.py b/erpnext/manufacturing/doctype/bom_creator/test_bom_creator.py
index d239d58..ee5886c 100644
--- a/erpnext/manufacturing/doctype/bom_creator/test_bom_creator.py
+++ b/erpnext/manufacturing/doctype/bom_creator/test_bom_creator.py
@@ -180,6 +180,73 @@
 
 		self.assertEqual(doc.raw_material_cost, fg_valuation_rate)
 
+	def test_make_boms_from_bom_creator(self):
+		final_product = "Bicycle Test"
+		make_item(
+			final_product,
+			{
+				"item_group": "Raw Material",
+				"stock_uom": "Nos",
+			},
+		)
+
+		doc = make_bom_creator(
+			name="Bicycle BOM Test",
+			company="_Test Company",
+			item_code=final_product,
+			qty=1,
+			rm_cosy_as_per="Valuation Rate",
+			currency="INR",
+			plc_conversion_rate=1,
+			conversion_rate=1,
+		)
+
+		add_item(
+			parent=doc.name,
+			fg_item=final_product,
+			fg_reference_id=doc.name,
+			item_code="Pedal Assembly",
+			qty=2,
+		)
+
+		doc.reload()
+		self.assertEqual(doc.items[0].is_expandable, 0)
+
+		add_sub_assembly(
+			convert_to_sub_assembly=1,
+			parent=doc.name,
+			fg_item=final_product,
+			fg_reference_id=doc.items[0].name,
+			bom_item={
+				"item_code": "Pedal Assembly",
+				"qty": 2,
+				"items": [
+					{
+						"item_code": "Pedal Body",
+						"qty": 2,
+					},
+					{
+						"item_code": "Pedal Axle",
+						"qty": 2,
+					},
+				],
+			},
+		)
+
+		doc.reload()
+		self.assertEqual(doc.items[0].is_expandable, 1)
+
+		doc.submit()
+		doc.create_boms()
+		doc.reload()
+
+		data = frappe.get_all("BOM", filters={"bom_creator": doc.name, "docstatus": 1})
+		self.assertEqual(len(data), 2)
+
+		doc.create_boms()
+		data = frappe.get_all("BOM", filters={"bom_creator": doc.name, "docstatus": 1})
+		self.assertEqual(len(data), 2)
+
 
 def create_items():
 	raw_materials = [
diff --git a/erpnext/manufacturing/doctype/material_request_plan_item/material_request_plan_item.json b/erpnext/manufacturing/doctype/material_request_plan_item/material_request_plan_item.json
index 09bf1d8..d07bf0f 100644
--- a/erpnext/manufacturing/doctype/material_request_plan_item/material_request_plan_item.json
+++ b/erpnext/manufacturing/doctype/material_request_plan_item/material_request_plan_item.json
@@ -10,22 +10,25 @@
   "warehouse",
   "item_name",
   "material_request_type",
-  "actual_qty",
-  "ordered_qty",
+  "quantity",
   "required_bom_qty",
   "column_break_4",
-  "quantity",
+  "schedule_date",
   "uom",
   "conversion_factor",
-  "projected_qty",
-  "reserved_qty_for_production",
-  "safety_stock",
   "item_details",
   "description",
   "min_order_qty",
   "section_break_8",
   "sales_order",
-  "requested_qty"
+  "bin_qty_section",
+  "actual_qty",
+  "requested_qty",
+  "reserved_qty_for_production",
+  "column_break_yhelv",
+  "ordered_qty",
+  "projected_qty",
+  "safety_stock"
  ],
  "fields": [
   {
@@ -65,7 +68,7 @@
    "fieldtype": "Column Break"
   },
   {
-   "columns": 1,
+   "columns": 2,
    "fieldname": "quantity",
    "fieldtype": "Float",
    "in_list_view": 1,
@@ -80,12 +83,12 @@
    "read_only": 1
   },
   {
-   "columns": 2,
+   "columns": 1,
    "default": "0",
    "fieldname": "actual_qty",
    "fieldtype": "Float",
    "in_list_view": 1,
-   "label": "Available Qty",
+   "label": "Qty In Stock",
    "no_copy": 1,
    "read_only": 1
   },
@@ -176,11 +179,27 @@
    "fieldtype": "Float",
    "label": "Conversion Factor",
    "read_only": 1
+  },
+  {
+   "columns": 1,
+   "fieldname": "schedule_date",
+   "fieldtype": "Date",
+   "in_list_view": 1,
+   "label": "Required By"
+  },
+  {
+   "fieldname": "bin_qty_section",
+   "fieldtype": "Section Break",
+   "label": "BIN Qty"
+  },
+  {
+   "fieldname": "column_break_yhelv",
+   "fieldtype": "Column Break"
   }
  ],
  "istable": 1,
  "links": [],
- "modified": "2023-05-03 12:43:29.895754",
+ "modified": "2023-09-12 12:09:08.358326",
  "modified_by": "Administrator",
  "module": "Manufacturing",
  "name": "Material Request Plan Item",
diff --git a/erpnext/manufacturing/doctype/production_plan/production_plan.py b/erpnext/manufacturing/doctype/production_plan/production_plan.py
index b7a2489..7bde29f 100644
--- a/erpnext/manufacturing/doctype/production_plan/production_plan.py
+++ b/erpnext/manufacturing/doctype/production_plan/production_plan.py
@@ -726,7 +726,7 @@
 
 			# key for Sales Order:Material Request Type:Customer
 			key = "{}:{}:{}".format(item.sales_order, material_request_type, item_doc.customer or "")
-			schedule_date = add_days(nowdate(), cint(item_doc.lead_time_days))
+			schedule_date = item.schedule_date or add_days(nowdate(), cint(item_doc.lead_time_days))
 
 			if not key in material_request_map:
 				# make a new MR for the combination
diff --git a/erpnext/manufacturing/doctype/production_plan/test_production_plan.py b/erpnext/manufacturing/doctype/production_plan/test_production_plan.py
index dccb903..6ed7506 100644
--- a/erpnext/manufacturing/doctype/production_plan/test_production_plan.py
+++ b/erpnext/manufacturing/doctype/production_plan/test_production_plan.py
@@ -2,7 +2,7 @@
 # See license.txt
 import frappe
 from frappe.tests.utils import FrappeTestCase
-from frappe.utils import add_to_date, flt, now_datetime, nowdate
+from frappe.utils import add_to_date, flt, getdate, now_datetime, nowdate
 
 from erpnext.controllers.item_variant import create_variant
 from erpnext.manufacturing.doctype.production_plan.production_plan import (
@@ -58,6 +58,9 @@
 		pln = create_production_plan(item_code="Test Production Item 1")
 		self.assertTrue(len(pln.mr_items), 2)
 
+		for row in pln.mr_items:
+			row.schedule_date = add_to_date(nowdate(), days=10)
+
 		pln.make_material_request()
 		pln.reload()
 		self.assertTrue(pln.status, "Material Requested")
@@ -71,6 +74,13 @@
 
 		self.assertTrue(len(material_requests), 2)
 
+		for row in material_requests:
+			mr_schedule_date = getdate(frappe.db.get_value("Material Request", row[0], "schedule_date"))
+
+			expected_date = getdate(add_to_date(nowdate(), days=10))
+
+			self.assertEqual(mr_schedule_date, expected_date)
+
 		pln.make_work_order()
 		work_orders = frappe.get_all(
 			"Work Order", fields=["name"], filters={"production_plan": pln.name}, as_list=1
diff --git a/erpnext/projects/doctype/project/project.py b/erpnext/projects/doctype/project/project.py
index c2ed579..a66b549 100644
--- a/erpnext/projects/doctype/project/project.py
+++ b/erpnext/projects/doctype/project/project.py
@@ -87,6 +87,7 @@
 				issue=task_details.issue,
 				is_group=task_details.is_group,
 				color=task_details.color,
+				template_task=task_details.name,
 			)
 		).insert()
 
@@ -106,9 +107,13 @@
 		return date
 
 	def dependency_mapping(self, template_tasks, project_tasks):
-		for template_task in template_tasks:
-			project_task = list(filter(lambda x: x.subject == template_task.subject, project_tasks))[0]
-			project_task = frappe.get_doc("Task", project_task.name)
+		for project_task in project_tasks:
+			if project_task.get("template_task"):
+				template_task = frappe.get_doc("Task", project_task.template_task)
+			else:
+				template_task = list(filter(lambda x: x.subject == project_task.subject, template_tasks))[0]
+				template_task = frappe.get_doc("Task", template_task.name)
+
 			self.check_depends_on_value(template_task, project_task, project_tasks)
 			self.check_for_parent_tasks(template_task, project_task, project_tasks)
 
@@ -120,6 +125,7 @@
 					filter(lambda x: x.subject == child_task_subject, project_tasks)
 				)
 				if len(corresponding_project_task):
+					project_task.reload()  # reload, as it might have been updated in the previous iteration
 					project_task.append("depends_on", {"task": corresponding_project_task[0].name})
 					project_task.save()
 
diff --git a/erpnext/projects/doctype/project/test_project.py b/erpnext/projects/doctype/project/test_project.py
index 8a599ce..e49fecd 100644
--- a/erpnext/projects/doctype/project/test_project.py
+++ b/erpnext/projects/doctype/project/test_project.py
@@ -1,9 +1,8 @@
 # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
 # License: GNU General Public License v3. See license.txt
 
-import unittest
-
 import frappe
+from frappe.tests.utils import FrappeTestCase
 from frappe.utils import add_days, getdate, nowdate
 
 from erpnext.projects.doctype.project_template.test_project_template import make_project_template
@@ -15,7 +14,7 @@
 test_ignore = ["Sales Order"]
 
 
-class TestProject(unittest.TestCase):
+class TestProject(FrappeTestCase):
 	def test_project_with_template_having_no_parent_and_depend_tasks(self):
 		project_name = "Test Project with Template - No Parent and Dependend Tasks"
 		frappe.db.sql(""" delete from tabTask where project = %s """, project_name)
@@ -155,6 +154,50 @@
 		so.reload()
 		self.assertFalse(so.project)
 
+	def test_project_with_template_tasks_having_common_name(self):
+		# Step - 1: Create Template Parent Tasks
+		template_parent_task1 = create_task(subject="Parent Task - 1", is_template=1, is_group=1)
+		template_parent_task2 = create_task(subject="Parent Task - 2", is_template=1, is_group=1)
+		template_parent_task3 = create_task(subject="Parent Task - 1", is_template=1, is_group=1)
+
+		# Step - 2: Create Template Child Tasks
+		template_task1 = create_task(
+			subject="Task - 1", is_template=1, parent_task=template_parent_task1.name
+		)
+		template_task2 = create_task(
+			subject="Task - 2", is_template=1, parent_task=template_parent_task2.name
+		)
+		template_task3 = create_task(
+			subject="Task - 1", is_template=1, parent_task=template_parent_task3.name
+		)
+
+		# Step - 3: Create Project Template
+		template_tasks = [
+			template_parent_task1,
+			template_task1,
+			template_parent_task2,
+			template_task2,
+			template_parent_task3,
+			template_task3,
+		]
+		project_template = make_project_template(
+			"Project template with common Task Subject", template_tasks
+		)
+
+		# Step - 4: Create Project against the Project Template
+		project = get_project("Project with common Task Subject", project_template)
+		project_tasks = frappe.get_all(
+			"Task", {"project": project.name}, ["subject", "parent_task", "is_group"]
+		)
+
+		# Test - 1: No. of Project Tasks should be equal to No. of Template Tasks
+		self.assertEquals(len(project_tasks), len(template_tasks))
+
+		# Test - 2: All child Project Tasks should have Parent Task linked
+		for pt in project_tasks:
+			if not pt.is_group:
+				self.assertIsNotNone(pt.parent_task)
+
 
 def get_project(name, template):
 
diff --git a/erpnext/projects/doctype/task/task.json b/erpnext/projects/doctype/task/task.json
index 62ec9e0..05a70c3 100644
--- a/erpnext/projects/doctype/task/task.json
+++ b/erpnext/projects/doctype/task/task.json
@@ -52,13 +52,15 @@
   "company",
   "lft",
   "rgt",
-  "old_parent"
+  "old_parent",
+  "template_task"
  ],
  "fields": [
   {
    "fieldname": "subject",
    "fieldtype": "Data",
    "in_global_search": 1,
+   "in_list_view": 1,
    "in_standard_filter": 1,
    "label": "Subject",
    "reqd": 1,
@@ -138,6 +140,7 @@
    "fieldname": "parent_task",
    "fieldtype": "Link",
    "ignore_user_permissions": 1,
+   "in_list_view": 1,
    "label": "Parent Task",
    "options": "Task",
    "search_index": 1
@@ -382,6 +385,12 @@
    "fieldtype": "Date",
    "label": "Completed On",
    "mandatory_depends_on": "eval: doc.status == \"Completed\""
+  },
+  {
+   "fieldname": "template_task",
+   "fieldtype": "Data",
+   "hidden": 1,
+   "label": "Template Task"
   }
  ],
  "icon": "fa fa-check",
@@ -389,7 +398,7 @@
  "is_tree": 1,
  "links": [],
  "max_attachments": 5,
- "modified": "2023-04-17 21:06:50.174418",
+ "modified": "2023-09-06 13:52:05.861175",
  "modified_by": "Administrator",
  "module": "Projects",
  "name": "Task",
diff --git a/erpnext/selling/doctype/customer/customer.js b/erpnext/selling/doctype/customer/customer.js
index 60f0941..e274a52 100644
--- a/erpnext/selling/doctype/customer/customer.js
+++ b/erpnext/selling/doctype/customer/customer.js
@@ -23,6 +23,7 @@
 			let d  = locals[cdt][cdn];
 			let filters = {
 				'account_type': 'Receivable',
+				'root_type': 'Asset',
 				'company': d.company,
 				"is_group": 0
 			};
diff --git a/erpnext/selling/doctype/sales_order/test_sales_order.py b/erpnext/selling/doctype/sales_order/test_sales_order.py
index ed270be..83689a2 100644
--- a/erpnext/selling/doctype/sales_order/test_sales_order.py
+++ b/erpnext/selling/doctype/sales_order/test_sales_order.py
@@ -1889,6 +1889,61 @@
 		self.assertEqual(len(dn.packed_items), 1)
 		self.assertEqual(dn.items[0].item_code, "_Test Product Bundle Item Partial 2")
 
+	@change_settings("Selling Settings", {"editable_bundle_item_rates": 1})
+	def test_expired_rate_for_packed_item(self):
+		bundle = "_Test Product Bundle 1"
+		packed_item = "_Packed Item 1"
+
+		# test Update Items with product bundle
+		for product_bundle in [bundle]:
+			if not frappe.db.exists("Item", product_bundle):
+				bundle_item = make_item(product_bundle, {"is_stock_item": 0})
+				bundle_item.append(
+					"item_defaults", {"company": "_Test Company", "default_warehouse": "_Test Warehouse - _TC"}
+				)
+				bundle_item.save(ignore_permissions=True)
+
+		for product_bundle in [packed_item]:
+			if not frappe.db.exists("Item", product_bundle):
+				make_item(product_bundle, {"is_stock_item": 0, "stock_uom": "Nos"})
+
+		make_product_bundle(bundle, [packed_item], 1)
+
+		for scenario in [
+			{"valid_upto": add_days(nowdate(), -1), "expected_rate": 0.0},
+			{"valid_upto": add_days(nowdate(), 1), "expected_rate": 111.0},
+		]:
+			with self.subTest(scenario=scenario):
+				frappe.get_doc(
+					{
+						"doctype": "Item Price",
+						"item_code": packed_item,
+						"selling": 1,
+						"price_list": "_Test Price List",
+						"valid_from": add_days(nowdate(), -1),
+						"valid_upto": scenario.get("valid_upto"),
+						"price_list_rate": 111,
+					}
+				).save()
+
+				so = frappe.new_doc("Sales Order")
+				so.transaction_date = nowdate()
+				so.delivery_date = nowdate()
+				so.set_warehouse = ""
+				so.company = "_Test Company"
+				so.customer = "_Test Customer"
+				so.currency = "INR"
+				so.selling_price_list = "_Test Price List"
+				so.append("items", {"item_code": bundle, "qty": 1})
+				so.save()
+
+				self.assertEqual(len(so.items), 1)
+				self.assertEqual(len(so.packed_items), 1)
+				self.assertEqual(so.items[0].item_code, bundle)
+				self.assertEqual(so.packed_items[0].item_code, packed_item)
+				self.assertEqual(so.items[0].rate, scenario.get("expected_rate"))
+				self.assertEqual(so.packed_items[0].rate, scenario.get("expected_rate"))
+
 
 def automatically_fetch_payment_terms(enable=1):
 	accounts_settings = frappe.get_doc("Accounts Settings")
diff --git a/erpnext/setup/doctype/company/company.js b/erpnext/setup/doctype/company/company.js
index fa207ec..4973dab 100644
--- a/erpnext/setup/doctype/company/company.js
+++ b/erpnext/setup/doctype/company/company.js
@@ -200,8 +200,8 @@
 	$.each([
 		["default_bank_account", {"account_type": "Bank"}],
 		["default_cash_account", {"account_type": "Cash"}],
-		["default_receivable_account", {"account_type": "Receivable"}],
-		["default_payable_account", {"account_type": "Payable"}],
+		["default_receivable_account", { "root_type": "Asset", "account_type": "Receivable" }],
+		["default_payable_account", { "root_type": "Liability", "account_type": "Payable" }],
 		["default_expense_account", {"root_type": "Expense"}],
 		["default_income_account", {"root_type": "Income"}],
 		["round_off_account", {"root_type": "Expense"}],
diff --git a/erpnext/setup/doctype/company/company.json b/erpnext/setup/doctype/company/company.json
index ed2852e..24d7da4 100644
--- a/erpnext/setup/doctype/company/company.json
+++ b/erpnext/setup/doctype/company/company.json
@@ -33,22 +33,17 @@
   "fax",
   "website",
   "address_html",
+  "registration_info",
+  "registration_details",
+  "lft",
+  "rgt",
+  "old_parent",
+  "accounts_tab",
   "section_break_28",
   "create_chart_of_accounts_based_on",
   "existing_company",
   "column_break_26",
   "chart_of_accounts",
-  "charts_section",
-  "sales_settings",
-  "default_buying_terms",
-  "sales_monthly_history",
-  "monthly_sales_target",
-  "total_monthly_sales",
-  "column_break_goals",
-  "default_selling_terms",
-  "default_warehouse_for_sales_return",
-  "credit_limit",
-  "transactions_annual_history",
   "default_settings",
   "default_bank_account",
   "default_cash_account",
@@ -75,16 +70,12 @@
   "column_break_fwcf",
   "default_advance_received_account",
   "default_advance_paid_account",
-  "auto_accounting_for_stock_settings",
-  "enable_perpetual_inventory",
-  "enable_provisional_accounting_for_non_stock_items",
-  "default_inventory_account",
-  "stock_adjustment_account",
-  "default_in_transit_warehouse",
-  "column_break_32",
-  "stock_received_but_not_billed",
-  "default_provisional_account",
-  "expenses_included_in_valuation",
+  "exchange_rate_revaluation_settings_section",
+  "auto_exchange_rate_revaluation",
+  "auto_err_frequency",
+  "submit_err_jv",
+  "budget_detail",
+  "exception_budget_approver_role",
   "fixed_asset_defaults",
   "accumulated_depreciation_account",
   "depreciation_expense_account",
@@ -95,17 +86,29 @@
   "depreciation_cost_center",
   "capital_work_in_progress_account",
   "asset_received_but_not_billed",
-  "exchange_rate_revaluation_settings_section",
-  "auto_exchange_rate_revaluation",
-  "auto_err_frequency",
-  "submit_err_jv",
-  "budget_detail",
-  "exception_budget_approver_role",
-  "registration_info",
-  "registration_details",
-  "lft",
-  "rgt",
-  "old_parent"
+  "buying_and_selling_tab",
+  "sales_settings",
+  "default_buying_terms",
+  "sales_monthly_history",
+  "monthly_sales_target",
+  "total_monthly_sales",
+  "column_break_goals",
+  "default_selling_terms",
+  "default_warehouse_for_sales_return",
+  "credit_limit",
+  "transactions_annual_history",
+  "stock_tab",
+  "auto_accounting_for_stock_settings",
+  "enable_perpetual_inventory",
+  "enable_provisional_accounting_for_non_stock_items",
+  "default_inventory_account",
+  "stock_adjustment_account",
+  "default_in_transit_warehouse",
+  "column_break_32",
+  "stock_received_but_not_billed",
+  "default_provisional_account",
+  "expenses_included_in_valuation",
+  "dashboard_tab"
  ],
  "fields": [
   {
@@ -212,11 +215,6 @@
    "read_only": 1
   },
   {
-   "fieldname": "charts_section",
-   "fieldtype": "Section Break",
-   "label": "Default Values"
-  },
-  {
    "fieldname": "default_currency",
    "fieldtype": "Link",
    "ignore_user_permissions": 1,
@@ -535,7 +533,6 @@
    "options": "Account"
   },
   {
-   "collapsible": 1,
    "fieldname": "budget_detail",
    "fieldtype": "Section Break",
    "label": "Budget Detail"
@@ -680,7 +677,6 @@
    "fieldtype": "Column Break"
   },
   {
-   "collapsible": 1,
    "fieldname": "fixed_asset_defaults",
    "fieldtype": "Section Break",
    "label": "Fixed Asset Defaults"
@@ -758,6 +754,27 @@
    "fieldname": "submit_err_jv",
    "fieldtype": "Check",
    "label": "Submit ERR Journals?"
+  },
+  {
+   "fieldname": "accounts_tab",
+   "fieldtype": "Tab Break",
+   "label": "Accounts"
+  },
+  {
+   "fieldname": "buying_and_selling_tab",
+   "fieldtype": "Tab Break",
+   "label": "Buying and Selling"
+  },
+  {
+   "fieldname": "stock_tab",
+   "fieldtype": "Tab Break",
+   "label": "Stock"
+  },
+  {
+   "fieldname": "dashboard_tab",
+   "fieldtype": "Tab Break",
+   "label": "Dashboard",
+   "show_dashboard": 1
   }
  ],
  "icon": "fa fa-building",
@@ -765,7 +782,7 @@
  "image_field": "company_logo",
  "is_tree": 1,
  "links": [],
- "modified": "2023-07-07 05:41:41.537256",
+ "modified": "2023-09-10 21:53:13.860791",
  "modified_by": "Administrator",
  "module": "Setup",
  "name": "Company",
diff --git a/erpnext/setup/doctype/customer_group/customer_group.js b/erpnext/setup/doctype/customer_group/customer_group.js
index 49a90f9..3c81b02 100644
--- a/erpnext/setup/doctype/customer_group/customer_group.js
+++ b/erpnext/setup/doctype/customer_group/customer_group.js
@@ -30,6 +30,7 @@
 		frm.set_query('account', 'accounts', function (doc, cdt, cdn) {
 			return {
 				filters: {
+					'root_type': 'Asset',
 					"account_type": 'Receivable',
 					"company": locals[cdt][cdn].company,
 					"is_group": 0
diff --git a/erpnext/setup/doctype/supplier_group/supplier_group.js b/erpnext/setup/doctype/supplier_group/supplier_group.js
index b2acfd7..3362929 100644
--- a/erpnext/setup/doctype/supplier_group/supplier_group.js
+++ b/erpnext/setup/doctype/supplier_group/supplier_group.js
@@ -30,6 +30,7 @@
 		frm.set_query('account', 'accounts', function (doc, cdt, cdn) {
 			return {
 				filters: {
+					'root_type': 'Liability',
 					'account_type': 'Payable',
 					'company': locals[cdt][cdn].company,
 					"is_group": 0
diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.json b/erpnext/stock/doctype/delivery_note/delivery_note.json
index 6a9e241..e0d4919 100644
--- a/erpnext/stock/doctype/delivery_note/delivery_note.json
+++ b/erpnext/stock/doctype/delivery_note/delivery_note.json
@@ -1253,6 +1253,7 @@
    "depends_on": "eval: doc.is_internal_customer",
    "fieldname": "set_target_warehouse",
    "fieldtype": "Link",
+   "ignore_user_permissions": 1,
    "in_standard_filter": 1,
    "label": "Set Target Warehouse",
    "no_copy": 1,
@@ -1400,7 +1401,7 @@
  "idx": 146,
  "is_submittable": 1,
  "links": [],
- "modified": "2023-06-16 14:58:55.066602",
+ "modified": "2023-09-04 14:15:28.363184",
  "modified_by": "Administrator",
  "module": "Stock",
  "name": "Delivery Note",
diff --git a/erpnext/stock/doctype/delivery_note/delivery_note_dashboard.py b/erpnext/stock/doctype/delivery_note/delivery_note_dashboard.py
index e66c233..d4a574d 100644
--- a/erpnext/stock/doctype/delivery_note/delivery_note_dashboard.py
+++ b/erpnext/stock/doctype/delivery_note/delivery_note_dashboard.py
@@ -11,10 +11,12 @@
 		},
 		"internal_links": {
 			"Sales Order": ["items", "against_sales_order"],
-			"Sales Invoice": ["items", "against_sales_invoice"],
 			"Material Request": ["items", "material_request"],
 			"Purchase Order": ["items", "purchase_order"],
 		},
+		"internal_and_external_links": {
+			"Sales Invoice": ["items", "against_sales_invoice"],
+		},
 		"transactions": [
 			{"label": _("Related"), "items": ["Sales Invoice", "Packing Slip", "Delivery Trip"]},
 			{"label": _("Reference"), "items": ["Sales Order", "Shipment", "Quality Inspection"]},
diff --git a/erpnext/stock/doctype/packed_item/packed_item.py b/erpnext/stock/doctype/packed_item/packed_item.py
index dbd8de4..a9e9ad1 100644
--- a/erpnext/stock/doctype/packed_item/packed_item.py
+++ b/erpnext/stock/doctype/packed_item/packed_item.py
@@ -207,6 +207,9 @@
 			"conversion_rate": doc.get("conversion_rate"),
 		}
 	)
+	if not row_data.get("transaction_date"):
+		row_data.update({"transaction_date": doc.get("transaction_date")})
+
 	rate = get_price_list_rate(row_data, item_doc).get("price_list_rate")
 
 	pi_row.rate = rate or item_data.get("valuation_rate") or 0.0
diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
index 60aefdd..04eff54 100644
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
@@ -603,7 +603,7 @@
 			account=provisional_account,
 			cost_center=item.cost_center,
 			debit=0.0,
-			credit=multiplication_factor * item.amount,
+			credit=multiplication_factor * item.base_amount,
 			remarks=remarks,
 			against_account=expense_account,
 			account_currency=credit_currency,
@@ -617,7 +617,7 @@
 			gl_entries=gl_entries,
 			account=expense_account,
 			cost_center=item.cost_center,
-			debit=multiplication_factor * item.amount,
+			debit=multiplication_factor * item.base_amount,
 			credit=0.0,
 			remarks=remarks,
 			against_account=provisional_account,
diff --git a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
index 6134bfa..b7712ee 100644
--- a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
+++ b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
@@ -2017,6 +2017,49 @@
 		ste7.reload()
 		self.assertEqual(ste7.items[0].valuation_rate, valuation_rate)
 
+	def test_purchase_receipt_provisional_accounting(self):
+		# Step - 1: Create Supplier with Default Currency as USD
+		from erpnext.buying.doctype.supplier.test_supplier import create_supplier
+
+		supplier = create_supplier(default_currency="USD")
+
+		# Step - 2: Setup Company for Provisional Accounting
+		from erpnext.accounts.doctype.account.test_account import create_account
+
+		provisional_account = create_account(
+			account_name="Provision Account",
+			parent_account="Current Liabilities - _TC",
+			company="_Test Company",
+		)
+		company = frappe.get_doc("Company", "_Test Company")
+		company.enable_provisional_accounting_for_non_stock_items = 1
+		company.default_provisional_account = provisional_account
+		company.save()
+
+		# Step - 3: Create Non-Stock Item
+		item = make_item(properties={"is_stock_item": 0})
+
+		# Step - 4: Create Purchase Receipt
+		pr = make_purchase_receipt(
+			qty=2,
+			item_code=item.name,
+			company=company.name,
+			supplier=supplier.name,
+			currency=supplier.default_currency,
+		)
+
+		# Test - 1: Total and Base Total should not be the same as the currency is different
+		self.assertNotEqual(flt(pr.total, 2), flt(pr.base_total, 2))
+		self.assertEqual(flt(pr.total * pr.conversion_rate, 2), flt(pr.base_total, 2))
+
+		# Test - 2: Sum of Debit or Credit should be equal to Purchase Receipt Base Total
+		amount = frappe.db.get_value("GL Entry", {"docstatus": 1, "voucher_no": pr.name}, ["sum(debit)"])
+		expected_amount = pr.base_total
+		self.assertEqual(amount, expected_amount)
+
+		company.enable_provisional_accounting_for_non_stock_items = 0
+		company.save()
+
 
 def prepare_data_for_internal_transfer():
 	from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_internal_supplier