Merge pull request #32009 from ruthra-kumar/add_remarks_to_payment_ledger

refactor: readd remarks field to payment ledger
diff --git a/CODEOWNERS b/CODEOWNERS
index b6aadb3..e406f8f 100644
--- a/CODEOWNERS
+++ b/CODEOWNERS
@@ -14,8 +14,8 @@
 erpnext/buying/                 @rohitwaghchaure @s-aga-r
 erpnext/maintenance/            @rohitwaghchaure @s-aga-r
 erpnext/manufacturing/          @rohitwaghchaure @s-aga-r
-erpnext/quality_management/     @marination @rohitwaghchaure @s-aga-r
-erpnext/stock/                  @marination @rohitwaghchaure @s-aga-r
+erpnext/quality_management/     @rohitwaghchaure @s-aga-r
+erpnext/stock/                  @rohitwaghchaure @s-aga-r
 
 erpnext/crm/                    @NagariaHussain
 erpnext/education/              @rutwikhdev
diff --git a/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json b/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json
index b417c7d..7cddf12 100644
--- a/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json
+++ b/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json
@@ -282,7 +282,6 @@
    "label": "Discount (%) on Price List Rate with Margin",
    "oldfieldname": "adj_rate",
    "oldfieldtype": "Float",
-   "precision": "2",
    "print_hide": 1
   },
   {
@@ -846,7 +845,7 @@
  "idx": 1,
  "istable": 1,
  "links": [],
- "modified": "2022-06-17 05:33:15.335912",
+ "modified": "2022-08-26 12:06:31.205417",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Sales Invoice Item",
diff --git a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py
index 90a431d..3f504b1 100755
--- a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py
+++ b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py
@@ -733,6 +733,7 @@
 	def prepare_conditions(self):
 		self.qb_selection_filter = []
 		party_type_field = scrub(self.party_type)
+		self.qb_selection_filter.append(self.ple.party_type == self.party_type)
 
 		self.add_common_filters(party_type_field=party_type_field)
 
diff --git a/erpnext/controllers/taxes_and_totals.py b/erpnext/controllers/taxes_and_totals.py
index bc38d08..9dbcdb0 100644
--- a/erpnext/controllers/taxes_and_totals.py
+++ b/erpnext/controllers/taxes_and_totals.py
@@ -41,6 +41,7 @@
 		if self.doc.apply_discount_on == "Grand Total" and self.doc.get("is_cash_or_non_trade_discount"):
 			self.doc.grand_total -= self.doc.discount_amount
 			self.doc.base_grand_total -= self.doc.base_discount_amount
+			self.set_rounded_total()
 
 		self.calculate_shipping_charges()
 
diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py
index 8c03cb5..09a9652 100755
--- a/erpnext/selling/doctype/sales_order/sales_order.py
+++ b/erpnext/selling/doctype/sales_order/sales_order.py
@@ -892,6 +892,7 @@
 		target.additional_discount_percentage = 0.0
 		target.discount_amount = 0.0
 		target.inter_company_order_reference = ""
+		target.shipping_rule = ""
 
 		default_price_list = frappe.get_value("Supplier", supplier, "default_price_list")
 		if default_price_list:
@@ -1010,6 +1011,7 @@
 		target.additional_discount_percentage = 0.0
 		target.discount_amount = 0.0
 		target.inter_company_order_reference = ""
+		target.shipping_rule = ""
 		target.customer = ""
 		target.customer_name = ""
 		target.run_method("set_missing_values")
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py
index c68d1db..d709522 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.py
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.py
@@ -2229,7 +2229,7 @@
 		return sorted(list(set(get_serial_nos(self.pro_doc.serial_no)) - set(used_serial_nos)))
 
 	def update_subcontracting_order_status(self):
-		if self.subcontracting_order and self.purpose == "Send to Subcontractor":
+		if self.subcontracting_order and self.purpose in ["Send to Subcontractor", "Material Transfer"]:
 			from erpnext.subcontracting.doctype.subcontracting_order.subcontracting_order import (
 				update_subcontracting_order_status,
 			)
@@ -2568,27 +2568,26 @@
 
 @frappe.whitelist()
 def get_items_from_subcontracting_order(source_name, target_doc=None):
-	sco = frappe.get_doc("Subcontracting Order", source_name)
+	def post_process(source, target):
+		target.stock_entry_type = target.purpose = "Send to Subcontractor"
+		target.subcontracting_order = source_name
 
-	if sco.docstatus == 1:
-		if target_doc and isinstance(target_doc, str):
-			target_doc = frappe.get_doc(json.loads(target_doc))
-
-		if target_doc.items:
-			target_doc.items = []
+		if target.items:
+			target.items = []
 
 		warehouses = {}
-		for item in sco.items:
+		for item in source.items:
 			warehouses[item.name] = item.warehouse
 
-		for item in sco.supplied_items:
-			target_doc.append(
+		for item in source.supplied_items:
+			target.append(
 				"items",
 				{
 					"s_warehouse": warehouses.get(item.reference_name),
-					"t_warehouse": sco.supplier_warehouse,
+					"t_warehouse": source.supplier_warehouse,
+					"subcontracted_item": item.main_item_code,
 					"item_code": item.rm_item_code,
-					"qty": item.required_qty,
+					"qty": max(item.required_qty - item.total_supplied_qty, 0),
 					"transfer_qty": item.required_qty,
 					"uom": item.stock_uom,
 					"stock_uom": item.stock_uom,
@@ -2596,6 +2595,23 @@
 				},
 			)
 
+	target_doc = get_mapped_doc(
+		"Subcontracting Order",
+		source_name,
+		{
+			"Subcontracting Order": {
+				"doctype": "Stock Entry",
+				"field_no_map": ["purchase_order"],
+				"validation": {
+					"docstatus": ["=", 1],
+				},
+			},
+		},
+		target_doc,
+		post_process,
+		ignore_child_tables=True,
+	)
+
 	return target_doc
 
 
diff --git a/erpnext/subcontracting/doctype/subcontracting_order/subcontracting_order.js b/erpnext/subcontracting/doctype/subcontracting_order/subcontracting_order.js
index c20f8ab..065ef39 100644
--- a/erpnext/subcontracting/doctype/subcontracting_order/subcontracting_order.js
+++ b/erpnext/subcontracting/doctype/subcontracting_order/subcontracting_order.js
@@ -107,9 +107,9 @@
 	get_materials_from_supplier: function (frm) {
 		let sco_rm_details = [];
 
-		if (frm.doc.supplied_items && (frm.doc.per_received == 100)) {
+		if (frm.doc.supplied_items && frm.doc.per_received > 0) {
 			frm.doc.supplied_items.forEach(d => {
-				if (d.total_supplied_qty && d.total_supplied_qty != d.consumed_qty) {
+				if (d.total_supplied_qty > 0 && d.total_supplied_qty != d.consumed_qty) {
 					sco_rm_details.push(d.name);
 				}
 			});
@@ -160,14 +160,11 @@
 		var me = this;
 
 		if (doc.docstatus == 1) {
-			if (doc.status != 'Completed') {
+			if (!['Closed', 'Completed'].includes(doc.status)) {
 				if (flt(doc.per_received) < 100) {
 					cur_frm.add_custom_button(__('Subcontracting Receipt'), this.make_subcontracting_receipt, __('Create'));
 					if (me.has_unsupplied_items()) {
-						cur_frm.add_custom_button(__('Material to Supplier'),
-							() => {
-								me.make_stock_entry();
-							}, __('Transfer'));
+						cur_frm.add_custom_button(__('Material to Supplier'), this.make_stock_entry, __('Transfer'));
 					}
 				}
 				cur_frm.page.set_inner_btn_group_as_primary(__('Create'));
@@ -195,120 +192,6 @@
 		transaction_controller.autofill_warehouse(child_table, warehouse_field, warehouse);
 	}
 
-	make_stock_entry() {
-		var items = $.map(cur_frm.doc.items, (d) => d.bom ? d.item_code : false);
-		var me = this;
-
-		if (items.length >= 1) {
-			me.raw_material_data = [];
-			me.show_dialog = 1;
-			let title = __('Transfer Material to Supplier');
-			let fields = [
-				{ fieldtype: 'Section Break', label: __('Raw Materials') },
-				{
-					fieldname: 'sub_con_rm_items', fieldtype: 'Table', label: __('Items'),
-					fields: [
-						{
-							fieldtype: 'Data',
-							fieldname: 'item_code',
-							label: __('Item'),
-							read_only: 1,
-							in_list_view: 1
-						},
-						{
-							fieldtype: 'Data',
-							fieldname: 'rm_item_code',
-							label: __('Raw Material'),
-							read_only: 1,
-							in_list_view: 1
-						},
-						{
-							fieldtype: 'Float',
-							read_only: 1,
-							fieldname: 'qty',
-							label: __('Quantity'),
-							in_list_view: 1
-						},
-						{
-							fieldtype: 'Data',
-							read_only: 1,
-							fieldname: 'warehouse',
-							label: __('Reserve Warehouse'),
-							in_list_view: 1
-						},
-						{
-							fieldtype: 'Float',
-							read_only: 1,
-							fieldname: 'rate',
-							label: __('Rate'),
-							hidden: 1
-						},
-						{
-							fieldtype: 'Float',
-							read_only: 1,
-							fieldname: 'amount',
-							label: __('Amount'),
-							hidden: 1
-						},
-						{
-							fieldtype: 'Link',
-							read_only: 1,
-							fieldname: 'uom',
-							label: __('UOM'),
-							hidden: 1
-						}
-					],
-					data: me.raw_material_data,
-					get_data: () => me.raw_material_data
-				}
-			];
-
-			me.dialog = new frappe.ui.Dialog({
-				title: title, fields: fields
-			});
-
-			if (me.frm.doc['supplied_items']) {
-				me.frm.doc['supplied_items'].forEach((item) => {
-					if (item.rm_item_code && item.main_item_code && item.required_qty - item.supplied_qty != 0) {
-						me.raw_material_data.push({
-							'name': item.name,
-							'item_code': item.main_item_code,
-							'rm_item_code': item.rm_item_code,
-							'item_name': item.rm_item_code,
-							'qty': item.required_qty - item.supplied_qty,
-							'warehouse': item.reserve_warehouse,
-							'rate': item.rate,
-							'amount': item.amount,
-							'stock_uom': item.stock_uom
-						});
-						me.dialog.fields_dict.sub_con_rm_items.grid.refresh();
-					}
-				});
-			}
-
-			me.dialog.get_field('sub_con_rm_items').check_all_rows();
-
-			me.dialog.show();
-			this.dialog.set_primary_action(__('Transfer'), () => {
-				me.values = me.dialog.get_values();
-				if (me.values) {
-					me.values.sub_con_rm_items.map((row, i) => {
-						if (!row.item_code || !row.rm_item_code || !row.warehouse || !row.qty || row.qty === 0) {
-							let row_id = i + 1;
-							frappe.throw(__('Item Code, warehouse and quantity are required on row {0}', [row_id]));
-						}
-					});
-					me.make_rm_stock_entry(me.dialog.fields_dict.sub_con_rm_items.grid.get_selected_children());
-					me.dialog.hide();
-				}
-			});
-		}
-
-		me.dialog.get_close_btn().on('click', () => {
-			me.dialog.hide();
-		});
-	}
-
 	has_unsupplied_items() {
 		return this.frm.doc['supplied_items'].some(item => item.required_qty > item.supplied_qty);
 	}
@@ -321,6 +204,15 @@
 		});
 	}
 
+	make_stock_entry() {
+		frappe.model.open_mapped_doc({
+			method: 'erpnext.stock.doctype.stock_entry.stock_entry.get_items_from_subcontracting_order',
+			source_name: cur_frm.doc.name,
+			freeze: true,
+			freeze_message: __('Creating Stock Entry ...')
+		});
+	}
+
 	make_rm_stock_entry(rm_items) {
 		frappe.call({
 			method: 'erpnext.controllers.subcontracting_controller.make_rm_stock_entry',
diff --git a/erpnext/subcontracting/doctype/subcontracting_order/subcontracting_order.py b/erpnext/subcontracting/doctype/subcontracting_order/subcontracting_order.py
index 156f027..e6de72d 100644
--- a/erpnext/subcontracting/doctype/subcontracting_order/subcontracting_order.py
+++ b/erpnext/subcontracting/doctype/subcontracting_order/subcontracting_order.py
@@ -153,7 +153,7 @@
 			else:
 				self.set_missing_values()
 
-	def update_status(self, status=None, update_modified=False):
+	def update_status(self, status=None, update_modified=True):
 		if self.docstatus >= 1 and not status:
 			if self.docstatus == 1:
 				if self.status == "Draft":
@@ -162,6 +162,10 @@
 					status = "Completed"
 				elif self.per_received > 0 and self.per_received < 100:
 					status = "Partially Received"
+					for item in self.supplied_items:
+						if item.returned_qty:
+							status = "Closed"
+							break
 				else:
 					total_required_qty = total_supplied_qty = 0
 					for item in self.supplied_items:
@@ -176,7 +180,10 @@
 			elif self.docstatus == 2:
 				status = "Cancelled"
 
-			frappe.db.set_value("Subcontracting Order", self.name, "status", status, update_modified)
+		if status:
+			frappe.db.set_value(
+				"Subcontracting Order", self.name, "status", status, update_modified=update_modified
+			)
 
 
 @frappe.whitelist()
diff --git a/erpnext/subcontracting/doctype/subcontracting_order/subcontracting_order_list.js b/erpnext/subcontracting/doctype/subcontracting_order/subcontracting_order_list.js
index 650419c..aab2fc9 100644
--- a/erpnext/subcontracting/doctype/subcontracting_order/subcontracting_order_list.js
+++ b/erpnext/subcontracting/doctype/subcontracting_order/subcontracting_order_list.js
@@ -10,6 +10,7 @@
 			"Completed": "green",
 			"Partial Material Transferred": "purple",
 			"Material Transferred": "blue",
+			"Closed": "red",
 		};
 		return [__(doc.status), status_colors[doc.status], "status,=," + doc.status];
 	},
diff --git a/erpnext/subcontracting/doctype/subcontracting_order/test_subcontracting_order.py b/erpnext/subcontracting/doctype/subcontracting_order/test_subcontracting_order.py
index 94bb38e..098242a 100644
--- a/erpnext/subcontracting/doctype/subcontracting_order/test_subcontracting_order.py
+++ b/erpnext/subcontracting/doctype/subcontracting_order/test_subcontracting_order.py
@@ -7,7 +7,10 @@
 from frappe.tests.utils import FrappeTestCase
 
 from erpnext.buying.doctype.purchase_order.purchase_order import get_mapped_subcontracting_order
-from erpnext.controllers.subcontracting_controller import make_rm_stock_entry
+from erpnext.controllers.subcontracting_controller import (
+	get_materials_from_supplier,
+	make_rm_stock_entry,
+)
 from erpnext.controllers.tests.test_subcontracting_controller import (
 	get_rm_items,
 	get_subcontracting_order,
@@ -89,6 +92,16 @@
 		sco.load_from_db()
 		self.assertEqual(sco.status, "Partially Received")
 
+		# Closed
+		ste = get_materials_from_supplier(sco.name, [d.name for d in sco.supplied_items])
+		ste.save()
+		ste.submit()
+		sco.load_from_db()
+		self.assertEqual(sco.status, "Closed")
+		ste.cancel()
+		sco.load_from_db()
+		self.assertEqual(sco.status, "Partially Received")
+
 		# Completed
 		scr = make_subcontracting_receipt(sco.name)
 		scr.save()
diff --git a/erpnext/subcontracting/doctype/subcontracting_order_supplied_item/subcontracting_order_supplied_item.json b/erpnext/subcontracting/doctype/subcontracting_order_supplied_item/subcontracting_order_supplied_item.json
index a206a21..8f7128b 100644
--- a/erpnext/subcontracting/doctype/subcontracting_order_supplied_item/subcontracting_order_supplied_item.json
+++ b/erpnext/subcontracting/doctype/subcontracting_order_supplied_item/subcontracting_order_supplied_item.json
@@ -150,8 +150,7 @@
             "label": "Returned Qty",
             "no_copy": 1,
             "print_hide": 1,
-            "read_only": 1,
-            "hidden": 1
+            "read_only": 1
         },
         {
             "fieldname": "total_supplied_qty",
@@ -166,7 +165,7 @@
     "hide_toolbar": 1,
     "istable": 1,
     "links": [],
-    "modified": "2022-04-07 12:58:28.208847",
+    "modified": "2022-08-26 16:04:56.125951",
     "modified_by": "Administrator",
     "module": "Subcontracting",
     "name": "Subcontracting Order Supplied Item",
diff --git a/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.json b/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.json
index 84e9554..5cd4e63 100644
--- a/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.json
+++ b/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.json
@@ -369,7 +369,7 @@
             "in_standard_filter": 1,
             "label": "Status",
             "no_copy": 1,
-            "options": "\nDraft\nCompleted\nReturn\nReturn Issued\nCancelled",
+            "options": "\nDraft\nCompleted\nReturn\nReturn Issued\nCancelled\nClosed",
             "print_hide": 1,
             "print_width": "150px",
             "read_only": 1,
@@ -628,7 +628,7 @@
     "in_create": 1,
     "is_submittable": 1,
     "links": [],
-    "modified": "2022-08-22 17:30:40.827517",
+    "modified": "2022-08-26 21:02:26.353870",
     "modified_by": "Administrator",
     "module": "Subcontracting",
     "name": "Subcontracting Receipt",