Merge pull request #36304 from frappe/mergify/bp/develop/pr-36300

fix: added missing option Partially Received in the status field (backport #36300)
diff --git a/erpnext/assets/report/fixed_asset_register/fixed_asset_register.py b/erpnext/assets/report/fixed_asset_register/fixed_asset_register.py
index 6911f94..94c77ea 100644
--- a/erpnext/assets/report/fixed_asset_register/fixed_asset_register.py
+++ b/erpnext/assets/report/fixed_asset_register/fixed_asset_register.py
@@ -54,12 +54,12 @@
 		conditions["cost_center"] = filters.get("cost_center")
 
 	if status:
-		# In Store assets are those that are not sold or scrapped
+		# In Store assets are those that are not sold or scrapped or capitalized or decapitalized
 		operand = "not in"
 		if status not in "In Location":
 			operand = "in"
 
-		conditions["status"] = (operand, ["Sold", "Scrapped"])
+		conditions["status"] = (operand, ["Sold", "Scrapped", "Capitalized", "Decapitalized"])
 
 	return conditions
 
@@ -71,36 +71,6 @@
 	pr_supplier_map = get_purchase_receipt_supplier_map()
 	pi_supplier_map = get_purchase_invoice_supplier_map()
 
-	group_by = frappe.scrub(filters.get("group_by"))
-
-	if group_by == "asset_category":
-		fields = ["asset_category", "gross_purchase_amount", "opening_accumulated_depreciation"]
-		assets_record = frappe.db.get_all("Asset", filters=conditions, fields=fields, group_by=group_by)
-
-	elif group_by == "location":
-		fields = ["location", "gross_purchase_amount", "opening_accumulated_depreciation"]
-		assets_record = frappe.db.get_all("Asset", filters=conditions, fields=fields, group_by=group_by)
-
-	else:
-		fields = [
-			"name as asset_id",
-			"asset_name",
-			"status",
-			"department",
-			"company",
-			"cost_center",
-			"calculate_depreciation",
-			"purchase_receipt",
-			"asset_category",
-			"purchase_date",
-			"gross_purchase_amount",
-			"location",
-			"available_for_use_date",
-			"purchase_invoice",
-			"opening_accumulated_depreciation",
-		]
-		assets_record = frappe.db.get_all("Asset", filters=conditions, fields=fields)
-
 	assets_linked_to_fb = get_assets_linked_to_fb(filters)
 
 	company_fb = frappe.get_cached_value("Company", filters.company, "default_finance_book")
@@ -114,6 +84,31 @@
 
 	depreciation_amount_map = get_asset_depreciation_amount_map(filters, finance_book)
 
+	group_by = frappe.scrub(filters.get("group_by"))
+
+	if group_by in ("asset_category", "location"):
+		data = get_group_by_data(group_by, conditions, assets_linked_to_fb, depreciation_amount_map)
+		return data
+
+	fields = [
+		"name as asset_id",
+		"asset_name",
+		"status",
+		"department",
+		"company",
+		"cost_center",
+		"calculate_depreciation",
+		"purchase_receipt",
+		"asset_category",
+		"purchase_date",
+		"gross_purchase_amount",
+		"location",
+		"available_for_use_date",
+		"purchase_invoice",
+		"opening_accumulated_depreciation",
+	]
+	assets_record = frappe.db.get_all("Asset", filters=conditions, fields=fields)
+
 	for asset in assets_record:
 		if (
 			assets_linked_to_fb
@@ -136,7 +131,7 @@
 			or pi_supplier_map.get(asset.purchase_invoice),
 			"gross_purchase_amount": asset.gross_purchase_amount,
 			"opening_accumulated_depreciation": asset.opening_accumulated_depreciation,
-			"depreciated_amount": get_depreciation_amount_of_asset(asset, depreciation_amount_map),
+			"depreciated_amount": depreciation_amount_map.get(asset.asset_id) or 0.0,
 			"available_for_use_date": asset.available_for_use_date,
 			"location": asset.location,
 			"asset_category": asset.asset_category,
@@ -230,12 +225,11 @@
 	return assets_linked_to_fb
 
 
-def get_depreciation_amount_of_asset(asset, depreciation_amount_map):
-	return depreciation_amount_map.get(asset.asset_id) or 0.0
-
-
 def get_asset_depreciation_amount_map(filters, finance_book):
-	date = filters.to_date if filters.filter_based_on == "Date Range" else filters.year_end_date
+	start_date = (
+		filters.from_date if filters.filter_based_on == "Date Range" else filters.year_start_date
+	)
+	end_date = filters.to_date if filters.filter_based_on == "Date Range" else filters.year_end_date
 
 	asset = frappe.qb.DocType("Asset")
 	gle = frappe.qb.DocType("GL Entry")
@@ -256,25 +250,77 @@
 		)
 		.where(gle.debit != 0)
 		.where(gle.is_cancelled == 0)
+		.where(company.name == filters.company)
 		.where(asset.docstatus == 1)
-		.groupby(asset.name)
 	)
 
