Merge pull request #37495 from ruthra-kumar/keyerror_on_comparison_report

fix: keyerror on gl and pl comparision report
diff --git a/erpnext/accounts/doctype/account_closing_balance/account_closing_balance.py b/erpnext/accounts/doctype/account_closing_balance/account_closing_balance.py
index e75af70..d06bd83 100644
--- a/erpnext/accounts/doctype/account_closing_balance/account_closing_balance.py
+++ b/erpnext/accounts/doctype/account_closing_balance/account_closing_balance.py
@@ -37,6 +37,7 @@
 			}
 		)
 		cle.flags.ignore_permissions = True
+		cle.flags.ignore_links = True
 		cle.submit()
 
 
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
index 85ed126..2433268 100644
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
@@ -539,8 +539,9 @@
 			]
 			child_tables = {"items": ("expense_account",), "taxes": ("account_head",)}
 			self.needs_repost = self.check_if_fields_updated(fields_to_check, child_tables)
-			self.validate_for_repost()
-			self.db_set("repost_required", self.needs_repost)
+			if self.needs_repost:
+				self.validate_for_repost()
+				self.db_set("repost_required", self.needs_repost)
 
 	def make_gl_entries(self, gl_entries=None, from_repost=False):
 		if not gl_entries:
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
index f380825..f6d9c93 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
@@ -536,8 +536,9 @@
 				"taxes": ("account_head",),
 			}
 			self.needs_repost = self.check_if_fields_updated(fields_to_check, child_tables)
-			self.validate_for_repost()
-			self.db_set("repost_required", self.needs_repost)
+			if self.needs_repost:
+				self.validate_for_repost()
+				self.db_set("repost_required", self.needs_repost)
 
 	def set_paid_amount(self):
 		paid_amount = 0.0
diff --git a/erpnext/accounts/report/gross_profit/gross_profit.py b/erpnext/accounts/report/gross_profit/gross_profit.py
index 3324a73..38060bb 100644
--- a/erpnext/accounts/report/gross_profit/gross_profit.py
+++ b/erpnext/accounts/report/gross_profit/gross_profit.py
@@ -544,6 +544,8 @@
 						new_row.qty += flt(row.qty)
 						new_row.buying_amount += flt(row.buying_amount, self.currency_precision)
 						new_row.base_amount += flt(row.base_amount, self.currency_precision)
+						if self.filters.get("group_by") == "Sales Person":
+							new_row.allocated_amount += flt(row.allocated_amount, self.currency_precision)
 				new_row = self.set_average_rate(new_row)
 				self.grouped_data.append(new_row)
 
