Merge pull request #33091 from ssiyad/fix/pos/partial_return_amount

fix(pos): partial return amount update
diff --git a/erpnext/accounts/doctype/pos_invoice/pos_invoice.js b/erpnext/accounts/doctype/pos_invoice/pos_invoice.js
index fa11b7d..56b8579 100644
--- a/erpnext/accounts/doctype/pos_invoice/pos_invoice.js
+++ b/erpnext/accounts/doctype/pos_invoice/pos_invoice.js
@@ -14,16 +14,27 @@
 
 	company() {
 		erpnext.accounts.dimensions.update_dimension(this.frm, this.frm.doctype);
+		this.frm.set_value("set_warehouse", "");
+		this.frm.set_value("taxes_and_charges", "");
 	}
 
 	onload(doc) {
 		super.onload();
 		this.frm.ignore_doctypes_on_cancel_all = ['POS Invoice Merge Log', 'POS Closing Entry'];
+
 		if(doc.__islocal && doc.is_pos && frappe.get_route_str() !== 'point-of-sale') {
 			this.frm.script_manager.trigger("is_pos");
 			this.frm.refresh_fields();
 		}
 
+		this.frm.set_query("set_warehouse", function(doc) {
+			return {
+				filters: {
+					company: doc.company ? doc.company : '',
+				}
+			}
+		});
+
 		erpnext.accounts.dimensions.setup_dimension_filters(this.frm, this.frm.doctype);
 	}
 
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 5c1cb0d..1fa7e7f 100644
--- a/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json
+++ b/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json
@@ -40,7 +40,6 @@
   "discount_amount",
   "base_rate_with_margin",
   "sec_break2",
-  "apply_tds",
   "rate",
   "amount",
   "item_tax_template",
@@ -50,6 +49,7 @@
   "pricing_rules",
   "stock_uom_rate",
   "is_free_item",
+  "apply_tds",
   "section_break_22",
   "net_rate",
   "net_amount",
@@ -871,16 +871,16 @@
    "read_only": 1
   },
   {
-    "default": "1",
-    "fieldname": "apply_tds",
-    "fieldtype": "Check",
-    "label": "Apply TDS"
+   "default": "1",
+   "fieldname": "apply_tds",
+   "fieldtype": "Check",
+   "label": "Apply TDS"
   }
  ],
  "idx": 1,
  "istable": 1,
  "links": [],
- "modified": "2022-10-26 16:05:37.304788",
+ "modified": "2022-11-29 13:01:20.438217",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Purchase Invoice Item",
diff --git a/erpnext/accounts/report/tds_computation_summary/tds_computation_summary.py b/erpnext/accounts/report/tds_computation_summary/tds_computation_summary.py
index db3d5d4..c6aa21c 100644
--- a/erpnext/accounts/report/tds_computation_summary/tds_computation_summary.py
+++ b/erpnext/accounts/report/tds_computation_summary/tds_computation_summary.py
@@ -14,9 +14,17 @@
 	filters.naming_series = frappe.db.get_single_value("Buying Settings", "supp_master_name")
 
 	columns = get_columns(filters)
-	tds_docs, tds_accounts, tax_category_map, journal_entry_party_map = get_tds_docs(filters)
+	(
+		tds_docs,
+		tds_accounts,
+		tax_category_map,
+		journal_entry_party_map,
+		invoice_total_map,
+	) = get_tds_docs(filters)
 
-	res = get_result(filters, tds_docs, tds_accounts, tax_category_map, journal_entry_party_map)
+	res = get_result(
+		filters, tds_docs, tds_accounts, tax_category_map, journal_entry_party_map, invoice_total_map
+	)
 	final_result = group_by_supplier_and_category(res)
 
 	return columns, final_result
diff --git a/erpnext/accounts/report/tds_payable_monthly/tds_payable_monthly.py b/erpnext/accounts/report/tds_payable_monthly/tds_payable_monthly.py
index f2809a9..9883890 100644
--- a/erpnext/accounts/report/tds_payable_monthly/tds_payable_monthly.py
+++ b/erpnext/accounts/report/tds_payable_monthly/tds_payable_monthly.py
@@ -8,11 +8,19 @@
 
 def execute(filters=None):
 	validate_filters(filters)