+	if filters.only_existing_assets:
+		query = query.where(asset.is_existing_asset == 1)
+	if filters.asset_category:
+		query = query.where(asset.asset_category == filters.asset_category)
+	if filters.cost_center:
+		query = query.where(asset.cost_center == filters.cost_center)
+	if filters.status:
+		if filters.status == "In Location":
+			query = query.where(asset.status.notin(["Sold", "Scrapped", "Capitalized", "Decapitalized"]))
+		else:
+			query = query.where(asset.status.isin(["Sold", "Scrapped", "Capitalized", "Decapitalized"]))
 	if finance_book:
 		query = query.where(
 			(gle.finance_book.isin([cstr(finance_book), ""])) | (gle.finance_book.isnull())
 		)
 	else:
 		query = query.where((gle.finance_book.isin([""])) | (gle.finance_book.isnull()))
-
 	if filters.filter_based_on in ("Date Range", "Fiscal Year"):
-		query = query.where(gle.posting_date <= date)
+		query = query.where(gle.posting_date >= start_date)
+		query = query.where(gle.posting_date <= end_date)
+
+	query = query.groupby(asset.name)
 
 	asset_depr_amount_map = query.run()
 
 	return dict(asset_depr_amount_map)
 
 
+def get_group_by_data(group_by, conditions, assets_linked_to_fb, depreciation_amount_map):
+	fields = [
+		group_by,
+		"name",
+		"gross_purchase_amount",
+		"opening_accumulated_depreciation",
+		"calculate_depreciation",
+	]
+	assets = frappe.db.get_all("Asset", filters=conditions, fields=fields)
+
+	data = []
+
+	for a in assets:
+		if assets_linked_to_fb and a.calculate_depreciation and a.name not in assets_linked_to_fb:
+			continue
+
+		a["depreciated_amount"] = depreciation_amount_map.get(a["name"], 0.0)
+		a["asset_value"] = (
+			a["gross_purchase_amount"] - a["opening_accumulated_depreciation"] - a["depreciated_amount"]
+		)
+
+		del a["name"]
+		del a["calculate_depreciation"]
+
+		idx = ([i for i, d in enumerate(data) if a[group_by] == d[group_by]] or [None])[0]
+		if idx is None:
+			data.append(a)
+		else:
+			for field in (
+				"gross_purchase_amount",
+				"opening_accumulated_depreciation",
+				"depreciated_amount",
+				"asset_value",
+			):
+				data[idx][field] = data[idx][field] + a[field]
+
+	return data
+
+
 def get_purchase_receipt_supplier_map():
 	return frappe._dict(
 		frappe.db.sql(
@@ -313,35 +359,35 @@
 				"fieldtype": "Link",
 				"fieldname": frappe.scrub(filters.get("group_by")),
 				"options": filters.get("group_by"),
-				"width": 120,
+				"width": 216,
 			},
 			{
 				"label": _("Gross Purchase Amount"),
 				"fieldname": "gross_purchase_amount",
 				"fieldtype": "Currency",
 				"options": "company:currency",
-				"width": 100,
+				"width": 250,
 			},
 			{
 				"label": _("Opening Accumulated Depreciation"),
 				"fieldname": "opening_accumulated_depreciation",
 				"fieldtype": "Currency",
 				"options": "company:currency",
-				"width": 90,
+				"width": 250,
 			},
 			{
 				"label": _("Depreciated Amount"),
 				"fieldname": "depreciated_amount",
 				"fieldtype": "Currency",
 				"options": "company:currency",
-				"width": 100,
+				"width": 250,
 			},
 			{
 				"label": _("Asset Value"),
 				"fieldname": "asset_value",
 				"fieldtype": "Currency",
 				"options": "company:currency",
-				"width": 100,
+				"width": 250,
 			},
 		]
 
diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js
index 6410333..59d2b15 100644
--- a/erpnext/public/js/controllers/transaction.js
+++ b/erpnext/public/js/controllers/transaction.js
@@ -991,6 +991,16 @@
 		this.frm.set_df_property("conversion_rate", "read_only", erpnext.stale_rate_allowed() ? 0 : 1);
 	}
 
+	apply_discount_on_item(doc, cdt, cdn, field) {
+		var item = frappe.get_doc(cdt, cdn);
+		if(!item.price_list_rate) {
+			item[field] = 0.0;
+		} else {
+			this.price_list_rate(doc, cdt, cdn);
+		}
+		this.set_gross_profit(item);
+	}
+
 	shipping_rule() {
 		var me = this;
 		if(this.frm.doc.shipping_rule) {
@@ -1661,6 +1671,9 @@
 						() => {
 							if(args.items.length) {
 								me._set_values_for_item_list(r.message.children);
+								$.each(r.message.children || [], function(i, d) {
+									me.apply_discount_on_item(d, d.doctype, d.name, 'discount_percentage');
+								});
 							}
 						},
 						() => { me.in_apply_price_list = false; }
diff --git a/erpnext/public/js/utils/sales_common.js b/erpnext/public/js/utils/sales_common.js
index 517d871..89dcaa6 100644
--- a/erpnext/public/js/utils/sales_common.js
+++ b/erpnext/public/js/utils/sales_common.js
@@ -142,16 +142,6 @@
 				this.apply_discount_on_item(doc, cdt, cdn, 'discount_amount');
 			}
 
-			apply_discount_on_item(doc, cdt, cdn, field) {
-				var item = frappe.get_doc(cdt, cdn);
-				if(!item.price_list_rate) {
-					item[field] = 0.0;
-				} else {
-					this.price_list_rate(doc, cdt, cdn);
-				}
-				this.set_gross_profit(item);
-			}
-
 			commission_rate() {
 				this.calculate_commission();
 			}