Merge pull request #39488 from rohitwaghchaure/fixed-validate-stock-uom-integer-value

fix: UOM needs to be whole number not being checked in quotations
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/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/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/public/js/utils/sales_common.js b/erpnext/public/js/utils/sales_common.js
index b92b02e..b8ec77f 100644
--- a/erpnext/public/js/utils/sales_common.js
+++ b/erpnext/public/js/utils/sales_common.js
@@ -22,6 +22,15 @@
 						}
 					};
 				});
+
+				this.frm.set_query('project', function(doc) {
+					return {
+						query: "erpnext.controllers.queries.get_project_name",
+						filters: {
+							'customer': doc.customer
+						}
+					}
+				});
 			}
 
 			setup_queries() {
@@ -439,4 +448,4 @@
 			}
 		});
 	}
-}
\ No newline at end of file
+}
diff --git a/erpnext/selling/doctype/sales_order/sales_order.js b/erpnext/selling/doctype/sales_order/sales_order.js
index 56c745c..2bb093d 100644
--- a/erpnext/selling/doctype/sales_order/sales_order.js
+++ b/erpnext/selling/doctype/sales_order/sales_order.js
@@ -144,15 +144,6 @@
 			};
 		});
 
-		frm.set_query('project', function(doc, cdt, cdn) {
-			return {
-				query: "erpnext.controllers.queries.get_project_name",
-				filters: {
-					'customer': doc.customer
-				}
-			}
-		});
-
 		frm.set_query('warehouse', 'items', function(doc, cdt, cdn) {
 			let row  = locals[cdt][cdn];
 			let query = {
diff --git a/erpnext/setup/doctype/company/company.js b/erpnext/setup/doctype/company/company.js
index 1bd469b..340a917 100644
--- a/erpnext/setup/doctype/company/company.js
+++ b/erpnext/setup/doctype/company/company.js
@@ -140,38 +140,48 @@
 	},
 
 	delete_company_transactions: function(frm) {
-		frappe.verify_password(function() {
-			var d = frappe.prompt({
-				fieldtype:"Data",
-				fieldname: "company_name",
-				label: __("Please enter the company name to confirm"),
-				reqd: 1,
-				description: __("Please make sure you really want to delete all the transactions for this company. Your master data will remain as it is. This action cannot be undone.")
+		frappe.call({
+			method: "erpnext.setup.doctype.company.company.is_deletion_job_running",
+			args: {
+				company: frm.doc.name
 			},
-			function(data) {
-				if(data.company_name !== frm.doc.name) {
-					frappe.msgprint(__("Company name not same"));
-					return;
+			freeze: true,
+			callback: function(r) {
+				if(!r.exc) {
+					frappe.verify_password(function() {
+						var d = frappe.prompt({
+							fieldtype:"Data",
+							fieldname: "company_name",
+							label: __("Please enter the company name to confirm"),
+							reqd: 1,
+							description: __("Please make sure you really want to delete all the transactions for this company. Your master data will remain as it is. This action cannot be undone.")
+						},
+								      function(data) {
+									      if(data.company_name !== frm.doc.name) {
+										      frappe.msgprint(__("Company name not same"));
+										      return;
+									      }
+									      frappe.call({
+										      method: "erpnext.setup.doctype.company.company.create_transaction_deletion_request",
+										      args: {
+											      company: data.company_name
+										      },
+										      freeze: true,
+										      callback: function(r, rt) { },
+										      onerror: function() {
+											      frappe.msgprint(__("Wrong Password"));
+										      }
+									      });
+								      },
+								      __("Delete all the Transactions for this Company"), __("Delete")
+								     );
+						d.get_primary_btn().addClass("btn-danger");
+					});
 				}
-				frappe.call({
-					method: "erpnext.setup.doctype.company.company.create_transaction_deletion_request",
-					args: {
-						company: data.company_name
-					},
-					freeze: true,
-					callback: function(r, rt) {
-						if(!r.exc)
-							frappe.msgprint(__("Successfully deleted all transactions related to this company!"));
-					},
-					onerror: function() {
-						frappe.msgprint(__("Wrong Password"));
-					}
-				});
+
 			},
-			__("Delete all the Transactions for this Company"), __("Delete")
-			);
-			d.get_primary_btn().addClass("btn-danger");
 		});
+
 	}
 });
 
diff --git a/erpnext/setup/doctype/company/company.py b/erpnext/setup/doctype/company/company.py
index ec953b8..68a3854 100644
--- a/erpnext/setup/doctype/company/company.py
+++ b/erpnext/setup/doctype/company/company.py
@@ -11,7 +11,8 @@
 from frappe.contacts.address_and_contact import load_address_and_contact
 from frappe.custom.doctype.property_setter.property_setter import make_property_setter
 from frappe.desk.page.setup_wizard.setup_wizard import make_records
-from frappe.utils import cint, formatdate, get_timestamp, today
+from frappe.utils import cint, formatdate, get_link_to_form, get_timestamp, today
+from frappe.utils.background_jobs import get_job, is_job_enqueued
 from frappe.utils.nestedset import NestedSet, rebuild_tree
 
 from erpnext.accounts.doctype.account.account import get_account_currency
@@ -900,8 +901,37 @@
 		return None
 
 
+def generate_id_for_deletion_job(company):
+	return "delete_company_transactions_" + company
+
+
+@frappe.whitelist()
+def is_deletion_job_running(company):
+	job_id = generate_id_for_deletion_job(company)
+	job_name = get_job(job_id).get_id()  # job name will have site prefix
+	if is_job_enqueued(job_id):
+		frappe.throw(
+			_("A Transaction Deletion Job: {0} is already running for {1}").format(
+				frappe.bold(get_link_to_form("RQ Job", job_name)), frappe.bold(company)
+			)
+		)
+
+
 @frappe.whitelist()
 def create_transaction_deletion_request(company):
+	is_deletion_job_running(company)
+	job_id = generate_id_for_deletion_job(company)
+
 	tdr = frappe.get_doc({"doctype": "Transaction Deletion Record", "company": company})
 	tdr.insert()
-	tdr.submit()
+
+	frappe.enqueue(
+		"frappe.utils.background_jobs.run_doc_method",
+		doctype=tdr.doctype,
+		name=tdr.name,
+		doc_method="submit",
+		job_id=job_id,
+		queue="long",
+		enqueue_after_commit=True,
+	)
+	frappe.msgprint(_("A Transaction Deletion Job is triggered for {0}").format(frappe.bold(company)))
diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.js b/erpnext/stock/doctype/delivery_note/delivery_note.js
index ec68549..14aedca 100644
--- a/erpnext/stock/doctype/delivery_note/delivery_note.js
+++ b/erpnext/stock/doctype/delivery_note/delivery_note.js
@@ -31,15 +31,6 @@
 		});
 		erpnext.queries.setup_warehouse_query(frm);
 
-		frm.set_query('project', function(doc) {
-			return {
-				query: "erpnext.controllers.queries.get_project_name",
-				filters: {
-					'customer': doc.customer
-				}
-			}
-		})
-
 		frm.set_query('transporter', function() {
 			return {
 				filters: {