-	tds_docs, tds_accounts, tax_category_map, journal_entry_party_map = get_tds_docs(filters)
+	(
+		tds_docs,
+		tds_accounts,
+		tax_category_map,
+		journal_entry_party_map,
+		invoice_net_total_map,
+	) = get_tds_docs(filters)
 
 	columns = get_columns(filters)
 
-	res = get_result(filters, tds_docs, tds_accounts, tax_category_map, journal_entry_party_map)
+	res = get_result(
+		filters, tds_docs, tds_accounts, tax_category_map, journal_entry_party_map, invoice_net_total_map
+	)
 	return columns, res
 
 
@@ -22,7 +30,9 @@
 		frappe.throw(_("From Date must be before To Date"))
 
 
-def get_result(filters, tds_docs, tds_accounts, tax_category_map, journal_entry_party_map):
+def get_result(
+	filters, tds_docs, tds_accounts, tax_category_map, journal_entry_party_map, invoice_net_total_map
+):
 	supplier_map = get_supplier_pan_map()
 	tax_rate_map = get_tax_rate_map(filters)
 	gle_map = get_gle_map(tds_docs)
@@ -50,7 +60,10 @@
 			if entry.account in tds_accounts:
 				tds_deducted += entry.credit - entry.debit
 
-			total_amount_credited += entry.credit
+			if invoice_net_total_map.get(name):
+				total_amount_credited = invoice_net_total_map.get(name)
+			else:
+				total_amount_credited += entry.credit
 
 		if tds_deducted:
 			row = {
@@ -179,9 +192,10 @@
 	purchase_invoices = []
 	payment_entries = []
 	journal_entries = []
-	tax_category_map = {}
-	or_filters = {}
-	journal_entry_party_map = {}
+	tax_category_map = frappe._dict()
+	invoice_net_total_map = frappe._dict()
+	or_filters = frappe._dict()
+	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(
@@ -218,16 +232,22 @@
 		tds_documents.append(d.voucher_no)
 
 	if purchase_invoices:
-		get_tax_category_map(purchase_invoices, "Purchase Invoice", tax_category_map)
+		get_doc_info(purchase_invoices, "Purchase Invoice", tax_category_map, invoice_net_total_map)
 
 	if payment_entries:
-		get_tax_category_map(payment_entries, "Payment Entry", tax_category_map)
+		get_doc_info(payment_entries, "Payment Entry", tax_category_map)
 
 	if journal_entries:
 		journal_entry_party_map = get_journal_entry_party_map(journal_entries)
-		get_tax_category_map(journal_entries, "Journal Entry", tax_category_map)
+		get_doc_info(journal_entries, "Journal Entry", tax_category_map)
 
-	return tds_documents, tds_accounts, tax_category_map, journal_entry_party_map
+	return (
+		tds_documents,
+		tds_accounts,
+		tax_category_map,
+		journal_entry_party_map,
+		invoice_net_total_map,
+	)
 
 
 def get_journal_entry_party_map(journal_entries):
@@ -244,17 +264,18 @@
 	return journal_entry_party_map
 
 
-def get_tax_category_map(vouchers, doctype, tax_category_map):
-	tax_category_map.update(
-		frappe._dict(
-			frappe.get_all(
-				doctype,
-				filters={"name": ("in", vouchers)},
-				fields=["name", "tax_withholding_category"],
-				as_list=1,
-			)
-		)
-	)
+def get_doc_info(vouchers, doctype, tax_category_map, invoice_net_total_map=None):
+	if doctype == "Purchase Invoice":
+		fields = ["name", "tax_withholding_category", "base_tax_withholding_net_total"]
+	else:
+		fields = ["name", "tax_withholding_category"]
+
+	entries = frappe.get_all(doctype, filters={"name": ("in", vouchers)}, fields=fields)
+
+	for entry in entries:
+		tax_category_map.update({entry.name: entry.tax_withholding_category})
+		if doctype == "Purchase Invoice":
+			invoice_net_total_map.update({entry.name: entry.base_tax_withholding_net_total})
 
 
 def get_tax_rate_map(filters):
diff --git a/erpnext/assets/doctype/asset/test_asset.py b/erpnext/assets/doctype/asset/test_asset.py
index 136a033..2bec273 100644
--- a/erpnext/assets/doctype/asset/test_asset.py
+++ b/erpnext/assets/doctype/asset/test_asset.py
@@ -12,6 +12,7 @@
 	get_first_day,
 	get_last_day,
 	getdate,
+	is_last_day_of_the_month,
 	nowdate,
 )
 
@@ -264,7 +265,7 @@
 			asset.gross_purchase_amount - asset.finance_books[0].value_after_depreciation,
 			asset.precision("gross_purchase_amount"),
 		)