diff --git a/erpnext/assets/doctype/asset/asset.js b/erpnext/assets/doctype/asset/asset.js
index 5395f15..f0e4c82 100644
--- a/erpnext/assets/doctype/asset/asset.js
+++ b/erpnext/assets/doctype/asset/asset.js
@@ -337,7 +337,7 @@
 
 
 	item_code: function(frm) {
-		if(frm.doc.item_code && frm.doc.calculate_depreciation) {
+		if(frm.doc.item_code && frm.doc.calculate_depreciation && frm.doc.gross_purchase_amount) {
 			frm.trigger('set_finance_book');
 		} else {
 			frm.set_value('finance_books', []);
@@ -490,7 +490,7 @@
 
 	calculate_depreciation: function(frm) {
 		frm.toggle_reqd("finance_books", frm.doc.calculate_depreciation);
-		if (frm.doc.item_code && frm.doc.calculate_depreciation ) {
+		if (frm.doc.item_code && frm.doc.calculate_depreciation && frm.doc.gross_purchase_amount) {
 			frm.trigger("set_finance_book");
 		} else {
 			frm.set_value("finance_books", []);
diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py
index 6812940..e170044 100644
--- a/erpnext/controllers/accounts_controller.py
+++ b/erpnext/controllers/accounts_controller.py
@@ -13,6 +13,7 @@
 	add_days,
 	add_months,
 	cint,
+	comma_and,
 	flt,
 	fmt_money,
 	formatdate,
@@ -181,6 +182,17 @@
 		self.validate_party_account_currency()
 
 		if self.doctype in ["Purchase Invoice", "Sales Invoice"]:
+			if invalid_advances := [
+				x for x in self.advances if not x.reference_type or not x.reference_name
+			]:
+				frappe.throw(
+					_(
+						"Rows: {0} in {1} section are Invalid. Reference Name should point to a valid Payment Entry or Journal Entry."
+					).format(
+						frappe.bold(comma_and([x.idx for x in invalid_advances])), frappe.bold(_("Advance Payments"))
+					)
+				)
+
 			pos_check_field = "is_pos" if self.doctype == "Sales Invoice" else "is_paid"
 			if cint(self.allocate_advances_automatically) and not cint(self.get(pos_check_field)):
 				self.set_advances()
diff --git a/erpnext/manufacturing/doctype/production_plan/production_plan.py b/erpnext/manufacturing/doctype/production_plan/production_plan.py
index deef020..ddd9375 100644
--- a/erpnext/manufacturing/doctype/production_plan/production_plan.py
+++ b/erpnext/manufacturing/doctype/production_plan/production_plan.py
@@ -8,7 +8,6 @@
 import frappe
 from frappe import _, msgprint
 from frappe.model.document import Document
-from frappe.query_builder import Case
 from frappe.query_builder.functions import IfNull, Sum
 from frappe.utils import (
 	add_days,
@@ -1618,21 +1617,13 @@
 	table = frappe.qb.DocType("Production Plan")
 	child = frappe.qb.DocType("Material Request Plan Item")
 
-	completed_production_plans = get_completed_production_plans()
+	non_completed_production_plans = get_non_completed_production_plans()
 
-	case = Case()
 	query = (
 		frappe.qb.from_(table)
 		.inner_join(child)
 		.on(table.name == child.parent)
-		.select(
-			Sum(
-				child.quantity
-				* IfNull(
-					case.when(child.material_request_type == "Purchase", child.conversion_factor).else_(1.0), 1.0
-				)
-			)
-		)
+		.select(Sum(child.required_bom_qty))
 		.where(
 			(table.docstatus == 1)
 			& (child.item_code == item_code)
@@ -1641,8 +1632,8 @@
 		)
 	)
 
-	if completed_production_plans:
-		query = query.where(table.name.notin(completed_production_plans))
+	if non_completed_production_plans:
+		query = query.where(table.name.isin(non_completed_production_plans))
 
 	query = query.run()
 
@@ -1653,7 +1644,7 @@
 
 	reserved_qty_for_production = flt(
 		get_reserved_qty_for_production(
-			item_code, warehouse, completed_production_plans, check_production_plan=True
+			item_code, warehouse, non_completed_production_plans, check_production_plan=True
 		)
 	)
 
@@ -1663,7 +1654,7 @@
 	return reserved_qty_for_production_plan - reserved_qty_for_production
 
 
-def get_completed_production_plans():
+def get_non_completed_production_plans():
 	table = frappe.qb.DocType("Production Plan")
 	child = frappe.qb.DocType("Production Plan Item")
 
@@ -1675,7 +1666,7 @@
 		.where(
 			(table.docstatus == 1)
 			& (table.status.notin(["Completed", "Closed"]))
-			& (child.ordered_qty >= child.planned_qty)
+			& (child.planned_qty > child.ordered_qty)
 		)
 	).run(as_dict=True)
 
diff --git a/erpnext/manufacturing/doctype/production_plan/test_production_plan.py b/erpnext/manufacturing/doctype/production_plan/test_production_plan.py
index 4ff9d29..6ab9232 100644
--- a/erpnext/manufacturing/doctype/production_plan/test_production_plan.py
+++ b/erpnext/manufacturing/doctype/production_plan/test_production_plan.py
@@ -6,8 +6,8 @@
 
 from erpnext.controllers.item_variant import create_variant
 from erpnext.manufacturing.doctype.production_plan.production_plan import (
-	get_completed_production_plans,
 	get_items_for_material_requests,
+	get_non_completed_production_plans,
 	get_sales_orders,
 	get_warehouse_list,
 )
@@ -1143,9 +1143,9 @@
 
 		self.assertEqual(after_qty, before_qty)
 
-		completed_plans = get_completed_production_plans()
+		completed_plans = get_non_completed_production_plans()
 		for plan in plans:
-			self.assertTrue(plan in completed_plans)
+			self.assertFalse(plan in completed_plans)
 
 	def test_resered_qty_for_production_plan_for_material_requests_with_multi_UOM(self):
 		from erpnext.stock.utils import get_or_make_bin
diff --git a/erpnext/manufacturing/doctype/work_order/work_order.py b/erpnext/manufacturing/doctype/work_order/work_order.py
index 3dc33ac..f9fddcb 100644
--- a/erpnext/manufacturing/doctype/work_order/work_order.py
+++ b/erpnext/manufacturing/doctype/work_order/work_order.py
@@ -1515,7 +1515,7 @@
 def get_reserved_qty_for_production(
 	item_code: str,
 	warehouse: str,
-	completed_production_plans: list = None,
+	non_completed_production_plans: list = None,
 	check_production_plan: bool = False,
 ) -> float:
 	"""Get total reserved quantity for any item in specified warehouse"""
@@ -1538,19 +1538,22 @@
 			& (wo_item.parent == wo.name)
 			& (wo.docstatus == 1)
 			& (wo_item.source_warehouse == warehouse)
-			& (wo.status.notin(["Stopped", "Completed", "Closed"]))
-			& (
-				(wo_item.required_qty > wo_item.transferred_qty)
-				| (wo_item.required_qty > wo_item.consumed_qty)
-			)
 		)
 	)
 
 	if check_production_plan:
 		query = query.where(wo.production_plan.isnotnull())
+	else:
+		query = query.where(
+			(wo.status.notin(["Stopped", "Completed", "Closed"]))
+			& (
+				(wo_item.required_qty > wo_item.transferred_qty)
+				| (wo_item.required_qty > wo_item.consumed_qty)
+			)
+		)
 
-	if completed_production_plans:
-		query = query.where(wo.production_plan.notin(completed_production_plans))
+	if non_completed_production_plans:
+		query = query.where(wo.production_plan.isin(non_completed_production_plans))
 
 	return query.run()[0][0] or 0.0
 
diff --git a/erpnext/public/js/controllers/accounts.js b/erpnext/public/js/controllers/accounts.js
index a2e4bda..3545521 100644
--- a/erpnext/public/js/controllers/accounts.js
+++ b/erpnext/public/js/controllers/accounts.js
@@ -116,7 +116,7 @@
 			account_head: function(frm, cdt, cdn) {
 				let d = locals[cdt][cdn];
 
-				if (doc.docstatus == 1) {
+				if (d.docstatus == 1) {
 					// Should not trigger any changes on change post submit
 					return;
 				}
diff --git a/erpnext/stock/doctype/material_request/material_request.js b/erpnext/stock/doctype/material_request/material_request.js
index bf3301f..9673a70 100644
--- a/erpnext/stock/doctype/material_request/material_request.js
+++ b/erpnext/stock/doctype/material_request/material_request.js
@@ -102,6 +102,12 @@
 
 		if (frm.doc.docstatus == 1 && frm.doc.status != 'Stopped') {
 			let precision = frappe.defaults.get_default("float_precision");
+
+			if (flt(frm.doc.per_received, precision) < 100) {
+				frm.add_custom_button(__('Stop'),
+					() => frm.events.update_status(frm, 'Stopped'));
+			}
+
 			if (flt(frm.doc.per_ordered, precision) < 100) {
 				let add_create_pick_list_button = () => {
 					frm.add_custom_button(__('Pick List'),
@@ -148,11 +154,6 @@
 				}
 
 				frm.page.set_inner_btn_group_as_primary(__('Create'));
-
-				// stop
-				frm.add_custom_button(__('Stop'),
-					() => frm.events.update_status(frm, 'Stopped'));
-
 			}
 		}
 
diff --git a/erpnext/translations/de.csv b/erpnext/translations/de.csv
index 79777f2..79b9574 100644
--- a/erpnext/translations/de.csv
+++ b/erpnext/translations/de.csv
@@ -4586,7 +4586,7 @@
 Tax Withholding Category,Steuereinbehalt Kategorie,
 Edit Posting Date and Time,Buchungsdatum und -uhrzeit bearbeiten,
 Is Paid,Ist bezahlt,
-Is Return (Debit Note),ist Rücklieferung (Lastschrift),
+Is Return (Debit Note),Ist Rechnungskorrektur (Retoure),
 Apply Tax Withholding Amount,Steuereinbehaltungsbetrag anwenden,
 Accounting Dimensions ,Buchhaltung Dimensionen,
 Supplier Invoice Details,Lieferant Rechnungsdetails,
@@ -4710,7 +4710,7 @@
 ACC-SINV-.YYYY.-,ACC-SINV-.JJJJ.-,
 Include Payment (POS),(POS) Zahlung einschließen,
 Offline POS Name,Offline-Verkaufsstellen-Name,
-Is Return (Credit Note),ist Rücklieferung (Gutschrift),
+Is Return (Credit Note),Ist Rechnungskorrektur (Retoure),
 Update Billed Amount in Sales Order,Aktualisierung des Rechnungsbetrags im Auftrag,
 Customer PO Details,Auftragsdetails,
 Customer's Purchase Order,Bestellung des Kunden,
@@ -6998,7 +6998,7 @@
 Tariff Number,Tarifnummer,
 Delivery To,Lieferung an,
 MAT-DN-.YYYY.-,MAT-DN-.YYYY.-,
-Is Return,Ist Rückgabe,
+Is Return,Ist Retoure,
 Issue Credit Note,Gutschrift ausgeben,
 Return Against Delivery Note,Zurück zum Lieferschein,
 Customer's Purchase Order No,Bestellnummer des Kunden,