-		this_month_depr_amount = 9000.0 if get_last_day(date) == date else 0
+		this_month_depr_amount = 9000.0 if is_last_day_of_the_month(date) else 0
 
 		self.assertEquals(accumulated_depr_amount, 18000.0 + this_month_depr_amount)
 
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 d471783..c645b04 100644
--- a/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json
+++ b/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json
@@ -44,7 +44,6 @@
   "discount_amount",
   "base_rate_with_margin",
   "sec_break2",
-  "apply_tds",
   "rate",
   "amount",
   "item_tax_template",
@@ -54,6 +53,7 @@
   "pricing_rules",
   "stock_uom_rate",
   "is_free_item",
+  "apply_tds",
   "section_break_29",
   "net_rate",
   "net_amount",
@@ -902,7 +902,7 @@
  "index_web_pages_for_search": 1,
  "istable": 1,
  "links": [],
- "modified": "2022-10-26 16:47:41.364387",
+ "modified": "2022-11-29 16:47:41.364387",
  "modified_by": "Administrator",
  "module": "Buying",
  "name": "Purchase Order Item",
diff --git a/erpnext/buying/doctype/request_for_quotation/request_for_quotation.js b/erpnext/buying/doctype/request_for_quotation/request_for_quotation.js
index 31a4837..98c7dc9 100644
--- a/erpnext/buying/doctype/request_for_quotation/request_for_quotation.js
+++ b/erpnext/buying/doctype/request_for_quotation/request_for_quotation.js
@@ -22,6 +22,13 @@
 				}
 			};
 		}
+
+		frm.set_query('warehouse', 'items', () => ({
+			filters: {
+				company: frm.doc.company,
+				is_group: 0
+			}
+		}));
 	},
 
 	onload: function(frm) {
diff --git a/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.js b/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.js
index d595a80..8aec532 100644
--- a/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.js
+++ b/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.js
@@ -34,6 +34,22 @@
 		frm.trigger('setup_realtime_progress');
 	},
 
+	based_on: function(frm) {
+		var fields_to_reset = [];
+
+		if (frm.doc.based_on == 'Transaction') {
+			fields_to_reset = ['item_code', 'warehouse'];
+		} else if (frm.doc.based_on == 'Item and Warehouse') {
+			fields_to_reset = ['voucher_type', 'voucher_no'];
+		}
+
+		if (fields_to_reset) {
+			fields_to_reset.forEach(field => {
+				frm.set_value(field, undefined);
+			});
+		}
+	},
+
 	setup_realtime_progress: function(frm) {
 		frappe.realtime.on('item_reposting_progress', data => {
 			if (frm.doc.name !== data.name) {
diff --git a/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.json b/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.json
index e093933..8a5309c 100644
--- a/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.json
+++ b/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.json
@@ -50,13 +50,15 @@
    "fieldname": "posting_date",
    "fieldtype": "Date",
    "label": "Posting Date",
+   "read_only_depends_on": "eval: doc.based_on == \"Transaction\"",
    "reqd": 1
   },
   {
    "fetch_from": "voucher_no.posting_time",
    "fieldname": "posting_time",
    "fieldtype": "Time",
-   "label": "Posting Time"
+   "label": "Posting Time",
+   "read_only_depends_on": "eval: doc.based_on == \"Transaction\""
   },
   {
    "default": "Queued",
@@ -195,7 +197,7 @@
  "index_web_pages_for_search": 1,
  "is_submittable": 1,
  "links": [],
- "modified": "2022-06-13 12:20:22.182322",
+ "modified": "2022-11-28 16:00:05.637440",
  "modified_by": "Administrator",
  "module": "Stock",
  "name": "Repost Item Valuation",
diff --git a/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py b/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py
index d6f9bae..8e914e6 100644
--- a/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py
+++ b/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py
@@ -5,7 +5,7 @@
 from frappe import _
 from frappe.exceptions import QueryDeadlockError, QueryTimeoutError
 from frappe.model.document import Document
-from frappe.utils import cint, get_link_to_form, get_weekday, now, nowtime
+from frappe.utils import cint, get_link_to_form, get_weekday, getdate, now, nowtime
 from frappe.utils.user import get_users_with_role
 from rq.timeouts import JobTimeoutException
 
@@ -25,6 +25,27 @@
 		self.set_status(write=False)
 		self.reset_field_values()
 		self.set_company()
+		self.validate_accounts_freeze()
+
+	def validate_accounts_freeze(self):
+		acc_settings = frappe.db.get_value(
+			"Accounts Settings",
+			"Accounts Settings",
+			["acc_frozen_upto", "frozen_accounts_modifier"],
+			as_dict=1,
+		)
+		if not acc_settings.acc_frozen_upto:
+			return
+		if getdate(self.posting_date) <= getdate(acc_settings.acc_frozen_upto):
+			if (
+				acc_settings.frozen_accounts_modifier
+				and frappe.session.user in get_users_with_role(acc_settings.frozen_accounts_modifier)
+			):
+				frappe.msgprint(_("Caution: This might alter frozen accounts."))
+				return
+			frappe.throw(
+				_("You cannot repost item valuation before {}").format(acc_settings.acc_frozen_upto)
+			)
 
 	def reset_field_values(self):
 		if self.based_on == "Transaction":
@@ -240,7 +261,7 @@
 def notify_error_to_stock_managers(doc, traceback):
 	recipients = get_users_with_role("Stock Manager")
 	if not recipients:
-		get_users_with_role("System Manager")
+		recipients = get_users_with_role("System Manager")
 
 	subject = _("Error while reposting item valuation")
 	message = (
diff --git a/erpnext/stock/doctype/repost_item_valuation/test_repost_item_valuation.py b/erpnext/stock/doctype/repost_item_valuation/test_repost_item_valuation.py
index e0f2479..f166775 100644
--- a/erpnext/stock/doctype/repost_item_valuation/test_repost_item_valuation.py
+++ b/erpnext/stock/doctype/repost_item_valuation/test_repost_item_valuation.py
@@ -327,3 +327,26 @@
 		# outstanding should not be affected
 		sinv.reload()
 		self.assertEqual(sinv.outstanding_amount, 100)
+
+	def test_account_freeze_validation(self):
+		today = nowdate()
+
+		riv = frappe.get_doc(
+			doctype="Repost Item Valuation",
+			item_code="_Test Item",
+			warehouse="_Test Warehouse - _TC",
+			based_on="Item and Warehouse",
+			posting_date=today,
+			posting_time="00:01:00",
+		)
+		riv.flags.dont_run_in_test = True  # keep it queued
+
+		accounts_settings = frappe.get_doc("Accounts Settings")
+		accounts_settings.acc_frozen_upto = today
+		accounts_settings.frozen_accounts_modifier = ""
+		accounts_settings.save()
+
+		self.assertRaises(frappe.ValidationError, riv.save)
+
+		accounts_settings.acc_frozen_upto = ""
+		accounts_settings.save()
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.js b/erpnext/stock/doctype/stock_entry/stock_entry.js
index 266ea5f..b910244 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.js
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.js
@@ -1079,7 +1079,8 @@
 	if (frm.doc.purpose === 'Material Receipt') return;
 
 	frappe.require("assets/erpnext/js/utils/serial_no_batch_selector.js", function() {
-		new erpnext.SerialNoBatchSelector({
+		if (frm.batch_selector?.dialog?.display) return;
+		frm.batch_selector = new erpnext.SerialNoBatchSelector({
 			frm: frm,
 			item: item,
 			warehouse_details: get_warehouse_type_and_name(item),