style: format code with black
diff --git a/erpnext/manufacturing/dashboard_fixtures.py b/erpnext/manufacturing/dashboard_fixtures.py
index 1bc12ff..9e64f4d 100644
--- a/erpnext/manufacturing/dashboard_fixtures.py
+++ b/erpnext/manufacturing/dashboard_fixtures.py
@@ -11,33 +11,39 @@
 
 
 def get_data():
-	return frappe._dict({
-		"dashboards": get_dashboards(),
-		"charts": get_charts(),
-		"number_cards": get_number_cards(),
-	})
+	return frappe._dict(
+		{
+			"dashboards": get_dashboards(),
+			"charts": get_charts(),
+			"number_cards": get_number_cards(),
+		}
+	)
+
 
 def get_dashboards():
-	return [{
-		"name": "Manufacturing",
-		"dashboard_name": "Manufacturing",
-		"charts": [
-			{ "chart": "Produced Quantity", "width": "Half" },
-			{ "chart": "Completed Operation", "width": "Half" },
-			{ "chart": "Work Order Analysis", "width": "Half" },
-			{ "chart": "Quality Inspection Analysis", "width": "Half" },
-			{ "chart": "Pending Work Order", "width": "Half" },
-			{ "chart": "Last Month Downtime Analysis", "width": "Half" },
-			{ "chart": "Work Order Qty Analysis", "width": "Full" },
-			{ "chart": "Job Card Analysis", "width": "Full" }
-		],
-		"cards": [
-			{ "card": "Monthly Total Work Order" },
-			{ "card": "Monthly Completed Work Order" },
-			{ "card": "Ongoing Job Card" },
-			{ "card": "Monthly Quality Inspection"}
-		]
-	}]
+	return [
+		{
+			"name": "Manufacturing",
+			"dashboard_name": "Manufacturing",
+			"charts": [
+				{"chart": "Produced Quantity", "width": "Half"},
+				{"chart": "Completed Operation", "width": "Half"},
+				{"chart": "Work Order Analysis", "width": "Half"},
+				{"chart": "Quality Inspection Analysis", "width": "Half"},
+				{"chart": "Pending Work Order", "width": "Half"},
+				{"chart": "Last Month Downtime Analysis", "width": "Half"},
+				{"chart": "Work Order Qty Analysis", "width": "Full"},
+				{"chart": "Job Card Analysis", "width": "Full"},
+			],
+			"cards": [
+				{"card": "Monthly Total Work Order"},
+				{"card": "Monthly Completed Work Order"},
+				{"card": "Ongoing Job Card"},
+				{"card": "Monthly Quality Inspection"},
+			],
+		}
+	]
+
 
 def get_charts():
 	company = erpnext.get_default_company()
@@ -45,200 +51,198 @@
 	if not company:
 		company = frappe.db.get_value("Company", {"is_group": 0}, "name")
 
-	return [{
-		"doctype": "Dashboard Chart",
-		"based_on": "modified",
-		"chart_type": "Sum",
-		"chart_name": _("Produced Quantity"),
-		"name": "Produced Quantity",
-		"document_type": "Work Order",
-		"filters_json": json.dumps([['Work Order', 'docstatus', '=', 1, False]]),
-		"group_by_type": "Count",
-		"time_interval": "Monthly",
-		"timespan": "Last Year",
-		"owner": "Administrator",
-		"type": "Line",
-		"value_based_on": "produced_qty",
-		"is_public": 1,
-		"timeseries": 1
-	}, {
-		"doctype": "Dashboard Chart",
-		"based_on": "creation",
-		"chart_type": "Sum",
-		"chart_name": _("Completed Operation"),
-		"name": "Completed Operation",
-		"document_type": "Work Order Operation",
-		"filters_json": json.dumps([['Work Order Operation', 'docstatus', '=', 1, False]]),
-		"group_by_type": "Count",
-		"time_interval": "Quarterly",
-		"timespan": "Last Year",
-		"owner": "Administrator",
-		"type": "Line",
-		"value_based_on": "completed_qty",
-		"is_public": 1,
-		"timeseries": 1
-	}, {
-		"doctype": "Dashboard Chart",
-		"time_interval": "Yearly",
-		"chart_type": "Report",
-		"chart_name": _("Work Order Analysis"),
-		"name": "Work Order Analysis",
-		"timespan": "Last Year",
-		"report_name": "Work Order Summary",
-		"owner": "Administrator",
-		"filters_json": json.dumps({"company": company, "charts_based_on": "Status"}),
-		"type": "Donut",
-		"is_public": 1,
-		"is_custom": 1,
-		"custom_options": json.dumps({
-			"axisOptions": {
-				"shortenYAxisNumbers": 1
-			},
-			"height": 300
-		}),
-	}, {
-		"doctype": "Dashboard Chart",
-		"time_interval": "Yearly",
-		"chart_type": "Report",
-		"chart_name": _("Quality Inspection Analysis"),
-		"name": "Quality Inspection Analysis",
-		"timespan": "Last Year",
-		"report_name": "Quality Inspection Summary",
-		"owner": "Administrator",
-		"filters_json": json.dumps({}),
-		"type": "Donut",
-		"is_public": 1,
-		"is_custom": 1,
-		"custom_options": json.dumps({
-			"axisOptions": {
-				"shortenYAxisNumbers": 1
-			},
-			"height": 300
-		}),
-	}, {
-		"doctype": "Dashboard Chart",
-		"time_interval": "Yearly",
-		"chart_type": "Report",
-		"chart_name": _("Pending Work Order"),
-		"name": "Pending Work Order",
-		"timespan": "Last Year",
-		"report_name": "Work Order Summary",
-		"filters_json": json.dumps({"company": company, "charts_based_on": "Age"}),
-		"owner": "Administrator",
-		"type": "Donut",
-		"is_public": 1,
-		"is_custom": 1,
-		"custom_options": json.dumps({
-			"axisOptions": {
-				"shortenYAxisNumbers": 1
-			},
-			"height": 300
-		}),
-	}, {
-		"doctype": "Dashboard Chart",
-		"time_interval": "Yearly",
-		"chart_type": "Report",
-		"chart_name": _("Last Month Downtime Analysis"),
-		"name": "Last Month Downtime Analysis",
-		"timespan": "Last Year",
-		"filters_json": json.dumps({}),
-		"report_name": "Downtime Analysis",
-		"owner": "Administrator",
-		"is_public": 1,
-		"is_custom": 1,
-		"type": "Bar"
-	}, {
-		"doctype": "Dashboard Chart",
-		"time_interval": "Yearly",
-		"chart_type": "Report",
-		"chart_name": _("Work Order Qty Analysis"),
-		"name": "Work Order Qty Analysis",
-		"timespan": "Last Year",
-		"report_name": "Work Order Summary",
-		"filters_json": json.dumps({"company": company, "charts_based_on": "Quantity"}),
-		"owner": "Administrator",
-		"type": "Bar",
-		"is_public": 1,
-		"is_custom": 1,
-		"custom_options": json.dumps({
-			"barOptions": { "stacked": 1 }
-		}),
-	}, {
-		"doctype": "Dashboard Chart",
-		"time_interval": "Yearly",
-		"chart_type": "Report",
-		"chart_name": _("Job Card Analysis"),
-		"name": "Job Card Analysis",
-		"timespan": "Last Year",
-		"report_name": "Job Card Summary",
-		"owner": "Administrator",
-		"is_public": 1,
-		"is_custom": 1,
-		"filters_json": json.dumps({"company": company, "docstatus": 1, "range":"Monthly"}),
-		"custom_options": json.dumps({
-			"barOptions": { "stacked": 1 }
-		}),
-		"type": "Bar"
-	}]
+	return [
+		{
+			"doctype": "Dashboard Chart",
+			"based_on": "modified",
+			"chart_type": "Sum",
+			"chart_name": _("Produced Quantity"),
+			"name": "Produced Quantity",
+			"document_type": "Work Order",
+			"filters_json": json.dumps([["Work Order", "docstatus", "=", 1, False]]),
+			"group_by_type": "Count",
+			"time_interval": "Monthly",
+			"timespan": "Last Year",
+			"owner": "Administrator",
+			"type": "Line",
+			"value_based_on": "produced_qty",
+			"is_public": 1,
+			"timeseries": 1,
+		},
+		{
+			"doctype": "Dashboard Chart",
+			"based_on": "creation",
+			"chart_type": "Sum",
+			"chart_name": _("Completed Operation"),
+			"name": "Completed Operation",
+			"document_type": "Work Order Operation",
+			"filters_json": json.dumps([["Work Order Operation", "docstatus", "=", 1, False]]),
+			"group_by_type": "Count",
+			"time_interval": "Quarterly",
+			"timespan": "Last Year",
+			"owner": "Administrator",
+			"type": "Line",
+			"value_based_on": "completed_qty",
+			"is_public": 1,
+			"timeseries": 1,
+		},
+		{
+			"doctype": "Dashboard Chart",
+			"time_interval": "Yearly",
+			"chart_type": "Report",
+			"chart_name": _("Work Order Analysis"),
+			"name": "Work Order Analysis",
+			"timespan": "Last Year",
+			"report_name": "Work Order Summary",
+			"owner": "Administrator",
+			"filters_json": json.dumps({"company": company, "charts_based_on": "Status"}),
+			"type": "Donut",
+			"is_public": 1,
+			"is_custom": 1,
+			"custom_options": json.dumps({"axisOptions": {"shortenYAxisNumbers": 1}, "height": 300}),
+		},
+		{
+			"doctype": "Dashboard Chart",
+			"time_interval": "Yearly",
+			"chart_type": "Report",
+			"chart_name": _("Quality Inspection Analysis"),
+			"name": "Quality Inspection Analysis",
+			"timespan": "Last Year",
+			"report_name": "Quality Inspection Summary",
+			"owner": "Administrator",
+			"filters_json": json.dumps({}),
+			"type": "Donut",
+			"is_public": 1,
+			"is_custom": 1,
+			"custom_options": json.dumps({"axisOptions": {"shortenYAxisNumbers": 1}, "height": 300}),
+		},
+		{
+			"doctype": "Dashboard Chart",
+			"time_interval": "Yearly",
+			"chart_type": "Report",
+			"chart_name": _("Pending Work Order"),
+			"name": "Pending Work Order",
+			"timespan": "Last Year",
+			"report_name": "Work Order Summary",
+			"filters_json": json.dumps({"company": company, "charts_based_on": "Age"}),
+			"owner": "Administrator",
+			"type": "Donut",
+			"is_public": 1,
+			"is_custom": 1,
+			"custom_options": json.dumps({"axisOptions": {"shortenYAxisNumbers": 1}, "height": 300}),
+		},
+		{
+			"doctype": "Dashboard Chart",
+			"time_interval": "Yearly",
+			"chart_type": "Report",
+			"chart_name": _("Last Month Downtime Analysis"),
+			"name": "Last Month Downtime Analysis",
+			"timespan": "Last Year",
+			"filters_json": json.dumps({}),
+			"report_name": "Downtime Analysis",
+			"owner": "Administrator",
+			"is_public": 1,
+			"is_custom": 1,
+			"type": "Bar",
+		},
+		{
+			"doctype": "Dashboard Chart",
+			"time_interval": "Yearly",
+			"chart_type": "Report",
+			"chart_name": _("Work Order Qty Analysis"),
+			"name": "Work Order Qty Analysis",
+			"timespan": "Last Year",
+			"report_name": "Work Order Summary",
+			"filters_json": json.dumps({"company": company, "charts_based_on": "Quantity"}),
+			"owner": "Administrator",
+			"type": "Bar",
+			"is_public": 1,
+			"is_custom": 1,
+			"custom_options": json.dumps({"barOptions": {"stacked": 1}}),
+		},
+		{
+			"doctype": "Dashboard Chart",
+			"time_interval": "Yearly",
+			"chart_type": "Report",
+			"chart_name": _("Job Card Analysis"),
+			"name": "Job Card Analysis",
+			"timespan": "Last Year",
+			"report_name": "Job Card Summary",
+			"owner": "Administrator",
+			"is_public": 1,
+			"is_custom": 1,
+			"filters_json": json.dumps({"company": company, "docstatus": 1, "range": "Monthly"}),
+			"custom_options": json.dumps({"barOptions": {"stacked": 1}}),
+			"type": "Bar",
+		},
+	]
+
 
 def get_number_cards():
 	start_date = add_months(nowdate(), -1)
 	end_date = nowdate()
 
-	return [{
-		"doctype": "Number Card",
-		"document_type": "Work Order",
-		"name": "Monthly Total Work Order",
-		"filters_json": json.dumps([
-			['Work Order', 'docstatus', '=', 1],
-			['Work Order', 'creation', 'between', [start_date, end_date]]
-		]),
-		"function": "Count",
-		"is_public": 1,
-		"label": _("Monthly Total Work Orders"),
-		"show_percentage_stats": 1,
-		"stats_time_interval": "Weekly"
-	},
-	{
-		"doctype": "Number Card",
-		"document_type": "Work Order",
-		"name": "Monthly Completed Work Order",
-		"filters_json": json.dumps([
-			['Work Order', 'status', '=', 'Completed'],
-			['Work Order', 'docstatus', '=', 1],
-			['Work Order', 'creation', 'between', [start_date, end_date]]
-		]),
-		"function": "Count",
-		"is_public": 1,
-		"label": _("Monthly Completed Work Orders"),
-		"show_percentage_stats": 1,
-		"stats_time_interval": "Weekly"
-	},
-	{
-		"doctype": "Number Card",
-		"document_type": "Job Card",
-		"name": "Ongoing Job Card",
-		"filters_json": json.dumps([
-			['Job Card', 'status','!=','Completed'],
-			['Job Card', 'docstatus', '=', 1]
-		]),
-		"function": "Count",
-		"is_public": 1,
-		"label": _("Ongoing Job Cards"),
-		"show_percentage_stats": 1,
-		"stats_time_interval": "Weekly"
-	},
-	{
-		"doctype": "Number Card",
-		"document_type": "Quality Inspection",
-		"name": "Monthly Quality Inspection",
-		"filters_json": json.dumps([
-			['Quality Inspection', 'docstatus', '=', 1],
-			['Quality Inspection', 'creation', 'between', [start_date, end_date]]
-		]),
-		"function": "Count",
-		"is_public": 1,
-		"label": _("Monthly Quality Inspections"),
-		"show_percentage_stats": 1,
-		"stats_time_interval": "Weekly"
-	}]
+	return [
+		{
+			"doctype": "Number Card",
+			"document_type": "Work Order",
+			"name": "Monthly Total Work Order",
+			"filters_json": json.dumps(
+				[
+					["Work Order", "docstatus", "=", 1],
+					["Work Order", "creation", "between", [start_date, end_date]],
+				]
+			),
+			"function": "Count",
+			"is_public": 1,
+			"label": _("Monthly Total Work Orders"),
+			"show_percentage_stats": 1,
+			"stats_time_interval": "Weekly",
+		},
+		{
+			"doctype": "Number Card",
+			"document_type": "Work Order",
+			"name": "Monthly Completed Work Order",
+			"filters_json": json.dumps(
+				[
+					["Work Order", "status", "=", "Completed"],
+					["Work Order", "docstatus", "=", 1],
+					["Work Order", "creation", "between", [start_date, end_date]],
+				]
+			),
+			"function": "Count",
+			"is_public": 1,
+			"label": _("Monthly Completed Work Orders"),
+			"show_percentage_stats": 1,
+			"stats_time_interval": "Weekly",
+		},
+		{
+			"doctype": "Number Card",
+			"document_type": "Job Card",
+			"name": "Ongoing Job Card",
+			"filters_json": json.dumps(
+				[["Job Card", "status", "!=", "Completed"], ["Job Card", "docstatus", "=", 1]]
+			),
+			"function": "Count",
+			"is_public": 1,
+			"label": _("Ongoing Job Cards"),
+			"show_percentage_stats": 1,
+			"stats_time_interval": "Weekly",
+		},
+		{
+			"doctype": "Number Card",
+			"document_type": "Quality Inspection",
+			"name": "Monthly Quality Inspection",
+			"filters_json": json.dumps(
+				[
+					["Quality Inspection", "docstatus", "=", 1],
+					["Quality Inspection", "creation", "between", [start_date, end_date]],
+				]
+			),
+			"function": "Count",
+			"is_public": 1,
+			"label": _("Monthly Quality Inspections"),
+			"show_percentage_stats": 1,
+			"stats_time_interval": "Weekly",
+		},
+	]
diff --git a/erpnext/manufacturing/doctype/blanket_order/blanket_order.py b/erpnext/manufacturing/doctype/blanket_order/blanket_order.py
index 5340c51..ff21401 100644
--- a/erpnext/manufacturing/doctype/blanket_order/blanket_order.py
+++ b/erpnext/manufacturing/doctype/blanket_order/blanket_order.py
@@ -29,7 +29,9 @@
 
 	def update_ordered_qty(self):
 		ref_doctype = "Sales Order" if self.blanket_order_type == "Selling" else "Purchase Order"
-		item_ordered_qty = frappe._dict(frappe.db.sql("""
+		item_ordered_qty = frappe._dict(
+			frappe.db.sql(
+				"""
 			select trans_item.item_code, sum(trans_item.stock_qty) as qty
 			from `tab{0} Item` trans_item, `tab{0}` trans
 			where trans.name = trans_item.parent
@@ -37,18 +39,24 @@
 				and trans.docstatus=1
 				and trans.status not in ('Closed', 'Stopped')
 			group by trans_item.item_code
-		""".format(ref_doctype), self.name))
+		""".format(
+					ref_doctype
+				),
+				self.name,
+			)
+		)
 
 		for d in self.items:
 			d.db_set("ordered_qty", item_ordered_qty.get(d.item_code, 0))
 
+
 @frappe.whitelist()
 def make_order(source_name):
 	doctype = frappe.flags.args.doctype
 
 	def update_doc(source_doc, target_doc, source_parent):
-		if doctype == 'Quotation':
-			target_doc.quotation_to = 'Customer'
+		if doctype == "Quotation":
+			target_doc.quotation_to = "Customer"
 			target_doc.party_name = source_doc.customer
 
 	def update_item(source, target, source_parent):
@@ -62,18 +70,16 @@
 			target.against_blanket_order = 1
 			target.blanket_order = source_name
 
-	target_doc = get_mapped_doc("Blanket Order", source_name, {
-		"Blanket Order": {
-			"doctype": doctype,
-			"postprocess": update_doc
-		},
-		"Blanket Order Item": {
-			"doctype": doctype + " Item",
-			"field_map": {
-				"rate": "blanket_order_rate",
-				"parent": "blanket_order"
+	target_doc = get_mapped_doc(
+		"Blanket Order",
+		source_name,
+		{
+			"Blanket Order": {"doctype": doctype, "postprocess": update_doc},
+			"Blanket Order Item": {
+				"doctype": doctype + " Item",
+				"field_map": {"rate": "blanket_order_rate", "parent": "blanket_order"},
+				"postprocess": update_item,
 			},
-			"postprocess": update_item
-		}
-	})
+		},
+	)
 	return target_doc
diff --git a/erpnext/manufacturing/doctype/blanket_order/blanket_order_dashboard.py b/erpnext/manufacturing/doctype/blanket_order/blanket_order_dashboard.py
index c6745c8..3106234 100644
--- a/erpnext/manufacturing/doctype/blanket_order/blanket_order_dashboard.py
+++ b/erpnext/manufacturing/doctype/blanket_order/blanket_order_dashboard.py
@@ -1,9 +1,5 @@
 def get_data():
 	return {
-		'fieldname': 'blanket_order',
-		'transactions': [
-			{
-				'items': ['Purchase Order', 'Sales Order', 'Quotation']
-			}
-		]
+		"fieldname": "blanket_order",
+		"transactions": [{"items": ["Purchase Order", "Sales Order", "Quotation"]}],
 	}
diff --git a/erpnext/manufacturing/doctype/blanket_order/test_blanket_order.py b/erpnext/manufacturing/doctype/blanket_order/test_blanket_order.py
index d4d337d..2f1f3ae 100644
--- a/erpnext/manufacturing/doctype/blanket_order/test_blanket_order.py
+++ b/erpnext/manufacturing/doctype/blanket_order/test_blanket_order.py
@@ -16,7 +16,7 @@
 	def test_sales_order_creation(self):
 		bo = make_blanket_order(blanket_order_type="Selling")
 
-		frappe.flags.args.doctype = 'Sales Order'
+		frappe.flags.args.doctype = "Sales Order"
 		so = make_order(bo.name)
 		so.currency = get_company_currency(so.company)
 		so.delivery_date = today()
@@ -33,16 +33,15 @@
 		self.assertEqual(so.items[0].qty, bo.items[0].ordered_qty)
 
 		# test the quantity
-		frappe.flags.args.doctype = 'Sales Order'
+		frappe.flags.args.doctype = "Sales Order"
 		so1 = make_order(bo.name)
 		so1.currency = get_company_currency(so1.company)
-		self.assertEqual(so1.items[0].qty, (bo.items[0].qty-bo.items[0].ordered_qty))
-
+		self.assertEqual(so1.items[0].qty, (bo.items[0].qty - bo.items[0].ordered_qty))
 
 	def test_purchase_order_creation(self):
 		bo = make_blanket_order(blanket_order_type="Purchasing")
 
-		frappe.flags.args.doctype = 'Purchase Order'
+		frappe.flags.args.doctype = "Purchase Order"
 		po = make_order(bo.name)
 		po.currency = get_company_currency(po.company)
 		po.schedule_date = today()
@@ -59,11 +58,10 @@
 		self.assertEqual(po.items[0].qty, bo.items[0].ordered_qty)
 
 		# test the quantity
-		frappe.flags.args.doctype = 'Purchase Order'
+		frappe.flags.args.doctype = "Purchase Order"
 		po1 = make_order(bo.name)
 		po1.currency = get_company_currency(po1.company)
-		self.assertEqual(po1.items[0].qty, (bo.items[0].qty-bo.items[0].ordered_qty))
-
+		self.assertEqual(po1.items[0].qty, (bo.items[0].qty - bo.items[0].ordered_qty))
 
 
 def make_blanket_order(**args):
@@ -80,11 +78,14 @@
 	bo.from_date = today()
 	bo.to_date = add_months(bo.from_date, months=12)
 
-	bo.append("items", {
-		"item_code": args.item_code or "_Test Item",
-		"qty": args.quantity or 1000,
-		"rate": args.rate or 100
-	})
+	bo.append(
+		"items",
+		{
+			"item_code": args.item_code or "_Test Item",
+			"qty": args.quantity or 1000,
+			"rate": args.rate or 100,
+		},
+	)
 
 	bo.insert()
 	bo.submit()
diff --git a/erpnext/manufacturing/doctype/bom/bom.py b/erpnext/manufacturing/doctype/bom/bom.py
index 4d7e459..bf29474 100644
--- a/erpnext/manufacturing/doctype/bom/bom.py
+++ b/erpnext/manufacturing/doctype/bom/bom.py
@@ -19,9 +19,7 @@
 from erpnext.stock.doctype.item.item import get_item_details
 from erpnext.stock.get_item_details import get_conversion_factor, get_price_list_rate
 
-form_grid_templates = {
-	"items": "templates/form_grid/item_grid.html"
-}
+form_grid_templates = {"items": "templates/form_grid/item_grid.html"}
 
 
 class BOMTree:
@@ -31,10 +29,12 @@
 	# ref: https://docs.python.org/3/reference/datamodel.html#slots
 	__slots__ = ["name", "child_items", "is_bom", "item_code", "exploded_qty", "qty"]
 
-	def __init__(self, name: str, is_bom: bool = True, exploded_qty: float = 1.0, qty: float = 1) -> None:
+	def __init__(
+		self, name: str, is_bom: bool = True, exploded_qty: float = 1.0, qty: float = 1
+	) -> None:
 		self.name = name  # name of node, BOM number if is_bom else item_code
 		self.child_items: List["BOMTree"] = []  # list of child items
-		self.is_bom = is_bom   # true if the node is a BOM and not a leaf item
+		self.is_bom = is_bom  # true if the node is a BOM and not a leaf item
 		self.item_code: str = None  # item_code associated with node
 		self.qty = qty  # required unit quantity to make one unit of parent item.
 		self.exploded_qty = exploded_qty  # total exploded qty required for making root of tree.
@@ -62,12 +62,12 @@
 		"""Get level order traversal of tree.
 		E.g. for following tree the traversal will return list of nodes in order from top to bottom.
 		BOM:
-			- SubAssy1
-				- item1
-				- item2
-			- SubAssy2
-				- item3
-			- item4
+		        - SubAssy1
+		                - item1
+		                - item2
+		        - SubAssy2
+		                - item3
+		        - item4
 
 		returns = [SubAssy1, item1, item2, SubAssy2, item3, item4]
 		"""
@@ -96,19 +96,18 @@
 			rep += child.__repr__(level=level + 1)
 		return rep
 
+
 class BOM(WebsiteGenerator):
 	website = frappe._dict(
 		# page_title_field = "item_name",
-		condition_field = "show_in_website",
-		template = "templates/generators/bom.html"
+		condition_field="show_in_website",
+		template="templates/generators/bom.html",
 	)
 
 	def autoname(self):
 		# ignore amended documents while calculating current index
 		existing_boms = frappe.get_all(
-			"BOM",
-			filters={"item": self.item, "amended_from": ["is", "not set"]},
-			pluck="name"
+			"BOM", filters={"item": self.item, "amended_from": ["is", "not set"]}, pluck="name"
 		)
 
 		if existing_boms:
@@ -135,11 +134,15 @@
 			conflicting_bom = frappe.get_doc("BOM", name)
 
 			if conflicting_bom.item != self.item:
-				msg = (_("A BOM with name {0} already exists for item {1}.")
-					.format(frappe.bold(name), frappe.bold(conflicting_bom.item)))
+				msg = _("A BOM with name {0} already exists for item {1}.").format(
+					frappe.bold(name), frappe.bold(conflicting_bom.item)
+				)
 
-				frappe.throw(_("{0}{1} Did you rename the item? Please contact Administrator / Tech support")
-					.format(msg, "<br>"))
+				frappe.throw(
+					_("{0}{1} Did you rename the item? Please contact Administrator / Tech support").format(
+						msg, "<br>"
+					)
+				)
 
 		self.name = name
 
@@ -164,7 +167,7 @@
 		return index
 
 	def validate(self):
-		self.route = frappe.scrub(self.name).replace('_', '-')
+		self.route = frappe.scrub(self.name).replace("_", "-")
 
 		if not self.company:
 			frappe.throw(_("Please select a Company first."), title=_("Mandatory"))
@@ -184,14 +187,14 @@
 		self.validate_operations()
 		self.calculate_cost()
 		self.update_stock_qty()
-		self.update_cost(update_parent=False, from_child_bom=True, update_hour_rate = False, save=False)
+		self.update_cost(update_parent=False, from_child_bom=True, update_hour_rate=False, save=False)
 		self.validate_scrap_items()
 
 	def get_context(self, context):
-		context.parents = [{'name': 'boms', 'title': _('All BOMs') }]
+		context.parents = [{"name": "boms", "title": _("All BOMs")}]
 
 	def on_update(self):
-		frappe.cache().hdel('bom_children', self.name)
+		frappe.cache().hdel("bom_children", self.name)
 		self.check_recursion()
 
 	def on_submit(self):
@@ -221,37 +224,53 @@
 	def get_routing(self):
 		if self.routing:
 			self.set("operations", [])
-			fields = ["sequence_id", "operation", "workstation", "description",
-				"time_in_mins", "batch_size", "operating_cost", "idx", "hour_rate",
-				"set_cost_based_on_bom_qty", "fixed_time"]
+			fields = [
+				"sequence_id",
+				"operation",
+				"workstation",
+				"description",
+				"time_in_mins",
+				"batch_size",
+				"operating_cost",
+				"idx",
+				"hour_rate",
+				"set_cost_based_on_bom_qty",
+				"fixed_time",
+			]
 
-			for row in frappe.get_all("BOM Operation", fields = fields,
-				filters = {'parenttype': 'Routing', 'parent': self.routing}, order_by="sequence_id, idx"):
-				child = self.append('operations', row)
+			for row in frappe.get_all(
+				"BOM Operation",
+				fields=fields,
+				filters={"parenttype": "Routing", "parent": self.routing},
+				order_by="sequence_id, idx",
+			):
+				child = self.append("operations", row)
 				child.hour_rate = flt(row.hour_rate / self.conversion_rate, child.precision("hour_rate"))
 
 	def set_bom_material_details(self):
 		for item in self.get("items"):
 			self.validate_bom_currency(item)
 
-			item.bom_no = ''
+			item.bom_no = ""
 			if not item.do_not_explode:
 				item.bom_no = item.bom_no
 
-			ret = self.get_bom_material_detail({
-				"company": self.company,
-				"item_code": item.item_code,
-				"item_name": item.item_name,
-				"bom_no": item.bom_no,
-				"stock_qty": item.stock_qty,
-				"include_item_in_manufacturing": item.include_item_in_manufacturing,
-				"qty": item.qty,
-				"uom": item.uom,
-				"stock_uom": item.stock_uom,
-				"conversion_factor": item.conversion_factor,
-				"sourced_by_supplier": item.sourced_by_supplier,
-				"do_not_explode": item.do_not_explode
-			})
+			ret = self.get_bom_material_detail(
+				{
+					"company": self.company,
+					"item_code": item.item_code,
+					"item_name": item.item_name,
+					"bom_no": item.bom_no,
+					"stock_qty": item.stock_qty,
+					"include_item_in_manufacturing": item.include_item_in_manufacturing,
+					"qty": item.qty,
+					"uom": item.uom,
+					"stock_uom": item.stock_uom,
+					"conversion_factor": item.conversion_factor,
+					"sourced_by_supplier": item.sourced_by_supplier,
+					"do_not_explode": item.do_not_explode,
+				}
+			)
 
 			for r in ret:
 				if not item.get(r):
@@ -263,7 +282,7 @@
 				"item_code": item.item_code,
 				"company": self.company,
 				"scrap_items": True,
-				"bom_no": '',
+				"bom_no": "",
 			}
 			ret = self.get_bom_material_detail(args)
 			for key, value in ret.items():
@@ -272,75 +291,93 @@
 
 	@frappe.whitelist()
 	def get_bom_material_detail(self, args=None):
-		""" Get raw material details like uom, desc and rate"""
+		"""Get raw material details like uom, desc and rate"""
 		if not args:
-			args = frappe.form_dict.get('args')
+			args = frappe.form_dict.get("args")
 
 		if isinstance(args, str):
 			import json
+
 			args = json.loads(args)
 
-		item = self.get_item_det(args['item_code'])
+		item = self.get_item_det(args["item_code"])
 
-		args['bom_no'] = args['bom_no'] or item and cstr(item['default_bom']) or ''
-		args['transfer_for_manufacture'] = (cstr(args.get('include_item_in_manufacturing', '')) or
-			item and item.include_item_in_manufacturing or 0)
+		args["bom_no"] = args["bom_no"] or item and cstr(item["default_bom"]) or ""
+		args["transfer_for_manufacture"] = (
+			cstr(args.get("include_item_in_manufacturing", ""))
+			or item
+			and item.include_item_in_manufacturing
+			or 0
+		)
 		args.update(item)
 
 		rate = self.get_rm_rate(args)
 		ret_item = {
-			 'item_name'	: item and args['item_name'] or '',
-			 'description'  : item and args['description'] or '',
-			 'image'		: item and args['image'] or '',
-			 'stock_uom'	: item and args['stock_uom'] or '',
-			 'uom'			: item and args['stock_uom'] or '',
- 			 'conversion_factor': 1,
-			 'bom_no'		: args['bom_no'],
-			 'rate'			: rate,
-			 'qty'			: args.get("qty") or args.get("stock_qty") or 1,
-			 'stock_qty'	: args.get("qty") or args.get("stock_qty") or 1,
-			 'base_rate'	: flt(rate) * (flt(self.conversion_rate) or 1),
-			 'include_item_in_manufacturing': cint(args.get('transfer_for_manufacture')),
-			 'sourced_by_supplier'		: args.get('sourced_by_supplier', 0)
+			"item_name": item and args["item_name"] or "",
+			"description": item and args["description"] or "",
+			"image": item and args["image"] or "",
+			"stock_uom": item and args["stock_uom"] or "",
+			"uom": item and args["stock_uom"] or "",
+			"conversion_factor": 1,
+			"bom_no": args["bom_no"],
+			"rate": rate,
+			"qty": args.get("qty") or args.get("stock_qty") or 1,
+			"stock_qty": args.get("qty") or args.get("stock_qty") or 1,
+			"base_rate": flt(rate) * (flt(self.conversion_rate) or 1),
+			"include_item_in_manufacturing": cint(args.get("transfer_for_manufacture")),
+			"sourced_by_supplier": args.get("sourced_by_supplier", 0),
 		}
 
-		if args.get('do_not_explode'):
-			ret_item['bom_no'] = ''
+		if args.get("do_not_explode"):
+			ret_item["bom_no"] = ""
 
 		return ret_item
 
 	def validate_bom_currency(self, item):
-		if item.get('bom_no') and frappe.db.get_value('BOM', item.get('bom_no'), 'currency') != self.currency:
-			frappe.throw(_("Row {0}: Currency of the BOM #{1} should be equal to the selected currency {2}")
-				.format(item.idx, item.bom_no, self.currency))
+		if (
+			item.get("bom_no")
+			and frappe.db.get_value("BOM", item.get("bom_no"), "currency") != self.currency
+		):
+			frappe.throw(
+				_("Row {0}: Currency of the BOM #{1} should be equal to the selected currency {2}").format(
+					item.idx, item.bom_no, self.currency
+				)
+			)
 
 	def get_rm_rate(self, arg):
-		"""	Get raw material rate as per selected method, if bom exists takes bom cost """
+		"""Get raw material rate as per selected method, if bom exists takes bom cost"""
 		rate = 0
 		if not self.rm_cost_as_per:
 			self.rm_cost_as_per = "Valuation Rate"
 
-		if arg.get('scrap_items'):
+		if arg.get("scrap_items"):
 			rate = get_valuation_rate(arg)
 		elif arg:
-			#Customer Provided parts and Supplier sourced parts will have zero rate
-			if not frappe.db.get_value('Item', arg["item_code"], 'is_customer_provided_item') and not arg.get('sourced_by_supplier'):
-				if arg.get('bom_no') and self.set_rate_of_sub_assembly_item_based_on_bom:
-					rate = flt(self.get_bom_unitcost(arg['bom_no'])) * (arg.get("conversion_factor") or 1)
+			# Customer Provided parts and Supplier sourced parts will have zero rate
+			if not frappe.db.get_value(
+				"Item", arg["item_code"], "is_customer_provided_item"
+			) and not arg.get("sourced_by_supplier"):
+				if arg.get("bom_no") and self.set_rate_of_sub_assembly_item_based_on_bom:
+					rate = flt(self.get_bom_unitcost(arg["bom_no"])) * (arg.get("conversion_factor") or 1)
 				else:
 					rate = get_bom_item_rate(arg, self)
 
 					if not rate:
 						if self.rm_cost_as_per == "Price List":
-							frappe.msgprint(_("Price not found for item {0} in price list {1}")
-								.format(arg["item_code"], self.buying_price_list), alert=True)
+							frappe.msgprint(
+								_("Price not found for item {0} in price list {1}").format(
+									arg["item_code"], self.buying_price_list
+								),
+								alert=True,
+							)
 						else:
-							frappe.msgprint(_("{0} not found for item {1}")
-								.format(self.rm_cost_as_per, arg["item_code"]), alert=True)
+							frappe.msgprint(
+								_("{0} not found for item {1}").format(self.rm_cost_as_per, arg["item_code"]), alert=True
+							)
 		return flt(rate) * flt(self.plc_conversion_rate or 1) / (self.conversion_rate or 1)
 
 	@frappe.whitelist()
-	def update_cost(self, update_parent=True, from_child_bom=False, update_hour_rate = True, save=True):
+	def update_cost(self, update_parent=True, from_child_bom=False, update_hour_rate=True, save=True):
 		if self.docstatus == 2:
 			return
 
@@ -350,16 +387,18 @@
 			if not d.item_code:
 				continue
 
-			rate = self.get_rm_rate({
-				"company": self.company,
-				"item_code": d.item_code,
-				"bom_no": d.bom_no,
-				"qty": d.qty,
-				"uom": d.uom,
-				"stock_uom": d.stock_uom,
-				"conversion_factor": d.conversion_factor,
-				"sourced_by_supplier": d.sourced_by_supplier
-			})
+			rate = self.get_rm_rate(
+				{
+					"company": self.company,
+					"item_code": d.item_code,
+					"bom_no": d.bom_no,
+					"qty": d.qty,
+					"uom": d.uom,
+					"stock_uom": d.stock_uom,
+					"conversion_factor": d.conversion_factor,
+					"sourced_by_supplier": d.sourced_by_supplier,
+				}
+			)
 
 			if rate:
 				d.rate = rate
@@ -380,8 +419,11 @@
 
 		# update parent BOMs
 		if self.total_cost != existing_bom_cost and update_parent:
-			parent_boms = frappe.db.sql_list("""select distinct parent from `tabBOM Item`
-				where bom_no = %s and docstatus=1 and parenttype='BOM'""", self.name)
+			parent_boms = frappe.db.sql_list(
+				"""select distinct parent from `tabBOM Item`
+				where bom_no = %s and docstatus=1 and parenttype='BOM'""",
+				self.name,
+			)
 
 			for bom in parent_boms:
 				frappe.get_doc("BOM", bom).update_cost(from_child_bom=True)
@@ -393,45 +435,54 @@
 		if self.total_cost:
 			cost = self.total_cost / self.quantity
 
-			frappe.db.sql("""update `tabBOM Item` set rate=%s, amount=stock_qty*%s
+			frappe.db.sql(
+				"""update `tabBOM Item` set rate=%s, amount=stock_qty*%s
 				where bom_no = %s and docstatus < 2 and parenttype='BOM'""",
-				(cost, cost, self.name))
+				(cost, cost, self.name),
+			)
 
 	def get_bom_unitcost(self, bom_no):
-		bom = frappe.db.sql("""select name, base_total_cost/quantity as unit_cost from `tabBOM`
-			where is_active = 1 and name = %s""", bom_no, as_dict=1)
-		return bom and bom[0]['unit_cost'] or 0
+		bom = frappe.db.sql(
+			"""select name, base_total_cost/quantity as unit_cost from `tabBOM`
+			where is_active = 1 and name = %s""",
+			bom_no,
+			as_dict=1,
+		)
+		return bom and bom[0]["unit_cost"] or 0
 
 	def manage_default_bom(self):
-		""" Uncheck others if current one is selected as default or
-			check the current one as default if it the only bom for the selected item,
-			update default bom in item master
+		"""Uncheck others if current one is selected as default or
+		check the current one as default if it the only bom for the selected item,
+		update default bom in item master
 		"""
 		if self.is_default and self.is_active:
 			from frappe.model.utils import set_default
+
 			set_default(self, "item")
 			item = frappe.get_doc("Item", self.item)
 			if item.default_bom != self.name:
-				frappe.db.set_value('Item', self.item, 'default_bom', self.name)
-		elif not frappe.db.exists(dict(doctype='BOM', docstatus=1, item=self.item, is_default=1)) \
-			and self.is_active:
+				frappe.db.set_value("Item", self.item, "default_bom", self.name)
+		elif (
+			not frappe.db.exists(dict(doctype="BOM", docstatus=1, item=self.item, is_default=1))
+			and self.is_active
+		):
 			frappe.db.set(self, "is_default", 1)
 		else:
 			frappe.db.set(self, "is_default", 0)
 			item = frappe.get_doc("Item", self.item)
 			if item.default_bom == self.name:
-				frappe.db.set_value('Item', self.item, 'default_bom', None)
+				frappe.db.set_value("Item", self.item, "default_bom", None)
 
 	def clear_operations(self):
 		if not self.with_operations:
-			self.set('operations', [])
+			self.set("operations", [])
 
 	def clear_inspection(self):
 		if not self.inspection_required:
 			self.quality_inspection_template = None
 
 	def validate_main_item(self):
-		""" Validate main FG item"""
+		"""Validate main FG item"""
 		item = self.get_item_det(self.item)
 		if not item:
 			frappe.throw(_("Item {0} does not exist in the system or has expired").format(self.item))
@@ -439,30 +490,34 @@
 			ret = frappe.db.get_value("Item", self.item, ["description", "stock_uom", "item_name"])
 			self.description = ret[0]
 			self.uom = ret[1]
-			self.item_name= ret[2]
+			self.item_name = ret[2]
 
 		if not self.quantity:
 			frappe.throw(_("Quantity should be greater than 0"))
 
 	def validate_currency(self):
-		if self.rm_cost_as_per == 'Price List':
-			price_list_currency = frappe.db.get_value('Price List', self.buying_price_list, 'currency')
+		if self.rm_cost_as_per == "Price List":
+			price_list_currency = frappe.db.get_value("Price List", self.buying_price_list, "currency")
 			if price_list_currency not in (self.currency, self.company_currency()):
-				frappe.throw(_("Currency of the price list {0} must be {1} or {2}")
-					.format(self.buying_price_list, self.currency, self.company_currency()))
+				frappe.throw(
+					_("Currency of the price list {0} must be {1} or {2}").format(
+						self.buying_price_list, self.currency, self.company_currency()
+					)
+				)
 
 	def update_stock_qty(self):
-		for m in self.get('items'):
+		for m in self.get("items"):
 			if not m.conversion_factor:
-				m.conversion_factor = flt(get_conversion_factor(m.item_code, m.uom)['conversion_factor'])
+				m.conversion_factor = flt(get_conversion_factor(m.item_code, m.uom)["conversion_factor"])
 			if m.uom and m.qty:
-				m.stock_qty = flt(m.conversion_factor)*flt(m.qty)
+				m.stock_qty = flt(m.conversion_factor) * flt(m.qty)
 			if not m.uom and m.stock_uom:
 				m.uom = m.stock_uom
 				m.qty = m.stock_qty
 
 	def validate_uom_is_interger(self):
 		from erpnext.utilities.transaction_base import validate_uom_is_integer
+
 		validate_uom_is_integer(self, "uom", "qty", "BOM Item")
 		validate_uom_is_integer(self, "stock_uom", "stock_qty", "BOM Item")
 
@@ -470,23 +525,26 @@
 		if self.currency == self.company_currency():
 			self.conversion_rate = 1
 		elif self.conversion_rate == 1 or flt(self.conversion_rate) <= 0:
-			self.conversion_rate = get_exchange_rate(self.currency, self.company_currency(), args="for_buying")
+			self.conversion_rate = get_exchange_rate(
+				self.currency, self.company_currency(), args="for_buying"
+			)
 
 	def set_plc_conversion_rate(self):
 		if self.rm_cost_as_per in ["Valuation Rate", "Last Purchase Rate"]:
 			self.plc_conversion_rate = 1
 		elif not self.plc_conversion_rate and self.price_list_currency:
-			self.plc_conversion_rate = get_exchange_rate(self.price_list_currency,
-				self.company_currency(), args="for_buying")
+			self.plc_conversion_rate = get_exchange_rate(
+				self.price_list_currency, self.company_currency(), args="for_buying"
+			)
 
 	def validate_materials(self):
-		""" Validate raw material entries """
+		"""Validate raw material entries"""
 
-		if not self.get('items'):
+		if not self.get("items"):
 			frappe.throw(_("Raw Materials cannot be blank."))
 
 		check_list = []
-		for m in self.get('items'):
+		for m in self.get("items"):
 			if m.bom_no:
 				validate_bom_no(m.item_code, m.bom_no)
 			if flt(m.qty) <= 0:
@@ -494,13 +552,20 @@
 			check_list.append(m)
 
 	def check_recursion(self, bom_list=None):
-		""" Check whether recursion occurs in any bom"""
+		"""Check whether recursion occurs in any bom"""
+
 		def _throw_error(bom_name):
 			frappe.throw(_("BOM recursion: {0} cannot be parent or child of {0}").format(bom_name))
 
 		bom_list = self.traverse_tree()
-		child_items = frappe.get_all('BOM Item', fields=["bom_no", "item_code"],
-			filters={'parent': ('in', bom_list), 'parenttype': 'BOM'}) or []
+		child_items = (
+			frappe.get_all(
+				"BOM Item",
+				fields=["bom_no", "item_code"],
+				filters={"parent": ("in", bom_list), "parenttype": "BOM"},
+			)
+			or []
+		)
 
 		child_bom = {d.bom_no for d in child_items}
 		child_items_codes = {d.item_code for d in child_items}
@@ -511,19 +576,26 @@
 		if self.item in child_items_codes:
 			_throw_error(self.item)
 
-		bom_nos = frappe.get_all('BOM Item', fields=["parent"],
-			filters={'bom_no': self.name, 'parenttype': 'BOM'}) or []
+		bom_nos = (
+			frappe.get_all(
+				"BOM Item", fields=["parent"], filters={"bom_no": self.name, "parenttype": "BOM"}
+			)
+			or []
+		)
 
 		if self.name in {d.parent for d in bom_nos}:
 			_throw_error(self.name)
 
 	def traverse_tree(self, bom_list=None):
 		def _get_children(bom_no):
-			children = frappe.cache().hget('bom_children', bom_no)
+			children = frappe.cache().hget("bom_children", bom_no)
 			if children is None:
-				children = frappe.db.sql_list("""SELECT `bom_no` FROM `tabBOM Item`
-					WHERE `parent`=%s AND `bom_no`!='' AND `parenttype`='BOM'""", bom_no)
-				frappe.cache().hset('bom_children', bom_no, children)
+				children = frappe.db.sql_list(
+					"""SELECT `bom_no` FROM `tabBOM Item`
+					WHERE `parent`=%s AND `bom_no`!='' AND `parenttype`='BOM'""",
+					bom_no,
+				)
+				frappe.cache().hset("bom_children", bom_no, children)
 			return children
 
 		count = 0
@@ -533,7 +605,7 @@
 		if self.name not in bom_list:
 			bom_list.append(self.name)
 
-		while(count < len(bom_list)):
+		while count < len(bom_list):
 			for child_bom in _get_children(bom_list[count]):
 				if child_bom not in bom_list:
 					bom_list.append(child_bom)
@@ -541,19 +613,21 @@
 		bom_list.reverse()
 		return bom_list
 
-	def calculate_cost(self, update_hour_rate = False):
+	def calculate_cost(self, update_hour_rate=False):
 		"""Calculate bom totals"""
 		self.calculate_op_cost(update_hour_rate)
 		self.calculate_rm_cost()
 		self.calculate_sm_cost()
 		self.total_cost = self.operating_cost + self.raw_material_cost - self.scrap_material_cost
-		self.base_total_cost = self.base_operating_cost + self.base_raw_material_cost - self.base_scrap_material_cost
+		self.base_total_cost = (
+			self.base_operating_cost + self.base_raw_material_cost - self.base_scrap_material_cost
+		)
 
-	def calculate_op_cost(self, update_hour_rate = False):
+	def calculate_op_cost(self, update_hour_rate=False):
 		"""Update workstation rate and calculates totals"""
 		self.operating_cost = 0
 		self.base_operating_cost = 0
-		for d in self.get('operations'):
+		for d in self.get("operations"):
 			if d.workstation:
 				self.update_rate_and_time(d, update_hour_rate)
 
@@ -566,13 +640,14 @@
 			self.operating_cost += flt(operating_cost)
 			self.base_operating_cost += flt(base_operating_cost)
 
-	def update_rate_and_time(self, row, update_hour_rate = False):
+	def update_rate_and_time(self, row, update_hour_rate=False):
 		if not row.hour_rate or update_hour_rate:
 			hour_rate = flt(frappe.get_cached_value("Workstation", row.workstation, "hour_rate"))
 
 			if hour_rate:
-				row.hour_rate = (hour_rate / flt(self.conversion_rate)
-					if self.conversion_rate and hour_rate else hour_rate)
+				row.hour_rate = (
+					hour_rate / flt(self.conversion_rate) if self.conversion_rate and hour_rate else hour_rate
+				)
 
 		if row.hour_rate and row.time_in_mins:
 			row.base_hour_rate = flt(row.hour_rate) * flt(self.conversion_rate)
@@ -589,12 +664,13 @@
 		total_rm_cost = 0
 		base_total_rm_cost = 0
 
-		for d in self.get('items'):
+		for d in self.get("items"):
 			d.base_rate = flt(d.rate) * flt(self.conversion_rate)
 			d.amount = flt(d.rate, d.precision("rate")) * flt(d.qty, d.precision("qty"))
 			d.base_amount = d.amount * flt(self.conversion_rate)
-			d.qty_consumed_per_unit = flt(d.stock_qty, d.precision("stock_qty")) \
-				/ flt(self.quantity, self.precision("quantity"))
+			d.qty_consumed_per_unit = flt(d.stock_qty, d.precision("stock_qty")) / flt(
+				self.quantity, self.precision("quantity")
+			)
 
 			total_rm_cost += d.amount
 			base_total_rm_cost += d.base_amount
@@ -607,10 +683,14 @@
 		total_sm_cost = 0
 		base_total_sm_cost = 0
 
-		for d in self.get('scrap_items'):
-			d.base_rate = flt(d.rate, d.precision("rate")) * flt(self.conversion_rate, self.precision("conversion_rate"))
+		for d in self.get("scrap_items"):
+			d.base_rate = flt(d.rate, d.precision("rate")) * flt(
+				self.conversion_rate, self.precision("conversion_rate")
+			)
 			d.amount = flt(d.rate, d.precision("rate")) * flt(d.stock_qty, d.precision("stock_qty"))
-			d.base_amount = flt(d.amount, d.precision("amount")) * flt(self.conversion_rate, self.precision("conversion_rate"))
+			d.base_amount = flt(d.amount, d.precision("amount")) * flt(
+				self.conversion_rate, self.precision("conversion_rate")
+			)
 			total_sm_cost += d.amount
 			base_total_sm_cost += d.base_amount
 
@@ -619,37 +699,42 @@
 
 	def update_new_bom(self, old_bom, new_bom, rate):
 		for d in self.get("items"):
-			if d.bom_no != old_bom: continue
+			if d.bom_no != old_bom:
+				continue
 
 			d.bom_no = new_bom
 			d.rate = rate
 			d.amount = (d.stock_qty or d.qty) * rate
 
 	def update_exploded_items(self, save=True):
-		""" Update Flat BOM, following will be correct data"""
+		"""Update Flat BOM, following will be correct data"""
 		self.get_exploded_items()
 		self.add_exploded_items(save=save)
 
 	def get_exploded_items(self):
-		""" Get all raw materials including items from child bom"""
+		"""Get all raw materials including items from child bom"""
 		self.cur_exploded_items = {}
-		for d in self.get('items'):
+		for d in self.get("items"):
 			if d.bom_no:
 				self.get_child_exploded_items(d.bom_no, d.stock_qty)
 			elif d.item_code:
-				self.add_to_cur_exploded_items(frappe._dict({
-					'item_code'		: d.item_code,
-					'item_name'		: d.item_name,
-					'operation'		: d.operation,
-					'source_warehouse': d.source_warehouse,
-					'description'	: d.description,
-					'image'			: d.image,
-					'stock_uom'		: d.stock_uom,
-					'stock_qty'		: flt(d.stock_qty),
-					'rate'			: flt(d.base_rate) / (flt(d.conversion_factor) or 1.0),
-					'include_item_in_manufacturing': d.include_item_in_manufacturing,
-					'sourced_by_supplier': d.sourced_by_supplier
-				}))
+				self.add_to_cur_exploded_items(
+					frappe._dict(
+						{
+							"item_code": d.item_code,
+							"item_name": d.item_name,
+							"operation": d.operation,
+							"source_warehouse": d.source_warehouse,
+							"description": d.description,
+							"image": d.image,
+							"stock_uom": d.stock_uom,
+							"stock_qty": flt(d.stock_qty),
+							"rate": flt(d.base_rate) / (flt(d.conversion_factor) or 1.0),
+							"include_item_in_manufacturing": d.include_item_in_manufacturing,
+							"sourced_by_supplier": d.sourced_by_supplier,
+						}
+					)
+				)
 
 	def company_currency(self):
 		return erpnext.get_company_currency(self.company)
@@ -661,9 +746,10 @@
 			self.cur_exploded_items[args.item_code] = args
 
 	def get_child_exploded_items(self, bom_no, stock_qty):
-		""" Add all items from Flat BOM of child BOM"""
+		"""Add all items from Flat BOM of child BOM"""
 		# Did not use qty_consumed_per_unit in the query, as it leads to rounding loss
-		child_fb_items = frappe.db.sql("""
+		child_fb_items = frappe.db.sql(
+			"""
 			SELECT
 				bom_item.item_code,
 				bom_item.item_name,
@@ -681,31 +767,38 @@
 				bom_item.parent = bom.name
 				AND bom.name = %s
 				AND bom.docstatus = 1
-		""", bom_no, as_dict = 1)
+		""",
+			bom_no,
+			as_dict=1,
+		)
 
 		for d in child_fb_items:
-			self.add_to_cur_exploded_items(frappe._dict({
-				'item_code'				: d['item_code'],
-				'item_name'				: d['item_name'],
-				'source_warehouse'		: d['source_warehouse'],
-				'operation'				: d['operation'],
-				'description'			: d['description'],
-				'stock_uom'				: d['stock_uom'],
-				'stock_qty'				: d['qty_consumed_per_unit'] * stock_qty,
-				'rate'					: flt(d['rate']),
-				'include_item_in_manufacturing': d.get('include_item_in_manufacturing', 0),
-				'sourced_by_supplier': d.get('sourced_by_supplier', 0)
-			}))
+			self.add_to_cur_exploded_items(
+				frappe._dict(
+					{
+						"item_code": d["item_code"],
+						"item_name": d["item_name"],
+						"source_warehouse": d["source_warehouse"],
+						"operation": d["operation"],
+						"description": d["description"],
+						"stock_uom": d["stock_uom"],
+						"stock_qty": d["qty_consumed_per_unit"] * stock_qty,
+						"rate": flt(d["rate"]),
+						"include_item_in_manufacturing": d.get("include_item_in_manufacturing", 0),
+						"sourced_by_supplier": d.get("sourced_by_supplier", 0),
+					}
+				)
+			)
 
 	def add_exploded_items(self, save=True):
 		"Add items to Flat BOM table"
-		self.set('exploded_items', [])
+		self.set("exploded_items", [])
 
 		if save:
 			frappe.db.sql("""delete from `tabBOM Explosion Item` where parent=%s""", self.name)
 
 		for d in sorted(self.cur_exploded_items, key=itemgetter(0)):
-			ch = self.append('exploded_items', {})
+			ch = self.append("exploded_items", {})
 			for i in self.cur_exploded_items[d].keys():
 				ch.set(i, self.cur_exploded_items[d][i])
 			ch.amount = flt(ch.stock_qty) * flt(ch.rate)
@@ -717,10 +810,13 @@
 
 	def validate_bom_links(self):
 		if not self.is_active:
-			act_pbom = frappe.db.sql("""select distinct bom_item.parent from `tabBOM Item` bom_item
+			act_pbom = frappe.db.sql(
+				"""select distinct bom_item.parent from `tabBOM Item` bom_item
 				where bom_item.bom_no = %s and bom_item.docstatus = 1 and bom_item.parenttype='BOM'
 				and exists (select * from `tabBOM` where name = bom_item.parent
-					and docstatus = 1 and is_active = 1)""", self.name)
+					and docstatus = 1 and is_active = 1)""",
+				self.name,
+			)
 
 			if act_pbom and act_pbom[0][0]:
 				frappe.throw(_("Cannot deactivate or cancel BOM as it is linked with other BOMs"))
@@ -729,20 +825,23 @@
 		if not self.with_operations:
 			self.transfer_material_against = "Work Order"
 		if not self.transfer_material_against and not self.is_new():
-			frappe.throw(_("Setting {} is required").format(self.meta.get_label("transfer_material_against")), title=_("Missing value"))
+			frappe.throw(
+				_("Setting {} is required").format(self.meta.get_label("transfer_material_against")),
+				title=_("Missing value"),
+			)
 
 	def set_routing_operations(self):
 		if self.routing and self.with_operations and not self.operations:
 			self.get_routing()
 
 	def validate_operations(self):
-		if self.with_operations and not self.get('operations') and self.docstatus == 1:
+		if self.with_operations and not self.get("operations") and self.docstatus == 1:
 			frappe.throw(_("Operations cannot be left blank"))
 
 		if self.with_operations:
 			for d in self.operations:
 				if not d.description:
-					d.description = frappe.db.get_value('Operation', d.operation, 'description')
+					d.description = frappe.db.get_value("Operation", d.operation, "description")
 				if not d.batch_size or d.batch_size <= 0:
 					d.batch_size = 1
 
@@ -754,64 +853,75 @@
 		for item in self.scrap_items:
 			msg = ""
 			if item.item_code == self.item and not item.is_process_loss:
-				msg = _('Scrap/Loss Item: {0} should have Is Process Loss checked as it is the same as the item to be manufactured or repacked.') \
-					.format(frappe.bold(item.item_code))
+				msg = _(
+					"Scrap/Loss Item: {0} should have Is Process Loss checked as it is the same as the item to be manufactured or repacked."
+				).format(frappe.bold(item.item_code))
 			elif item.item_code != self.item and item.is_process_loss:
-				msg = _('Scrap/Loss Item: {0} should not have Is Process Loss checked as it is different from  the item to be manufactured or repacked') \
-					.format(frappe.bold(item.item_code))
+				msg = _(
+					"Scrap/Loss Item: {0} should not have Is Process Loss checked as it is different from  the item to be manufactured or repacked"
+				).format(frappe.bold(item.item_code))
 
 			must_be_whole_number = frappe.get_value("UOM", item.stock_uom, "must_be_whole_number")
 			if item.is_process_loss and must_be_whole_number:
-				msg = _("Item: {0} with Stock UOM: {1} cannot be a Scrap/Loss Item as {1} is a whole UOM.") \
-					.format(frappe.bold(item.item_code), frappe.bold(item.stock_uom))
+				msg = _(
+					"Item: {0} with Stock UOM: {1} cannot be a Scrap/Loss Item as {1} is a whole UOM."
+				).format(frappe.bold(item.item_code), frappe.bold(item.stock_uom))
 
 			if item.is_process_loss and (item.stock_qty >= self.quantity):
-				msg = _("Scrap/Loss Item: {0} should have Qty less than finished goods Quantity.") \
-					.format(frappe.bold(item.item_code))
+				msg = _("Scrap/Loss Item: {0} should have Qty less than finished goods Quantity.").format(
+					frappe.bold(item.item_code)
+				)
 
 			if item.is_process_loss and (item.rate > 0):
-				msg = _("Scrap/Loss Item: {0} should have Rate set to 0 because Is Process Loss is checked.") \
-					.format(frappe.bold(item.item_code))
+				msg = _(
+					"Scrap/Loss Item: {0} should have Rate set to 0 because Is Process Loss is checked."
+				).format(frappe.bold(item.item_code))
 
 			if msg:
 				frappe.throw(msg, title=_("Note"))
 
+
 def get_bom_item_rate(args, bom_doc):
-	if bom_doc.rm_cost_as_per == 'Valuation Rate':
+	if bom_doc.rm_cost_as_per == "Valuation Rate":
 		rate = get_valuation_rate(args) * (args.get("conversion_factor") or 1)
-	elif bom_doc.rm_cost_as_per == 'Last Purchase Rate':
-		rate = (flt(args.get('last_purchase_rate'))
-			or flt(frappe.db.get_value("Item", args['item_code'], "last_purchase_rate"))) \
-				* (args.get("conversion_factor") or 1)
+	elif bom_doc.rm_cost_as_per == "Last Purchase Rate":
+		rate = (
+			flt(args.get("last_purchase_rate"))
+			or flt(frappe.db.get_value("Item", args["item_code"], "last_purchase_rate"))
+		) * (args.get("conversion_factor") or 1)
 	elif bom_doc.rm_cost_as_per == "Price List":
 		if not bom_doc.buying_price_list:
 			frappe.throw(_("Please select Price List"))
-		bom_args = frappe._dict({
-			"doctype": "BOM",
-			"price_list": bom_doc.buying_price_list,
-			"qty": args.get("qty") or 1,
-			"uom": args.get("uom") or args.get("stock_uom"),
-			"stock_uom": args.get("stock_uom"),
-			"transaction_type": "buying",
-			"company": bom_doc.company,
-			"currency": bom_doc.currency,
-			"conversion_rate": 1, # Passed conversion rate as 1 purposefully, as conversion rate is applied at the end of the function
-			"conversion_factor": args.get("conversion_factor") or 1,
-			"plc_conversion_rate": 1,
-			"ignore_party": True,
-			"ignore_conversion_rate": True
-		})
+		bom_args = frappe._dict(
+			{
+				"doctype": "BOM",
+				"price_list": bom_doc.buying_price_list,
+				"qty": args.get("qty") or 1,
+				"uom": args.get("uom") or args.get("stock_uom"),
+				"stock_uom": args.get("stock_uom"),
+				"transaction_type": "buying",
+				"company": bom_doc.company,
+				"currency": bom_doc.currency,
+				"conversion_rate": 1,  # Passed conversion rate as 1 purposefully, as conversion rate is applied at the end of the function
+				"conversion_factor": args.get("conversion_factor") or 1,
+				"plc_conversion_rate": 1,
+				"ignore_party": True,
+				"ignore_conversion_rate": True,
+			}
+		)
 		item_doc = frappe.get_cached_doc("Item", args.get("item_code"))
 		price_list_data = get_price_list_rate(bom_args, item_doc)
 		rate = price_list_data.price_list_rate
 
 	return flt(rate)
 
+
 def get_valuation_rate(args):
-	""" Get weighted average of valuation rate from all warehouses """
+	"""Get weighted average of valuation rate from all warehouses"""
 
 	total_qty, total_value, valuation_rate = 0.0, 0.0, 0.0
-	item_bins = frappe.db.sql("""
+	item_bins = frappe.db.sql(
+		"""
 		select
 			bin.actual_qty, bin.stock_value
 		from
@@ -820,33 +930,48 @@
 			bin.item_code=%(item)s
 			and bin.warehouse = warehouse.name
 			and warehouse.company=%(company)s""",
-		{"item": args['item_code'], "company": args['company']}, as_dict=1)
+		{"item": args["item_code"], "company": args["company"]},
+		as_dict=1,
+	)
 
 	for d in item_bins:
 		total_qty += flt(d.actual_qty)
 		total_value += flt(d.stock_value)
 
 	if total_qty:
-		valuation_rate =  total_value / total_qty
+		valuation_rate = total_value / total_qty
 
 	if valuation_rate <= 0:
-		last_valuation_rate = frappe.db.sql("""select valuation_rate
+		last_valuation_rate = frappe.db.sql(
+			"""select valuation_rate
 			from `tabStock Ledger Entry`
 			where item_code = %s and valuation_rate > 0 and is_cancelled = 0
-			order by posting_date desc, posting_time desc, creation desc limit 1""", args['item_code'])
+			order by posting_date desc, posting_time desc, creation desc limit 1""",
+			args["item_code"],
+		)
 
 		valuation_rate = flt(last_valuation_rate[0][0]) if last_valuation_rate else 0
 
 	if not valuation_rate:
-		valuation_rate = frappe.db.get_value("Item", args['item_code'], "valuation_rate")
+		valuation_rate = frappe.db.get_value("Item", args["item_code"], "valuation_rate")
 
 	return flt(valuation_rate)
 
+
 def get_list_context(context):
 	context.title = _("Bill of Materials")
 	# context.introduction = _('Boms')
 
-def get_bom_items_as_dict(bom, company, qty=1, fetch_exploded=1, fetch_scrap_items=0, include_non_stock_items=False, fetch_qty_in_stock_uom=True):
+
+def get_bom_items_as_dict(
+	bom,
+	company,
+	qty=1,
+	fetch_exploded=1,
+	fetch_scrap_items=0,
+	include_non_stock_items=False,
+	fetch_qty_in_stock_uom=True,
+):
 	item_dict = {}
 
 	# Did not use qty_consumed_per_unit in the query, as it leads to rounding loss
@@ -883,30 +1008,40 @@
 
 	is_stock_item = 0 if include_non_stock_items else 1
 	if cint(fetch_exploded):
-		query = query.format(table="BOM Explosion Item",
+		query = query.format(
+			table="BOM Explosion Item",
 			where_conditions="",
 			is_stock_item=is_stock_item,
 			qty_field="stock_qty",
-			select_columns = """, bom_item.source_warehouse, bom_item.operation,
+			select_columns=""", bom_item.source_warehouse, bom_item.operation,
 				bom_item.include_item_in_manufacturing, bom_item.description, bom_item.rate, bom_item.sourced_by_supplier,
-				(Select idx from `tabBOM Item` where item_code = bom_item.item_code and parent = %(parent)s limit 1) as idx""")
-
-		items = frappe.db.sql(query, { "parent": bom, "qty": qty, "bom": bom, "company": company }, as_dict=True)
-	elif fetch_scrap_items:
-		query = query.format(
-			table="BOM Scrap Item", where_conditions="",
-			select_columns=", bom_item.idx, item.description, is_process_loss",
-			is_stock_item=is_stock_item, qty_field="stock_qty"
+				(Select idx from `tabBOM Item` where item_code = bom_item.item_code and parent = %(parent)s limit 1) as idx""",
 		)
 
-		items = frappe.db.sql(query, { "qty": qty, "bom": bom, "company": company }, as_dict=True)
+		items = frappe.db.sql(
+			query, {"parent": bom, "qty": qty, "bom": bom, "company": company}, as_dict=True
+		)
+	elif fetch_scrap_items:
+		query = query.format(
+			table="BOM Scrap Item",
+			where_conditions="",
+			select_columns=", bom_item.idx, item.description, is_process_loss",
+			is_stock_item=is_stock_item,
+			qty_field="stock_qty",
+		)
+
+		items = frappe.db.sql(query, {"qty": qty, "bom": bom, "company": company}, as_dict=True)
 	else:
-		query = query.format(table="BOM Item", where_conditions="", is_stock_item=is_stock_item,
+		query = query.format(
+			table="BOM Item",
+			where_conditions="",
+			is_stock_item=is_stock_item,
 			qty_field="stock_qty" if fetch_qty_in_stock_uom else "qty",
-			select_columns = """, bom_item.uom, bom_item.conversion_factor, bom_item.source_warehouse,
+			select_columns=""", bom_item.uom, bom_item.conversion_factor, bom_item.source_warehouse,
 				bom_item.idx, bom_item.operation, bom_item.include_item_in_manufacturing, bom_item.sourced_by_supplier,
-				bom_item.description, bom_item.base_rate as rate """)
-		items = frappe.db.sql(query, { "qty": qty, "bom": bom, "company": company }, as_dict=True)
+				bom_item.description, bom_item.base_rate as rate """,
+		)
+		items = frappe.db.sql(query, {"qty": qty, "bom": bom, "company": company}, as_dict=True)
 
 	for item in items:
 		if item.item_code in item_dict:
@@ -915,21 +1050,28 @@
 			item_dict[item.item_code] = item
 
 	for item, item_details in item_dict.items():
-		for d in [["Account", "expense_account", "stock_adjustment_account"],
-			["Cost Center", "cost_center", "cost_center"], ["Warehouse", "default_warehouse", ""]]:
-				company_in_record = frappe.db.get_value(d[0], item_details.get(d[1]), "company")
-				if not item_details.get(d[1]) or (company_in_record and company != company_in_record):
-					item_dict[item][d[1]] = frappe.get_cached_value('Company',  company,  d[2]) if d[2] else None
+		for d in [
+			["Account", "expense_account", "stock_adjustment_account"],
+			["Cost Center", "cost_center", "cost_center"],
+			["Warehouse", "default_warehouse", ""],
+		]:
+			company_in_record = frappe.db.get_value(d[0], item_details.get(d[1]), "company")
+			if not item_details.get(d[1]) or (company_in_record and company != company_in_record):
+				item_dict[item][d[1]] = frappe.get_cached_value("Company", company, d[2]) if d[2] else None
 
 	return item_dict
 
+
 @frappe.whitelist()
 def get_bom_items(bom, company, qty=1, fetch_exploded=1):
-	items = get_bom_items_as_dict(bom, company, qty, fetch_exploded, include_non_stock_items=True).values()
+	items = get_bom_items_as_dict(
+		bom, company, qty, fetch_exploded, include_non_stock_items=True
+	).values()
 	items = list(items)
-	items.sort(key = functools.cmp_to_key(lambda a, b: a.item_code > b.item_code and 1 or -1))
+	items.sort(key=functools.cmp_to_key(lambda a, b: a.item_code > b.item_code and 1 or -1))
 	return items
 
+
 def validate_bom_no(item, bom_no):
 	"""Validate BOM No of sub-contracted items"""
 	bom = frappe.get_doc("BOM", bom_no)
@@ -941,21 +1083,24 @@
 	if item:
 		rm_item_exists = False
 		for d in bom.items:
-			if (d.item_code.lower() == item.lower()):
+			if d.item_code.lower() == item.lower():
 				rm_item_exists = True
 		for d in bom.scrap_items:
-			if (d.item_code.lower() == item.lower()):
+			if d.item_code.lower() == item.lower():
 				rm_item_exists = True
-		if bom.item.lower() == item.lower() or \
-			bom.item.lower() == cstr(frappe.db.get_value("Item", item, "variant_of")).lower():
-				rm_item_exists = True
+		if (
+			bom.item.lower() == item.lower()
+			or bom.item.lower() == cstr(frappe.db.get_value("Item", item, "variant_of")).lower()
+		):
+			rm_item_exists = True
 		if not rm_item_exists:
 			frappe.throw(_("BOM {0} does not belong to Item {1}").format(bom_no, item))
 
+
 @frappe.whitelist()
 def get_children(parent=None, is_root=False, **filters):
-	if not parent or parent=="BOM":
-		frappe.msgprint(_('Please select a BOM'))
+	if not parent or parent == "BOM":
+		frappe.msgprint(_("Please select a BOM"))
 		return
 
 	if parent:
@@ -965,38 +1110,45 @@
 		bom_doc = frappe.get_cached_doc("BOM", frappe.form_dict.parent)
 		frappe.has_permission("BOM", doc=bom_doc, throw=True)
 
-		bom_items = frappe.get_all('BOM Item',
-			fields=['item_code', 'bom_no as value', 'stock_qty'],
-			filters=[['parent', '=', frappe.form_dict.parent]],
-			order_by='idx')
+		bom_items = frappe.get_all(
+			"BOM Item",
+			fields=["item_code", "bom_no as value", "stock_qty"],
+			filters=[["parent", "=", frappe.form_dict.parent]],
+			order_by="idx",
+		)
 
-		item_names = tuple(d.get('item_code') for d in bom_items)
+		item_names = tuple(d.get("item_code") for d in bom_items)
 
-		items = frappe.get_list('Item',
-			fields=['image', 'description', 'name', 'stock_uom', 'item_name', 'is_sub_contracted_item'],
-			filters=[['name', 'in', item_names]]) # to get only required item dicts
+		items = frappe.get_list(
+			"Item",
+			fields=["image", "description", "name", "stock_uom", "item_name", "is_sub_contracted_item"],
+			filters=[["name", "in", item_names]],
+		)  # to get only required item dicts
 
 		for bom_item in bom_items:
 			# extend bom_item dict with respective item dict
 			bom_item.update(
 				# returns an item dict from items list which matches with item_code
-				next(item for item in items if item.get('name')
-					== bom_item.get('item_code'))
+				next(item for item in items if item.get("name") == bom_item.get("item_code"))
 			)
 
 			bom_item.parent_bom_qty = bom_doc.quantity
-			bom_item.expandable = 0 if bom_item.value in ('', None)  else 1
+			bom_item.expandable = 0 if bom_item.value in ("", None) else 1
 			bom_item.image = frappe.db.escape(bom_item.image)
 
 		return bom_items
 
+
 def get_boms_in_bottom_up_order(bom_no=None):
 	def _get_parent(bom_no):
-		return frappe.db.sql_list("""
+		return frappe.db.sql_list(
+			"""
 			select distinct bom_item.parent from `tabBOM Item` bom_item
 			where bom_item.bom_no = %s and bom_item.docstatus=1 and bom_item.parenttype='BOM'
 				and exists(select bom.name from `tabBOM` bom where bom.name=bom_item.parent and bom.is_active=1)
-		""", bom_no)
+		""",
+			bom_no,
+		)
 
 	count = 0
 	bom_list = []
@@ -1004,12 +1156,14 @@
 		bom_list.append(bom_no)
 	else:
 		# get all leaf BOMs
-		bom_list = frappe.db.sql_list("""select name from `tabBOM` bom
+		bom_list = frappe.db.sql_list(
+			"""select name from `tabBOM` bom
 			where docstatus=1 and is_active=1
 				and not exists(select bom_no from `tabBOM Item`
-					where parent=bom.name and ifnull(bom_no, '')!='')""")
+					where parent=bom.name and ifnull(bom_no, '')!='')"""
+		)
 
-	while(count < len(bom_list)):
+	while count < len(bom_list):
 		for child_bom in _get_parent(bom_list[count]):
 			if child_bom not in bom_list:
 				bom_list.append(child_bom)
@@ -1017,69 +1171,92 @@
 
 	return bom_list
 
+
 def add_additional_cost(stock_entry, work_order):
 	# Add non stock items cost in the additional cost
 	stock_entry.additional_costs = []
-	expenses_included_in_valuation = frappe.get_cached_value("Company", work_order.company,
-		"expenses_included_in_valuation")
+	expenses_included_in_valuation = frappe.get_cached_value(
+		"Company", work_order.company, "expenses_included_in_valuation"
+	)
 
 	add_non_stock_items_cost(stock_entry, work_order, expenses_included_in_valuation)
 	add_operations_cost(stock_entry, work_order, expenses_included_in_valuation)
 
+
 def add_non_stock_items_cost(stock_entry, work_order, expense_account):
-	bom = frappe.get_doc('BOM', work_order.bom_no)
-	table = 'exploded_items' if work_order.get('use_multi_level_bom') else 'items'
+	bom = frappe.get_doc("BOM", work_order.bom_no)
+	table = "exploded_items" if work_order.get("use_multi_level_bom") else "items"
 
 	items = {}
 	for d in bom.get(table):
 		items.setdefault(d.item_code, d.amount)
 
-	non_stock_items = frappe.get_all('Item',
-		fields="name", filters={'name': ('in', list(items.keys())), 'ifnull(is_stock_item, 0)': 0}, as_list=1)
+	non_stock_items = frappe.get_all(
+		"Item",
+		fields="name",
+		filters={"name": ("in", list(items.keys())), "ifnull(is_stock_item, 0)": 0},
+		as_list=1,
+	)
 
 	non_stock_items_cost = 0.0
 	for name in non_stock_items:
-		non_stock_items_cost += flt(items.get(name[0])) * flt(stock_entry.fg_completed_qty) / flt(bom.quantity)
+		non_stock_items_cost += (
+			flt(items.get(name[0])) * flt(stock_entry.fg_completed_qty) / flt(bom.quantity)
+		)
 
 	if non_stock_items_cost:
-		stock_entry.append('additional_costs', {
-			'expense_account': expense_account,
-			'description': _("Non stock items"),
-			'amount': non_stock_items_cost
-		})
+		stock_entry.append(
+			"additional_costs",
+			{
+				"expense_account": expense_account,
+				"description": _("Non stock items"),
+				"amount": non_stock_items_cost,
+			},
+		)
+
 
 def add_operations_cost(stock_entry, work_order=None, expense_account=None):
 	from erpnext.stock.doctype.stock_entry.stock_entry import get_operating_cost_per_unit
+
 	operating_cost_per_unit = get_operating_cost_per_unit(work_order, stock_entry.bom_no)
 
 	if operating_cost_per_unit:
-		stock_entry.append('additional_costs', {
-			"expense_account": expense_account,
-			"description": _("Operating Cost as per Work Order / BOM"),
-			"amount": operating_cost_per_unit * flt(stock_entry.fg_completed_qty)
-		})
+		stock_entry.append(
+			"additional_costs",
+			{
+				"expense_account": expense_account,
+				"description": _("Operating Cost as per Work Order / BOM"),
+				"amount": operating_cost_per_unit * flt(stock_entry.fg_completed_qty),
+			},
+		)
 
 	if work_order and work_order.additional_operating_cost and work_order.qty:
-		additional_operating_cost_per_unit = \
-			flt(work_order.additional_operating_cost) / flt(work_order.qty)
+		additional_operating_cost_per_unit = flt(work_order.additional_operating_cost) / flt(
+			work_order.qty
+		)
 
 		if additional_operating_cost_per_unit:
-			stock_entry.append('additional_costs', {
-				"expense_account": expense_account,
-				"description": "Additional Operating Cost",
-				"amount": additional_operating_cost_per_unit * flt(stock_entry.fg_completed_qty)
-			})
+			stock_entry.append(
+				"additional_costs",
+				{
+					"expense_account": expense_account,
+					"description": "Additional Operating Cost",
+					"amount": additional_operating_cost_per_unit * flt(stock_entry.fg_completed_qty),
+				},
+			)
+
 
 @frappe.whitelist()
 def get_bom_diff(bom1, bom2):
 	from frappe.model import table_fields
 
 	if bom1 == bom2:
-		frappe.throw(_("BOM 1 {0} and BOM 2 {1} should not be same")
-			.format(frappe.bold(bom1), frappe.bold(bom2)))
+		frappe.throw(
+			_("BOM 1 {0} and BOM 2 {1} should not be same").format(frappe.bold(bom1), frappe.bold(bom2))
+		)
 
-	doc1 = frappe.get_doc('BOM', bom1)
-	doc2 = frappe.get_doc('BOM', bom2)
+	doc1 = frappe.get_doc("BOM", bom1)
+	doc2 = frappe.get_doc("BOM", bom2)
 
 	out = get_diff(doc1, doc2)
 	out.row_changed = []
@@ -1089,10 +1266,10 @@
 	meta = doc1.meta
 
 	identifiers = {
-		'operations': 'operation',
-		'items': 'item_code',
-		'scrap_items': 'item_code',
-		'exploded_items': 'item_code'
+		"operations": "operation",
+		"items": "item_code",
+		"scrap_items": "item_code",
+		"exploded_items": "item_code",
 	}
 
 	for df in meta.fields:
@@ -1123,6 +1300,7 @@
 
 	return out
 
+
 @frappe.whitelist()
 @frappe.validate_and_sanitize_search_inputs
 def item_query(doctype, txt, searchfield, start, page_len, filters):
@@ -1132,25 +1310,28 @@
 	order_by = "idx desc, name, item_name"
 
 	fields = ["name", "item_group", "item_name", "description"]
-	fields.extend([field for field in searchfields
-		if not field in ["name", "item_group", "description"]])
+	fields.extend(
+		[field for field in searchfields if not field in ["name", "item_group", "description"]]
+	)
 
-	searchfields = searchfields + [field for field in [searchfield or "name", "item_code", "item_group", "item_name"]
-		if not field in searchfields]
+	searchfields = searchfields + [
+		field
+		for field in [searchfield or "name", "item_code", "item_group", "item_name"]
+		if not field in searchfields
+	]
 
-	query_filters = {
-		"disabled": 0,
-		"ifnull(end_of_life, '5050-50-50')": (">", today())
-	}
+	query_filters = {"disabled": 0, "ifnull(end_of_life, '5050-50-50')": (">", today())}
 
 	or_cond_filters = {}
 	if txt:
 		for s_field in searchfields:
 			or_cond_filters[s_field] = ("like", "%{0}%".format(txt))
 
-		barcodes = frappe.get_all("Item Barcode",
+		barcodes = frappe.get_all(
+			"Item Barcode",
 			fields=["distinct parent as item_code"],
-			filters = {"barcode": ("like", "%{0}%".format(txt))})
+			filters={"barcode": ("like", "%{0}%".format(txt))},
+		)
 
 		barcodes = [d.item_code for d in barcodes]
 		if barcodes:
@@ -1164,10 +1345,17 @@
 	if filters and filters.get("is_stock_item"):
 		query_filters["is_stock_item"] = 1
 
-	return frappe.get_list("Item",
-		fields = fields, filters=query_filters,
-		or_filters = or_cond_filters, order_by=order_by,
-		limit_start=start, limit_page_length=page_len, as_list=1)
+	return frappe.get_list(
+		"Item",
+		fields=fields,
+		filters=query_filters,
+		or_filters=or_cond_filters,
+		order_by=order_by,
+		limit_start=start,
+		limit_page_length=page_len,
+		as_list=1,
+	)
+
 
 @frappe.whitelist()
 def make_variant_bom(source_name, bom_no, item, variant_items, target_doc=None):
@@ -1178,28 +1366,31 @@
 		doc.quantity = 1
 
 		item_data = get_item_details(item)
-		doc.update({
-			"item_name": item_data.item_name,
-			"description": item_data.description,
-			"uom": item_data.stock_uom,
-			"allow_alternative_item": item_data.allow_alternative_item
-		})
+		doc.update(
+			{
+				"item_name": item_data.item_name,
+				"description": item_data.description,
+				"uom": item_data.stock_uom,
+				"allow_alternative_item": item_data.allow_alternative_item,
+			}
+		)
 
 		add_variant_item(variant_items, doc, source_name)
 
-	doc = get_mapped_doc('BOM', source_name, {
-		'BOM': {
-			'doctype': 'BOM',
-			'validation': {
-				'docstatus': ['=', 1]
-			}
+	doc = get_mapped_doc(
+		"BOM",
+		source_name,
+		{
+			"BOM": {"doctype": "BOM", "validation": {"docstatus": ["=", 1]}},
+			"BOM Item": {
+				"doctype": "BOM Item",
+				# stop get_mapped_doc copying parent bom_no to children
+				"field_no_map": ["bom_no"],
+				"condition": lambda doc: doc.has_variants == 0,
+			},
 		},
-		'BOM Item': {
-			'doctype': 'BOM Item',
-			# stop get_mapped_doc copying parent bom_no to children
-			'field_no_map': ['bom_no'],
-			'condition': lambda doc: doc.has_variants == 0
-		},
-	}, target_doc, postprocess)
+		target_doc,
+		postprocess,
+	)
 
 	return doc
diff --git a/erpnext/manufacturing/doctype/bom/bom_dashboard.py b/erpnext/manufacturing/doctype/bom/bom_dashboard.py
index 0699f74..d8a810b 100644
--- a/erpnext/manufacturing/doctype/bom/bom_dashboard.py
+++ b/erpnext/manufacturing/doctype/bom/bom_dashboard.py
@@ -3,27 +3,28 @@
 
 def get_data():
 	return {
-		'fieldname': 'bom_no',
-		'non_standard_fieldnames': {
-			'Item': 'default_bom',
-			'Purchase Order': 'bom',
-			'Purchase Receipt': 'bom',
-			'Purchase Invoice': 'bom'
+		"fieldname": "bom_no",
+		"non_standard_fieldnames": {
+			"Item": "default_bom",
+			"Purchase Order": "bom",
+			"Purchase Receipt": "bom",
+			"Purchase Invoice": "bom",
 		},
-		'transactions': [
+		"transactions": [
+			{"label": _("Stock"), "items": ["Item", "Stock Entry", "Quality Inspection"]},
+			{"label": _("Manufacture"), "items": ["BOM", "Work Order", "Job Card"]},
 			{
-				'label': _('Stock'),
-				'items': ['Item', 'Stock Entry', 'Quality Inspection']
+				"label": _("Subcontract"),
+				"items": ["Purchase Order", "Purchase Receipt", "Purchase Invoice"],
 			},
-			{
-				'label': _('Manufacture'),
-				'items': ['BOM', 'Work Order', 'Job Card']
-			},
-			{
-				'label': _('Subcontract'),
-				'items': ['Purchase Order', 'Purchase Receipt', 'Purchase Invoice']
-			}
 		],
-		'disable_create_buttons': ["Item", "Purchase Order", "Purchase Receipt",
-			"Purchase Invoice", "Job Card", "Stock Entry", "BOM"]
+		"disable_create_buttons": [
+			"Item",
+			"Purchase Order",
+			"Purchase Receipt",
+			"Purchase Invoice",
+			"Job Card",
+			"Stock Entry",
+			"BOM",
+		],
 	}
diff --git a/erpnext/manufacturing/doctype/bom/test_bom.py b/erpnext/manufacturing/doctype/bom/test_bom.py
index 21e0006..524f45b 100644
--- a/erpnext/manufacturing/doctype/bom/test_bom.py
+++ b/erpnext/manufacturing/doctype/bom/test_bom.py
@@ -18,22 +18,27 @@
 )
 from erpnext.tests.test_subcontracting import set_backflush_based_on
 
-test_records = frappe.get_test_records('BOM')
+test_records = frappe.get_test_records("BOM")
 test_dependencies = ["Item", "Quality Inspection Template"]
 
+
 class TestBOM(FrappeTestCase):
 	def test_get_items(self):
 		from erpnext.manufacturing.doctype.bom.bom import get_bom_items_as_dict
-		items_dict = get_bom_items_as_dict(bom=get_default_bom(),
-			company="_Test Company", qty=1, fetch_exploded=0)
+
+		items_dict = get_bom_items_as_dict(
+			bom=get_default_bom(), company="_Test Company", qty=1, fetch_exploded=0
+		)
 		self.assertTrue(test_records[2]["items"][0]["item_code"] in items_dict)
 		self.assertTrue(test_records[2]["items"][1]["item_code"] in items_dict)
 		self.assertEqual(len(items_dict.values()), 2)
 
 	def test_get_items_exploded(self):
 		from erpnext.manufacturing.doctype.bom.bom import get_bom_items_as_dict
-		items_dict = get_bom_items_as_dict(bom=get_default_bom(),
-			company="_Test Company", qty=1, fetch_exploded=1)
+
+		items_dict = get_bom_items_as_dict(
+			bom=get_default_bom(), company="_Test Company", qty=1, fetch_exploded=1
+		)
 		self.assertTrue(test_records[2]["items"][0]["item_code"] in items_dict)
 		self.assertFalse(test_records[2]["items"][1]["item_code"] in items_dict)
 		self.assertTrue(test_records[0]["items"][0]["item_code"] in items_dict)
@@ -42,13 +47,14 @@
 
 	def test_get_items_list(self):
 		from erpnext.manufacturing.doctype.bom.bom import get_bom_items
+
 		self.assertEqual(len(get_bom_items(bom=get_default_bom(), company="_Test Company")), 3)
 
 	def test_default_bom(self):
 		def _get_default_bom_in_item():
 			return cstr(frappe.db.get_value("Item", "_Test FG Item 2", "default_bom"))
 
-		bom = frappe.get_doc("BOM", {"item":"_Test FG Item 2", "is_default": 1})
+		bom = frappe.get_doc("BOM", {"item": "_Test FG Item 2", "is_default": 1})
 		self.assertEqual(_get_default_bom_in_item(), bom.name)
 
 		bom.is_active = 0
@@ -56,28 +62,33 @@
 		self.assertEqual(_get_default_bom_in_item(), "")
 
 		bom.is_active = 1
-		bom.is_default=1
+		bom.is_default = 1
 		bom.save()
 
 		self.assertTrue(_get_default_bom_in_item(), bom.name)
 
 	def test_update_bom_cost_in_all_boms(self):
 		# get current rate for '_Test Item 2'
-		rm_rate = frappe.db.sql("""select rate from `tabBOM Item`
+		rm_rate = frappe.db.sql(
+			"""select rate from `tabBOM Item`
 			where parent='BOM-_Test Item Home Desktop Manufactured-001'
-			and item_code='_Test Item 2' and docstatus=1 and parenttype='BOM'""")
+			and item_code='_Test Item 2' and docstatus=1 and parenttype='BOM'"""
+		)
 		rm_rate = rm_rate[0][0] if rm_rate else 0
 
 		# Reset item valuation rate
-		reset_item_valuation_rate(item_code='_Test Item 2', qty=200, rate=rm_rate + 10)
+		reset_item_valuation_rate(item_code="_Test Item 2", qty=200, rate=rm_rate + 10)
 
 		# update cost of all BOMs based on latest valuation rate
 		update_cost()
 
 		# check if new valuation rate updated in all BOMs
-		for d in frappe.db.sql("""select rate from `tabBOM Item`
-			where item_code='_Test Item 2' and docstatus=1 and parenttype='BOM'""", as_dict=1):
-				self.assertEqual(d.rate, rm_rate + 10)
+		for d in frappe.db.sql(
+			"""select rate from `tabBOM Item`
+			where item_code='_Test Item 2' and docstatus=1 and parenttype='BOM'""",
+			as_dict=1,
+		):
+			self.assertEqual(d.rate, rm_rate + 10)
 
 	def test_bom_cost(self):
 		bom = frappe.copy_doc(test_records[2])
@@ -92,7 +103,9 @@
 		for row in bom.items:
 			raw_material_cost += row.amount
 
-		base_raw_material_cost = raw_material_cost * flt(bom.conversion_rate, bom.precision("conversion_rate"))
+		base_raw_material_cost = raw_material_cost * flt(
+			bom.conversion_rate, bom.precision("conversion_rate")
+		)
 		base_op_cost = op_cost * flt(bom.conversion_rate, bom.precision("conversion_rate"))
 
 		# test amounts in selected currency, almostEqual checks for 7 digits by default
@@ -120,14 +133,15 @@
 		for op_row in bom.operations:
 			self.assertAlmostEqual(op_row.cost_per_unit, op_row.operating_cost / 2)
 
-		self.assertAlmostEqual(bom.operating_cost, op_cost/2)
+		self.assertAlmostEqual(bom.operating_cost, op_cost / 2)
 		bom.delete()
 
 	def test_bom_cost_multi_uom_multi_currency_based_on_price_list(self):
 		frappe.db.set_value("Price List", "_Test Price List", "price_not_uom_dependent", 1)
 		for item_code, rate in (("_Test Item", 3600), ("_Test Item Home Desktop Manufactured", 3000)):
-			frappe.db.sql("delete from `tabItem Price` where price_list='_Test Price List' and item_code=%s",
-				item_code)
+			frappe.db.sql(
+				"delete from `tabItem Price` where price_list='_Test Price List' and item_code=%s", item_code
+			)
 			item_price = frappe.new_doc("Item Price")
 			item_price.price_list = "_Test Price List"
 			item_price.item_code = item_code
@@ -142,7 +156,7 @@
 		bom.items[0].conversion_factor = 5
 		bom.insert()
 
-		bom.update_cost(update_hour_rate = False)
+		bom.update_cost(update_hour_rate=False)
 
 		# test amounts in selected currency
 		self.assertEqual(bom.items[0].rate, 300)
@@ -167,11 +181,12 @@
 		bom.insert()
 
 		reset_item_valuation_rate(
-			item_code='_Test Item',
-			warehouse_list=frappe.get_all("Warehouse",
-				{"is_group":0, "company": bom.company}, pluck="name"),
+			item_code="_Test Item",
+			warehouse_list=frappe.get_all(
+				"Warehouse", {"is_group": 0, "company": bom.company}, pluck="name"
+			),
 			qty=200,
-			rate=200
+			rate=200,
 		)
 
 		bom.update_cost()
@@ -180,68 +195,64 @@
 
 	def test_subcontractor_sourced_item(self):
 		item_code = "_Test Subcontracted FG Item 1"
-		set_backflush_based_on('Material Transferred for Subcontract')
+		set_backflush_based_on("Material Transferred for Subcontract")
 
-		if not frappe.db.exists('Item', item_code):
-			make_item(item_code, {
-				'is_stock_item': 1,
-				'is_sub_contracted_item': 1,
-				'stock_uom': 'Nos'
-			})
+		if not frappe.db.exists("Item", item_code):
+			make_item(item_code, {"is_stock_item": 1, "is_sub_contracted_item": 1, "stock_uom": "Nos"})
 
-		if not frappe.db.exists('Item', "Test Extra Item 1"):
-			make_item("Test Extra Item 1", {
-				'is_stock_item': 1,
-				'stock_uom': 'Nos'
-			})
+		if not frappe.db.exists("Item", "Test Extra Item 1"):
+			make_item("Test Extra Item 1", {"is_stock_item": 1, "stock_uom": "Nos"})
 
-		if not frappe.db.exists('Item', "Test Extra Item 2"):
-			make_item("Test Extra Item 2", {
-				'is_stock_item': 1,
-				'stock_uom': 'Nos'
-			})
+		if not frappe.db.exists("Item", "Test Extra Item 2"):
+			make_item("Test Extra Item 2", {"is_stock_item": 1, "stock_uom": "Nos"})
 
-		if not frappe.db.exists('Item', "Test Extra Item 3"):
-			make_item("Test Extra Item 3", {
-				'is_stock_item': 1,
-				'stock_uom': 'Nos'
-			})
-		bom = frappe.get_doc({
-			'doctype': 'BOM',
-			'is_default': 1,
-			'item': item_code,
-			'currency': 'USD',
-			'quantity': 1,
-			'company': '_Test Company'
-		})
+		if not frappe.db.exists("Item", "Test Extra Item 3"):
+			make_item("Test Extra Item 3", {"is_stock_item": 1, "stock_uom": "Nos"})
+		bom = frappe.get_doc(
+			{
+				"doctype": "BOM",
+				"is_default": 1,
+				"item": item_code,
+				"currency": "USD",
+				"quantity": 1,
+				"company": "_Test Company",
+			}
+		)
 
 		for item in ["Test Extra Item 1", "Test Extra Item 2"]:
-			item_doc = frappe.get_doc('Item', item)
+			item_doc = frappe.get_doc("Item", item)
 
-			bom.append('items', {
-				'item_code': item,
-				'qty': 1,
-				'uom': item_doc.stock_uom,
-				'stock_uom': item_doc.stock_uom,
-				'rate': item_doc.valuation_rate
-			})
+			bom.append(
+				"items",
+				{
+					"item_code": item,
+					"qty": 1,
+					"uom": item_doc.stock_uom,
+					"stock_uom": item_doc.stock_uom,
+					"rate": item_doc.valuation_rate,
+				},
+			)
 
-		bom.append('items', {
-			'item_code': "Test Extra Item 3",
-			'qty': 1,
-			'uom': item_doc.stock_uom,
-			'stock_uom': item_doc.stock_uom,
-			'rate': 0,
-			'sourced_by_supplier': 1
-		})
+		bom.append(
+			"items",
+			{
+				"item_code": "Test Extra Item 3",
+				"qty": 1,
+				"uom": item_doc.stock_uom,
+				"stock_uom": item_doc.stock_uom,
+				"rate": 0,
+				"sourced_by_supplier": 1,
+			},
+		)
 		bom.insert(ignore_permissions=True)
 		bom.update_cost()
 		bom.submit()
 		# test that sourced_by_supplier rate is zero even after updating cost
 		self.assertEqual(bom.items[2].rate, 0)
 		# test in Purchase Order sourced_by_supplier is not added to Supplied Item
-		po = create_purchase_order(item_code=item_code, qty=1,
-			is_subcontracted="Yes", supplier_warehouse="_Test Warehouse 1 - _TC")
+		po = create_purchase_order(
+			item_code=item_code, qty=1, is_subcontracted="Yes", supplier_warehouse="_Test Warehouse 1 - _TC"
+		)
 		bom_items = sorted([d.item_code for d in bom.items if d.sourced_by_supplier != 1])
 		supplied_items = sorted([d.rm_item_code for d in po.supplied_items])
 		self.assertEqual(bom_items, supplied_items)
@@ -249,7 +260,10 @@
 	def test_bom_tree_representation(self):
 		bom_tree = {
 			"Assembly": {
-				"SubAssembly1": {"ChildPart1": {}, "ChildPart2": {},},
+				"SubAssembly1": {
+					"ChildPart1": {},
+					"ChildPart2": {},
+				},
 				"SubAssembly2": {"ChildPart3": {}},
 				"SubAssembly3": {"SubSubAssy1": {"ChildPart4": {}}},
 				"ChildPart5": {},
@@ -260,7 +274,7 @@
 		parent_bom = create_nested_bom(bom_tree, prefix="")
 		created_tree = parent_bom.get_tree_representation()
 
-		reqd_order = level_order_traversal(bom_tree)[1:] # skip first item
+		reqd_order = level_order_traversal(bom_tree)[1:]  # skip first item
 		created_order = created_tree.level_order_traversal()
 
 		self.assertEqual(len(reqd_order), len(created_order))
@@ -272,14 +286,23 @@
 		from erpnext.controllers.item_variant import create_variant
 
 		template_item = make_item(
-			"_TestTemplateItem", {"has_variants": 1, "attributes": [{"attribute": "Test Size"},]}
+			"_TestTemplateItem",
+			{
+				"has_variants": 1,
+				"attributes": [
+					{"attribute": "Test Size"},
+				],
+			},
 		)
 		variant = create_variant(template_item.item_code, {"Test Size": "Large"})
 		variant.insert(ignore_if_duplicate=True)
 
 		bom_tree = {
 			template_item.item_code: {
-				"SubAssembly1": {"ChildPart1": {}, "ChildPart2": {},},
+				"SubAssembly1": {
+					"ChildPart1": {},
+					"ChildPart2": {},
+				},
 				"ChildPart5": {},
 			}
 		}
@@ -302,7 +325,7 @@
 	def test_bom_recursion_1st_level(self):
 		"""BOM should not allow BOM item again in child"""
 		item_code = "_Test BOM Recursion"
-		make_item(item_code, {'is_stock_item': 1})
+		make_item(item_code, {"is_stock_item": 1})
 
 		bom = frappe.new_doc("BOM")
 		bom.item = item_code
@@ -316,8 +339,8 @@
 	def test_bom_recursion_transitive(self):
 		item1 = "_Test BOM Recursion"
 		item2 = "_Test BOM Recursion 2"
-		make_item(item1, {'is_stock_item': 1})
-		make_item(item2, {'is_stock_item': 1})
+		make_item(item1, {"is_stock_item": 1})
+		make_item(item2, {"is_stock_item": 1})
 
 		bom1 = frappe.new_doc("BOM")
 		bom1.item = item1
@@ -373,19 +396,29 @@
 		self.assertRaises(frappe.ValidationError, bom_doc.submit)
 
 	def test_bom_item_query(self):
-		query = partial(item_query, doctype="Item", txt="", searchfield="name", start=0, page_len=20, filters={"is_stock_item": 1})
+		query = partial(
+			item_query,
+			doctype="Item",
+			txt="",
+			searchfield="name",
+			start=0,
+			page_len=20,
+			filters={"is_stock_item": 1},
+		)
 
 		test_items = query(txt="_Test")
 		filtered = query(txt="_Test Item 2")
 
-		self.assertNotEqual(len(test_items), len(filtered), msg="Item filtering showing excessive results")
+		self.assertNotEqual(
+			len(test_items), len(filtered), msg="Item filtering showing excessive results"
+		)
 		self.assertTrue(0 < len(filtered) <= 3, msg="Item filtering showing excessive results")
 
 	def test_exclude_exploded_items_from_bom(self):
 		bom_no = get_default_bom()
-		new_bom = frappe.copy_doc(frappe.get_doc('BOM', bom_no))
+		new_bom = frappe.copy_doc(frappe.get_doc("BOM", bom_no))
 		for row in new_bom.items:
-			if row.item_code == '_Test Item Home Desktop Manufactured':
+			if row.item_code == "_Test Item Home Desktop Manufactured":
 				self.assertTrue(row.bom_no)
 				row.do_not_explode = True
 
@@ -394,13 +427,15 @@
 		new_bom.load_from_db()
 
 		for row in new_bom.items:
-			if row.item_code == '_Test Item Home Desktop Manufactured' and row.do_not_explode:
+			if row.item_code == "_Test Item Home Desktop Manufactured" and row.do_not_explode:
 				self.assertFalse(row.bom_no)
 
 		new_bom.delete()
 
 	def test_valid_transfer_defaults(self):
-		bom_with_op = frappe.db.get_value("BOM", {"item": "_Test FG Item 2", "with_operations": 1, "is_active": 1})
+		bom_with_op = frappe.db.get_value(
+			"BOM", {"item": "_Test FG Item 2", "with_operations": 1, "is_active": 1}
+		)
 		bom = frappe.copy_doc(frappe.get_doc("BOM", bom_with_op), ignore_no_copy=False)
 
 		# test defaults
@@ -429,12 +464,8 @@
 		bom.delete()
 
 	def test_bom_name_length(self):
-		""" test >140 char names"""
-		bom_tree = {
-			"x" * 140 : {
-				" ".join(["abc"] * 35): {}
-			}
-		}
+		"""test >140 char names"""
+		bom_tree = {"x" * 140: {" ".join(["abc"] * 35): {}}}
 		create_nested_bom(bom_tree, prefix="")
 
 	def test_version_index(self):
@@ -452,15 +483,14 @@
 
 		for expected_index, existing_boms in version_index_test_cases:
 			with self.subTest():
-				self.assertEqual(expected_index, bom.get_next_version_index(existing_boms),
-						msg=f"Incorrect index for {existing_boms}")
+				self.assertEqual(
+					expected_index,
+					bom.get_next_version_index(existing_boms),
+					msg=f"Incorrect index for {existing_boms}",
+				)
 
 	def test_bom_versioning(self):
-		bom_tree = {
-			frappe.generate_hash(length=10) : {
-				frappe.generate_hash(length=10): {}
-			}
-		}
+		bom_tree = {frappe.generate_hash(length=10): {frappe.generate_hash(length=10): {}}}
 		bom = create_nested_bom(bom_tree, prefix="")
 		self.assertEqual(int(bom.name.split("-")[-1]), 1)
 		original_bom_name = bom.name
@@ -501,7 +531,7 @@
 		bom.save()
 		bom.reload()
 
-		self.assertEqual(bom.quality_inspection_template, '_Test Quality Inspection Template')
+		self.assertEqual(bom.quality_inspection_template, "_Test Quality Inspection Template")
 
 		bom.inspection_required = 0
 		bom.save()
@@ -514,8 +544,7 @@
 
 		parent = frappe.generate_hash(length=10)
 		child = frappe.generate_hash(length=10)
-		bom_tree = {parent: {child: {}}
-		}
+		bom_tree = {parent: {child: {}}}
 		bom = create_nested_bom(bom_tree, prefix="")
 
 		# add last purchase price
@@ -534,6 +563,7 @@
 def get_default_bom(item_code="_Test FG Item 2"):
 	return frappe.db.get_value("BOM", {"item": item_code, "is_active": 1, "is_default": 1})
 
+
 def level_order_traversal(node):
 	traversal = []
 	q = deque()
@@ -548,9 +578,9 @@
 
 	return traversal
 
+
 def create_nested_bom(tree, prefix="_Test bom "):
-	""" Helper function to create a simple nested bom from tree describing item names. (along with required items)
-	"""
+	"""Helper function to create a simple nested bom from tree describing item names. (along with required items)"""
 
 	def create_items(bom_tree):
 		for item_code, subtree in bom_tree.items():
@@ -558,6 +588,7 @@
 			if not frappe.db.exists("Item", bom_item_code):
 				frappe.get_doc(doctype="Item", item_code=bom_item_code, item_group="_Test Item Group").insert()
 			create_items(subtree)
+
 	create_items(tree)
 
 	def dfs(tree, node):
@@ -592,10 +623,13 @@
 		warehouse_list = [warehouse_list]
 
 	if not warehouse_list:
-		warehouse_list = frappe.db.sql_list("""
+		warehouse_list = frappe.db.sql_list(
+			"""
 			select warehouse from `tabBin`
 			where item_code=%s and actual_qty > 0
-		""", item_code)
+		""",
+			item_code,
+		)
 
 		if not warehouse_list:
 			warehouse_list.append("_Test Warehouse - _TC")
@@ -603,44 +637,51 @@
 	for warehouse in warehouse_list:
 		create_stock_reconciliation(item_code=item_code, warehouse=warehouse, qty=qty, rate=rate)
 
+
 def create_bom_with_process_loss_item(
-		fg_item, bom_item, scrap_qty, scrap_rate, fg_qty=2, is_process_loss=1):
+	fg_item, bom_item, scrap_qty, scrap_rate, fg_qty=2, is_process_loss=1
+):
 	bom_doc = frappe.new_doc("BOM")
 	bom_doc.item = fg_item.item_code
 	bom_doc.quantity = fg_qty
-	bom_doc.append("items", {
-		"item_code": bom_item.item_code,
-		"qty": 1,
-		"uom": bom_item.stock_uom,
-		"stock_uom": bom_item.stock_uom,
-		"rate": 100.0
-	})
-	bom_doc.append("scrap_items", {
-		"item_code": fg_item.item_code,
-		"qty": scrap_qty,
-		"stock_qty": scrap_qty,
-		"uom": fg_item.stock_uom,
-		"stock_uom": fg_item.stock_uom,
-		"rate": scrap_rate,
-		"is_process_loss": is_process_loss
-	})
+	bom_doc.append(
+		"items",
+		{
+			"item_code": bom_item.item_code,
+			"qty": 1,
+			"uom": bom_item.stock_uom,
+			"stock_uom": bom_item.stock_uom,
+			"rate": 100.0,
+		},
+	)
+	bom_doc.append(
+		"scrap_items",
+		{
+			"item_code": fg_item.item_code,
+			"qty": scrap_qty,
+			"stock_qty": scrap_qty,
+			"uom": fg_item.stock_uom,
+			"stock_uom": fg_item.stock_uom,
+			"rate": scrap_rate,
+			"is_process_loss": is_process_loss,
+		},
+	)
 	bom_doc.currency = "INR"
 	return bom_doc
 
+
 def create_process_loss_bom_items():
 	item_list = [
 		("_Test Item - Non Whole UOM", "Kg"),
 		("_Test Item - Whole UOM", "Unit"),
-		("_Test PL BOM Item", "Unit")
+		("_Test PL BOM Item", "Unit"),
 	]
 	return [create_process_loss_bom_item(it) for it in item_list]
 
+
 def create_process_loss_bom_item(item_tuple):
 	item_code, stock_uom = item_tuple
 	if frappe.db.exists("Item", item_code) is None:
-		return make_item(
-			item_code,
-			{'stock_uom':stock_uom, 'valuation_rate':100}
-		)
+		return make_item(item_code, {"stock_uom": stock_uom, "valuation_rate": 100})
 	else:
 		return frappe.get_doc("Item", item_code)
diff --git a/erpnext/manufacturing/doctype/bom_update_tool/bom_update_tool.py b/erpnext/manufacturing/doctype/bom_update_tool/bom_update_tool.py
index 0e3955f..00711ca 100644
--- a/erpnext/manufacturing/doctype/bom_update_tool/bom_update_tool.py
+++ b/erpnext/manufacturing/doctype/bom_update_tool/bom_update_tool.py
@@ -20,14 +20,14 @@
 		unit_cost = get_new_bom_unit_cost(self.new_bom)
 		self.update_new_bom(unit_cost)
 
-		frappe.cache().delete_key('bom_children')
+		frappe.cache().delete_key("bom_children")
 		bom_list = self.get_parent_boms(self.new_bom)
 
 		with click.progressbar(bom_list) as bom_list:
 			pass
 		for bom in bom_list:
 			try:
-				bom_obj = frappe.get_cached_doc('BOM', bom)
+				bom_obj = frappe.get_cached_doc("BOM", bom)
 				# this is only used for versioning and we do not want
 				# to make separate db calls by using load_doc_before_save
 				# which proves to be expensive while doing bulk replace
@@ -37,7 +37,7 @@
 				bom_obj.calculate_cost()
 				bom_obj.update_parent_cost()
 				bom_obj.db_update()
-				if bom_obj.meta.get('track_changes') and not bom_obj.flags.ignore_version:
+				if bom_obj.meta.get("track_changes") and not bom_obj.flags.ignore_version:
 					bom_obj.save_version()
 			except Exception:
 				frappe.log_error(frappe.get_traceback())
@@ -46,20 +46,26 @@
 		if cstr(self.current_bom) == cstr(self.new_bom):
 			frappe.throw(_("Current BOM and New BOM can not be same"))
 
-		if frappe.db.get_value("BOM", self.current_bom, "item") \
-			!= frappe.db.get_value("BOM", self.new_bom, "item"):
-				frappe.throw(_("The selected BOMs are not for the same item"))
+		if frappe.db.get_value("BOM", self.current_bom, "item") != frappe.db.get_value(
+			"BOM", self.new_bom, "item"
+		):
+			frappe.throw(_("The selected BOMs are not for the same item"))
 
 	def update_new_bom(self, unit_cost):
-		frappe.db.sql("""update `tabBOM Item` set bom_no=%s,
+		frappe.db.sql(
+			"""update `tabBOM Item` set bom_no=%s,
 			rate=%s, amount=stock_qty*%s where bom_no = %s and docstatus < 2 and parenttype='BOM'""",
-			(self.new_bom, unit_cost, unit_cost, self.current_bom))
+			(self.new_bom, unit_cost, unit_cost, self.current_bom),
+		)
 
 	def get_parent_boms(self, bom, bom_list=None):
 		if bom_list is None:
 			bom_list = []
-		data = frappe.db.sql("""SELECT DISTINCT parent FROM `tabBOM Item`
-			WHERE bom_no = %s AND docstatus < 2 AND parenttype='BOM'""", bom)
+		data = frappe.db.sql(
+			"""SELECT DISTINCT parent FROM `tabBOM Item`
+			WHERE bom_no = %s AND docstatus < 2 AND parenttype='BOM'""",
+			bom,
+		)
 
 		for d in data:
 			if self.new_bom == d[0]:
@@ -70,29 +76,45 @@
 
 		return list(set(bom_list))
 
+
 def get_new_bom_unit_cost(bom):
-	new_bom_unitcost = frappe.db.sql("""SELECT `total_cost`/`quantity`
-		FROM `tabBOM` WHERE name = %s""", bom)
+	new_bom_unitcost = frappe.db.sql(
+		"""SELECT `total_cost`/`quantity`
+		FROM `tabBOM` WHERE name = %s""",
+		bom,
+	)
 
 	return flt(new_bom_unitcost[0][0]) if new_bom_unitcost else 0
 
+
 @frappe.whitelist()
 def enqueue_replace_bom(args):
 	if isinstance(args, str):
 		args = json.loads(args)
 
-	frappe.enqueue("erpnext.manufacturing.doctype.bom_update_tool.bom_update_tool.replace_bom", args=args, timeout=40000)
+	frappe.enqueue(
+		"erpnext.manufacturing.doctype.bom_update_tool.bom_update_tool.replace_bom",
+		args=args,
+		timeout=40000,
+	)
 	frappe.msgprint(_("Queued for replacing the BOM. It may take a few minutes."))
 
+
 @frappe.whitelist()
 def enqueue_update_cost():
-	frappe.enqueue("erpnext.manufacturing.doctype.bom_update_tool.bom_update_tool.update_cost", timeout=40000)
-	frappe.msgprint(_("Queued for updating latest price in all Bill of Materials. It may take a few minutes."))
+	frappe.enqueue(
+		"erpnext.manufacturing.doctype.bom_update_tool.bom_update_tool.update_cost", timeout=40000
+	)
+	frappe.msgprint(
+		_("Queued for updating latest price in all Bill of Materials. It may take a few minutes.")
+	)
+
 
 def update_latest_price_in_all_boms():
 	if frappe.db.get_single_value("Manufacturing Settings", "update_bom_costs_automatically"):
 		update_cost()
 
+
 def replace_bom(args):
 	frappe.db.auto_commit_on_many_writes = 1
 	args = frappe._dict(args)
@@ -104,6 +126,7 @@
 
 	frappe.db.auto_commit_on_many_writes = 0
 
+
 def update_cost():
 	frappe.db.auto_commit_on_many_writes = 1
 	bom_list = get_boms_in_bottom_up_order()
diff --git a/erpnext/manufacturing/doctype/bom_update_tool/test_bom_update_tool.py b/erpnext/manufacturing/doctype/bom_update_tool/test_bom_update_tool.py
index b4c625d..57785e5 100644
--- a/erpnext/manufacturing/doctype/bom_update_tool/test_bom_update_tool.py
+++ b/erpnext/manufacturing/doctype/bom_update_tool/test_bom_update_tool.py
@@ -8,7 +8,8 @@
 from erpnext.manufacturing.doctype.production_plan.test_production_plan import make_bom
 from erpnext.stock.doctype.item.test_item import create_item
 
-test_records = frappe.get_test_records('BOM')
+test_records = frappe.get_test_records("BOM")
+
 
 class TestBOMUpdateTool(FrappeTestCase):
 	def test_replace_bom(self):
@@ -37,10 +38,13 @@
 			if item_doc.valuation_rate != 100.00:
 				frappe.db.set_value("Item", item_doc.name, "valuation_rate", 100)
 
-		bom_no = frappe.db.get_value('BOM', {'item': 'BOM Cost Test Item 1'}, "name")
+		bom_no = frappe.db.get_value("BOM", {"item": "BOM Cost Test Item 1"}, "name")
 		if not bom_no:
-			doc = make_bom(item = 'BOM Cost Test Item 1',
-				raw_materials =['BOM Cost Test Item 2', 'BOM Cost Test Item 3'], currency="INR")
+			doc = make_bom(
+				item="BOM Cost Test Item 1",
+				raw_materials=["BOM Cost Test Item 2", "BOM Cost Test Item 3"],
+				currency="INR",
+			)
 		else:
 			doc = frappe.get_doc("BOM", bom_no)
 
diff --git a/erpnext/manufacturing/doctype/job_card/job_card.py b/erpnext/manufacturing/doctype/job_card/job_card.py
index 960d0e5..bf4f82f 100644
--- a/erpnext/manufacturing/doctype/job_card/job_card.py
+++ b/erpnext/manufacturing/doctype/job_card/job_card.py
@@ -26,15 +26,27 @@
 )
 
 
-class OverlapError(frappe.ValidationError): pass
+class OverlapError(frappe.ValidationError):
+	pass
 
-class OperationMismatchError(frappe.ValidationError): pass
-class OperationSequenceError(frappe.ValidationError): pass
-class JobCardCancelError(frappe.ValidationError): pass
+
+class OperationMismatchError(frappe.ValidationError):
+	pass
+
+
+class OperationSequenceError(frappe.ValidationError):
+	pass
+
+
+class JobCardCancelError(frappe.ValidationError):
+	pass
+
 
 class JobCard(Document):
 	def onload(self):
-		excess_transfer = frappe.db.get_single_value("Manufacturing Settings", "job_card_excess_transfer")
+		excess_transfer = frappe.db.get_single_value(
+			"Manufacturing Settings", "job_card_excess_transfer"
+		)
 		self.set_onload("job_card_excess_transfer", excess_transfer)
 		self.set_onload("work_order_closed", self.is_work_order_closed())
 
@@ -50,25 +62,33 @@
 	def set_sub_operations(self):
 		if not self.sub_operations and self.operation:
 			self.sub_operations = []
-			for row in frappe.get_all('Sub Operation',
-				filters = {'parent': self.operation}, fields=['operation', 'idx'], order_by='idx'):
-				row.status = 'Pending'
+			for row in frappe.get_all(
+				"Sub Operation",
+				filters={"parent": self.operation},
+				fields=["operation", "idx"],
+				order_by="idx",
+			):
+				row.status = "Pending"
 				row.sub_operation = row.operation
-				self.append('sub_operations', row)
+				self.append("sub_operations", row)
 
 	def validate_time_logs(self):
 		self.total_time_in_mins = 0.0
 		self.total_completed_qty = 0.0
 
-		if self.get('time_logs'):
-			for d in self.get('time_logs'):
+		if self.get("time_logs"):
+			for d in self.get("time_logs"):
 				if d.to_time and get_datetime(d.from_time) > get_datetime(d.to_time):
 					frappe.throw(_("Row {0}: From time must be less than to time").format(d.idx))
 
 				data = self.get_overlap_for(d)
 				if data:
-					frappe.throw(_("Row {0}: From Time and To Time of {1} is overlapping with {2}")
-						.format(d.idx, self.name, data.name), OverlapError)
+					frappe.throw(
+						_("Row {0}: From Time and To Time of {1} is overlapping with {2}").format(
+							d.idx, self.name, data.name
+						),
+						OverlapError,
+					)
 
 				if d.from_time and d.to_time:
 					d.time_in_mins = time_diff_in_hours(d.to_time, d.from_time) * 60
@@ -86,8 +106,9 @@
 		production_capacity = 1
 
 		if self.workstation:
-			production_capacity = frappe.get_cached_value("Workstation",
-				self.workstation, 'production_capacity') or 1
+			production_capacity = (
+				frappe.get_cached_value("Workstation", self.workstation, "production_capacity") or 1
+			)
 			validate_overlap_for = " and jc.workstation = %(workstation)s "
 
 		if args.get("employee"):
@@ -95,11 +116,12 @@
 			production_capacity = 1
 			validate_overlap_for = " and jctl.employee = %(employee)s "
 
-		extra_cond = ''
+		extra_cond = ""
 		if check_next_available_slot:
 			extra_cond = " or (%(from_time)s <= jctl.from_time and %(to_time)s <= jctl.to_time)"
 
-		existing = frappe.db.sql("""select jc.name as name, jctl.to_time from
+		existing = frappe.db.sql(
+			"""select jc.name as name, jctl.to_time from
 			`tabJob Card Time Log` jctl, `tabJob Card` jc where jctl.parent = jc.name and
 			(
 				(%(from_time)s > jctl.from_time and %(from_time)s < jctl.to_time) or
@@ -107,15 +129,19 @@
 				(%(from_time)s <= jctl.from_time and %(to_time)s >= jctl.to_time) {0}
 			)
 			and jctl.name != %(name)s and jc.name != %(parent)s and jc.docstatus < 2 {1}
-			order by jctl.to_time desc limit 1""".format(extra_cond, validate_overlap_for),
+			order by jctl.to_time desc limit 1""".format(
+				extra_cond, validate_overlap_for
+			),
 			{
 				"from_time": args.from_time,
 				"to_time": args.to_time,
 				"name": args.name or "No Name",
 				"parent": args.parent or "No Name",
 				"employee": args.get("employee"),
-				"workstation": self.workstation
-			}, as_dict=True)
+				"workstation": self.workstation,
+			},
+			as_dict=True,
+		)
 
 		if existing and production_capacity > len(existing):
 			return
@@ -125,10 +151,7 @@
 	def schedule_time_logs(self, row):
 		row.remaining_time_in_mins = row.time_in_mins
 		while row.remaining_time_in_mins > 0:
-			args = frappe._dict({
-				"from_time": row.planned_start_time,
-				"to_time": row.planned_end_time
-			})
+			args = frappe._dict({"from_time": row.planned_start_time, "to_time": row.planned_end_time})
 
 			self.validate_overlap_for_workstation(args, row)
 			self.check_workstation_time(row)
@@ -141,13 +164,16 @@
 
 	def check_workstation_time(self, row):
 		workstation_doc = frappe.get_cached_doc("Workstation", self.workstation)
-		if (not workstation_doc.working_hours or
-			cint(frappe.db.get_single_value("Manufacturing Settings", "allow_overtime"))):
+		if not workstation_doc.working_hours or cint(
+			frappe.db.get_single_value("Manufacturing Settings", "allow_overtime")
+		):
 			if get_datetime(row.planned_end_time) < get_datetime(row.planned_start_time):
 				row.planned_end_time = add_to_date(row.planned_start_time, minutes=row.time_in_mins)
 				row.remaining_time_in_mins = 0.0
 			else:
-				row.remaining_time_in_mins -= time_diff_in_minutes(row.planned_end_time, row.planned_start_time)
+				row.remaining_time_in_mins -= time_diff_in_minutes(
+					row.planned_end_time, row.planned_start_time
+				)
 
 			self.update_time_logs(row)
 			return
@@ -167,14 +193,15 @@
 			workstation_start_time = datetime.datetime.combine(start_date, get_time(time_slot.start_time))
 			workstation_end_time = datetime.datetime.combine(start_date, get_time(time_slot.end_time))
 
-			if (get_datetime(row.planned_start_time) >= workstation_start_time and
-				get_datetime(row.planned_start_time) <= workstation_end_time):
+			if (
+				get_datetime(row.planned_start_time) >= workstation_start_time
+				and get_datetime(row.planned_start_time) <= workstation_end_time
+			):
 				time_in_mins = time_diff_in_minutes(workstation_end_time, row.planned_start_time)
 
 				# If remaining time fit in workstation time logs else split hours as per workstation time
 				if time_in_mins > row.remaining_time_in_mins:
-					row.planned_end_time = add_to_date(row.planned_start_time,
-						minutes=row.remaining_time_in_mins)
+					row.planned_end_time = add_to_date(row.planned_start_time, minutes=row.remaining_time_in_mins)
 					row.remaining_time_in_mins = 0
 				else:
 					row.planned_end_time = add_to_date(row.planned_start_time, minutes=time_in_mins)
@@ -182,14 +209,16 @@
 
 				self.update_time_logs(row)
 
-				if total_idx != (i+1) and row.remaining_time_in_mins > 0:
-					row.planned_start_time = datetime.datetime.combine(start_date,
-						get_time(workstation_doc.working_hours[i+1].start_time))
+				if total_idx != (i + 1) and row.remaining_time_in_mins > 0:
+					row.planned_start_time = datetime.datetime.combine(
+						start_date, get_time(workstation_doc.working_hours[i + 1].start_time)
+					)
 
 		if row.remaining_time_in_mins > 0:
 			start_date = add_days(start_date, 1)
-			row.planned_start_time = datetime.datetime.combine(start_date,
-				get_time(workstation_doc.working_hours[0].start_time))
+			row.planned_start_time = datetime.datetime.combine(
+				start_date, get_time(workstation_doc.working_hours[0].start_time)
+			)
 
 	def add_time_log(self, args):
 		last_row = []
@@ -204,21 +233,25 @@
 		if last_row and args.get("complete_time"):
 			for row in self.time_logs:
 				if not row.to_time:
-					row.update({
-						"to_time": get_datetime(args.get("complete_time")),
-						"operation": args.get("sub_operation"),
-						"completed_qty": args.get("completed_qty") or 0.0
-					})
+					row.update(
+						{
+							"to_time": get_datetime(args.get("complete_time")),
+							"operation": args.get("sub_operation"),
+							"completed_qty": args.get("completed_qty") or 0.0,
+						}
+					)
 		elif args.get("start_time"):
-			new_args = frappe._dict({
-				"from_time": get_datetime(args.get("start_time")),
-				"operation": args.get("sub_operation"),
-				"completed_qty": 0.0
-			})
+			new_args = frappe._dict(
+				{
+					"from_time": get_datetime(args.get("start_time")),
+					"operation": args.get("sub_operation"),
+					"completed_qty": 0.0,
+				}
+			)
 
 			if employees:
 				for name in employees:
-					new_args.employee = name.get('employee')
+					new_args.employee = name.get("employee")
 					self.add_start_time_log(new_args)
 			else:
 				self.add_start_time_log(new_args)
@@ -236,10 +269,7 @@
 
 	def set_employees(self, employees):
 		for name in employees:
-			self.append('employee', {
-				'employee': name.get('employee'),
-				'completed_qty': 0.0
-			})
+			self.append("employee", {"employee": name.get("employee"), "completed_qty": 0.0})
 
 	def reset_timer_value(self, args):
 		self.started_time = None
@@ -263,13 +293,17 @@
 		operation_wise_completed_time = {}
 		for time_log in self.time_logs:
 			if time_log.operation not in operation_wise_completed_time:
-				operation_wise_completed_time.setdefault(time_log.operation,
-					frappe._dict({"status": "Pending", "completed_qty":0.0, "completed_time": 0.0, "employee": []}))
+				operation_wise_completed_time.setdefault(
+					time_log.operation,
+					frappe._dict(
+						{"status": "Pending", "completed_qty": 0.0, "completed_time": 0.0, "employee": []}
+					),
+				)
 
 			op_row = operation_wise_completed_time[time_log.operation]
 			op_row.status = "Work In Progress" if not time_log.time_in_mins else "Complete"
-			if self.status == 'On Hold':
-				op_row.status = 'Pause'
+			if self.status == "On Hold":
+				op_row.status = "Pause"
 
 			op_row.employee.append(time_log.employee)
 			if time_log.time_in_mins:
@@ -279,7 +313,7 @@
 		for row in self.sub_operations:
 			operation_deatils = operation_wise_completed_time.get(row.sub_operation)
 			if operation_deatils:
-				if row.status != 'Complete':
+				if row.status != "Complete":
 					row.status = operation_deatils.status
 
 				row.completed_time = operation_deatils.completed_time
@@ -289,43 +323,52 @@
 					if operation_deatils.completed_qty:
 						row.completed_qty = operation_deatils.completed_qty / len(set(operation_deatils.employee))
 			else:
-				row.status = 'Pending'
+				row.status = "Pending"
 				row.completed_time = 0.0
 				row.completed_qty = 0.0
 
 	def update_time_logs(self, row):
-		self.append("time_logs", {
-			"from_time": row.planned_start_time,
-			"to_time": row.planned_end_time,
-			"completed_qty": 0,
-			"time_in_mins": time_diff_in_minutes(row.planned_end_time, row.planned_start_time),
-		})
+		self.append(
+			"time_logs",
+			{
+				"from_time": row.planned_start_time,
+				"to_time": row.planned_end_time,
+				"completed_qty": 0,
+				"time_in_mins": time_diff_in_minutes(row.planned_end_time, row.planned_start_time),
+			},
+		)
 
 	@frappe.whitelist()
 	def get_required_items(self):
-		if not self.get('work_order'):
+		if not self.get("work_order"):
 			return
 
-		doc = frappe.get_doc('Work Order', self.get('work_order'))
-		if doc.transfer_material_against == 'Work Order' or doc.skip_transfer:
+		doc = frappe.get_doc("Work Order", self.get("work_order"))
+		if doc.transfer_material_against == "Work Order" or doc.skip_transfer:
 			return
 
 		for d in doc.required_items:
 			if not d.operation:
-				frappe.throw(_("Row {0} : Operation is required against the raw material item {1}")
-					.format(d.idx, d.item_code))
+				frappe.throw(
+					_("Row {0} : Operation is required against the raw material item {1}").format(
+						d.idx, d.item_code
+					)
+				)
 
-			if self.get('operation') == d.operation:
-				self.append('items', {
-					"item_code": d.item_code,
-					"source_warehouse": d.source_warehouse,
-					"uom": frappe.db.get_value("Item", d.item_code, 'stock_uom'),
-					"item_name": d.item_name,
-					"description": d.description,
-					"required_qty": (d.required_qty * flt(self.for_quantity)) / doc.qty,
-					"rate": d.rate,
-					"amount": d.amount
-				})
+			if self.get("operation") == d.operation:
+				self.append(
+					"items",
+					{
+						"item_code": d.item_code,
+						"source_warehouse": d.source_warehouse,
+						"uom": frappe.db.get_value("Item", d.item_code, "stock_uom"),
+						"item_name": d.item_name,
+						"description": d.description,
+						"required_qty": (d.required_qty * flt(self.for_quantity)) / doc.qty,
+						"rate": d.rate,
+						"amount": d.amount,
+					},
+				)
 
 	def on_submit(self):
 		self.validate_transfer_qty()
@@ -339,31 +382,52 @@
 
 	def validate_transfer_qty(self):
 		if self.items and self.transferred_qty < self.for_quantity:
-			frappe.throw(_('Materials needs to be transferred to the work in progress warehouse for the job card {0}')
-				.format(self.name))
+			frappe.throw(
+				_(
+					"Materials needs to be transferred to the work in progress warehouse for the job card {0}"
+				).format(self.name)
+			)
 
 	def validate_job_card(self):
-		if self.work_order and frappe.get_cached_value('Work Order', self.work_order, 'status') == 'Stopped':
-			frappe.throw(_("Transaction not allowed against stopped Work Order {0}")
-				.format(get_link_to_form('Work Order', self.work_order)))
+		if (
+			self.work_order
+			and frappe.get_cached_value("Work Order", self.work_order, "status") == "Stopped"
+		):
+			frappe.throw(
+				_("Transaction not allowed against stopped Work Order {0}").format(
+					get_link_to_form("Work Order", self.work_order)
+				)
+			)
 
 		if not self.time_logs:
-			frappe.throw(_("Time logs are required for {0} {1}")
-				.format(bold("Job Card"), get_link_to_form("Job Card", self.name)))
+			frappe.throw(
+				_("Time logs are required for {0} {1}").format(
+					bold("Job Card"), get_link_to_form("Job Card", self.name)
+				)
+			)
 
 		if self.for_quantity and self.total_completed_qty != self.for_quantity:
 			total_completed_qty = bold(_("Total Completed Qty"))
 			qty_to_manufacture = bold(_("Qty to Manufacture"))
 
-			frappe.throw(_("The {0} ({1}) must be equal to {2} ({3})")
-				.format(total_completed_qty, bold(self.total_completed_qty), qty_to_manufacture,bold(self.for_quantity)))
+			frappe.throw(
+				_("The {0} ({1}) must be equal to {2} ({3})").format(
+					total_completed_qty,
+					bold(self.total_completed_qty),
+					qty_to_manufacture,
+					bold(self.for_quantity),
+				)
+			)
 
 	def update_work_order(self):
 		if not self.work_order:
 			return
 
-		if self.is_corrective_job_card and not cint(frappe.db.get_single_value('Manufacturing Settings',
-			'add_corrective_operation_cost_in_finished_good_valuation')):
+		if self.is_corrective_job_card and not cint(
+			frappe.db.get_single_value(
+				"Manufacturing Settings", "add_corrective_operation_cost_in_finished_good_valuation"
+			)
+		):
 			return
 
 		for_quantity, time_in_mins = 0, 0
@@ -375,7 +439,7 @@
 			for_quantity = flt(data[0].completed_qty)
 			time_in_mins = flt(data[0].time_in_mins)
 
-		wo = frappe.get_doc('Work Order', self.work_order)
+		wo = frappe.get_doc("Work Order", self.work_order)
 
 		if self.is_corrective_job_card:
 			self.update_corrective_in_work_order(wo)
@@ -386,8 +450,11 @@
 
 	def update_corrective_in_work_order(self, wo):
 		wo.corrective_operation_cost = 0.0
-		for row in frappe.get_all('Job Card', fields = ['total_time_in_mins', 'hour_rate'],
-			filters = {'is_corrective_job_card': 1, 'docstatus': 1, 'work_order': self.work_order}):
+		for row in frappe.get_all(
+			"Job Card",
+			fields=["total_time_in_mins", "hour_rate"],
+			filters={"is_corrective_job_card": 1, "docstatus": 1, "work_order": self.work_order},
+		):
 			wo.corrective_operation_cost += flt(row.total_time_in_mins) * flt(row.hour_rate)
 
 		wo.calculate_operating_cost()
@@ -395,27 +462,37 @@
 		wo.save()
 
 	def validate_produced_quantity(self, for_quantity, wo):
-		if self.docstatus < 2: return
+		if self.docstatus < 2:
+			return
 
 		if wo.produced_qty > for_quantity:
-			first_part_msg = (_("The {0} {1} is used to calculate the valuation cost for the finished good {2}.")
-				.format(frappe.bold(_("Job Card")), frappe.bold(self.name), frappe.bold(self.production_item)))
+			first_part_msg = _(
+				"The {0} {1} is used to calculate the valuation cost for the finished good {2}."
+			).format(
+				frappe.bold(_("Job Card")), frappe.bold(self.name), frappe.bold(self.production_item)
+			)
 
-			second_part_msg = (_("Kindly cancel the Manufacturing Entries first against the work order {0}.")
-				.format(frappe.bold(get_link_to_form("Work Order", self.work_order))))
+			second_part_msg = _(
+				"Kindly cancel the Manufacturing Entries first against the work order {0}."
+			).format(frappe.bold(get_link_to_form("Work Order", self.work_order)))
 
-			frappe.throw(_("{0} {1}").format(first_part_msg, second_part_msg),
-				JobCardCancelError, title = _("Error"))
+			frappe.throw(
+				_("{0} {1}").format(first_part_msg, second_part_msg), JobCardCancelError, title=_("Error")
+			)
 
 	def update_work_order_data(self, for_quantity, time_in_mins, wo):
-		time_data = frappe.db.sql("""
+		time_data = frappe.db.sql(
+			"""
 				SELECT
 					min(from_time) as start_time, max(to_time) as end_time
 				FROM `tabJob Card` jc, `tabJob Card Time Log` jctl
 				WHERE
 					jctl.parent = jc.name and jc.work_order = %s and jc.operation_id = %s
 					and jc.docstatus = 1 and IFNULL(jc.is_corrective_job_card, 0) = 0
-			""", (self.work_order, self.operation_id), as_dict=1)
+			""",
+			(self.work_order, self.operation_id),
+			as_dict=1,
+		)
 
 		for data in wo.operations:
 			if data.get("name") == self.operation_id:
@@ -434,91 +511,118 @@
 		wo.save()
 
 	def get_current_operation_data(self):
-		return frappe.get_all('Job Card',
-			fields = ["sum(total_time_in_mins) as time_in_mins", "sum(total_completed_qty) as completed_qty"],
-			filters = {"docstatus": 1, "work_order": self.work_order, "operation_id": self.operation_id,
-				"is_corrective_job_card": 0})
+		return frappe.get_all(
+			"Job Card",
+			fields=["sum(total_time_in_mins) as time_in_mins", "sum(total_completed_qty) as completed_qty"],
+			filters={
+				"docstatus": 1,
+				"work_order": self.work_order,
+				"operation_id": self.operation_id,
+				"is_corrective_job_card": 0,
+			},
+		)
 
 	def set_transferred_qty_in_job_card(self, ste_doc):
 		for row in ste_doc.items:
-			if not row.job_card_item: continue
+			if not row.job_card_item:
+				continue
 
-			qty = frappe.db.sql(""" SELECT SUM(qty) from `tabStock Entry Detail` sed, `tabStock Entry` se
+			qty = frappe.db.sql(
+				""" SELECT SUM(qty) from `tabStock Entry Detail` sed, `tabStock Entry` se
 				WHERE  sed.job_card_item = %s and se.docstatus = 1 and sed.parent = se.name and
 				se.purpose = 'Material Transfer for Manufacture'
-			""", (row.job_card_item))[0][0]
+			""",
+				(row.job_card_item),
+			)[0][0]
 
-			frappe.db.set_value('Job Card Item', row.job_card_item, 'transferred_qty', flt(qty))
+			frappe.db.set_value("Job Card Item", row.job_card_item, "transferred_qty", flt(qty))
 
 	def set_transferred_qty(self, update_status=False):
 		"Set total FG Qty for which RM was transferred."
 		if not self.items:
 			self.transferred_qty = self.for_quantity if self.docstatus == 1 else 0
 
-		doc = frappe.get_doc('Work Order', self.get('work_order'))
-		if doc.transfer_material_against == 'Work Order' or doc.skip_transfer:
+		doc = frappe.get_doc("Work Order", self.get("work_order"))
+		if doc.transfer_material_against == "Work Order" or doc.skip_transfer:
 			return
 
 		if self.items:
 			# sum of 'For Quantity' of Stock Entries against JC
-			self.transferred_qty = frappe.db.get_value('Stock Entry', {
-				'job_card': self.name,
-				'work_order': self.work_order,
-				'docstatus': 1,
-				'purpose': 'Material Transfer for Manufacture'
-			}, 'sum(fg_completed_qty)') or 0
+			self.transferred_qty = (
+				frappe.db.get_value(
+					"Stock Entry",
+					{
+						"job_card": self.name,
+						"work_order": self.work_order,
+						"docstatus": 1,
+						"purpose": "Material Transfer for Manufacture",
+					},
+					"sum(fg_completed_qty)",
+				)
+				or 0
+			)
 
 		self.db_set("transferred_qty", self.transferred_qty)
 
 		qty = 0
 		if self.work_order:
-			doc = frappe.get_doc('Work Order', self.work_order)
-			if doc.transfer_material_against == 'Job Card' and not doc.skip_transfer:
+			doc = frappe.get_doc("Work Order", self.work_order)
+			if doc.transfer_material_against == "Job Card" and not doc.skip_transfer:
 				completed = True
 				for d in doc.operations:
-					if d.status != 'Completed':
+					if d.status != "Completed":
 						completed = False
 						break
 
 				if completed:
-					job_cards = frappe.get_all('Job Card', filters = {'work_order': self.work_order,
-						'docstatus': ('!=', 2)}, fields = 'sum(transferred_qty) as qty', group_by='operation_id')
+					job_cards = frappe.get_all(
+						"Job Card",
+						filters={"work_order": self.work_order, "docstatus": ("!=", 2)},
+						fields="sum(transferred_qty) as qty",
+						group_by="operation_id",
+					)
 
 					if job_cards:
 						qty = min(d.qty for d in job_cards)
 
-			doc.db_set('material_transferred_for_manufacturing', qty)
+			doc.db_set("material_transferred_for_manufacturing", qty)
 
 		self.set_status(update_status)
 
 	def set_status(self, update_status=False):
-		if self.status == "On Hold": return
+		if self.status == "On Hold":
+			return
 
-		self.status = {
-			0: "Open",
-			1: "Submitted",
-			2: "Cancelled"
-		}[self.docstatus or 0]
+		self.status = {0: "Open", 1: "Submitted", 2: "Cancelled"}[self.docstatus or 0]
 
 		if self.for_quantity <= self.transferred_qty:
-			self.status = 'Material Transferred'
+			self.status = "Material Transferred"
 
 		if self.time_logs:
-			self.status = 'Work In Progress'
+			self.status = "Work In Progress"
 
-		if (self.docstatus == 1 and
-			(self.for_quantity <= self.total_completed_qty or not self.items)):
-			self.status = 'Completed'
+		if self.docstatus == 1 and (self.for_quantity <= self.total_completed_qty or not self.items):
+			self.status = "Completed"
 
 		if update_status:
-			self.db_set('status', self.status)
+			self.db_set("status", self.status)
 
 	def validate_operation_id(self):
-		if (self.get("operation_id") and self.get("operation_row_number") and self.operation and self.work_order and
-			frappe.get_cached_value("Work Order Operation", self.operation_row_number, "name") != self.operation_id):
+		if (
+			self.get("operation_id")
+			and self.get("operation_row_number")
+			and self.operation
+			and self.work_order
+			and frappe.get_cached_value("Work Order Operation", self.operation_row_number, "name")
+			!= self.operation_id
+		):
 			work_order = bold(get_link_to_form("Work Order", self.work_order))
-			frappe.throw(_("Operation {0} does not belong to the work order {1}")
-				.format(bold(self.operation), work_order), OperationMismatchError)
+			frappe.throw(
+				_("Operation {0} does not belong to the work order {1}").format(
+					bold(self.operation), work_order
+				),
+				OperationMismatchError,
+			)
 
 	def validate_sequence_id(self):
 		if self.is_corrective_job_card:
@@ -534,18 +638,25 @@
 
 		current_operation_qty += flt(self.total_completed_qty)
 
-		data = frappe.get_all("Work Order Operation",
-			fields = ["operation", "status", "completed_qty"],
-			filters={"docstatus": 1, "parent": self.work_order, "sequence_id": ('<', self.sequence_id)},
-			order_by = "sequence_id, idx")
+		data = frappe.get_all(
+			"Work Order Operation",
+			fields=["operation", "status", "completed_qty"],
+			filters={"docstatus": 1, "parent": self.work_order, "sequence_id": ("<", self.sequence_id)},
+			order_by="sequence_id, idx",
+		)
 
-		message = "Job Card {0}: As per the sequence of the operations in the work order {1}".format(bold(self.name),
-			bold(get_link_to_form("Work Order", self.work_order)))
+		message = "Job Card {0}: As per the sequence of the operations in the work order {1}".format(
+			bold(self.name), bold(get_link_to_form("Work Order", self.work_order))
+		)
 
 		for row in data:
 			if row.status != "Completed" and row.completed_qty < current_operation_qty:
-				frappe.throw(_("{0}, complete the operation {1} before the operation {2}.")
-					.format(message, bold(row.operation), bold(self.operation)), OperationSequenceError)
+				frappe.throw(
+					_("{0}, complete the operation {1} before the operation {2}.").format(
+						message, bold(row.operation), bold(self.operation)
+					),
+					OperationSequenceError,
+				)
 
 	def validate_work_order(self):
 		if self.is_work_order_closed():
@@ -553,13 +664,14 @@
 
 	def is_work_order_closed(self):
 		if self.work_order:
-			status = frappe.get_value('Work Order', self.work_order)
+			status = frappe.get_value("Work Order", self.work_order)
 
 			if status == "Closed":
 				return True
 
 		return False
 
+
 @frappe.whitelist()
 def make_time_log(args):
 	if isinstance(args, str):
@@ -570,16 +682,17 @@
 	doc.validate_sequence_id()
 	doc.add_time_log(args)
 
+
 @frappe.whitelist()
 def get_operation_details(work_order, operation):
 	if work_order and operation:
-		return frappe.get_all("Work Order Operation", fields = ["name", "idx"],
-			filters = {
-				"parent": work_order,
-				"operation": operation
-			}
+		return frappe.get_all(
+			"Work Order Operation",
+			fields=["name", "idx"],
+			filters={"parent": work_order, "operation": operation},
 		)
 
+
 @frappe.whitelist()
 def get_operations(doctype, txt, searchfield, start, page_len, filters):
 	if not filters.get("work_order"):
@@ -589,12 +702,16 @@
 	if txt:
 		args["operation"] = ("like", "%{0}%".format(txt))
 
-	return frappe.get_all("Work Order Operation",
-		filters = args,
-		fields = ["distinct operation as operation"],
-		limit_start = start,
-		limit_page_length = page_len,
-		order_by="idx asc", as_list=1)
+	return frappe.get_all(
+		"Work Order Operation",
+		filters=args,
+		fields=["distinct operation as operation"],
+		limit_start=start,
+		limit_page_length=page_len,
+		order_by="idx asc",
+		as_list=1,
+	)
+
 
 @frappe.whitelist()
 def make_material_request(source_name, target_doc=None):
@@ -604,26 +721,29 @@
 	def set_missing_values(source, target):
 		target.material_request_type = "Material Transfer"
 
-	doclist = get_mapped_doc("Job Card", source_name, {
-		"Job Card": {
-			"doctype": "Material Request",
-			"field_map": {
-				"name": "job_card",
+	doclist = get_mapped_doc(
+		"Job Card",
+		source_name,
+		{
+			"Job Card": {
+				"doctype": "Material Request",
+				"field_map": {
+					"name": "job_card",
+				},
+			},
+			"Job Card Item": {
+				"doctype": "Material Request Item",
+				"field_map": {"required_qty": "qty", "uom": "stock_uom", "name": "job_card_item"},
+				"postprocess": update_item,
 			},
 		},
-		"Job Card Item": {
-			"doctype": "Material Request Item",
-			"field_map": {
-				"required_qty": "qty",
-				"uom": "stock_uom",
-				"name": "job_card_item"
-			},
-			"postprocess": update_item,
-		}
-	}, target_doc, set_missing_values)
+		target_doc,
+		set_missing_values,
+	)
 
 	return doclist
 
+
 @frappe.whitelist()
 def make_stock_entry(source_name, target_doc=None):
 	def update_item(source, target, source_parent):
@@ -641,7 +761,7 @@
 		target.from_bom = 1
 
 		# avoid negative 'For Quantity'
-		pending_fg_qty = flt(source.get('for_quantity', 0)) - flt(source.get('transferred_qty', 0))
+		pending_fg_qty = flt(source.get("for_quantity", 0)) - flt(source.get("transferred_qty", 0))
 		target.fg_completed_qty = pending_fg_qty if pending_fg_qty > 0 else 0
 
 		target.set_transfer_qty()
@@ -649,36 +769,45 @@
 		target.set_missing_values()
 		target.set_stock_entry_type()
 
-		wo_allows_alternate_item = frappe.db.get_value("Work Order", target.work_order, "allow_alternative_item")
+		wo_allows_alternate_item = frappe.db.get_value(
+			"Work Order", target.work_order, "allow_alternative_item"
+		)
 		for item in target.items:
-			item.allow_alternative_item = int(wo_allows_alternate_item and
-					frappe.get_cached_value("Item", item.item_code, "allow_alternative_item"))
+			item.allow_alternative_item = int(
+				wo_allows_alternate_item
+				and frappe.get_cached_value("Item", item.item_code, "allow_alternative_item")
+			)
 
-	doclist = get_mapped_doc("Job Card", source_name, {
-		"Job Card": {
-			"doctype": "Stock Entry",
-			"field_map": {
-				"name": "job_card",
-				"for_quantity": "fg_completed_qty"
+	doclist = get_mapped_doc(
+		"Job Card",
+		source_name,
+		{
+			"Job Card": {
+				"doctype": "Stock Entry",
+				"field_map": {"name": "job_card", "for_quantity": "fg_completed_qty"},
+			},
+			"Job Card Item": {
+				"doctype": "Stock Entry Detail",
+				"field_map": {
+					"source_warehouse": "s_warehouse",
+					"required_qty": "qty",
+					"name": "job_card_item",
+				},
+				"postprocess": update_item,
+				"condition": lambda doc: doc.required_qty > 0,
 			},
 		},
-		"Job Card Item": {
-			"doctype": "Stock Entry Detail",
-			"field_map": {
-				"source_warehouse": "s_warehouse",
-				"required_qty": "qty",
-				"name": "job_card_item"
-			},
-			"postprocess": update_item,
-			"condition": lambda doc: doc.required_qty > 0
-		}
-	}, target_doc, set_missing_values)
+		target_doc,
+		set_missing_values,
+	)
 
 	return doclist
 
+
 def time_diff_in_minutes(string_ed_date, string_st_date):
 	return time_diff(string_ed_date, string_st_date).total_seconds() / 60
 
+
 @frappe.whitelist()
 def get_job_details(start, end, filters=None):
 	events = []
@@ -686,41 +815,49 @@
 	event_color = {
 		"Completed": "#cdf5a6",
 		"Material Transferred": "#ffdd9e",
-		"Work In Progress": "#D3D3D3"
+		"Work In Progress": "#D3D3D3",
 	}
 
 	from frappe.desk.reportview import get_filters_cond
+
 	conditions = get_filters_cond("Job Card", filters, [])
 
-	job_cards = frappe.db.sql(""" SELECT `tabJob Card`.name, `tabJob Card`.work_order,
+	job_cards = frappe.db.sql(
+		""" SELECT `tabJob Card`.name, `tabJob Card`.work_order,
 			`tabJob Card`.status, ifnull(`tabJob Card`.remarks, ''),
 			min(`tabJob Card Time Log`.from_time) as from_time,
 			max(`tabJob Card Time Log`.to_time) as to_time
 		FROM `tabJob Card` , `tabJob Card Time Log`
 		WHERE
 			`tabJob Card`.name = `tabJob Card Time Log`.parent {0}
-			group by `tabJob Card`.name""".format(conditions), as_dict=1)
+			group by `tabJob Card`.name""".format(
+			conditions
+		),
+		as_dict=1,
+	)
 
 	for d in job_cards:
-			subject_data = []
-			for field in ["name", "work_order", "remarks"]:
-				if not d.get(field): continue
+		subject_data = []
+		for field in ["name", "work_order", "remarks"]:
+			if not d.get(field):
+				continue
 
-				subject_data.append(d.get(field))
+			subject_data.append(d.get(field))
 
-			color = event_color.get(d.status)
-			job_card_data = {
-				'from_time': d.from_time,
-				'to_time': d.to_time,
-				'name': d.name,
-				'subject': '\n'.join(subject_data),
-				'color': color if color else "#89bcde"
-			}
+		color = event_color.get(d.status)
+		job_card_data = {
+			"from_time": d.from_time,
+			"to_time": d.to_time,
+			"name": d.name,
+			"subject": "\n".join(subject_data),
+			"color": color if color else "#89bcde",
+		}
 
-			events.append(job_card_data)
+		events.append(job_card_data)
 
 	return events
 
+
 @frappe.whitelist()
 def make_corrective_job_card(source_name, operation=None, for_operation=None, target_doc=None):
 	def set_missing_values(source, target):
@@ -728,20 +865,26 @@
 		target.operation = operation
 		target.for_operation = for_operation
 
-		target.set('time_logs', [])
-		target.set('employee', [])
-		target.set('items', [])
+		target.set("time_logs", [])
+		target.set("employee", [])
+		target.set("items", [])
 		target.set_sub_operations()
 		target.get_required_items()
 		target.validate_time_logs()
 
-	doclist = get_mapped_doc("Job Card", source_name, {
-		"Job Card": {
-			"doctype": "Job Card",
-			"field_map": {
-				"name": "for_job_card",
-			},
-		}
-	}, target_doc, set_missing_values)
+	doclist = get_mapped_doc(
+		"Job Card",
+		source_name,
+		{
+			"Job Card": {
+				"doctype": "Job Card",
+				"field_map": {
+					"name": "for_job_card",
+				},
+			}
+		},
+		target_doc,
+		set_missing_values,
+	)
 
 	return doclist
diff --git a/erpnext/manufacturing/doctype/job_card/job_card_dashboard.py b/erpnext/manufacturing/doctype/job_card/job_card_dashboard.py
index 2c48872..14c1f36 100644
--- a/erpnext/manufacturing/doctype/job_card/job_card_dashboard.py
+++ b/erpnext/manufacturing/doctype/job_card/job_card_dashboard.py
@@ -3,18 +3,10 @@
 
 def get_data():
 	return {
-		'fieldname': 'job_card',
-		'non_standard_fieldnames': {
-			'Quality Inspection': 'reference_name'
-		},
-		'transactions': [
-			{
-				'label': _('Transactions'),
-				'items': ['Material Request', 'Stock Entry']
-			},
-			{
-				'label': _('Reference'),
-				'items': ['Quality Inspection']
-			}
-		]
+		"fieldname": "job_card",
+		"non_standard_fieldnames": {"Quality Inspection": "reference_name"},
+		"transactions": [
+			{"label": _("Transactions"), "items": ["Material Request", "Stock Entry"]},
+			{"label": _("Reference"), "items": ["Quality Inspection"]},
+		],
 	}
diff --git a/erpnext/manufacturing/doctype/job_card/test_job_card.py b/erpnext/manufacturing/doctype/job_card/test_job_card.py
index c5841c1..4647ddf 100644
--- a/erpnext/manufacturing/doctype/job_card/test_job_card.py
+++ b/erpnext/manufacturing/doctype/job_card/test_job_card.py
@@ -20,13 +20,11 @@
 
 		transfer_material_against, source_warehouse = None, None
 
-		tests_that_skip_setup = (
-			"test_job_card_material_transfer_correctness",
-		)
+		tests_that_skip_setup = ("test_job_card_material_transfer_correctness",)
 		tests_that_transfer_against_jc = (
 			"test_job_card_multiple_materials_transfer",
 			"test_job_card_excess_material_transfer",
-			"test_job_card_partial_material_transfer"
+			"test_job_card_partial_material_transfer",
 		)
 
 		if self._testMethodName in tests_that_skip_setup:
@@ -40,7 +38,7 @@
 			item="_Test FG Item 2",
 			qty=2,
 			transfer_material_against=transfer_material_against,
-			source_warehouse=source_warehouse
+			source_warehouse=source_warehouse,
 		)
 
 	def tearDown(self):
@@ -48,8 +46,9 @@
 
 	def test_job_card(self):
 
-		job_cards = frappe.get_all('Job Card',
-			filters = {'work_order': self.work_order.name}, fields = ["operation_id", "name"])
+		job_cards = frappe.get_all(
+			"Job Card", filters={"work_order": self.work_order.name}, fields=["operation_id", "name"]
+		)
 
 		if job_cards:
 			job_card = job_cards[0]
@@ -63,30 +62,38 @@
 			frappe.delete_doc("Job Card", d.name)
 
 	def test_job_card_with_different_work_station(self):
-		job_cards = frappe.get_all('Job Card',
-			filters = {'work_order': self.work_order.name},
-			fields = ["operation_id", "workstation", "name", "for_quantity"])
+		job_cards = frappe.get_all(
+			"Job Card",
+			filters={"work_order": self.work_order.name},
+			fields=["operation_id", "workstation", "name", "for_quantity"],
+		)
 
 		job_card = job_cards[0]
 
 		if job_card:
-			workstation = frappe.db.get_value("Workstation",
-				{"name": ("not in", [job_card.workstation])}, "name")
+			workstation = frappe.db.get_value(
+				"Workstation", {"name": ("not in", [job_card.workstation])}, "name"
+			)
 
 			if not workstation or job_card.workstation == workstation:
 				workstation = make_workstation(workstation_name=random_string(5)).name
 
 			doc = frappe.get_doc("Job Card", job_card.name)
 			doc.workstation = workstation
-			doc.append("time_logs", {
-				"from_time": "2009-01-01 12:06:25",
-				"to_time": "2009-01-01 12:37:25",
-				"time_in_mins": "31.00002",
-				"completed_qty": job_card.for_quantity
-			})
+			doc.append(
+				"time_logs",
+				{
+					"from_time": "2009-01-01 12:06:25",
+					"to_time": "2009-01-01 12:37:25",
+					"time_in_mins": "31.00002",
+					"completed_qty": job_card.for_quantity,
+				},
+			)
 			doc.submit()
 
-			completed_qty = frappe.db.get_value("Work Order Operation", job_card.operation_id, "completed_qty")
+			completed_qty = frappe.db.get_value(
+				"Work Order Operation", job_card.operation_id, "completed_qty"
+			)
 			self.assertEqual(completed_qty, job_card.for_quantity)
 
 			doc.cancel()
@@ -97,51 +104,49 @@
 	def test_job_card_overlap(self):
 		wo2 = make_wo_order_test_record(item="_Test FG Item 2", qty=2)
 
-		jc1_name = frappe.db.get_value("Job Card", {'work_order': self.work_order.name})
-		jc2_name = frappe.db.get_value("Job Card", {'work_order': wo2.name})
+		jc1_name = frappe.db.get_value("Job Card", {"work_order": self.work_order.name})
+		jc2_name = frappe.db.get_value("Job Card", {"work_order": wo2.name})
 
 		jc1 = frappe.get_doc("Job Card", jc1_name)
 		jc2 = frappe.get_doc("Job Card", jc2_name)
 
-		employee = "_T-Employee-00001" # from test records
+		employee = "_T-Employee-00001"  # from test records
 
-		jc1.append("time_logs", {
-			"from_time": "2021-01-01 00:00:00",
-			"to_time": "2021-01-01 08:00:00",
-			"completed_qty": 1,
-			"employee": employee,
-		})
+		jc1.append(
+			"time_logs",
+			{
+				"from_time": "2021-01-01 00:00:00",
+				"to_time": "2021-01-01 08:00:00",
+				"completed_qty": 1,
+				"employee": employee,
+			},
+		)
 		jc1.save()
 
 		# add a new entry in same time slice
-		jc2.append("time_logs", {
-			"from_time": "2021-01-01 00:01:00",
-			"to_time": "2021-01-01 06:00:00",
-			"completed_qty": 1,
-			"employee": employee,
-		})
+		jc2.append(
+			"time_logs",
+			{
+				"from_time": "2021-01-01 00:01:00",
+				"to_time": "2021-01-01 06:00:00",
+				"completed_qty": 1,
+				"employee": employee,
+			},
+		)
 		self.assertRaises(OverlapError, jc2.save)
 
 	def test_job_card_multiple_materials_transfer(self):
 		"Test transferring RMs separately against Job Card with multiple RMs."
+		make_stock_entry(item_code="_Test Item", target="Stores - _TC", qty=10, basic_rate=100)
 		make_stock_entry(
-			item_code="_Test Item",
-			target="Stores - _TC",
-			qty=10,
-			basic_rate=100
-		)
-		make_stock_entry(
-			item_code="_Test Item Home Desktop Manufactured",
-			target="Stores - _TC",
-			qty=6,
-			basic_rate=100
+			item_code="_Test Item Home Desktop Manufactured", target="Stores - _TC", qty=6, basic_rate=100
 		)
 
-		job_card_name = frappe.db.get_value("Job Card", {'work_order': self.work_order.name})
+		job_card_name = frappe.db.get_value("Job Card", {"work_order": self.work_order.name})
 		job_card = frappe.get_doc("Job Card", job_card_name)
 
 		transfer_entry_1 = make_stock_entry_from_jc(job_card_name)
-		del transfer_entry_1.items[1] # transfer only 1 of 2 RMs
+		del transfer_entry_1.items[1]  # transfer only 1 of 2 RMs
 		transfer_entry_1.insert()
 		transfer_entry_1.submit()
 
@@ -162,12 +167,12 @@
 
 	def test_job_card_excess_material_transfer(self):
 		"Test transferring more than required RM against Job Card."
-		make_stock_entry(item_code="_Test Item", target="Stores - _TC",
-			qty=25, basic_rate=100)
-		make_stock_entry(item_code="_Test Item Home Desktop Manufactured",
-			target="Stores - _TC", qty=15, basic_rate=100)
+		make_stock_entry(item_code="_Test Item", target="Stores - _TC", qty=25, basic_rate=100)
+		make_stock_entry(
+			item_code="_Test Item Home Desktop Manufactured", target="Stores - _TC", qty=15, basic_rate=100
+		)
 
-		job_card_name = frappe.db.get_value("Job Card", {'work_order': self.work_order.name})
+		job_card_name = frappe.db.get_value("Job Card", {"work_order": self.work_order.name})
 		job_card = frappe.get_doc("Job Card", job_card_name)
 		self.assertEqual(job_card.status, "Open")
 
@@ -193,11 +198,10 @@
 		transfer_entry_3 = make_stock_entry_from_jc(job_card_name)
 		self.assertEqual(transfer_entry_3.fg_completed_qty, 0)
 
-		job_card.append("time_logs", {
-			"from_time": "2021-01-01 00:01:00",
-			"to_time": "2021-01-01 06:00:00",
-			"completed_qty": 2
-		})
+		job_card.append(
+			"time_logs",
+			{"from_time": "2021-01-01 00:01:00", "to_time": "2021-01-01 06:00:00", "completed_qty": 2},
+		)
 		job_card.save()
 		job_card.submit()
 
@@ -207,12 +211,12 @@
 	def test_job_card_partial_material_transfer(self):
 		"Test partial material transfer against Job Card"
 
-		make_stock_entry(item_code="_Test Item", target="Stores - _TC",
-			qty=25, basic_rate=100)
-		make_stock_entry(item_code="_Test Item Home Desktop Manufactured",
-			target="Stores - _TC", qty=15, basic_rate=100)
+		make_stock_entry(item_code="_Test Item", target="Stores - _TC", qty=25, basic_rate=100)
+		make_stock_entry(
+			item_code="_Test Item Home Desktop Manufactured", target="Stores - _TC", qty=15, basic_rate=100
+		)
 
-		job_card_name = frappe.db.get_value("Job Card", {'work_order': self.work_order.name})
+		job_card_name = frappe.db.get_value("Job Card", {"work_order": self.work_order.name})
 		job_card = frappe.get_doc("Job Card", job_card_name)
 
 		# partially transfer
@@ -242,15 +246,14 @@
 
 	def test_job_card_material_transfer_correctness(self):
 		"""
-			1. Test if only current Job Card Items are pulled in a Stock Entry against a Job Card
-			2. Test impact of changing 'For Qty' in such a Stock Entry
+		1. Test if only current Job Card Items are pulled in a Stock Entry against a Job Card
+		2. Test impact of changing 'For Qty' in such a Stock Entry
 		"""
 		create_bom_with_multiple_operations()
 		work_order = make_wo_with_transfer_against_jc()
 
 		job_card_name = frappe.db.get_value(
-			"Job Card",
-			{"work_order": work_order.name,"operation": "Test Operation A"}
+			"Job Card", {"work_order": work_order.name, "operation": "Test Operation A"}
 		)
 		job_card = frappe.get_doc("Job Card", job_card_name)
 
@@ -276,6 +279,7 @@
 
 		# rollback via tearDown method
 
+
 def create_bom_with_multiple_operations():
 	"Create a BOM with multiple operations and Material Transfer against Job Card"
 	from erpnext.manufacturing.doctype.operation.test_operation import make_operation
@@ -287,19 +291,22 @@
 		"operation": "Test Operation A",
 		"workstation": "_Test Workstation A",
 		"hour_rate_rent": 300,
-		"time_in_mins": 60
+		"time_in_mins": 60,
 	}
 	make_workstation(row)
 	make_operation(row)
 
-	bom_doc.append("operations", {
-		"operation": "Test Operation A",
-		"description": "Test Operation A",
-		"workstation": "_Test Workstation A",
-		"hour_rate": 300,
-		"time_in_mins": 60,
-		"operating_cost": 100
-	})
+	bom_doc.append(
+		"operations",
+		{
+			"operation": "Test Operation A",
+			"description": "Test Operation A",
+			"workstation": "_Test Workstation A",
+			"hour_rate": 300,
+			"time_in_mins": 60,
+			"operating_cost": 100,
+		},
+	)
 
 	bom_doc.transfer_material_against = "Job Card"
 	bom_doc.save()
@@ -307,6 +314,7 @@
 
 	return bom_doc
 
+
 def make_wo_with_transfer_against_jc():
 	"Create a WO with multiple operations and Material Transfer against Job Card"
 
@@ -315,7 +323,7 @@
 		qty=4,
 		transfer_material_against="Job Card",
 		source_warehouse="Stores - _TC",
-		do_not_submit=True
+		do_not_submit=True,
 	)
 	work_order.required_items[0].operation = "Test Operation A"
 	work_order.required_items[1].operation = "_Test Operation 1"
@@ -323,8 +331,9 @@
 
 	return work_order
 
+
 def make_bom_for_jc_tests():
-	test_records = frappe.get_test_records('BOM')
+	test_records = frappe.get_test_records("BOM")
 	bom = frappe.copy_doc(test_records[2])
 	bom.set_rate_of_sub_assembly_item_based_on_bom = 0
 	bom.rm_cost_as_per = "Valuation Rate"
diff --git a/erpnext/manufacturing/doctype/manufacturing_settings/manufacturing_settings.py b/erpnext/manufacturing/doctype/manufacturing_settings/manufacturing_settings.py
index c919e8b..730a857 100644
--- a/erpnext/manufacturing/doctype/manufacturing_settings/manufacturing_settings.py
+++ b/erpnext/manufacturing/doctype/manufacturing_settings/manufacturing_settings.py
@@ -11,14 +11,19 @@
 class ManufacturingSettings(Document):
 	pass
 
+
 def get_mins_between_operations():
-	return relativedelta(minutes=cint(frappe.db.get_single_value("Manufacturing Settings",
-		"mins_between_operations")) or 10)
+	return relativedelta(
+		minutes=cint(frappe.db.get_single_value("Manufacturing Settings", "mins_between_operations"))
+		or 10
+	)
+
 
 @frappe.whitelist()
 def is_material_consumption_enabled():
-	if not hasattr(frappe.local, 'material_consumption'):
-		frappe.local.material_consumption = cint(frappe.db.get_single_value('Manufacturing Settings',
-			'material_consumption'))
+	if not hasattr(frappe.local, "material_consumption"):
+		frappe.local.material_consumption = cint(
+			frappe.db.get_single_value("Manufacturing Settings", "material_consumption")
+		)
 
 	return frappe.local.material_consumption
diff --git a/erpnext/manufacturing/doctype/operation/operation.py b/erpnext/manufacturing/doctype/operation/operation.py
index 41726f3..9c8f9ac 100644
--- a/erpnext/manufacturing/doctype/operation/operation.py
+++ b/erpnext/manufacturing/doctype/operation/operation.py
@@ -19,12 +19,14 @@
 		operation_list = []
 		for row in self.sub_operations:
 			if row.operation in operation_list:
-				frappe.throw(_("The operation {0} can not add multiple times")
-					.format(frappe.bold(row.operation)))
+				frappe.throw(
+					_("The operation {0} can not add multiple times").format(frappe.bold(row.operation))
+				)
 
 			if self.name == row.operation:
-				frappe.throw(_("The operation {0} can not be the sub operation")
-					.format(frappe.bold(row.operation)))
+				frappe.throw(
+					_("The operation {0} can not be the sub operation").format(frappe.bold(row.operation))
+				)
 
 			operation_list.append(row.operation)
 
diff --git a/erpnext/manufacturing/doctype/operation/operation_dashboard.py b/erpnext/manufacturing/doctype/operation/operation_dashboard.py
index 9f7efa2..8dc901a 100644
--- a/erpnext/manufacturing/doctype/operation/operation_dashboard.py
+++ b/erpnext/manufacturing/doctype/operation/operation_dashboard.py
@@ -3,11 +3,6 @@
 
 def get_data():
 	return {
-		'fieldname': 'operation',
-		'transactions': [
-			{
-				'label': _('Manufacture'),
-				'items': ['BOM', 'Work Order', 'Job Card']
-			}
-		]
+		"fieldname": "operation",
+		"transactions": [{"label": _("Manufacture"), "items": ["BOM", "Work Order", "Job Card"]}],
 	}
diff --git a/erpnext/manufacturing/doctype/operation/test_operation.py b/erpnext/manufacturing/doctype/operation/test_operation.py
index e511084..ce9f8e0 100644
--- a/erpnext/manufacturing/doctype/operation/test_operation.py
+++ b/erpnext/manufacturing/doctype/operation/test_operation.py
@@ -5,11 +5,13 @@
 
 import frappe
 
-test_records = frappe.get_test_records('Operation')
+test_records = frappe.get_test_records("Operation")
+
 
 class TestOperation(unittest.TestCase):
 	pass
 
+
 def make_operation(*args, **kwargs):
 	args = args if args else kwargs
 	if isinstance(args, tuple):
@@ -18,11 +20,9 @@
 	args = frappe._dict(args)
 
 	if not frappe.db.exists("Operation", args.operation):
-		doc = frappe.get_doc({
-			"doctype": "Operation",
-			"name": args.operation,
-			"workstation": args.workstation
-		})
+		doc = frappe.get_doc(
+			{"doctype": "Operation", "name": args.operation, "workstation": args.workstation}
+		)
 		doc.insert()
 		return doc
 
diff --git a/erpnext/manufacturing/doctype/production_plan/production_plan.py b/erpnext/manufacturing/doctype/production_plan/production_plan.py
index 349f40e..89f9ca6 100644
--- a/erpnext/manufacturing/doctype/production_plan/production_plan.py
+++ b/erpnext/manufacturing/doctype/production_plan/production_plan.py
@@ -36,7 +36,7 @@
 
 	def set_pending_qty_in_row_without_reference(self):
 		"Set Pending Qty in independent rows (not from SO or MR)."
-		if self.docstatus > 0: # set only to initialise value before submit
+		if self.docstatus > 0:  # set only to initialise value before submit
 			return
 
 		for item in self.po_items:
@@ -49,7 +49,7 @@
 			self.total_planned_qty += flt(d.planned_qty)
 
 	def validate_data(self):
-		for d in self.get('po_items'):
+		for d in self.get("po_items"):
 			if not d.bom_no:
 				frappe.throw(_("Please select BOM for Item in Row {0}").format(d.idx))
 			else:
@@ -59,9 +59,9 @@
 				frappe.throw(_("Please enter Planned Qty for Item {0} at row {1}").format(d.item_code, d.idx))
 
 	def _rename_temporary_references(self):
-		""" po_items and sub_assembly_items items are both constructed client side without saving.
+		"""po_items and sub_assembly_items items are both constructed client side without saving.
 
-			Attempt to fix linkages by using temporary names to map final row names.
+		Attempt to fix linkages by using temporary names to map final row names.
 		"""
 		new_name_map = {d.temporary_name: d.name for d in self.po_items if d.temporary_name}
 		actual_names = {d.name for d in self.po_items}
@@ -72,7 +72,7 @@
 
 	@frappe.whitelist()
 	def get_open_sales_orders(self):
-		""" Pull sales orders  which are pending to deliver based on criteria selected"""
+		"""Pull sales orders  which are pending to deliver based on criteria selected"""
 		open_so = get_sales_orders(self)
 
 		if open_so:
@@ -81,20 +81,23 @@
 			frappe.msgprint(_("Sales orders are not available for production"))
 
 	def add_so_in_table(self, open_so):
-		""" Add sales orders in the table"""
-		self.set('sales_orders', [])
+		"""Add sales orders in the table"""
+		self.set("sales_orders", [])
 
 		for data in open_so:
-			self.append('sales_orders', {
-				'sales_order': data.name,
-				'sales_order_date': data.transaction_date,
-				'customer': data.customer,
-				'grand_total': data.base_grand_total
-			})
+			self.append(
+				"sales_orders",
+				{
+					"sales_order": data.name,
+					"sales_order_date": data.transaction_date,
+					"customer": data.customer,
+					"grand_total": data.base_grand_total,
+				},
+			)
 
 	@frappe.whitelist()
 	def get_pending_material_requests(self):
-		""" Pull Material Requests that are pending based on criteria selected"""
+		"""Pull Material Requests that are pending based on criteria selected"""
 		mr_filter = item_filter = ""
 		if self.from_date:
 			mr_filter += " and mr.transaction_date >= %(from_date)s"
@@ -106,7 +109,8 @@
 		if self.item_code:
 			item_filter += " and mr_item.item_code = %(item)s"
 
-		pending_mr = frappe.db.sql("""
+		pending_mr = frappe.db.sql(
+			"""
 			select distinct mr.name, mr.transaction_date
 			from `tabMaterial Request` mr, `tabMaterial Request Item` mr_item
 			where mr_item.parent = mr.name
@@ -115,29 +119,34 @@
 				and mr_item.qty > ifnull(mr_item.ordered_qty,0) {0} {1}
 				and (exists (select name from `tabBOM` bom where bom.item=mr_item.item_code
 					and bom.is_active = 1))
-			""".format(mr_filter, item_filter), {
+			""".format(
+				mr_filter, item_filter
+			),
+			{
 				"from_date": self.from_date,
 				"to_date": self.to_date,
 				"warehouse": self.warehouse,
 				"item": self.item_code,
-				"company": self.company
-			}, as_dict=1)
+				"company": self.company,
+			},
+			as_dict=1,
+		)
 
 		self.add_mr_in_table(pending_mr)
 
 	def add_mr_in_table(self, pending_mr):
-		""" Add Material Requests in the table"""
-		self.set('material_requests', [])
+		"""Add Material Requests in the table"""
+		self.set("material_requests", [])
 
 		for data in pending_mr:
-			self.append('material_requests', {
-				'material_request': data.name,
-				'material_request_date': data.transaction_date
-			})
+			self.append(
+				"material_requests",
+				{"material_request": data.name, "material_request_date": data.transaction_date},
+			)
 
 	@frappe.whitelist()
 	def get_items(self):
-		self.set('po_items', [])
+		self.set("po_items", [])
 		if self.get_items_from == "Sales Order":
 			self.get_so_items()
 
@@ -152,10 +161,12 @@
 	def get_bom_item(self):
 		"""Check if Item or if its Template has a BOM."""
 		bom_item = None
-		has_bom = frappe.db.exists({'doctype': 'BOM', 'item': self.item_code, 'docstatus': 1})
+		has_bom = frappe.db.exists({"doctype": "BOM", "item": self.item_code, "docstatus": 1})
 		if not has_bom:
-			template_item = frappe.db.get_value('Item', self.item_code, ['variant_of'])
-			bom_item = "bom.item = {0}".format(frappe.db.escape(template_item)) if template_item else bom_item
+			template_item = frappe.db.get_value("Item", self.item_code, ["variant_of"])
+			bom_item = (
+				"bom.item = {0}".format(frappe.db.escape(template_item)) if template_item else bom_item
+			)
 		return bom_item
 
 	def get_so_items(self):
@@ -167,11 +178,12 @@
 
 		item_condition = ""
 		bom_item = "bom.item = so_item.item_code"
-		if self.item_code and frappe.db.exists('Item', self.item_code):
+		if self.item_code and frappe.db.exists("Item", self.item_code):
 			bom_item = self.get_bom_item() or bom_item
-			item_condition = ' and so_item.item_code = {0}'.format(frappe.db.escape(self.item_code))
+			item_condition = " and so_item.item_code = {0}".format(frappe.db.escape(self.item_code))
 
-		items = frappe.db.sql("""
+		items = frappe.db.sql(
+			"""
 			select
 				distinct parent, item_code, warehouse,
 				(qty - work_order_qty) * conversion_factor as pending_qty,
@@ -181,16 +193,17 @@
 			where
 				parent in (%s) and docstatus = 1 and qty > work_order_qty
 				and exists (select name from `tabBOM` bom where %s
-				and bom.is_active = 1) %s""" %
-			(", ".join(["%s"] * len(so_list)),
-			bom_item,
-			item_condition),
-			tuple(so_list), as_dict=1)
+				and bom.is_active = 1) %s"""
+			% (", ".join(["%s"] * len(so_list)), bom_item, item_condition),
+			tuple(so_list),
+			as_dict=1,
+		)
 
 		if self.item_code:
-			item_condition = ' and so_item.item_code = {0}'.format(frappe.db.escape(self.item_code))
+			item_condition = " and so_item.item_code = {0}".format(frappe.db.escape(self.item_code))
 
-		packed_items = frappe.db.sql("""select distinct pi.parent, pi.item_code, pi.warehouse as warehouse,
+		packed_items = frappe.db.sql(
+			"""select distinct pi.parent, pi.item_code, pi.warehouse as warehouse,
 			(((so_item.qty - so_item.work_order_qty) * pi.qty) / so_item.qty)
 				as pending_qty, pi.parent_item, pi.description, so_item.name
 			from `tabSales Order Item` so_item, `tabPacked Item` pi
@@ -198,16 +211,23 @@
 			and pi.parent_item = so_item.item_code
 			and so_item.parent in (%s) and so_item.qty > so_item.work_order_qty
 			and exists (select name from `tabBOM` bom where bom.item=pi.item_code
-					and bom.is_active = 1) %s""" % \
-			(", ".join(["%s"] * len(so_list)), item_condition), tuple(so_list), as_dict=1)
+					and bom.is_active = 1) %s"""
+			% (", ".join(["%s"] * len(so_list)), item_condition),
+			tuple(so_list),
+			as_dict=1,
+		)
 
 		self.add_items(items + packed_items)
 		self.calculate_total_planned_qty()
 
 	def get_mr_items(self):
 		# Check for empty table or empty rows
-		if not self.get("material_requests") or not self.get_so_mr_list("material_request", "material_requests"):
-			frappe.throw(_("Please fill the Material Requests table"), title=_("Material Requests Required"))
+		if not self.get("material_requests") or not self.get_so_mr_list(
+			"material_request", "material_requests"
+		):
+			frappe.throw(
+				_("Please fill the Material Requests table"), title=_("Material Requests Required")
+			)
 
 		mr_list = self.get_so_mr_list("material_request", "material_requests")
 
@@ -215,13 +235,17 @@
 		if self.item_code:
 			item_condition = " and mr_item.item_code ={0}".format(frappe.db.escape(self.item_code))
 
-		items = frappe.db.sql("""select distinct parent, name, item_code, warehouse, description,
+		items = frappe.db.sql(
+			"""select distinct parent, name, item_code, warehouse, description,
 			(qty - ordered_qty) * conversion_factor as pending_qty
 			from `tabMaterial Request Item` mr_item
 			where parent in (%s) and docstatus = 1 and qty > ordered_qty
 			and exists (select name from `tabBOM` bom where bom.item=mr_item.item_code
-				and bom.is_active = 1) %s""" % \
-			(", ".join(["%s"] * len(mr_list)), item_condition), tuple(mr_list), as_dict=1)
+				and bom.is_active = 1) %s"""
+			% (", ".join(["%s"] * len(mr_list)), item_condition),
+			tuple(mr_list),
+			as_dict=1,
+		)
 
 		self.add_items(items)
 		self.calculate_total_planned_qty()
@@ -232,37 +256,36 @@
 			item_details = get_item_details(data.item_code)
 			if self.combine_items:
 				if item_details.bom_no in refs:
-					refs[item_details.bom_no]['so_details'].append({
-						'sales_order': data.parent,
-						'sales_order_item': data.name,
-						'qty': data.pending_qty
-					})
-					refs[item_details.bom_no]['qty'] += data.pending_qty
+					refs[item_details.bom_no]["so_details"].append(
+						{"sales_order": data.parent, "sales_order_item": data.name, "qty": data.pending_qty}
+					)
+					refs[item_details.bom_no]["qty"] += data.pending_qty
 					continue
 
 				else:
 					refs[item_details.bom_no] = {
-						'qty': data.pending_qty,
-						'po_item_ref': data.name,
-						'so_details': []
+						"qty": data.pending_qty,
+						"po_item_ref": data.name,
+						"so_details": [],
 					}
-					refs[item_details.bom_no]['so_details'].append({
-						'sales_order': data.parent,
-						'sales_order_item': data.name,
-						'qty': data.pending_qty
-					})
+					refs[item_details.bom_no]["so_details"].append(
+						{"sales_order": data.parent, "sales_order_item": data.name, "qty": data.pending_qty}
+					)
 
-			pi = self.append('po_items', {
-				'warehouse': data.warehouse,
-				'item_code': data.item_code,
-				'description': data.description or item_details.description,
-				'stock_uom': item_details and item_details.stock_uom or '',
-				'bom_no': item_details and item_details.bom_no or '',
-				'planned_qty': data.pending_qty,
-				'pending_qty': data.pending_qty,
-				'planned_start_date': now_datetime(),
-				'product_bundle_item': data.parent_item
-			})
+			pi = self.append(
+				"po_items",
+				{
+					"warehouse": data.warehouse,
+					"item_code": data.item_code,
+					"description": data.description or item_details.description,
+					"stock_uom": item_details and item_details.stock_uom or "",
+					"bom_no": item_details and item_details.bom_no or "",
+					"planned_qty": data.pending_qty,
+					"pending_qty": data.pending_qty,
+					"planned_start_date": now_datetime(),
+					"product_bundle_item": data.parent_item,
+				},
+			)
 			pi._set_defaults()
 
 			if self.get_items_from == "Sales Order":
@@ -277,20 +300,23 @@
 
 		if refs:
 			for po_item in self.po_items:
-				po_item.planned_qty = refs[po_item.bom_no]['qty']
-				po_item.pending_qty = refs[po_item.bom_no]['qty']
-				po_item.sales_order = ''
+				po_item.planned_qty = refs[po_item.bom_no]["qty"]
+				po_item.pending_qty = refs[po_item.bom_no]["qty"]
+				po_item.sales_order = ""
 			self.add_pp_ref(refs)
 
 	def add_pp_ref(self, refs):
 		for bom_no in refs:
-			for so_detail in refs[bom_no]['so_details']:
-				self.append('prod_plan_references', {
-						'item_reference': refs[bom_no]['po_item_ref'],
-						'sales_order': so_detail['sales_order'],
-						'sales_order_item': so_detail['sales_order_item'],
-						'qty': so_detail['qty']
-				})
+			for so_detail in refs[bom_no]["so_details"]:
+				self.append(
+					"prod_plan_references",
+					{
+						"item_reference": refs[bom_no]["po_item_ref"],
+						"sales_order": so_detail["sales_order"],
+						"sales_order_item": so_detail["sales_order_item"],
+						"qty": so_detail["qty"],
+					},
+				)
 
 	def calculate_total_produced_qty(self):
 		self.total_produced_qty = 0
@@ -308,27 +334,24 @@
 
 		self.calculate_total_produced_qty()
 		self.set_status()
-		self.db_set('status', self.status)
+		self.db_set("status", self.status)
 
 	def on_cancel(self):
-		self.db_set('status', 'Cancelled')
+		self.db_set("status", "Cancelled")
 		self.delete_draft_work_order()
 
 	def delete_draft_work_order(self):
-		for d in frappe.get_all('Work Order', fields = ["name"],
-			filters = {'docstatus': 0, 'production_plan': ("=", self.name)}):
-			frappe.delete_doc('Work Order', d.name)
+		for d in frappe.get_all(
+			"Work Order", fields=["name"], filters={"docstatus": 0, "production_plan": ("=", self.name)}
+		):
+			frappe.delete_doc("Work Order", d.name)
 
 	@frappe.whitelist()
 	def set_status(self, close=None):
-		self.status = {
-			0: 'Draft',
-			1: 'Submitted',
-			2: 'Cancelled'
-		}.get(self.docstatus)
+		self.status = {0: "Draft", 1: "Submitted", 2: "Cancelled"}.get(self.docstatus)
 
 		if close:
-			self.db_set('status', 'Closed')
+			self.db_set("status", "Closed")
 			return
 
 		if self.total_produced_qty > 0:
@@ -336,12 +359,12 @@
 			if self.all_items_completed():
 				self.status = "Completed"
 
-		if self.status != 'Completed':
+		if self.status != "Completed":
 			self.update_ordered_status()
 			self.update_requested_status()
 
 		if close is not None:
-			self.db_set('status', self.status)
+			self.db_set("status", self.status)
 
 	def update_ordered_status(self):
 		update_status = False
@@ -349,8 +372,8 @@
 			if d.planned_qty == d.ordered_qty:
 				update_status = True
 
-		if update_status and self.status != 'Completed':
-			self.status = 'In Process'
+		if update_status and self.status != "Completed":
+			self.status = "In Process"
 
 	def update_requested_status(self):
 		if not self.mr_items:
@@ -362,44 +385,44 @@
 				update_status = False
 
 		if update_status:
-			self.status = 'Material Requested'
+			self.status = "Material Requested"
 
 	def get_production_items(self):
 		item_dict = {}
 
 		for d in self.po_items:
 			item_details = {
-				"production_item"		: d.item_code,
-				"use_multi_level_bom"   : d.include_exploded_items,
-				"sales_order"			: d.sales_order,
-				"sales_order_item"		: d.sales_order_item,
-				"material_request"		: d.material_request,
-				"material_request_item"	: d.material_request_item,
-				"bom_no"				: d.bom_no,
-				"description"			: d.description,
-				"stock_uom"				: d.stock_uom,
-				"company"				: self.company,
-				"fg_warehouse"			: d.warehouse,
-				"production_plan"       : self.name,
-				"production_plan_item"  : d.name,
-				"product_bundle_item"	: d.product_bundle_item,
-				"planned_start_date"    : d.planned_start_date,
-				"project"               : self.project
+				"production_item": d.item_code,
+				"use_multi_level_bom": d.include_exploded_items,
+				"sales_order": d.sales_order,
+				"sales_order_item": d.sales_order_item,
+				"material_request": d.material_request,
+				"material_request_item": d.material_request_item,
+				"bom_no": d.bom_no,
+				"description": d.description,
+				"stock_uom": d.stock_uom,
+				"company": self.company,
+				"fg_warehouse": d.warehouse,
+				"production_plan": self.name,
+				"production_plan_item": d.name,
+				"product_bundle_item": d.product_bundle_item,
+				"planned_start_date": d.planned_start_date,
+				"project": self.project,
 			}
 
-			if not item_details['project'] and d.sales_order:
-				item_details['project'] = frappe.get_cached_value("Sales Order", d.sales_order, "project")
+			if not item_details["project"] and d.sales_order:
+				item_details["project"] = frappe.get_cached_value("Sales Order", d.sales_order, "project")
 
 			if self.get_items_from == "Material Request":
-				item_details.update({
-					"qty": d.planned_qty
-				})
+				item_details.update({"qty": d.planned_qty})
 				item_dict[(d.item_code, d.material_request_item, d.warehouse)] = item_details
 			else:
-				item_details.update({
-					"qty": flt(item_dict.get((d.item_code, d.sales_order, d.warehouse),{})
-						.get("qty")) + (flt(d.planned_qty) - flt(d.ordered_qty))
-				})
+				item_details.update(
+					{
+						"qty": flt(item_dict.get((d.item_code, d.sales_order, d.warehouse), {}).get("qty"))
+						+ (flt(d.planned_qty) - flt(d.ordered_qty))
+					}
+				)
 				item_dict[(d.item_code, d.sales_order, d.warehouse)] = item_details
 
 		return item_dict
@@ -415,15 +438,15 @@
 		self.make_work_order_for_finished_goods(wo_list, default_warehouses)
 		self.make_work_order_for_subassembly_items(wo_list, subcontracted_po, default_warehouses)
 		self.make_subcontracted_purchase_order(subcontracted_po, po_list)
-		self.show_list_created_message('Work Order', wo_list)
-		self.show_list_created_message('Purchase Order', po_list)
+		self.show_list_created_message("Work Order", wo_list)
+		self.show_list_created_message("Purchase Order", po_list)
 
 	def make_work_order_for_finished_goods(self, wo_list, default_warehouses):
 		items_data = self.get_production_items()
 
 		for key, item in items_data.items():
 			if self.sub_assembly_items:
-				item['use_multi_level_bom'] = 0
+				item["use_multi_level_bom"] = 0
 
 			set_default_warehouses(item, default_warehouses)
 			work_order = self.create_work_order(item)
@@ -432,13 +455,13 @@
 
 	def make_work_order_for_subassembly_items(self, wo_list, subcontracted_po, default_warehouses):
 		for row in self.sub_assembly_items:
-			if row.type_of_manufacturing == 'Subcontract':
+			if row.type_of_manufacturing == "Subcontract":
 				subcontracted_po.setdefault(row.supplier, []).append(row)
 				continue
 
 			work_order_data = {
-				'wip_warehouse': default_warehouses.get('wip_warehouse'),
-				'fg_warehouse': default_warehouses.get('fg_warehouse')
+				"wip_warehouse": default_warehouses.get("wip_warehouse"),
+				"fg_warehouse": default_warehouses.get("fg_warehouse"),
 			}
 
 			self.prepare_data_for_sub_assembly_items(row, work_order_data)
@@ -447,41 +470,59 @@
 				wo_list.append(work_order)
 
 	def prepare_data_for_sub_assembly_items(self, row, wo_data):
-		for field in ["production_item", "item_name", "qty", "fg_warehouse",
-			"description", "bom_no", "stock_uom", "bom_level",
-			"production_plan_item", "schedule_date"]:
+		for field in [
+			"production_item",
+			"item_name",
+			"qty",
+			"fg_warehouse",
+			"description",
+			"bom_no",
+			"stock_uom",
+			"bom_level",
+			"production_plan_item",
+			"schedule_date",
+		]:
 			if row.get(field):
 				wo_data[field] = row.get(field)
 
-		wo_data.update({
-			"use_multi_level_bom": 0,
-			"production_plan": self.name,
-			"production_plan_sub_assembly_item": row.name
-		})
+		wo_data.update(
+			{
+				"use_multi_level_bom": 0,
+				"production_plan": self.name,
+				"production_plan_sub_assembly_item": row.name,
+			}
+		)
 
 	def make_subcontracted_purchase_order(self, subcontracted_po, purchase_orders):
 		if not subcontracted_po:
 			return
 
 		for supplier, po_list in subcontracted_po.items():
-			po = frappe.new_doc('Purchase Order')
+			po = frappe.new_doc("Purchase Order")
 			po.supplier = supplier
 			po.schedule_date = getdate(po_list[0].schedule_date) if po_list[0].schedule_date else nowdate()
-			po.is_subcontracted = 'Yes'
+			po.is_subcontracted = "Yes"
 			for row in po_list:
 				po_data = {
-					'item_code': row.production_item,
-					'warehouse': row.fg_warehouse,
-					'production_plan_sub_assembly_item': row.name,
-					'bom': row.bom_no,
-					'production_plan': self.name
+					"item_code": row.production_item,
+					"warehouse": row.fg_warehouse,
+					"production_plan_sub_assembly_item": row.name,
+					"bom": row.bom_no,
+					"production_plan": self.name,
 				}
 
-				for field in ['schedule_date', 'qty', 'uom', 'stock_uom', 'item_name',
-					'description', 'production_plan_item']:
+				for field in [
+					"schedule_date",
+					"qty",
+					"uom",
+					"stock_uom",
+					"item_name",
+					"description",
+					"production_plan_item",
+				]:
 					po_data[field] = row.get(field)
 
-				po.append('items', po_data)
+				po.append("items", po_data)
 
 			po.set_missing_values()
 			po.flags.ignore_mandatory = True
@@ -503,7 +544,7 @@
 
 		wo = frappe.new_doc("Work Order")
 		wo.update(item)
-		wo.planned_start_date = item.get('planned_start_date') or item.get('schedule_date')
+		wo.planned_start_date = item.get("planned_start_date") or item.get("schedule_date")
 
 		if item.get("warehouse"):
 			wo.fg_warehouse = item.get("warehouse")
@@ -521,54 +562,60 @@
 
 	@frappe.whitelist()
 	def make_material_request(self):
-		'''Create Material Requests grouped by Sales Order and Material Request Type'''
+		"""Create Material Requests grouped by Sales Order and Material Request Type"""
 		material_request_list = []
 		material_request_map = {}
 
 		for item in self.mr_items:
-			item_doc = frappe.get_cached_doc('Item', item.item_code)
+			item_doc = frappe.get_cached_doc("Item", item.item_code)
 
 			material_request_type = item.material_request_type or item_doc.default_material_request_type
 
 			# key for Sales Order:Material Request Type:Customer
-			key = '{}:{}:{}'.format(item.sales_order, material_request_type, item_doc.customer or '')
+			key = "{}:{}:{}".format(item.sales_order, material_request_type, item_doc.customer or "")
 			schedule_date = add_days(nowdate(), cint(item_doc.lead_time_days))
 
 			if not key in material_request_map:
 				# make a new MR for the combination
 				material_request_map[key] = frappe.new_doc("Material Request")
 				material_request = material_request_map[key]
-				material_request.update({
-					"transaction_date": nowdate(),
-					"status": "Draft",
-					"company": self.company,
-					'material_request_type': material_request_type,
-					'customer': item_doc.customer or ''
-				})
+				material_request.update(
+					{
+						"transaction_date": nowdate(),
+						"status": "Draft",
+						"company": self.company,
+						"material_request_type": material_request_type,
+						"customer": item_doc.customer or "",
+					}
+				)
 				material_request_list.append(material_request)
 			else:
 				material_request = material_request_map[key]
 
 			# add item
-			material_request.append("items", {
-				"item_code": item.item_code,
-				"from_warehouse": item.from_warehouse,
-				"qty": item.quantity,
-				"schedule_date": schedule_date,
-				"warehouse": item.warehouse,
-				"sales_order": item.sales_order,
-				'production_plan': self.name,
-				'material_request_plan_item': item.name,
-				"project": frappe.db.get_value("Sales Order", item.sales_order, "project") \
-					if item.sales_order else None
-			})
+			material_request.append(
+				"items",
+				{
+					"item_code": item.item_code,
+					"from_warehouse": item.from_warehouse,
+					"qty": item.quantity,
+					"schedule_date": schedule_date,
+					"warehouse": item.warehouse,
+					"sales_order": item.sales_order,
+					"production_plan": self.name,
+					"material_request_plan_item": item.name,
+					"project": frappe.db.get_value("Sales Order", item.sales_order, "project")
+					if item.sales_order
+					else None,
+				},
+			)
 
 		for material_request in material_request_list:
 			# submit
 			material_request.flags.ignore_permissions = 1
 			material_request.run_method("set_missing_values")
 
-			if self.get('submit_material_request'):
+			if self.get("submit_material_request"):
 				material_request.submit()
 			else:
 				material_request.save()
@@ -576,17 +623,19 @@
 		frappe.flags.mute_messages = False
 
 		if material_request_list:
-			material_request_list = ["""<a href="/app/Form/Material Request/{0}">{1}</a>""".format(m.name, m.name) \
-				for m in material_request_list]
+			material_request_list = [
+				"""<a href="/app/Form/Material Request/{0}">{1}</a>""".format(m.name, m.name)
+				for m in material_request_list
+			]
 			msgprint(_("{0} created").format(comma_and(material_request_list)))
-		else :
+		else:
 			msgprint(_("No material request created"))
 
 	@frappe.whitelist()
 	def get_sub_assembly_items(self, manufacturing_type=None):
 		"Fetch sub assembly items and optionally combine them."
 		self.sub_assembly_items = []
-		sub_assembly_items_store = [] # temporary store to process all subassembly items
+		sub_assembly_items_store = []  # temporary store to process all subassembly items
 
 		for row in self.po_items:
 			bom_data = []
@@ -598,7 +647,7 @@
 			# Combine subassembly items
 			sub_assembly_items_store = self.combine_subassembly_items(sub_assembly_items_store)
 
-		sub_assembly_items_store.sort(key= lambda d: d.bom_level, reverse=True) # sort by bom level
+		sub_assembly_items_store.sort(key=lambda d: d.bom_level, reverse=True)  # sort by bom level
 
 		for idx, row in enumerate(sub_assembly_items_store):
 			row.idx = idx + 1
@@ -611,16 +660,19 @@
 			data.production_plan_item = row.name
 			data.fg_warehouse = row.warehouse
 			data.schedule_date = row.planned_start_date
-			data.type_of_manufacturing = manufacturing_type or ("Subcontract" if data.is_sub_contracted_item
-				else "In House")
+			data.type_of_manufacturing = manufacturing_type or (
+				"Subcontract" if data.is_sub_contracted_item else "In House"
+			)
 
 	def combine_subassembly_items(self, sub_assembly_items_store):
 		"Aggregate if same: Item, Warehouse, Inhouse/Outhouse Manu.g, BOM No."
 		key_wise_data = {}
 		for row in sub_assembly_items_store:
 			key = (
-				row.get("production_item"), row.get("fg_warehouse"),
-				row.get("bom_no"), row.get("type_of_manufacturing")
+				row.get("production_item"),
+				row.get("fg_warehouse"),
+				row.get("bom_no"),
+				row.get("type_of_manufacturing"),
 			)
 			if key not in key_wise_data:
 				# intialise (item, wh, bom no, man.g type) wise dict
@@ -638,12 +690,15 @@
 				# add row with key
 				key_wise_data[key] = row
 
-		sub_assembly_items_store = [key_wise_data[key] for key in key_wise_data] # unpack into single level list
+		sub_assembly_items_store = [
+			key_wise_data[key] for key in key_wise_data
+		]  # unpack into single level list
 		return sub_assembly_items_store
 
 	def all_items_completed(self):
-		all_items_produced = all(flt(d.planned_qty) - flt(d.produced_qty) < 0.000001
-									for d in self.po_items)
+		all_items_produced = all(
+			flt(d.planned_qty) - flt(d.produced_qty) < 0.000001 for d in self.po_items
+		)
 		if not all_items_produced:
 			return False
 
@@ -660,40 +715,81 @@
 		all_work_orders_completed = all(s == "Completed" for s in wo_status)
 		return all_work_orders_completed
 
+
 @frappe.whitelist()
 def download_raw_materials(doc, warehouses=None):
 	if isinstance(doc, str):
 		doc = frappe._dict(json.loads(doc))
 
-	item_list = [['Item Code', 'Item Name', 'Description',
-		'Stock UOM', 'Warehouse', 'Required Qty as per BOM',
-		'Projected Qty', 'Available Qty In Hand', 'Ordered Qty', 'Planned Qty',
-		'Reserved Qty for Production', 'Safety Stock', 'Required Qty']]
+	item_list = [
+		[
+			"Item Code",
+			"Item Name",
+			"Description",
+			"Stock UOM",
+			"Warehouse",
+			"Required Qty as per BOM",
+			"Projected Qty",
+			"Available Qty In Hand",
+			"Ordered Qty",
+			"Planned Qty",
+			"Reserved Qty for Production",
+			"Safety Stock",
+			"Required Qty",
+		]
+	]
 
 	doc.warehouse = None
 	frappe.flags.show_qty_in_stock_uom = 1
-	items = get_items_for_material_requests(doc, warehouses=warehouses, get_parent_warehouse_data=True)
+	items = get_items_for_material_requests(
+		doc, warehouses=warehouses, get_parent_warehouse_data=True
+	)
 
 	for d in items:
-		item_list.append([d.get('item_code'), d.get('item_name'),
-			d.get('description'), d.get('stock_uom'), d.get('warehouse'),
-			d.get('required_bom_qty'), d.get('projected_qty'), d.get('actual_qty'), d.get('ordered_qty'),
-			d.get('planned_qty'), d.get('reserved_qty_for_production'), d.get('safety_stock'), d.get('quantity')])
+		item_list.append(
+			[
+				d.get("item_code"),
+				d.get("item_name"),
+				d.get("description"),
+				d.get("stock_uom"),
+				d.get("warehouse"),
+				d.get("required_bom_qty"),
+				d.get("projected_qty"),
+				d.get("actual_qty"),
+				d.get("ordered_qty"),
+				d.get("planned_qty"),
+				d.get("reserved_qty_for_production"),
+				d.get("safety_stock"),
+				d.get("quantity"),
+			]
+		)
 
-		if not doc.get('for_warehouse'):
-			row = {'item_code': d.get('item_code')}
+		if not doc.get("for_warehouse"):
+			row = {"item_code": d.get("item_code")}
 			for bin_dict in get_bin_details(row, doc.company, all_warehouse=True):
-				if d.get("warehouse") == bin_dict.get('warehouse'):
+				if d.get("warehouse") == bin_dict.get("warehouse"):
 					continue
 
-				item_list.append(['', '', '', bin_dict.get('warehouse'), '',
-					bin_dict.get('projected_qty', 0), bin_dict.get('actual_qty', 0),
-					bin_dict.get('ordered_qty', 0), bin_dict.get('reserved_qty_for_production', 0)])
+				item_list.append(
+					[
+						"",
+						"",
+						"",
+						bin_dict.get("warehouse"),
+						"",
+						bin_dict.get("projected_qty", 0),
+						bin_dict.get("actual_qty", 0),
+						bin_dict.get("ordered_qty", 0),
+						bin_dict.get("reserved_qty_for_production", 0),
+					]
+				)
 
 	build_csv_response(item_list, doc.name)
 
+
 def get_exploded_items(item_details, company, bom_no, include_non_stock_items, planned_qty=1):
-	for d in frappe.db.sql("""select bei.item_code, item.default_bom as bom,
+	for d in frappe.db.sql(
+		"""select bei.item_code, item.default_bom as bom,
 			ifnull(sum(bei.stock_qty/ifnull(bom.quantity, 1)), 0)*%s as qty, item.item_name,
 			bei.description, bei.stock_uom, item.min_order_qty, bei.source_warehouse,
 			item.default_material_request_type, item.min_order_qty, item_default.default_warehouse,
@@ -709,21 +805,38 @@
 		where
 			bei.docstatus < 2
 			and bom.name=%s and item.is_stock_item in (1, {0})
-		group by bei.item_code, bei.stock_uom""".format(0 if include_non_stock_items else 1),
-		(planned_qty, company, bom_no), as_dict=1):
+		group by bei.item_code, bei.stock_uom""".format(
+			0 if include_non_stock_items else 1
+		),
+		(planned_qty, company, bom_no),
+		as_dict=1,
+	):
 		if not d.conversion_factor and d.purchase_uom:
 			d.conversion_factor = get_uom_conversion_factor(d.item_code, d.purchase_uom)
-		item_details.setdefault(d.get('item_code'), d)
+		item_details.setdefault(d.get("item_code"), d)
 
 	return item_details
 
-def get_uom_conversion_factor(item_code, uom):
-	return frappe.db.get_value('UOM Conversion Detail',
-		{'parent': item_code, 'uom': uom}, 'conversion_factor')
 
-def get_subitems(doc, data, item_details, bom_no, company, include_non_stock_items,
-	include_subcontracted_items, parent_qty, planned_qty=1):
-	items = frappe.db.sql("""
+def get_uom_conversion_factor(item_code, uom):
+	return frappe.db.get_value(
+		"UOM Conversion Detail", {"parent": item_code, "uom": uom}, "conversion_factor"
+	)
+
+
+def get_subitems(
+	doc,
+	data,
+	item_details,
+	bom_no,
+	company,
+	include_non_stock_items,
+	include_subcontracted_items,
+	parent_qty,
+	planned_qty=1,
+):
+	items = frappe.db.sql(
+		"""
 		SELECT
 			bom_item.item_code, default_material_request_type, item.item_name,
 			ifnull(%(parent_qty)s * sum(bom_item.stock_qty/ifnull(bom.quantity, 1)) * %(planned_qty)s, 0) as qty,
@@ -743,15 +856,15 @@
 			bom.name = %(bom)s
 			and bom_item.docstatus < 2
 			and item.is_stock_item in (1, {0})
-		group by bom_item.item_code""".format(0 if include_non_stock_items else 1),{
-			'bom': bom_no,
-			'parent_qty': parent_qty,
-			'planned_qty': planned_qty,
-			'company': company
-		}, as_dict=1)
+		group by bom_item.item_code""".format(
+			0 if include_non_stock_items else 1
+		),
+		{"bom": bom_no, "parent_qty": parent_qty, "planned_qty": planned_qty, "company": company},
+		as_dict=1,
+	)
 
 	for d in items:
-		if not data.get('include_exploded_items') or not d.default_bom:
+		if not data.get("include_exploded_items") or not d.default_bom:
 			if d.item_code in item_details:
 				item_details[d.item_code].qty = item_details[d.item_code].qty + d.qty
 			else:
@@ -760,89 +873,107 @@
 
 				item_details[d.item_code] = d
 
-		if data.get('include_exploded_items') and d.default_bom:
-			if ((d.default_material_request_type in ["Manufacture", "Purchase"] and
-				not d.is_sub_contracted) or (d.is_sub_contracted and include_subcontracted_items)):
+		if data.get("include_exploded_items") and d.default_bom:
+			if (
+				d.default_material_request_type in ["Manufacture", "Purchase"] and not d.is_sub_contracted
+			) or (d.is_sub_contracted and include_subcontracted_items):
 				if d.qty > 0:
-					get_subitems(doc, data, item_details, d.default_bom, company,
-						include_non_stock_items, include_subcontracted_items, d.qty)
+					get_subitems(
+						doc,
+						data,
+						item_details,
+						d.default_bom,
+						company,
+						include_non_stock_items,
+						include_subcontracted_items,
+						d.qty,
+					)
 	return item_details
 
-def get_material_request_items(row, sales_order, company,
-	ignore_existing_ordered_qty, include_safety_stock, warehouse, bin_dict):
-	total_qty = row['qty']
+
+def get_material_request_items(
+	row, sales_order, company, ignore_existing_ordered_qty, include_safety_stock, warehouse, bin_dict
+):
+	total_qty = row["qty"]
 
 	required_qty = 0
 	if ignore_existing_ordered_qty or bin_dict.get("projected_qty", 0) < 0:
 		required_qty = total_qty
 	elif total_qty > bin_dict.get("projected_qty", 0):
 		required_qty = total_qty - bin_dict.get("projected_qty", 0)
-	if required_qty > 0 and required_qty < row['min_order_qty']:
-		required_qty = row['min_order_qty']
+	if required_qty > 0 and required_qty < row["min_order_qty"]:
+		required_qty = row["min_order_qty"]
 	item_group_defaults = get_item_group_defaults(row.item_code, company)
 
-	if not row['purchase_uom']:
-		row['purchase_uom'] = row['stock_uom']
+	if not row["purchase_uom"]:
+		row["purchase_uom"] = row["stock_uom"]
 
-	if row['purchase_uom'] != row['stock_uom']:
-		if not (row['conversion_factor'] or frappe.flags.show_qty_in_stock_uom):
-			frappe.throw(_("UOM Conversion factor ({0} -> {1}) not found for item: {2}")
-				.format(row['purchase_uom'], row['stock_uom'], row.item_code))
+	if row["purchase_uom"] != row["stock_uom"]:
+		if not (row["conversion_factor"] or frappe.flags.show_qty_in_stock_uom):
+			frappe.throw(
+				_("UOM Conversion factor ({0} -> {1}) not found for item: {2}").format(
+					row["purchase_uom"], row["stock_uom"], row.item_code
+				)
+			)
 
-			required_qty = required_qty / row['conversion_factor']
+			required_qty = required_qty / row["conversion_factor"]
 
-	if frappe.db.get_value("UOM", row['purchase_uom'], "must_be_whole_number"):
+	if frappe.db.get_value("UOM", row["purchase_uom"], "must_be_whole_number"):
 		required_qty = ceil(required_qty)
 
 	if include_safety_stock:
-		required_qty += flt(row['safety_stock'])
+		required_qty += flt(row["safety_stock"])
 
 	if required_qty > 0:
 		return {
-			'item_code': row.item_code,
-			'item_name': row.item_name,
-			'quantity': required_qty,
-			'required_bom_qty': total_qty,
-			'stock_uom': row.get("stock_uom"),
-			'warehouse': warehouse or row.get('source_warehouse') \
-				or row.get('default_warehouse') or item_group_defaults.get("default_warehouse"),
-			'safety_stock': row.safety_stock,
-			'actual_qty': bin_dict.get("actual_qty", 0),
-			'projected_qty': bin_dict.get("projected_qty", 0),
-			'ordered_qty': bin_dict.get("ordered_qty", 0),
-			'reserved_qty_for_production': bin_dict.get("reserved_qty_for_production", 0),
-			'min_order_qty': row['min_order_qty'],
-			'material_request_type': row.get("default_material_request_type"),
-			'sales_order': sales_order,
-			'description': row.get("description"),
-			'uom': row.get("purchase_uom") or row.get("stock_uom")
+			"item_code": row.item_code,
+			"item_name": row.item_name,
+			"quantity": required_qty,
+			"required_bom_qty": total_qty,
+			"stock_uom": row.get("stock_uom"),
+			"warehouse": warehouse
+			or row.get("source_warehouse")
+			or row.get("default_warehouse")
+			or item_group_defaults.get("default_warehouse"),
+			"safety_stock": row.safety_stock,
+			"actual_qty": bin_dict.get("actual_qty", 0),
+			"projected_qty": bin_dict.get("projected_qty", 0),
+			"ordered_qty": bin_dict.get("ordered_qty", 0),
+			"reserved_qty_for_production": bin_dict.get("reserved_qty_for_production", 0),
+			"min_order_qty": row["min_order_qty"],
+			"material_request_type": row.get("default_material_request_type"),
+			"sales_order": sales_order,
+			"description": row.get("description"),
+			"uom": row.get("purchase_uom") or row.get("stock_uom"),
 		}
 
+
 def get_sales_orders(self):
 	so_filter = item_filter = ""
 	bom_item = "bom.item = so_item.item_code"
 
 	date_field_mapper = {
-		'from_date': ('>=', 'so.transaction_date'),
-		'to_date': ('<=', 'so.transaction_date'),
-		'from_delivery_date': ('>=', 'so_item.delivery_date'),
-		'to_delivery_date': ('<=', 'so_item.delivery_date')
+		"from_date": (">=", "so.transaction_date"),
+		"to_date": ("<=", "so.transaction_date"),
+		"from_delivery_date": (">=", "so_item.delivery_date"),
+		"to_delivery_date": ("<=", "so_item.delivery_date"),
 	}
 
 	for field, value in date_field_mapper.items():
 		if self.get(field):
 			so_filter += f" and {value[1]} {value[0]} %({field})s"
 
-	for field in ['customer', 'project', 'sales_order_status']:
+	for field in ["customer", "project", "sales_order_status"]:
 		if self.get(field):
-			so_field = 'status' if field == 'sales_order_status' else field
+			so_field = "status" if field == "sales_order_status" else field
 			so_filter += f" and so.{so_field} = %({field})s"
 
-	if self.item_code and frappe.db.exists('Item', self.item_code):
+	if self.item_code and frappe.db.exists("Item", self.item_code):
 		bom_item = self.get_bom_item() or bom_item
 		item_filter += " and so_item.item_code = %(item_code)s"
 
-	open_so = frappe.db.sql(f"""
+	open_so = frappe.db.sql(
+		f"""
 		select distinct so.name, so.transaction_date, so.customer, so.base_grand_total
 		from `tabSales Order` so, `tabSales Order Item` so_item
 		where so_item.parent = so.name
@@ -855,10 +986,14 @@
 					where pi.parent = so.name and pi.parent_item = so_item.item_code
 						and exists (select name from `tabBOM` bom where bom.item=pi.item_code
 							and bom.is_active = 1)))
-		""", self.as_dict(), as_dict=1)
+		""",
+		self.as_dict(),
+		as_dict=1,
+	)
 
 	return open_so
 
+
 @frappe.whitelist()
 def get_bin_details(row, company, for_warehouse=None, all_warehouse=False):
 	if isinstance(row, str):
@@ -867,30 +1002,42 @@
 	company = frappe.db.escape(company)
 	conditions, warehouse = "", ""
 
-	conditions = " and warehouse in (select name from `tabWarehouse` where company = {0})".format(company)
+	conditions = " and warehouse in (select name from `tabWarehouse` where company = {0})".format(
+		company
+	)
 	if not all_warehouse:
-		warehouse = for_warehouse or row.get('source_warehouse') or row.get('default_warehouse')
+		warehouse = for_warehouse or row.get("source_warehouse") or row.get("default_warehouse")
 
 	if warehouse:
 		lft, rgt = frappe.db.get_value("Warehouse", warehouse, ["lft", "rgt"])
 		conditions = """ and warehouse in (select name from `tabWarehouse`
 			where lft >= {0} and rgt <= {1} and name=`tabBin`.warehouse and company = {2})
-		""".format(lft, rgt, company)
+		""".format(
+			lft, rgt, company
+		)
 
-	return frappe.db.sql(""" select ifnull(sum(projected_qty),0) as projected_qty,
+	return frappe.db.sql(
+		""" select ifnull(sum(projected_qty),0) as projected_qty,
 		ifnull(sum(actual_qty),0) as actual_qty, ifnull(sum(ordered_qty),0) as ordered_qty,
 		ifnull(sum(reserved_qty_for_production),0) as reserved_qty_for_production, warehouse,
 		ifnull(sum(planned_qty),0) as planned_qty
 		from `tabBin` where item_code = %(item_code)s {conditions}
 		group by item_code, warehouse
-	""".format(conditions=conditions), { "item_code": row['item_code'] }, as_dict=1)
+	""".format(
+			conditions=conditions
+		),
+		{"item_code": row["item_code"]},
+		as_dict=1,
+	)
+
 
 @frappe.whitelist()
 def get_so_details(sales_order):
-	return frappe.db.get_value("Sales Order", sales_order,
-		['transaction_date', 'customer', 'grand_total'], as_dict=1
+	return frappe.db.get_value(
+		"Sales Order", sales_order, ["transaction_date", "customer", "grand_total"], as_dict=1
 	)
 
+
 def get_warehouse_list(warehouses):
 	warehouse_list = []
 
@@ -898,7 +1045,7 @@
 		warehouses = json.loads(warehouses)
 
 	for row in warehouses:
-		child_warehouses = frappe.db.get_descendants('Warehouse', row.get("warehouse"))
+		child_warehouses = frappe.db.get_descendants("Warehouse", row.get("warehouse"))
 		if child_warehouses:
 			warehouse_list.extend(child_warehouses)
 		else:
@@ -906,6 +1053,7 @@
 
 	return warehouse_list
 
+
 @frappe.whitelist()
 def get_items_for_material_requests(doc, warehouses=None, get_parent_warehouse_data=None):
 	if isinstance(doc, str):
@@ -914,73 +1062,92 @@
 	if warehouses:
 		warehouses = list(set(get_warehouse_list(warehouses)))
 
-		if doc.get("for_warehouse") and not get_parent_warehouse_data and doc.get("for_warehouse") in warehouses:
+		if (
+			doc.get("for_warehouse")
+			and not get_parent_warehouse_data
+			and doc.get("for_warehouse") in warehouses
+		):
 			warehouses.remove(doc.get("for_warehouse"))
 
-	doc['mr_items'] = []
+	doc["mr_items"] = []
 
-	po_items = doc.get('po_items') if doc.get('po_items') else doc.get('items')
+	po_items = doc.get("po_items") if doc.get("po_items") else doc.get("items")
 	# Check for empty table or empty rows
-	if not po_items or not [row.get('item_code') for row in po_items if row.get('item_code')]:
-		frappe.throw(_("Items to Manufacture are required to pull the Raw Materials associated with it."),
-			title=_("Items Required"))
+	if not po_items or not [row.get("item_code") for row in po_items if row.get("item_code")]:
+		frappe.throw(
+			_("Items to Manufacture are required to pull the Raw Materials associated with it."),
+			title=_("Items Required"),
+		)
 
-	company = doc.get('company')
-	ignore_existing_ordered_qty = doc.get('ignore_existing_ordered_qty')
-	include_safety_stock = doc.get('include_safety_stock')
+	company = doc.get("company")
+	ignore_existing_ordered_qty = doc.get("ignore_existing_ordered_qty")
+	include_safety_stock = doc.get("include_safety_stock")
 
 	so_item_details = frappe._dict()
 	for data in po_items:
 		if not data.get("include_exploded_items") and doc.get("sub_assembly_items"):
 			data["include_exploded_items"] = 1
 
-		planned_qty = data.get('required_qty') or data.get('planned_qty')
-		ignore_existing_ordered_qty = data.get('ignore_existing_ordered_qty') or ignore_existing_ordered_qty
-		warehouse = doc.get('for_warehouse')
+		planned_qty = data.get("required_qty") or data.get("planned_qty")
+		ignore_existing_ordered_qty = (
+			data.get("ignore_existing_ordered_qty") or ignore_existing_ordered_qty
+		)
+		warehouse = doc.get("for_warehouse")
 
 		item_details = {}
 		if data.get("bom") or data.get("bom_no"):
-			if data.get('required_qty'):
-				bom_no = data.get('bom')
+			if data.get("required_qty"):
+				bom_no = data.get("bom")
 				include_non_stock_items = 1
-				include_subcontracted_items = 1 if data.get('include_exploded_items') else 0
+				include_subcontracted_items = 1 if data.get("include_exploded_items") else 0
 			else:
-				bom_no = data.get('bom_no')
-				include_subcontracted_items = doc.get('include_subcontracted_items')
-				include_non_stock_items = doc.get('include_non_stock_items')
+				bom_no = data.get("bom_no")
+				include_subcontracted_items = doc.get("include_subcontracted_items")
+				include_non_stock_items = doc.get("include_non_stock_items")
 
 			if not planned_qty:
-				frappe.throw(_("For row {0}: Enter Planned Qty").format(data.get('idx')))
+				frappe.throw(_("For row {0}: Enter Planned Qty").format(data.get("idx")))
 
 			if bom_no:
-				if data.get('include_exploded_items') and include_subcontracted_items:
+				if data.get("include_exploded_items") and include_subcontracted_items:
 					# fetch exploded items from BOM
-					item_details = get_exploded_items(item_details,
-						company, bom_no, include_non_stock_items, planned_qty=planned_qty)
+					item_details = get_exploded_items(
+						item_details, company, bom_no, include_non_stock_items, planned_qty=planned_qty
+					)
 				else:
-					item_details = get_subitems(doc, data, item_details, bom_no, company,
-						include_non_stock_items, include_subcontracted_items, 1, planned_qty=planned_qty)
-		elif data.get('item_code'):
-			item_master = frappe.get_doc('Item', data['item_code']).as_dict()
+					item_details = get_subitems(
+						doc,
+						data,
+						item_details,
+						bom_no,
+						company,
+						include_non_stock_items,
+						include_subcontracted_items,
+						1,
+						planned_qty=planned_qty,
+					)
+		elif data.get("item_code"):
+			item_master = frappe.get_doc("Item", data["item_code"]).as_dict()
 			purchase_uom = item_master.purchase_uom or item_master.stock_uom
-			conversion_factor = (get_uom_conversion_factor(item_master.name, purchase_uom)
-				if item_master.purchase_uom else 1.0)
+			conversion_factor = (
+				get_uom_conversion_factor(item_master.name, purchase_uom) if item_master.purchase_uom else 1.0
+			)
 
 			item_details[item_master.name] = frappe._dict(
 				{
-					'item_name' : item_master.item_name,
-					'default_bom' : doc.bom,
-					'purchase_uom' : purchase_uom,
-					'default_warehouse': item_master.default_warehouse,
-					'min_order_qty' : item_master.min_order_qty,
-					'default_material_request_type' : item_master.default_material_request_type,
-					'qty': planned_qty or 1,
-					'is_sub_contracted' : item_master.is_subcontracted_item,
-					'item_code' : item_master.name,
-					'description' : item_master.description,
-					'stock_uom' : item_master.stock_uom,
-					'conversion_factor' : conversion_factor,
-					'safety_stock': item_master.safety_stock
+					"item_name": item_master.item_name,
+					"default_bom": doc.bom,
+					"purchase_uom": purchase_uom,
+					"default_warehouse": item_master.default_warehouse,
+					"min_order_qty": item_master.min_order_qty,
+					"default_material_request_type": item_master.default_material_request_type,
+					"qty": planned_qty or 1,
+					"is_sub_contracted": item_master.is_subcontracted_item,
+					"item_code": item_master.name,
+					"description": item_master.description,
+					"stock_uom": item_master.stock_uom,
+					"conversion_factor": conversion_factor,
+					"safety_stock": item_master.safety_stock,
 				}
 			)
 
@@ -989,7 +1156,9 @@
 		for item_code, details in item_details.items():
 			so_item_details.setdefault(sales_order, frappe._dict())
 			if item_code in so_item_details.get(sales_order, {}):
-				so_item_details[sales_order][item_code]['qty'] = so_item_details[sales_order][item_code].get("qty", 0) + flt(details.qty)
+				so_item_details[sales_order][item_code]["qty"] = so_item_details[sales_order][item_code].get(
+					"qty", 0
+				) + flt(details.qty)
 			else:
 				so_item_details[sales_order][item_code] = details
 
@@ -1001,8 +1170,15 @@
 			bin_dict = bin_dict[0] if bin_dict else {}
 
 			if details.qty > 0:
-				items = get_material_request_items(details, sales_order, company,
-					ignore_existing_ordered_qty, include_safety_stock, warehouse, bin_dict)
+				items = get_material_request_items(
+					details,
+					sales_order,
+					company,
+					ignore_existing_ordered_qty,
+					include_safety_stock,
+					warehouse,
+					bin_dict,
+				)
 				if items:
 					mr_items.append(items)
 
@@ -1015,18 +1191,26 @@
 
 	if not mr_items:
 		to_enable = frappe.bold(_("Ignore Existing Projected Quantity"))
-		warehouse = frappe.bold(doc.get('for_warehouse'))
-		message = _("As there are sufficient raw materials, Material Request is not required for Warehouse {0}.").format(warehouse) + "<br><br>"
+		warehouse = frappe.bold(doc.get("for_warehouse"))
+		message = (
+			_(
+				"As there are sufficient raw materials, Material Request is not required for Warehouse {0}."
+			).format(warehouse)
+			+ "<br><br>"
+		)
 		message += _("If you still want to proceed, please enable {0}.").format(to_enable)
 
 		frappe.msgprint(message, title=_("Note"))
 
 	return mr_items
 
+
 def get_materials_from_other_locations(item, warehouses, new_mr_items, company):
 	from erpnext.stock.doctype.pick_list.pick_list import get_available_item_locations
-	locations = get_available_item_locations(item.get("item_code"),
-		warehouses, item.get("quantity"), company, ignore_validation=True)
+
+	locations = get_available_item_locations(
+		item.get("item_code"), warehouses, item.get("quantity"), company, ignore_validation=True
+	)
 
 	required_qty = item.get("quantity")
 	# get available material by transferring to production warehouse
@@ -1037,12 +1221,14 @@
 		new_dict = copy.deepcopy(item)
 		quantity = required_qty if d.get("qty") > required_qty else d.get("qty")
 
-		new_dict.update({
-			"quantity": quantity,
-			"material_request_type": "Material Transfer",
-			"uom": new_dict.get("stock_uom"),  # internal transfer should be in stock UOM
-			"from_warehouse": d.get("warehouse")
-		})
+		new_dict.update(
+			{
+				"quantity": quantity,
+				"material_request_type": "Material Transfer",
+				"uom": new_dict.get("stock_uom"),  # internal transfer should be in stock UOM
+				"from_warehouse": d.get("warehouse"),
+			}
+		)
 
 		required_qty -= quantity
 		new_mr_items.append(new_dict)
@@ -1050,16 +1236,17 @@
 	# raise purchase request for remaining qty
 	if required_qty:
 		stock_uom, purchase_uom = frappe.db.get_value(
-			'Item',
-			item['item_code'],
-			['stock_uom', 'purchase_uom']
+			"Item", item["item_code"], ["stock_uom", "purchase_uom"]
 		)
 
-		if purchase_uom != stock_uom and purchase_uom == item['uom']:
-			conversion_factor = get_uom_conversion_factor(item['item_code'], item['uom'])
+		if purchase_uom != stock_uom and purchase_uom == item["uom"]:
+			conversion_factor = get_uom_conversion_factor(item["item_code"], item["uom"])
 			if not (conversion_factor or frappe.flags.show_qty_in_stock_uom):
-				frappe.throw(_("UOM Conversion factor ({0} -> {1}) not found for item: {2}")
-					.format(purchase_uom, stock_uom, item['item_code']))
+				frappe.throw(
+					_("UOM Conversion factor ({0} -> {1}) not found for item: {2}").format(
+						purchase_uom, stock_uom, item["item_code"]
+					)
+				)
 
 			required_qty = required_qty / conversion_factor
 
@@ -1070,6 +1257,7 @@
 
 		new_mr_items.append(item)
 
+
 @frappe.whitelist()
 def get_item_data(item_code):
 	item_details = get_item_details(item_code)
@@ -1077,33 +1265,39 @@
 	return {
 		"bom_no": item_details.get("bom_no"),
 		"stock_uom": item_details.get("stock_uom")
-#		"description": item_details.get("description")
+		# 		"description": item_details.get("description")
 	}
 
+
 def get_sub_assembly_items(bom_no, bom_data, to_produce_qty, indent=0):
 	data = get_bom_children(parent=bom_no)
 	for d in data:
 		if d.expandable:
 			parent_item_code = frappe.get_cached_value("BOM", bom_no, "item")
 			stock_qty = (d.stock_qty / d.parent_bom_qty) * flt(to_produce_qty)
-			bom_data.append(frappe._dict({
-				'parent_item_code': parent_item_code,
-				'description': d.description,
-				'production_item': d.item_code,
-				'item_name': d.item_name,
-				'stock_uom': d.stock_uom,
-				'uom': d.stock_uom,
-				'bom_no': d.value,
-				'is_sub_contracted_item': d.is_sub_contracted_item,
-				'bom_level': indent,
-				'indent': indent,
-				'stock_qty': stock_qty
-			}))
+			bom_data.append(
+				frappe._dict(
+					{
+						"parent_item_code": parent_item_code,
+						"description": d.description,
+						"production_item": d.item_code,
+						"item_name": d.item_name,
+						"stock_uom": d.stock_uom,
+						"uom": d.stock_uom,
+						"bom_no": d.value,
+						"is_sub_contracted_item": d.is_sub_contracted_item,
+						"bom_level": indent,
+						"indent": indent,
+						"stock_qty": stock_qty,
+					}
+				)
+			)
 
 			if d.value:
-				get_sub_assembly_items(d.value, bom_data, stock_qty, indent=indent+1)
+				get_sub_assembly_items(d.value, bom_data, stock_qty, indent=indent + 1)
+
 
 def set_default_warehouses(row, default_warehouses):
-	for field in ['wip_warehouse', 'fg_warehouse']:
+	for field in ["wip_warehouse", "fg_warehouse"]:
 		if not row.get(field):
 			row[field] = default_warehouses.get(field)
diff --git a/erpnext/manufacturing/doctype/production_plan/production_plan_dashboard.py b/erpnext/manufacturing/doctype/production_plan/production_plan_dashboard.py
index e13f042..6fc28a3 100644
--- a/erpnext/manufacturing/doctype/production_plan/production_plan_dashboard.py
+++ b/erpnext/manufacturing/doctype/production_plan/production_plan_dashboard.py
@@ -3,15 +3,9 @@
 
 def get_data():
 	return {
-		'fieldname': 'production_plan',
-		'transactions': [
-			{
-				'label': _('Transactions'),
-				'items': ['Work Order', 'Material Request']
-			},
-			{
-				'label': _('Subcontract'),
-				'items': ['Purchase Order']
-			},
-		]
+		"fieldname": "production_plan",
+		"transactions": [
+			{"label": _("Transactions"), "items": ["Work Order", "Material Request"]},
+			{"label": _("Subcontract"), "items": ["Purchase Order"]},
+		],
 	}
diff --git a/erpnext/manufacturing/doctype/production_plan/test_production_plan.py b/erpnext/manufacturing/doctype/production_plan/test_production_plan.py
index ec49703..891a497 100644
--- a/erpnext/manufacturing/doctype/production_plan/test_production_plan.py
+++ b/erpnext/manufacturing/doctype/production_plan/test_production_plan.py
@@ -21,80 +21,88 @@
 
 class TestProductionPlan(FrappeTestCase):
 	def setUp(self):
-		for item in ['Test Production Item 1', 'Subassembly Item 1',
-			'Raw Material Item 1', 'Raw Material Item 2']:
+		for item in [
+			"Test Production Item 1",
+			"Subassembly Item 1",
+			"Raw Material Item 1",
+			"Raw Material Item 2",
+		]:
 			create_item(item, valuation_rate=100)
 
-			sr = frappe.db.get_value('Stock Reconciliation Item',
-				{'item_code': item, 'docstatus': 1}, 'parent')
+			sr = frappe.db.get_value(
+				"Stock Reconciliation Item", {"item_code": item, "docstatus": 1}, "parent"
+			)
 			if sr:
-				sr_doc = frappe.get_doc('Stock Reconciliation', sr)
+				sr_doc = frappe.get_doc("Stock Reconciliation", sr)
 				sr_doc.cancel()
 
-		create_item('Test Non Stock Raw Material', is_stock_item=0)
-		for item, raw_materials in {'Subassembly Item 1': ['Raw Material Item 1', 'Raw Material Item 2'],
-			'Test Production Item 1': ['Raw Material Item 1', 'Subassembly Item 1',
-			'Test Non Stock Raw Material']}.items():
-			if not frappe.db.get_value('BOM', {'item': item}):
-				make_bom(item = item, raw_materials = raw_materials)
+		create_item("Test Non Stock Raw Material", is_stock_item=0)
+		for item, raw_materials in {
+			"Subassembly Item 1": ["Raw Material Item 1", "Raw Material Item 2"],
+			"Test Production Item 1": [
+				"Raw Material Item 1",
+				"Subassembly Item 1",
+				"Test Non Stock Raw Material",
+			],
+		}.items():
+			if not frappe.db.get_value("BOM", {"item": item}):
+				make_bom(item=item, raw_materials=raw_materials)
 
 	def tearDown(self) -> None:
 		frappe.db.rollback()
 
 	def test_production_plan_mr_creation(self):
 		"Test if MRs are created for unavailable raw materials."
-		pln = create_production_plan(item_code='Test Production Item 1')
+		pln = create_production_plan(item_code="Test Production Item 1")
 		self.assertTrue(len(pln.mr_items), 2)
 
 		pln.make_material_request()
 		pln.reload()
-		self.assertTrue(pln.status, 'Material Requested')
+		self.assertTrue(pln.status, "Material Requested")
 
 		material_requests = frappe.get_all(
-			'Material Request Item',
-			fields = ['distinct parent'],
-			filters = {'production_plan': pln.name},
-			as_list=1
+			"Material Request Item",
+			fields=["distinct parent"],
+			filters={"production_plan": pln.name},
+			as_list=1,
 		)
 
 		self.assertTrue(len(material_requests), 2)
 
 		pln.make_work_order()
-		work_orders = frappe.get_all('Work Order', fields = ['name'],
-			filters = {'production_plan': pln.name}, as_list=1)
+		work_orders = frappe.get_all(
+			"Work Order", fields=["name"], filters={"production_plan": pln.name}, as_list=1
+		)
 
 		self.assertTrue(len(work_orders), len(pln.po_items))
 
 		for name in material_requests:
-			mr = frappe.get_doc('Material Request', name[0])
+			mr = frappe.get_doc("Material Request", name[0])
 			if mr.docstatus != 0:
 				mr.cancel()
 
 		for name in work_orders:
-			mr = frappe.delete_doc('Work Order', name[0])
+			mr = frappe.delete_doc("Work Order", name[0])
 
-		pln = frappe.get_doc('Production Plan', pln.name)
+		pln = frappe.get_doc("Production Plan", pln.name)
 		pln.cancel()
 
 	def test_production_plan_start_date(self):
 		"Test if Work Order has same Planned Start Date as Prod Plan."
 		planned_date = add_to_date(date=None, days=3)
 		plan = create_production_plan(
-			item_code='Test Production Item 1',
-			planned_start_date=planned_date
+			item_code="Test Production Item 1", planned_start_date=planned_date
 		)
 		plan.make_work_order()
 
 		work_orders = frappe.get_all(
-			'Work Order',
-			fields = ['name', 'planned_start_date'],
-			filters = {'production_plan': plan.name}
+			"Work Order", fields=["name", "planned_start_date"], filters={"production_plan": plan.name}
 		)
 
 		self.assertEqual(work_orders[0].planned_start_date, planned_date)
 
 		for wo in work_orders:
-			frappe.delete_doc('Work Order', wo.name)
+			frappe.delete_doc("Work Order", wo.name)
 
 		plan.reload()
 		plan.cancel()
@@ -104,15 +112,14 @@
 		- Enable 'ignore_existing_ordered_qty'.
 		- Test if MR Planning table pulls Raw Material Qty even if it is in stock.
 		"""
-		sr1 = create_stock_reconciliation(item_code="Raw Material Item 1",
-			target="_Test Warehouse - _TC", qty=1, rate=110)
-		sr2 = create_stock_reconciliation(item_code="Raw Material Item 2",
-			target="_Test Warehouse - _TC", qty=1, rate=120)
-
-		pln = create_production_plan(
-			item_code='Test Production Item 1',
-			ignore_existing_ordered_qty=1
+		sr1 = create_stock_reconciliation(
+			item_code="Raw Material Item 1", target="_Test Warehouse - _TC", qty=1, rate=110
 		)
+		sr2 = create_stock_reconciliation(
+			item_code="Raw Material Item 2", target="_Test Warehouse - _TC", qty=1, rate=120
+		)
+
+		pln = create_production_plan(item_code="Test Production Item 1", ignore_existing_ordered_qty=1)
 		self.assertTrue(len(pln.mr_items))
 		self.assertTrue(flt(pln.mr_items[0].quantity), 1.0)
 
@@ -122,19 +129,13 @@
 
 	def test_production_plan_with_non_stock_item(self):
 		"Test if MR Planning table includes Non Stock RM."
-		pln = create_production_plan(
-			item_code='Test Production Item 1',
-			include_non_stock_items=1
-		)
+		pln = create_production_plan(item_code="Test Production Item 1", include_non_stock_items=1)
 		self.assertTrue(len(pln.mr_items), 3)
 		pln.cancel()
 
 	def test_production_plan_without_multi_level(self):
 		"Test MR Planning table for non exploded BOM."
-		pln = create_production_plan(
-			item_code='Test Production Item 1',
-			use_multi_level_bom=0
-		)
+		pln = create_production_plan(item_code="Test Production Item 1", use_multi_level_bom=0)
 		self.assertTrue(len(pln.mr_items), 2)
 		pln.cancel()
 
@@ -144,15 +145,15 @@
 		- Test if MR Planning table avoids pulling Raw Material Qty as it is in stock for
 		non exploded BOM.
 		"""
-		sr1 = create_stock_reconciliation(item_code="Raw Material Item 1",
-			target="_Test Warehouse - _TC", qty=1, rate=130)
-		sr2 = create_stock_reconciliation(item_code="Subassembly Item 1",
-			target="_Test Warehouse - _TC", qty=1, rate=140)
+		sr1 = create_stock_reconciliation(
+			item_code="Raw Material Item 1", target="_Test Warehouse - _TC", qty=1, rate=130
+		)
+		sr2 = create_stock_reconciliation(
+			item_code="Subassembly Item 1", target="_Test Warehouse - _TC", qty=1, rate=140
+		)
 
 		pln = create_production_plan(
-			item_code='Test Production Item 1',
-			use_multi_level_bom=0,
-			ignore_existing_ordered_qty=0
+			item_code="Test Production Item 1", use_multi_level_bom=0, ignore_existing_ordered_qty=0
 		)
 		self.assertFalse(len(pln.mr_items))
 
@@ -162,73 +163,86 @@
 
 	def test_production_plan_sales_orders(self):
 		"Test if previously fulfilled SO (with WO) is pulled into Prod Plan."
-		item = 'Test Production Item 1'
+		item = "Test Production Item 1"
 		so = make_sales_order(item_code=item, qty=1)
 		sales_order = so.name
 		sales_order_item = so.items[0].name
 
-		pln = frappe.new_doc('Production Plan')
+		pln = frappe.new_doc("Production Plan")
 		pln.company = so.company
-		pln.get_items_from = 'Sales Order'
+		pln.get_items_from = "Sales Order"
 
-		pln.append('sales_orders', {
-			'sales_order': so.name,
-			'sales_order_date': so.transaction_date,
-			'customer': so.customer,
-			'grand_total': so.grand_total
-		})
+		pln.append(
+			"sales_orders",
+			{
+				"sales_order": so.name,
+				"sales_order_date": so.transaction_date,
+				"customer": so.customer,
+				"grand_total": so.grand_total,
+			},
+		)
 
 		pln.get_so_items()
 		pln.submit()
 		pln.make_work_order()
 
-		work_order = frappe.db.get_value('Work Order', {'sales_order': sales_order,
-			'production_plan': pln.name, 'sales_order_item': sales_order_item}, 'name')
+		work_order = frappe.db.get_value(
+			"Work Order",
+			{"sales_order": sales_order, "production_plan": pln.name, "sales_order_item": sales_order_item},
+			"name",
+		)
 
-		wo_doc = frappe.get_doc('Work Order', work_order)
-		wo_doc.update({
-			'wip_warehouse': 'Work In Progress - _TC',
-			'fg_warehouse': 'Finished Goods - _TC'
-		})
+		wo_doc = frappe.get_doc("Work Order", work_order)
+		wo_doc.update(
+			{"wip_warehouse": "Work In Progress - _TC", "fg_warehouse": "Finished Goods - _TC"}
+		)
 		wo_doc.submit()
 
-		so_wo_qty = frappe.db.get_value('Sales Order Item', sales_order_item, 'work_order_qty')
+		so_wo_qty = frappe.db.get_value("Sales Order Item", sales_order_item, "work_order_qty")
 		self.assertTrue(so_wo_qty, 5)
 
-		pln = frappe.new_doc('Production Plan')
-		pln.update({
-			'from_date': so.transaction_date,
-			'to_date': so.transaction_date,
-			'customer': so.customer,
-			'item_code': item,
-			'sales_order_status': so.status
-		})
+		pln = frappe.new_doc("Production Plan")
+		pln.update(
+			{
+				"from_date": so.transaction_date,
+				"to_date": so.transaction_date,
+				"customer": so.customer,
+				"item_code": item,
+				"sales_order_status": so.status,
+			}
+		)
 		sales_orders = get_sales_orders(pln) or {}
-		sales_orders = [d.get('name') for d in sales_orders if d.get('name') == sales_order]
+		sales_orders = [d.get("name") for d in sales_orders if d.get("name") == sales_order]
 
 		self.assertEqual(sales_orders, [])
 
 	def test_production_plan_combine_items(self):
 		"Test combining FG items in Production Plan."
-		item = 'Test Production Item 1'
+		item = "Test Production Item 1"
 		so1 = make_sales_order(item_code=item, qty=1)
 
-		pln = frappe.new_doc('Production Plan')
+		pln = frappe.new_doc("Production Plan")
 		pln.company = so1.company
-		pln.get_items_from = 'Sales Order'
-		pln.append('sales_orders', {
-			'sales_order': so1.name,
-			'sales_order_date': so1.transaction_date,
-			'customer': so1.customer,
-			'grand_total': so1.grand_total
-		})
+		pln.get_items_from = "Sales Order"
+		pln.append(
+			"sales_orders",
+			{
+				"sales_order": so1.name,
+				"sales_order_date": so1.transaction_date,
+				"customer": so1.customer,
+				"grand_total": so1.grand_total,
+			},
+		)
 		so2 = make_sales_order(item_code=item, qty=2)
-		pln.append('sales_orders', {
-			'sales_order': so2.name,
-			'sales_order_date': so2.transaction_date,
-			'customer': so2.customer,
-			'grand_total': so2.grand_total
-		})
+		pln.append(
+			"sales_orders",
+			{
+				"sales_order": so2.name,
+				"sales_order_date": so2.transaction_date,
+				"customer": so2.customer,
+				"grand_total": so2.grand_total,
+			},
+		)
 		pln.combine_items = 1
 		pln.get_items()
 		pln.submit()
@@ -236,26 +250,31 @@
 		self.assertTrue(pln.po_items[0].planned_qty, 3)
 
 		pln.make_work_order()
-		work_order = frappe.db.get_value('Work Order', {
-			'production_plan_item': pln.po_items[0].name,
-			'production_plan': pln.name
-		}, 'name')
+		work_order = frappe.db.get_value(
+			"Work Order",
+			{"production_plan_item": pln.po_items[0].name, "production_plan": pln.name},
+			"name",
+		)
 
-		wo_doc = frappe.get_doc('Work Order', work_order)
-		wo_doc.update({
-			'wip_warehouse': 'Work In Progress - _TC',
-		})
+		wo_doc = frappe.get_doc("Work Order", work_order)
+		wo_doc.update(
+			{
+				"wip_warehouse": "Work In Progress - _TC",
+			}
+		)
 
 		wo_doc.submit()
 		so_items = []
 		for plan_reference in pln.prod_plan_references:
 			so_items.append(plan_reference.sales_order_item)
-			so_wo_qty = frappe.db.get_value('Sales Order Item', plan_reference.sales_order_item, 'work_order_qty')
+			so_wo_qty = frappe.db.get_value(
+				"Sales Order Item", plan_reference.sales_order_item, "work_order_qty"
+			)
 			self.assertEqual(so_wo_qty, plan_reference.qty)
 
 		wo_doc.cancel()
 		for so_item in so_items:
-			so_wo_qty = frappe.db.get_value('Sales Order Item', so_item, 'work_order_qty')
+			so_wo_qty = frappe.db.get_value("Sales Order Item", so_item, "work_order_qty")
 			self.assertEqual(so_wo_qty, 0.0)
 
 		pln.reload()
@@ -269,12 +288,8 @@
 		"""
 		from erpnext.manufacturing.doctype.bom.test_bom import create_nested_bom
 
-		bom_tree_1 = {
-			"Red-Car": {"Wheel": {"Rubber": {}}}
-		}
-		bom_tree_2 = {
-			"Green-Car": {"Wheel": {"Rubber": {}}}
-		}
+		bom_tree_1 = {"Red-Car": {"Wheel": {"Rubber": {}}}}
+		bom_tree_2 = {"Green-Car": {"Wheel": {"Rubber": {}}}}
 
 		parent_bom_1 = create_nested_bom(bom_tree_1, prefix="")
 		parent_bom_2 = create_nested_bom(bom_tree_2, prefix="")
@@ -284,20 +299,23 @@
 		frappe.db.set_value("BOM Item", parent_bom_2.items[0].name, "bom_no", subassembly_bom)
 
 		plan = create_production_plan(item_code="Red-Car", use_multi_level_bom=1, do_not_save=True)
-		plan.append("po_items", { # Add Green-Car to Prod Plan
-			'use_multi_level_bom': 1,
-			'item_code': "Green-Car",
-			'bom_no': frappe.db.get_value('Item', "Green-Car", 'default_bom'),
-			'planned_qty': 1,
-			'planned_start_date': now_datetime()
-		})
+		plan.append(
+			"po_items",
+			{  # Add Green-Car to Prod Plan
+				"use_multi_level_bom": 1,
+				"item_code": "Green-Car",
+				"bom_no": frappe.db.get_value("Item", "Green-Car", "default_bom"),
+				"planned_qty": 1,
+				"planned_start_date": now_datetime(),
+			},
+		)
 		plan.get_sub_assembly_items()
 		self.assertTrue(len(plan.sub_assembly_items), 2)
 
 		plan.combine_sub_items = 1
 		plan.get_sub_assembly_items()
 
-		self.assertTrue(len(plan.sub_assembly_items), 1) # check if sub-assembly items merged
+		self.assertTrue(len(plan.sub_assembly_items), 1)  # check if sub-assembly items merged
 		self.assertEqual(plan.sub_assembly_items[0].qty, 2.0)
 		self.assertEqual(plan.sub_assembly_items[0].stock_qty, 2.0)
 
@@ -307,25 +325,29 @@
 		self.assertTrue(len(plan.sub_assembly_items), 2)
 
 	def test_pp_to_mr_customer_provided(self):
-		" Test Material Request from Production Plan for Customer Provided Item."
-		create_item('CUST-0987', is_customer_provided_item = 1, customer = '_Test Customer', is_purchase_item = 0)
-		create_item('Production Item CUST')
+		"Test Material Request from Production Plan for Customer Provided Item."
+		create_item(
+			"CUST-0987", is_customer_provided_item=1, customer="_Test Customer", is_purchase_item=0
+		)
+		create_item("Production Item CUST")
 
-		for item, raw_materials in {'Production Item CUST': ['Raw Material Item 1', 'CUST-0987']}.items():
-			if not frappe.db.get_value('BOM', {'item': item}):
-				make_bom(item = item, raw_materials = raw_materials)
-		production_plan = create_production_plan(item_code = 'Production Item CUST')
+		for item, raw_materials in {
+			"Production Item CUST": ["Raw Material Item 1", "CUST-0987"]
+		}.items():
+			if not frappe.db.get_value("BOM", {"item": item}):
+				make_bom(item=item, raw_materials=raw_materials)
+		production_plan = create_production_plan(item_code="Production Item CUST")
 		production_plan.make_material_request()
 
 		material_request = frappe.db.get_value(
-			'Material Request Item',
-			{'production_plan': production_plan.name, 'item_code': 'CUST-0987'},
-			'parent'
+			"Material Request Item",
+			{"production_plan": production_plan.name, "item_code": "CUST-0987"},
+			"parent",
 		)
-		mr = frappe.get_doc('Material Request', material_request)
+		mr = frappe.get_doc("Material Request", material_request)
 
-		self.assertTrue(mr.material_request_type, 'Customer Provided')
-		self.assertTrue(mr.customer, '_Test Customer')
+		self.assertTrue(mr.material_request_type, "Customer Provided")
+		self.assertTrue(mr.customer, "_Test Customer")
 
 	def test_production_plan_with_multi_level_bom(self):
 		"""
@@ -339,33 +361,34 @@
 			create_item(item_code, is_stock_item=1)
 
 		# created bom upto 3 level
-		if not frappe.db.get_value('BOM', {'item': "Test BOM 3"}):
-			make_bom(item = "Test BOM 3", raw_materials = ["Test RM BOM 1"], rm_qty=3)
+		if not frappe.db.get_value("BOM", {"item": "Test BOM 3"}):
+			make_bom(item="Test BOM 3", raw_materials=["Test RM BOM 1"], rm_qty=3)
 
-		if not frappe.db.get_value('BOM', {'item': "Test BOM 2"}):
-			make_bom(item = "Test BOM 2", raw_materials = ["Test BOM 3"], rm_qty=3)
+		if not frappe.db.get_value("BOM", {"item": "Test BOM 2"}):
+			make_bom(item="Test BOM 2", raw_materials=["Test BOM 3"], rm_qty=3)
 
-		if not frappe.db.get_value('BOM', {'item': "Test BOM 1"}):
-			make_bom(item = "Test BOM 1", raw_materials = ["Test BOM 2"], rm_qty=2)
+		if not frappe.db.get_value("BOM", {"item": "Test BOM 1"}):
+			make_bom(item="Test BOM 1", raw_materials=["Test BOM 2"], rm_qty=2)
 
 		item_code = "Test BOM 1"
-		pln = frappe.new_doc('Production Plan')
+		pln = frappe.new_doc("Production Plan")
 		pln.company = "_Test Company"
-		pln.append("po_items", {
-			"item_code": item_code,
-			"bom_no": frappe.db.get_value('BOM', {'item': "Test BOM 1"}),
-			"planned_qty": 3
-		})
+		pln.append(
+			"po_items",
+			{
+				"item_code": item_code,
+				"bom_no": frappe.db.get_value("BOM", {"item": "Test BOM 1"}),
+				"planned_qty": 3,
+			},
+		)
 
-		pln.get_sub_assembly_items('In House')
+		pln.get_sub_assembly_items("In House")
 		pln.submit()
 		pln.make_work_order()
 
-		#last level sub-assembly work order produce qty
+		# last level sub-assembly work order produce qty
 		to_produce_qty = frappe.db.get_value(
-			"Work Order",
-			{"production_plan": pln.name, "production_item": "Test BOM 3"},
-			"qty"
+			"Work Order", {"production_plan": pln.name, "production_item": "Test BOM 3"}, "qty"
 		)
 
 		self.assertEqual(to_produce_qty, 18.0)
@@ -374,70 +397,72 @@
 
 	def test_get_warehouse_list_group(self):
 		"Check if required child warehouses are returned."
-		warehouse_json = '[{\"warehouse\":\"_Test Warehouse Group - _TC\"}]'
+		warehouse_json = '[{"warehouse":"_Test Warehouse Group - _TC"}]'
 
 		warehouses = set(get_warehouse_list(warehouse_json))
 		expected_warehouses = {"_Test Warehouse Group-C1 - _TC", "_Test Warehouse Group-C2 - _TC"}
 
 		missing_warehouse = expected_warehouses - warehouses
 
-		self.assertTrue(len(missing_warehouse) == 0,
-				msg=f"Following warehouses were expected {', '.join(missing_warehouse)}")
+		self.assertTrue(
+			len(missing_warehouse) == 0,
+			msg=f"Following warehouses were expected {', '.join(missing_warehouse)}",
+		)
 
 	def test_get_warehouse_list_single(self):
 		"Check if same warehouse is returned in absence of child warehouses."
-		warehouse_json = '[{\"warehouse\":\"_Test Scrap Warehouse - _TC\"}]'
+		warehouse_json = '[{"warehouse":"_Test Scrap Warehouse - _TC"}]'
 
 		warehouses = set(get_warehouse_list(warehouse_json))
-		expected_warehouses = {"_Test Scrap Warehouse - _TC", }
+		expected_warehouses = {
+			"_Test Scrap Warehouse - _TC",
+		}
 
 		self.assertEqual(warehouses, expected_warehouses)
 
 	def test_get_sales_order_with_variant(self):
 		"Check if Template BOM is fetched in absence of Variant BOM."
-		rm_item = create_item('PIV_RM', valuation_rate = 100)
-		if not frappe.db.exists('Item', {"item_code": 'PIV'}):
-			item = create_item('PIV', valuation_rate = 100)
+		rm_item = create_item("PIV_RM", valuation_rate=100)
+		if not frappe.db.exists("Item", {"item_code": "PIV"}):
+			item = create_item("PIV", valuation_rate=100)
 			variant_settings = {
 				"attributes": [
-					{
-						"attribute": "Colour"
-					},
+					{"attribute": "Colour"},
 				],
-				"has_variants": 1
+				"has_variants": 1,
 			}
 			item.update(variant_settings)
 			item.save()
-			parent_bom = make_bom(item = 'PIV', raw_materials = [rm_item.item_code])
-		if not frappe.db.exists('BOM', {"item": 'PIV'}):
-			parent_bom = make_bom(item = 'PIV', raw_materials = [rm_item.item_code])
+			parent_bom = make_bom(item="PIV", raw_materials=[rm_item.item_code])
+		if not frappe.db.exists("BOM", {"item": "PIV"}):
+			parent_bom = make_bom(item="PIV", raw_materials=[rm_item.item_code])
 		else:
-			parent_bom = frappe.get_doc('BOM', {"item": 'PIV'})
+			parent_bom = frappe.get_doc("BOM", {"item": "PIV"})
 
-		if not frappe.db.exists('Item', {"item_code": 'PIV-RED'}):
+		if not frappe.db.exists("Item", {"item_code": "PIV-RED"}):
 			variant = create_variant("PIV", {"Colour": "Red"})
 			variant.save()
-			variant_bom = make_bom(item = variant.item_code, raw_materials = [rm_item.item_code])
+			variant_bom = make_bom(item=variant.item_code, raw_materials=[rm_item.item_code])
 		else:
-			variant = frappe.get_doc('Item', 'PIV-RED')
-		if not frappe.db.exists('BOM', {"item": 'PIV-RED'}):
-			variant_bom = make_bom(item = variant.item_code, raw_materials = [rm_item.item_code])
+			variant = frappe.get_doc("Item", "PIV-RED")
+		if not frappe.db.exists("BOM", {"item": "PIV-RED"}):
+			variant_bom = make_bom(item=variant.item_code, raw_materials=[rm_item.item_code])
 
 		"""Testing when item variant has a BOM"""
 		so = make_sales_order(item_code="PIV-RED", qty=5)
-		pln = frappe.new_doc('Production Plan')
+		pln = frappe.new_doc("Production Plan")
 		pln.company = so.company
-		pln.get_items_from = 'Sales Order'
-		pln.item_code = 'PIV-RED'
+		pln.get_items_from = "Sales Order"
+		pln.item_code = "PIV-RED"
 		pln.get_open_sales_orders()
 		self.assertEqual(pln.sales_orders[0].sales_order, so.name)
 		pln.get_so_items()
-		self.assertEqual(pln.po_items[0].item_code, 'PIV-RED')
+		self.assertEqual(pln.po_items[0].item_code, "PIV-RED")
 		self.assertEqual(pln.po_items[0].bom_no, variant_bom.name)
 		so.cancel()
-		frappe.delete_doc('Sales Order', so.name)
+		frappe.delete_doc("Sales Order", so.name)
 		variant_bom.cancel()
-		frappe.delete_doc('BOM', variant_bom.name)
+		frappe.delete_doc("BOM", variant_bom.name)
 
 		"""Testing when item variant doesn't have a BOM"""
 		so = make_sales_order(item_code="PIV-RED", qty=5)
@@ -445,7 +470,7 @@
 		self.assertEqual(pln.sales_orders[0].sales_order, so.name)
 		pln.po_items = []
 		pln.get_so_items()
-		self.assertEqual(pln.po_items[0].item_code, 'PIV-RED')
+		self.assertEqual(pln.po_items[0].item_code, "PIV-RED")
 		self.assertEqual(pln.po_items[0].bom_no, parent_bom.name)
 
 		frappe.db.rollback()
@@ -457,27 +482,35 @@
 		prefix = "_TestLevel_"
 		boms = {
 			"Assembly": {
-				"SubAssembly1": {"ChildPart1": {}, "ChildPart2": {},},
+				"SubAssembly1": {
+					"ChildPart1": {},
+					"ChildPart2": {},
+				},
 				"ChildPart6": {},
 				"SubAssembly4": {"SubSubAssy2": {"ChildPart7": {}}},
 			},
 			"MegaDeepAssy": {
-				"SecretSubassy": {"SecretPart": {"VerySecret" : { "SuperSecret": {"Classified": {}}}},},
-																# ^ assert that this is
-																# first item in subassy table
-			}
+				"SecretSubassy": {
+					"SecretPart": {"VerySecret": {"SuperSecret": {"Classified": {}}}},
+				},
+				# ^ assert that this is
+				# first item in subassy table
+			},
 		}
 		create_nested_bom(boms, prefix=prefix)
 
 		items = [prefix + item_code for item_code in boms.keys()]
 		plan = create_production_plan(item_code=items[0], do_not_save=True)
-		plan.append("po_items", {
-			'use_multi_level_bom': 1,
-			'item_code': items[1],
-			'bom_no': frappe.db.get_value('Item', items[1], 'default_bom'),
-			'planned_qty': 1,
-			'planned_start_date': now_datetime()
-		})
+		plan.append(
+			"po_items",
+			{
+				"use_multi_level_bom": 1,
+				"item_code": items[1],
+				"bom_no": frappe.db.get_value("Item", items[1], "default_bom"),
+				"planned_qty": 1,
+				"planned_start_date": now_datetime(),
+			},
+		)
 		plan.get_sub_assembly_items()
 
 		bom_level_order = [d.bom_level for d in plan.sub_assembly_items]
@@ -487,6 +520,7 @@
 
 	def test_multiple_work_order_for_production_plan_item(self):
 		"Test producing Prod Plan (making WO) in parts."
+
 		def create_work_order(item, pln, qty):
 			# Get Production Items
 			items_data = pln.get_production_items()
@@ -497,14 +531,13 @@
 			# Create and Submit Work Order for each item in items_data
 			for key, item in items_data.items():
 				if pln.sub_assembly_items:
-					item['use_multi_level_bom'] = 0
+					item["use_multi_level_bom"] = 0
 
 				wo_name = pln.create_work_order(item)
 				wo_doc = frappe.get_doc("Work Order", wo_name)
-				wo_doc.update({
-					'wip_warehouse': 'Work In Progress - _TC',
-					'fg_warehouse': 'Finished Goods - _TC'
-				})
+				wo_doc.update(
+					{"wip_warehouse": "Work In Progress - _TC", "fg_warehouse": "Finished Goods - _TC"}
+				)
 				wo_doc.submit()
 				wo_list.append(wo_name)
 
@@ -554,34 +587,30 @@
 			make_stock_entry as make_se_from_wo,
 		)
 
-		make_stock_entry(item_code="Raw Material Item 1",
-			target="Work In Progress - _TC",
-			qty=2, basic_rate=100
+		make_stock_entry(
+			item_code="Raw Material Item 1", target="Work In Progress - _TC", qty=2, basic_rate=100
 		)
-		make_stock_entry(item_code="Raw Material Item 2",
-			target="Work In Progress - _TC",
-			qty=2, basic_rate=100
+		make_stock_entry(
+			item_code="Raw Material Item 2", target="Work In Progress - _TC", qty=2, basic_rate=100
 		)
 
-		item = 'Test Production Item 1'
+		item = "Test Production Item 1"
 		so = make_sales_order(item_code=item, qty=1)
 
 		pln = create_production_plan(
-			company=so.company,
-			get_items_from="Sales Order",
-			sales_order=so,
-			skip_getting_mr_items=True
+			company=so.company, get_items_from="Sales Order", sales_order=so, skip_getting_mr_items=True
 		)
 		self.assertEqual(pln.po_items[0].pending_qty, 1)
 
 		wo = make_wo_order_test_record(
-			item_code=item, qty=1,
+			item_code=item,
+			qty=1,
 			company=so.company,
-			wip_warehouse='Work In Progress - _TC',
-			fg_warehouse='Finished Goods - _TC',
+			wip_warehouse="Work In Progress - _TC",
+			fg_warehouse="Finished Goods - _TC",
 			skip_transfer=1,
 			use_multi_level_bom=1,
-			do_not_submit=True
+			do_not_submit=True,
 		)
 		wo.production_plan = pln.name
 		wo.production_plan_item = pln.po_items[0].name
@@ -604,29 +633,25 @@
 			make_stock_entry as make_se_from_wo,
 		)
 
-		make_stock_entry(item_code="Raw Material Item 1",
-			target="Work In Progress - _TC",
-			qty=2, basic_rate=100
+		make_stock_entry(
+			item_code="Raw Material Item 1", target="Work In Progress - _TC", qty=2, basic_rate=100
 		)
-		make_stock_entry(item_code="Raw Material Item 2",
-			target="Work In Progress - _TC",
-			qty=2, basic_rate=100
+		make_stock_entry(
+			item_code="Raw Material Item 2", target="Work In Progress - _TC", qty=2, basic_rate=100
 		)
 
-		pln = create_production_plan(
-			item_code='Test Production Item 1',
-			skip_getting_mr_items=True
-		)
+		pln = create_production_plan(item_code="Test Production Item 1", skip_getting_mr_items=True)
 		self.assertEqual(pln.po_items[0].pending_qty, 1)
 
 		wo = make_wo_order_test_record(
-			item_code='Test Production Item 1', qty=1,
+			item_code="Test Production Item 1",
+			qty=1,
 			company=pln.company,
-			wip_warehouse='Work In Progress - _TC',
-			fg_warehouse='Finished Goods - _TC',
+			wip_warehouse="Work In Progress - _TC",
+			fg_warehouse="Finished Goods - _TC",
 			skip_transfer=1,
 			use_multi_level_bom=1,
-			do_not_submit=True
+			do_not_submit=True,
 		)
 		wo.production_plan = pln.name
 		wo.production_plan_item = pln.po_items[0].name
@@ -644,26 +669,23 @@
 
 	def test_qty_based_status(self):
 		pp = frappe.new_doc("Production Plan")
-		pp.po_items = [
-			frappe._dict(planned_qty=5, produce_qty=4)
-		]
+		pp.po_items = [frappe._dict(planned_qty=5, produce_qty=4)]
 		self.assertFalse(pp.all_items_completed())
 
 		pp.po_items = [
 			frappe._dict(planned_qty=5, produce_qty=10),
-			frappe._dict(planned_qty=5, produce_qty=4)
+			frappe._dict(planned_qty=5, produce_qty=4),
 		]
 		self.assertFalse(pp.all_items_completed())
 
 	def test_production_plan_planned_qty(self):
 		pln = create_production_plan(item_code="_Test FG Item", planned_qty=0.55)
 		pln.make_work_order()
-		work_order = frappe.db.get_value('Work Order', {'production_plan': pln.name}, 'name')
-		wo_doc = frappe.get_doc('Work Order', work_order)
-		wo_doc.update({
-			'wip_warehouse': 'Work In Progress - _TC',
-			'fg_warehouse': 'Finished Goods - _TC'
-		})
+		work_order = frappe.db.get_value("Work Order", {"production_plan": pln.name}, "name")
+		wo_doc = frappe.get_doc("Work Order", work_order)
+		wo_doc.update(
+			{"wip_warehouse": "Work In Progress - _TC", "fg_warehouse": "Finished Goods - _TC"}
+		)
 		wo_doc.submit()
 		self.assertEqual(wo_doc.qty, 0.55)
 
@@ -674,22 +696,21 @@
 		# this can not be unittested so mocking data that would be expected
 		# from client side.
 		for _ in range(10):
-			po_item = pp.append("po_items", {
-				"name": frappe.generate_hash(length=10),
-				"temporary_name": frappe.generate_hash(length=10),
-			})
-			pp.append("sub_assembly_items", {
-				"production_plan_item": po_item.temporary_name
-			})
+			po_item = pp.append(
+				"po_items",
+				{
+					"name": frappe.generate_hash(length=10),
+					"temporary_name": frappe.generate_hash(length=10),
+				},
+			)
+			pp.append("sub_assembly_items", {"production_plan_item": po_item.temporary_name})
 		pp._rename_temporary_references()
 
 		for po_item, subassy_item in zip(pp.po_items, pp.sub_assembly_items):
 			self.assertEqual(po_item.name, subassy_item.production_plan_item)
 
 		# bad links should be erased
-		pp.append("sub_assembly_items", {
-			"production_plan_item": frappe.generate_hash(length=16)
-		})
+		pp.append("sub_assembly_items", {"production_plan_item": frappe.generate_hash(length=16)})
 		pp._rename_temporary_references()
 		self.assertIsNone(pp.sub_assembly_items[-1].production_plan_item)
 		pp.sub_assembly_items.pop()
@@ -708,40 +729,48 @@
 	"""
 	args = frappe._dict(args)
 
-	pln = frappe.get_doc({
-		'doctype': 'Production Plan',
-		'company': args.company or '_Test Company',
-		'customer': args.customer or '_Test Customer',
-		'posting_date': nowdate(),
-		'include_non_stock_items': args.include_non_stock_items or 0,
-		'include_subcontracted_items': args.include_subcontracted_items or 0,
-		'ignore_existing_ordered_qty': args.ignore_existing_ordered_qty or 0,
-		'get_items_from': 'Sales Order'
-	})
+	pln = frappe.get_doc(
+		{
+			"doctype": "Production Plan",
+			"company": args.company or "_Test Company",
+			"customer": args.customer or "_Test Customer",
+			"posting_date": nowdate(),
+			"include_non_stock_items": args.include_non_stock_items or 0,
+			"include_subcontracted_items": args.include_subcontracted_items or 0,
+			"ignore_existing_ordered_qty": args.ignore_existing_ordered_qty or 0,
+			"get_items_from": "Sales Order",
+		}
+	)
 
 	if not args.get("sales_order"):
-		pln.append('po_items', {
-			'use_multi_level_bom': args.use_multi_level_bom or 1,
-			'item_code': args.item_code,
-			'bom_no': frappe.db.get_value('Item', args.item_code, 'default_bom'),
-			'planned_qty': args.planned_qty or 1,
-			'planned_start_date': args.planned_start_date or now_datetime()
-		})
+		pln.append(
+			"po_items",
+			{
+				"use_multi_level_bom": args.use_multi_level_bom or 1,
+				"item_code": args.item_code,
+				"bom_no": frappe.db.get_value("Item", args.item_code, "default_bom"),
+				"planned_qty": args.planned_qty or 1,
+				"planned_start_date": args.planned_start_date or now_datetime(),
+			},
+		)
 
 	if args.get("get_items_from") == "Sales Order" and args.get("sales_order"):
 		so = args.get("sales_order")
-		pln.append('sales_orders', {
-			'sales_order': so.name,
-			'sales_order_date': so.transaction_date,
-			'customer': so.customer,
-			'grand_total': so.grand_total
-		})
+		pln.append(
+			"sales_orders",
+			{
+				"sales_order": so.name,
+				"sales_order_date": so.transaction_date,
+				"customer": so.customer,
+				"grand_total": so.grand_total,
+			},
+		)
 		pln.get_items()
 
 	if not args.get("skip_getting_mr_items"):
 		mr_items = get_items_for_material_requests(pln.as_dict())
 		for d in mr_items:
-			pln.append('mr_items', d)
+			pln.append("mr_items", d)
 
 	if not args.do_not_save:
 		pln.insert()
@@ -750,31 +779,37 @@
 
 	return pln
 
+
 def make_bom(**args):
 	args = frappe._dict(args)
 
-	bom = frappe.get_doc({
-		'doctype': 'BOM',
-		'is_default': 1,
-		'item': args.item,
-		'currency': args.currency or 'USD',
-		'quantity': args.quantity or 1,
-		'company': args.company or '_Test Company',
-		'routing': args.routing,
-		'with_operations': args.with_operations or 0
-	})
+	bom = frappe.get_doc(
+		{
+			"doctype": "BOM",
+			"is_default": 1,
+			"item": args.item,
+			"currency": args.currency or "USD",
+			"quantity": args.quantity or 1,
+			"company": args.company or "_Test Company",
+			"routing": args.routing,
+			"with_operations": args.with_operations or 0,
+		}
+	)
 
 	for item in args.raw_materials:
-		item_doc = frappe.get_doc('Item', item)
+		item_doc = frappe.get_doc("Item", item)
 
-		bom.append('items', {
-			'item_code': item,
-			'qty': args.rm_qty or 1.0,
-			'uom': item_doc.stock_uom,
-			'stock_uom': item_doc.stock_uom,
-			'rate': item_doc.valuation_rate or args.rate,
-			'source_warehouse': args.source_warehouse
-		})
+		bom.append(
+			"items",
+			{
+				"item_code": item,
+				"qty": args.rm_qty or 1.0,
+				"uom": item_doc.stock_uom,
+				"stock_uom": item_doc.stock_uom,
+				"rate": item_doc.valuation_rate or args.rate,
+				"source_warehouse": args.source_warehouse,
+			},
+		)
 
 	if not args.do_not_save:
 		bom.insert(ignore_permissions=True)
diff --git a/erpnext/manufacturing/doctype/routing/routing.py b/erpnext/manufacturing/doctype/routing/routing.py
index b207906..d4c37cf 100644
--- a/erpnext/manufacturing/doctype/routing/routing.py
+++ b/erpnext/manufacturing/doctype/routing/routing.py
@@ -19,9 +19,11 @@
 	def calculate_operating_cost(self):
 		for operation in self.operations:
 			if not operation.hour_rate:
-				operation.hour_rate = frappe.db.get_value("Workstation", operation.workstation, 'hour_rate')
-			operation.operating_cost = flt(flt(operation.hour_rate) * flt(operation.time_in_mins) / 60,
-					operation.precision("operating_cost"))
+				operation.hour_rate = frappe.db.get_value("Workstation", operation.workstation, "hour_rate")
+			operation.operating_cost = flt(
+				flt(operation.hour_rate) * flt(operation.time_in_mins) / 60,
+				operation.precision("operating_cost"),
+			)
 
 	def set_routing_id(self):
 		sequence_id = 0
@@ -29,7 +31,10 @@
 			if not row.sequence_id:
 				row.sequence_id = sequence_id + 1
 			elif sequence_id and row.sequence_id and cint(sequence_id) > cint(row.sequence_id):
-				frappe.throw(_("At row #{0}: the sequence id {1} cannot be less than previous row sequence id {2}")
-					.format(row.idx, row.sequence_id, sequence_id))
+				frappe.throw(
+					_("At row #{0}: the sequence id {1} cannot be less than previous row sequence id {2}").format(
+						row.idx, row.sequence_id, sequence_id
+					)
+				)
 
 			sequence_id = row.sequence_id
diff --git a/erpnext/manufacturing/doctype/routing/routing_dashboard.py b/erpnext/manufacturing/doctype/routing/routing_dashboard.py
index d051e38..65d7a45 100644
--- a/erpnext/manufacturing/doctype/routing/routing_dashboard.py
+++ b/erpnext/manufacturing/doctype/routing/routing_dashboard.py
@@ -1,9 +1,2 @@
 def get_data():
-	return {
-		'fieldname': 'routing',
-		'transactions': [
-			{
-				'items': ['BOM']
-			}
-		]
-	}
+	return {"fieldname": "routing", "transactions": [{"items": ["BOM"]}]}
diff --git a/erpnext/manufacturing/doctype/routing/test_routing.py b/erpnext/manufacturing/doctype/routing/test_routing.py
index 696d9bc..48f1851 100644
--- a/erpnext/manufacturing/doctype/routing/test_routing.py
+++ b/erpnext/manufacturing/doctype/routing/test_routing.py
@@ -16,24 +16,27 @@
 
 	@classmethod
 	def tearDownClass(cls):
-		frappe.db.sql('delete from tabBOM where item=%s', cls.item_code)
+		frappe.db.sql("delete from tabBOM where item=%s", cls.item_code)
 
 	def test_sequence_id(self):
-		operations = [{"operation": "Test Operation A", "workstation": "Test Workstation A", "time_in_mins": 30},
-			{"operation": "Test Operation B", "workstation": "Test Workstation A", "time_in_mins": 20}]
+		operations = [
+			{"operation": "Test Operation A", "workstation": "Test Workstation A", "time_in_mins": 30},
+			{"operation": "Test Operation B", "workstation": "Test Workstation A", "time_in_mins": 20},
+		]
 
 		make_test_records("UOM")
 
 		setup_operations(operations)
 		routing_doc = create_routing(routing_name="Testing Route", operations=operations)
 		bom_doc = setup_bom(item_code=self.item_code, routing=routing_doc.name)
-		wo_doc = make_wo_order_test_record(production_item = self.item_code, bom_no=bom_doc.name)
+		wo_doc = make_wo_order_test_record(production_item=self.item_code, bom_no=bom_doc.name)
 
 		for row in routing_doc.operations:
 			self.assertEqual(row.sequence_id, row.idx)
 
-		for data in frappe.get_all("Job Card",
-			filters={"work_order": wo_doc.name}, order_by="sequence_id desc"):
+		for data in frappe.get_all(
+			"Job Card", filters={"work_order": wo_doc.name}, order_by="sequence_id desc"
+		):
 			job_card_doc = frappe.get_doc("Job Card", data.name)
 			job_card_doc.time_logs[0].completed_qty = 10
 			if job_card_doc.sequence_id != 1:
@@ -52,33 +55,25 @@
 				"operation": "Test Operation A",
 				"workstation": "_Test Workstation A",
 				"hour_rate_rent": 300,
-				"hour_rate_labour": 750 ,
-				"time_in_mins": 30
+				"hour_rate_labour": 750,
+				"time_in_mins": 30,
 			},
 			{
 				"operation": "Test Operation B",
 				"workstation": "_Test Workstation B",
 				"hour_rate_labour": 200,
 				"hour_rate_rent": 1000,
-				"time_in_mins": 20
-			}
+				"time_in_mins": 20,
+			},
 		]
 
 		test_routing_operations = [
-			{
-				"operation": "Test Operation A",
-				"workstation": "_Test Workstation A",
-				"time_in_mins": 30
-			},
-			{
-				"operation": "Test Operation B",
-				"workstation": "_Test Workstation A",
-				"time_in_mins": 20
-			}
+			{"operation": "Test Operation A", "workstation": "_Test Workstation A", "time_in_mins": 30},
+			{"operation": "Test Operation B", "workstation": "_Test Workstation A", "time_in_mins": 20},
 		]
 		setup_operations(operations)
 		routing_doc = create_routing(routing_name="Routing Test", operations=test_routing_operations)
-		bom_doc = setup_bom(item_code="_Testing Item", routing=routing_doc.name, currency = 'INR')
+		bom_doc = setup_bom(item_code="_Testing Item", routing=routing_doc.name, currency="INR")
 		self.assertEqual(routing_doc.operations[0].time_in_mins, 30)
 		self.assertEqual(routing_doc.operations[1].time_in_mins, 20)
 		routing_doc.operations[0].time_in_mins = 90
@@ -93,10 +88,12 @@
 def setup_operations(rows):
 	from erpnext.manufacturing.doctype.operation.test_operation import make_operation
 	from erpnext.manufacturing.doctype.workstation.test_workstation import make_workstation
+
 	for row in rows:
 		make_workstation(row)
 		make_operation(row)
 
+
 def create_routing(**args):
 	args = frappe._dict(args)
 
@@ -108,7 +105,7 @@
 			doc.insert()
 		except frappe.DuplicateEntryError:
 			doc = frappe.get_doc("Routing", args.routing_name)
-			doc.delete_key('operations')
+			doc.delete_key("operations")
 			for operation in args.operations:
 				doc.append("operations", operation)
 
@@ -116,28 +113,35 @@
 
 	return doc
 
+
 def setup_bom(**args):
 	from erpnext.manufacturing.doctype.production_plan.test_production_plan import make_bom
 
 	args = frappe._dict(args)
 
-	if not frappe.db.exists('Item', args.item_code):
-		make_item(args.item_code, {
-			'is_stock_item': 1
-		})
+	if not frappe.db.exists("Item", args.item_code):
+		make_item(args.item_code, {"is_stock_item": 1})
 
 	if not args.raw_materials:
-		if not frappe.db.exists('Item', "Test Extra Item N-1"):
-			make_item("Test Extra Item N-1", {
-				'is_stock_item': 1,
-			})
+		if not frappe.db.exists("Item", "Test Extra Item N-1"):
+			make_item(
+				"Test Extra Item N-1",
+				{
+					"is_stock_item": 1,
+				},
+			)
 
-		args.raw_materials = ['Test Extra Item N-1']
+		args.raw_materials = ["Test Extra Item N-1"]
 
-	name = frappe.db.get_value('BOM', {'item': args.item_code}, 'name')
+	name = frappe.db.get_value("BOM", {"item": args.item_code}, "name")
 	if not name:
-		bom_doc = make_bom(item = args.item_code, raw_materials = args.get("raw_materials"),
-			routing = args.routing, with_operations=1, currency = args.currency)
+		bom_doc = make_bom(
+			item=args.item_code,
+			raw_materials=args.get("raw_materials"),
+			routing=args.routing,
+			with_operations=1,
+			currency=args.currency,
+		)
 	else:
 		bom_doc = frappe.get_doc("BOM", name)
 
diff --git a/erpnext/manufacturing/doctype/work_order/test_work_order.py b/erpnext/manufacturing/doctype/work_order/test_work_order.py
index 6a8136d..3721704 100644
--- a/erpnext/manufacturing/doctype/work_order/test_work_order.py
+++ b/erpnext/manufacturing/doctype/work_order/test_work_order.py
@@ -26,29 +26,36 @@
 
 class TestWorkOrder(FrappeTestCase):
 	def setUp(self):
-		self.warehouse = '_Test Warehouse 2 - _TC'
-		self.item = '_Test Item'
+		self.warehouse = "_Test Warehouse 2 - _TC"
+		self.item = "_Test Item"
 
 	def tearDown(self):
 		frappe.db.rollback()
 
 	def check_planned_qty(self):
 
-		planned0 = frappe.db.get_value("Bin", {"item_code": "_Test FG Item",
-			"warehouse": "_Test Warehouse 1 - _TC"}, "planned_qty") or 0
+		planned0 = (
+			frappe.db.get_value(
+				"Bin", {"item_code": "_Test FG Item", "warehouse": "_Test Warehouse 1 - _TC"}, "planned_qty"
+			)
+			or 0
+		)
 
 		wo_order = make_wo_order_test_record()
 
-		planned1 = frappe.db.get_value("Bin", {"item_code": "_Test FG Item",
-			"warehouse": "_Test Warehouse 1 - _TC"}, "planned_qty")
+		planned1 = frappe.db.get_value(
+			"Bin", {"item_code": "_Test FG Item", "warehouse": "_Test Warehouse 1 - _TC"}, "planned_qty"
+		)
 
 		self.assertEqual(planned1, planned0 + 10)
 
 		# add raw materials to stores
-		test_stock_entry.make_stock_entry(item_code="_Test Item",
-			target="Stores - _TC", qty=100, basic_rate=100)
-		test_stock_entry.make_stock_entry(item_code="_Test Item Home Desktop 100",
-			target="Stores - _TC", qty=100, basic_rate=100)
+		test_stock_entry.make_stock_entry(
+			item_code="_Test Item", target="Stores - _TC", qty=100, basic_rate=100
+		)
+		test_stock_entry.make_stock_entry(
+			item_code="_Test Item Home Desktop 100", target="Stores - _TC", qty=100, basic_rate=100
+		)
 
 		# from stores to wip
 		s = frappe.get_doc(make_stock_entry(wo_order.name, "Material Transfer for Manufacture", 4))
@@ -64,8 +71,9 @@
 
 		self.assertEqual(frappe.db.get_value("Work Order", wo_order.name, "produced_qty"), 4)
 
-		planned2 = frappe.db.get_value("Bin", {"item_code": "_Test FG Item",
-			"warehouse": "_Test Warehouse 1 - _TC"}, "planned_qty")
+		planned2 = frappe.db.get_value(
+			"Bin", {"item_code": "_Test FG Item", "warehouse": "_Test Warehouse 1 - _TC"}, "planned_qty"
+		)
 
 		self.assertEqual(planned2, planned0 + 6)
 
@@ -74,10 +82,12 @@
 	def test_over_production(self):
 		wo_doc = self.check_planned_qty()
 
-		test_stock_entry.make_stock_entry(item_code="_Test Item",
-			target="_Test Warehouse - _TC", qty=100, basic_rate=100)
-		test_stock_entry.make_stock_entry(item_code="_Test Item Home Desktop 100",
-			target="_Test Warehouse - _TC", qty=100, basic_rate=100)
+		test_stock_entry.make_stock_entry(
+			item_code="_Test Item", target="_Test Warehouse - _TC", qty=100, basic_rate=100
+		)
+		test_stock_entry.make_stock_entry(
+			item_code="_Test Item Home Desktop 100", target="_Test Warehouse - _TC", qty=100, basic_rate=100
+		)
 
 		s = frappe.get_doc(make_stock_entry(wo_doc.name, "Manufacture", 7))
 		s.insert()
@@ -85,13 +95,14 @@
 		self.assertRaises(StockOverProductionError, s.submit)
 
 	def test_planned_operating_cost(self):
-		wo_order = make_wo_order_test_record(item="_Test FG Item 2",
-			planned_start_date=now(), qty=1, do_not_save=True)
+		wo_order = make_wo_order_test_record(
+			item="_Test FG Item 2", planned_start_date=now(), qty=1, do_not_save=True
+		)
 		wo_order.set_work_order_operations()
 		cost = wo_order.planned_operating_cost
 		wo_order.qty = 2
 		wo_order.set_work_order_operations()
-		self.assertEqual(wo_order.planned_operating_cost, cost*2)
+		self.assertEqual(wo_order.planned_operating_cost, cost * 2)
 
 	def test_reserved_qty_for_partial_completion(self):
 		item = "_Test Item"
@@ -102,27 +113,30 @@
 		# reset to correct value
 		bin1_at_start.update_reserved_qty_for_production()
 
-		wo_order = make_wo_order_test_record(item="_Test FG Item", qty=2,
-			source_warehouse=warehouse, skip_transfer=1)
+		wo_order = make_wo_order_test_record(
+			item="_Test FG Item", qty=2, source_warehouse=warehouse, skip_transfer=1
+		)
 
 		reserved_qty_on_submission = cint(get_bin(item, warehouse).reserved_qty_for_production)
 
 		# reserved qty for production is updated
 		self.assertEqual(cint(bin1_at_start.reserved_qty_for_production) + 2, reserved_qty_on_submission)
 
-
-		test_stock_entry.make_stock_entry(item_code="_Test Item",
-			target=warehouse, qty=100, basic_rate=100)
-		test_stock_entry.make_stock_entry(item_code="_Test Item Home Desktop 100",
-			target=warehouse, qty=100, basic_rate=100)
+		test_stock_entry.make_stock_entry(
+			item_code="_Test Item", target=warehouse, qty=100, basic_rate=100
+		)
+		test_stock_entry.make_stock_entry(
+			item_code="_Test Item Home Desktop 100", target=warehouse, qty=100, basic_rate=100
+		)
 
 		s = frappe.get_doc(make_stock_entry(wo_order.name, "Manufacture", 1))
 		s.submit()
 
 		bin1_at_completion = get_bin(item, warehouse)
 
-		self.assertEqual(cint(bin1_at_completion.reserved_qty_for_production),
-			reserved_qty_on_submission - 1)
+		self.assertEqual(
+			cint(bin1_at_completion.reserved_qty_for_production), reserved_qty_on_submission - 1
+		)
 
 	def test_production_item(self):
 		wo_order = make_wo_order_test_record(item="_Test FG Item", qty=1, do_not_save=True)
@@ -146,16 +160,20 @@
 		# reset to correct value
 		self.bin1_at_start.update_reserved_qty_for_production()
 
-		self.wo_order = make_wo_order_test_record(item="_Test FG Item", qty=2,
-			source_warehouse=self.warehouse)
+		self.wo_order = make_wo_order_test_record(
+			item="_Test FG Item", qty=2, source_warehouse=self.warehouse
+		)
 
 		self.bin1_on_submit = get_bin(self.item, self.warehouse)
 
 		# reserved qty for production is updated
-		self.assertEqual(cint(self.bin1_at_start.reserved_qty_for_production) + 2,
-			cint(self.bin1_on_submit.reserved_qty_for_production))
-		self.assertEqual(cint(self.bin1_at_start.projected_qty),
-			cint(self.bin1_on_submit.projected_qty) + 2)
+		self.assertEqual(
+			cint(self.bin1_at_start.reserved_qty_for_production) + 2,
+			cint(self.bin1_on_submit.reserved_qty_for_production),
+		)
+		self.assertEqual(
+			cint(self.bin1_at_start.projected_qty), cint(self.bin1_on_submit.projected_qty) + 2
+		)
 
 	def test_reserved_qty_for_production_cancel(self):
 		self.test_reserved_qty_for_production_submit()
@@ -165,52 +183,57 @@
 		bin1_on_cancel = get_bin(self.item, self.warehouse)
 
 		# reserved_qty_for_producion updated
-		self.assertEqual(cint(self.bin1_at_start.reserved_qty_for_production),
-			cint(bin1_on_cancel.reserved_qty_for_production))
-		self.assertEqual(self.bin1_at_start.projected_qty,
-			cint(bin1_on_cancel.projected_qty))
+		self.assertEqual(
+			cint(self.bin1_at_start.reserved_qty_for_production),
+			cint(bin1_on_cancel.reserved_qty_for_production),
+		)
+		self.assertEqual(self.bin1_at_start.projected_qty, cint(bin1_on_cancel.projected_qty))
 
 	def test_reserved_qty_for_production_on_stock_entry(self):
-		test_stock_entry.make_stock_entry(item_code="_Test Item",
-			target= self.warehouse, qty=100, basic_rate=100)
-		test_stock_entry.make_stock_entry(item_code="_Test Item Home Desktop 100",
-			target= self.warehouse, qty=100, basic_rate=100)
+		test_stock_entry.make_stock_entry(
+			item_code="_Test Item", target=self.warehouse, qty=100, basic_rate=100
+		)
+		test_stock_entry.make_stock_entry(
+			item_code="_Test Item Home Desktop 100", target=self.warehouse, qty=100, basic_rate=100
+		)
 
 		self.test_reserved_qty_for_production_submit()
 
-		s = frappe.get_doc(make_stock_entry(self.wo_order.name,
-			"Material Transfer for Manufacture", 2))
+		s = frappe.get_doc(make_stock_entry(self.wo_order.name, "Material Transfer for Manufacture", 2))
 
 		s.submit()
 
 		bin1_on_start_production = get_bin(self.item, self.warehouse)
 
 		# reserved_qty_for_producion updated
-		self.assertEqual(cint(self.bin1_at_start.reserved_qty_for_production),
-			cint(bin1_on_start_production.reserved_qty_for_production))
+		self.assertEqual(
+			cint(self.bin1_at_start.reserved_qty_for_production),
+			cint(bin1_on_start_production.reserved_qty_for_production),
+		)
 
 		# projected qty will now be 2 less (becuase of item movement)
-		self.assertEqual(cint(self.bin1_at_start.projected_qty),
-			cint(bin1_on_start_production.projected_qty) + 2)
+		self.assertEqual(
+			cint(self.bin1_at_start.projected_qty), cint(bin1_on_start_production.projected_qty) + 2
+		)
 
 		s = frappe.get_doc(make_stock_entry(self.wo_order.name, "Manufacture", 2))
 
 		bin1_on_end_production = get_bin(self.item, self.warehouse)
 
 		# no change in reserved / projected
-		self.assertEqual(cint(bin1_on_end_production.reserved_qty_for_production),
-			cint(bin1_on_start_production.reserved_qty_for_production))
+		self.assertEqual(
+			cint(bin1_on_end_production.reserved_qty_for_production),
+			cint(bin1_on_start_production.reserved_qty_for_production),
+		)
 
 	def test_reserved_qty_for_production_closed(self):
 
-		wo1 = make_wo_order_test_record(item="_Test FG Item", qty=2,
-			source_warehouse=self.warehouse)
+		wo1 = make_wo_order_test_record(item="_Test FG Item", qty=2, source_warehouse=self.warehouse)
 		item = wo1.required_items[0].item_code
 		bin_before = get_bin(item, self.warehouse)
 		bin_before.update_reserved_qty_for_production()
 
-		make_wo_order_test_record(item="_Test FG Item", qty=2,
-			source_warehouse=self.warehouse)
+		make_wo_order_test_record(item="_Test FG Item", qty=2, source_warehouse=self.warehouse)
 		close_work_order(wo1.name, "Closed")
 
 		bin_after = get_bin(item, self.warehouse)
@@ -220,10 +243,15 @@
 		cancel_stock_entry = []
 		allow_overproduction("overproduction_percentage_for_work_order", 30)
 		wo_order = make_wo_order_test_record(planned_start_date=now(), qty=100)
-		ste1 = test_stock_entry.make_stock_entry(item_code="_Test Item",
-			target="_Test Warehouse - _TC", qty=120, basic_rate=5000.0)
-		ste2 = test_stock_entry.make_stock_entry(item_code="_Test Item Home Desktop 100",
-			target="_Test Warehouse - _TC", qty=240, basic_rate=1000.0)
+		ste1 = test_stock_entry.make_stock_entry(
+			item_code="_Test Item", target="_Test Warehouse - _TC", qty=120, basic_rate=5000.0
+		)
+		ste2 = test_stock_entry.make_stock_entry(
+			item_code="_Test Item Home Desktop 100",
+			target="_Test Warehouse - _TC",
+			qty=240,
+			basic_rate=1000.0,
+		)
 
 		cancel_stock_entry.extend([ste1.name, ste2.name])
 
@@ -253,33 +281,37 @@
 		allow_overproduction("overproduction_percentage_for_work_order", 0)
 
 	def test_reserved_qty_for_stopped_production(self):
-		test_stock_entry.make_stock_entry(item_code="_Test Item",
-			target= self.warehouse, qty=100, basic_rate=100)
-		test_stock_entry.make_stock_entry(item_code="_Test Item Home Desktop 100",
-			target= self.warehouse, qty=100, basic_rate=100)
+		test_stock_entry.make_stock_entry(
+			item_code="_Test Item", target=self.warehouse, qty=100, basic_rate=100
+		)
+		test_stock_entry.make_stock_entry(
+			item_code="_Test Item Home Desktop 100", target=self.warehouse, qty=100, basic_rate=100
+		)
 
 		# 	0 0 0
 
 		self.test_reserved_qty_for_production_submit()
 
-		#2 0 -2
+		# 2 0 -2
 
-		s = frappe.get_doc(make_stock_entry(self.wo_order.name,
-			"Material Transfer for Manufacture", 1))
+		s = frappe.get_doc(make_stock_entry(self.wo_order.name, "Material Transfer for Manufacture", 1))
 
 		s.submit()
 
-		#1 -1 0
+		# 1 -1 0
 
 		bin1_on_start_production = get_bin(self.item, self.warehouse)
 
 		# reserved_qty_for_producion updated
-		self.assertEqual(cint(self.bin1_at_start.reserved_qty_for_production) + 1,
-			cint(bin1_on_start_production.reserved_qty_for_production))
+		self.assertEqual(
+			cint(self.bin1_at_start.reserved_qty_for_production) + 1,
+			cint(bin1_on_start_production.reserved_qty_for_production),
+		)
 
 		# projected qty will now be 2 less (becuase of item movement)
-		self.assertEqual(cint(self.bin1_at_start.projected_qty),
-			cint(bin1_on_start_production.projected_qty) + 2)
+		self.assertEqual(
+			cint(self.bin1_at_start.projected_qty), cint(bin1_on_start_production.projected_qty) + 2
+		)
 
 		# STOP
 		stop_unstop(self.wo_order.name, "Stopped")
@@ -287,19 +319,24 @@
 		bin1_on_stop_production = get_bin(self.item, self.warehouse)
 
 		# no change in reserved / projected
-		self.assertEqual(cint(bin1_on_stop_production.reserved_qty_for_production),
-			cint(self.bin1_at_start.reserved_qty_for_production))
-		self.assertEqual(cint(bin1_on_stop_production.projected_qty) + 1,
-			cint(self.bin1_at_start.projected_qty))
+		self.assertEqual(
+			cint(bin1_on_stop_production.reserved_qty_for_production),
+			cint(self.bin1_at_start.reserved_qty_for_production),
+		)
+		self.assertEqual(
+			cint(bin1_on_stop_production.projected_qty) + 1, cint(self.bin1_at_start.projected_qty)
+		)
 
 	def test_scrap_material_qty(self):
 		wo_order = make_wo_order_test_record(planned_start_date=now(), qty=2)
 
 		# add raw materials to stores
-		test_stock_entry.make_stock_entry(item_code="_Test Item",
-			target="Stores - _TC", qty=10, basic_rate=5000.0)
-		test_stock_entry.make_stock_entry(item_code="_Test Item Home Desktop 100",
-			target="Stores - _TC", qty=10, basic_rate=1000.0)
+		test_stock_entry.make_stock_entry(
+			item_code="_Test Item", target="Stores - _TC", qty=10, basic_rate=5000.0
+		)
+		test_stock_entry.make_stock_entry(
+			item_code="_Test Item Home Desktop 100", target="Stores - _TC", qty=10, basic_rate=1000.0
+		)
 
 		s = frappe.get_doc(make_stock_entry(wo_order.name, "Material Transfer for Manufacture", 2))
 		for d in s.get("items"):
@@ -311,8 +348,9 @@
 		s.insert()
 		s.submit()
 
-		wo_order_details = frappe.db.get_value("Work Order", wo_order.name,
-			["scrap_warehouse", "qty", "produced_qty", "bom_no"], as_dict=1)
+		wo_order_details = frappe.db.get_value(
+			"Work Order", wo_order.name, ["scrap_warehouse", "qty", "produced_qty", "bom_no"], as_dict=1
+		)
 
 		scrap_item_details = get_scrap_item_details(wo_order_details.bom_no)
 
@@ -321,15 +359,20 @@
 		for item in s.items:
 			if item.bom_no and item.item_code in scrap_item_details:
 				self.assertEqual(wo_order_details.scrap_warehouse, item.t_warehouse)
-				self.assertEqual(flt(wo_order_details.qty)*flt(scrap_item_details[item.item_code]), item.qty)
+				self.assertEqual(flt(wo_order_details.qty) * flt(scrap_item_details[item.item_code]), item.qty)
 
 	def test_allow_overproduction(self):
 		allow_overproduction("overproduction_percentage_for_work_order", 0)
 		wo_order = make_wo_order_test_record(planned_start_date=now(), qty=2)
-		test_stock_entry.make_stock_entry(item_code="_Test Item",
-			target="_Test Warehouse - _TC", qty=10, basic_rate=5000.0)
-		test_stock_entry.make_stock_entry(item_code="_Test Item Home Desktop 100",
-			target="_Test Warehouse - _TC", qty=10, basic_rate=1000.0)
+		test_stock_entry.make_stock_entry(
+			item_code="_Test Item", target="_Test Warehouse - _TC", qty=10, basic_rate=5000.0
+		)
+		test_stock_entry.make_stock_entry(
+			item_code="_Test Item Home Desktop 100",
+			target="_Test Warehouse - _TC",
+			qty=10,
+			basic_rate=1000.0,
+		)
 
 		s = frappe.get_doc(make_stock_entry(wo_order.name, "Material Transfer for Manufacture", 3))
 		s.insert()
@@ -346,42 +389,47 @@
 		so = make_sales_order(item_code="_Test FG Item", qty=2)
 
 		allow_overproduction("overproduction_percentage_for_sales_order", 0)
-		wo_order = make_wo_order_test_record(planned_start_date=now(),
-			sales_order=so.name, qty=3, do_not_save=True)
+		wo_order = make_wo_order_test_record(
+			planned_start_date=now(), sales_order=so.name, qty=3, do_not_save=True
+		)
 
 		self.assertRaises(OverProductionError, wo_order.save)
 
 		allow_overproduction("overproduction_percentage_for_sales_order", 50)
-		wo_order = make_wo_order_test_record(planned_start_date=now(),
-			sales_order=so.name, qty=3)
+		wo_order = make_wo_order_test_record(planned_start_date=now(), sales_order=so.name, qty=3)
 
 		self.assertEqual(wo_order.docstatus, 1)
 
 		allow_overproduction("overproduction_percentage_for_sales_order", 0)
 
 	def test_work_order_with_non_stock_item(self):
-		items = {'Finished Good Test Item For non stock': 1, '_Test FG Item': 1, '_Test FG Non Stock Item': 0}
+		items = {
+			"Finished Good Test Item For non stock": 1,
+			"_Test FG Item": 1,
+			"_Test FG Non Stock Item": 0,
+		}
 		for item, is_stock_item in items.items():
-			make_item(item, {
-				'is_stock_item': is_stock_item
-			})
+			make_item(item, {"is_stock_item": is_stock_item})
 
-		if not frappe.db.get_value('Item Price', {'item_code': '_Test FG Non Stock Item'}):
-			frappe.get_doc({
-				'doctype': 'Item Price',
-				'item_code': '_Test FG Non Stock Item',
-				'price_list_rate': 1000,
-				'price_list': 'Standard Buying'
-			}).insert(ignore_permissions=True)
+		if not frappe.db.get_value("Item Price", {"item_code": "_Test FG Non Stock Item"}):
+			frappe.get_doc(
+				{
+					"doctype": "Item Price",
+					"item_code": "_Test FG Non Stock Item",
+					"price_list_rate": 1000,
+					"price_list": "Standard Buying",
+				}
+			).insert(ignore_permissions=True)
 
-		fg_item = 'Finished Good Test Item For non stock'
-		test_stock_entry.make_stock_entry(item_code="_Test FG Item",
-			target="_Test Warehouse - _TC", qty=1, basic_rate=100)
+		fg_item = "Finished Good Test Item For non stock"
+		test_stock_entry.make_stock_entry(
+			item_code="_Test FG Item", target="_Test Warehouse - _TC", qty=1, basic_rate=100
+		)
 
-		if not frappe.db.get_value('BOM', {'item': fg_item}):
-			make_bom(item=fg_item, rate=1000, raw_materials = ['_Test FG Item', '_Test FG Non Stock Item'])
+		if not frappe.db.get_value("BOM", {"item": fg_item}):
+			make_bom(item=fg_item, rate=1000, raw_materials=["_Test FG Item", "_Test FG Non Stock Item"])
 
-		wo = make_wo_order_test_record(production_item = fg_item)
+		wo = make_wo_order_test_record(production_item=fg_item)
 
 		se = frappe.get_doc(make_stock_entry(wo.name, "Material Transfer for Manufacture", 1))
 		se.insert()
@@ -395,25 +443,25 @@
 	@timeout(seconds=60)
 	def test_job_card(self):
 		stock_entries = []
-		bom = frappe.get_doc('BOM', {
-			'docstatus': 1,
-			'with_operations': 1,
-			'company': '_Test Company'
-		})
+		bom = frappe.get_doc("BOM", {"docstatus": 1, "with_operations": 1, "company": "_Test Company"})
 
-		work_order = make_wo_order_test_record(item=bom.item, qty=1,
-			bom_no=bom.name, source_warehouse="_Test Warehouse - _TC")
+		work_order = make_wo_order_test_record(
+			item=bom.item, qty=1, bom_no=bom.name, source_warehouse="_Test Warehouse - _TC"
+		)
 
 		for row in work_order.required_items:
-			stock_entry_doc = test_stock_entry.make_stock_entry(item_code=row.item_code,
-				target="_Test Warehouse - _TC", qty=row.required_qty, basic_rate=100)
+			stock_entry_doc = test_stock_entry.make_stock_entry(
+				item_code=row.item_code, target="_Test Warehouse - _TC", qty=row.required_qty, basic_rate=100
+			)
 			stock_entries.append(stock_entry_doc)
 
 		ste = frappe.get_doc(make_stock_entry(work_order.name, "Material Transfer for Manufacture", 1))
 		ste.submit()
 		stock_entries.append(ste)
 
-		job_cards = frappe.get_all('Job Card', filters = {'work_order': work_order.name}, order_by='creation asc')
+		job_cards = frappe.get_all(
+			"Job Card", filters={"work_order": work_order.name}, order_by="creation asc"
+		)
 		self.assertEqual(len(job_cards), len(bom.operations))
 
 		for i, job_card in enumerate(job_cards):
@@ -434,29 +482,33 @@
 			stock_entry.cancel()
 
 	def test_capcity_planning(self):
-		frappe.db.set_value("Manufacturing Settings", None, {
-			"disable_capacity_planning": 0,
-			"capacity_planning_for_days": 1
-		})
+		frappe.db.set_value(
+			"Manufacturing Settings",
+			None,
+			{"disable_capacity_planning": 0, "capacity_planning_for_days": 1},
+		)
 
-		data = frappe.get_cached_value('BOM', {'docstatus': 1, 'item': '_Test FG Item 2',
-			'with_operations': 1, 'company': '_Test Company'}, ['name', 'item'])
+		data = frappe.get_cached_value(
+			"BOM",
+			{"docstatus": 1, "item": "_Test FG Item 2", "with_operations": 1, "company": "_Test Company"},
+			["name", "item"],
+		)
 
 		if data:
 			bom, bom_item = data
 
 			planned_start_date = add_months(today(), months=-1)
-			work_order = make_wo_order_test_record(item=bom_item,
-				qty=10, bom_no=bom, planned_start_date=planned_start_date)
+			work_order = make_wo_order_test_record(
+				item=bom_item, qty=10, bom_no=bom, planned_start_date=planned_start_date
+			)
 
-			work_order1 = make_wo_order_test_record(item=bom_item,
-				qty=30, bom_no=bom, planned_start_date=planned_start_date, do_not_submit=1)
+			work_order1 = make_wo_order_test_record(
+				item=bom_item, qty=30, bom_no=bom, planned_start_date=planned_start_date, do_not_submit=1
+			)
 
 			self.assertRaises(CapacityError, work_order1.submit)
 
-			frappe.db.set_value("Manufacturing Settings", None, {
-				"capacity_planning_for_days": 30
-			})
+			frappe.db.set_value("Manufacturing Settings", None, {"capacity_planning_for_days": 30})
 
 			work_order1.reload()
 			work_order1.submit()
@@ -466,22 +518,22 @@
 			work_order.cancel()
 
 	def test_work_order_with_non_transfer_item(self):
-		items = {'Finished Good Transfer Item': 1, '_Test FG Item': 1, '_Test FG Item 1': 0}
+		items = {"Finished Good Transfer Item": 1, "_Test FG Item": 1, "_Test FG Item 1": 0}
 		for item, allow_transfer in items.items():
-			make_item(item, {
-				'include_item_in_manufacturing': allow_transfer
-			})
+			make_item(item, {"include_item_in_manufacturing": allow_transfer})
 
-		fg_item = 'Finished Good Transfer Item'
-		test_stock_entry.make_stock_entry(item_code="_Test FG Item",
-			target="_Test Warehouse - _TC", qty=1, basic_rate=100)
-		test_stock_entry.make_stock_entry(item_code="_Test FG Item 1",
-			target="_Test Warehouse - _TC", qty=1, basic_rate=100)
+		fg_item = "Finished Good Transfer Item"
+		test_stock_entry.make_stock_entry(
+			item_code="_Test FG Item", target="_Test Warehouse - _TC", qty=1, basic_rate=100
+		)
+		test_stock_entry.make_stock_entry(
+			item_code="_Test FG Item 1", target="_Test Warehouse - _TC", qty=1, basic_rate=100
+		)
 
-		if not frappe.db.get_value('BOM', {'item': fg_item}):
-			make_bom(item=fg_item, raw_materials = ['_Test FG Item', '_Test FG Item 1'])
+		if not frappe.db.get_value("BOM", {"item": fg_item}):
+			make_bom(item=fg_item, raw_materials=["_Test FG Item", "_Test FG Item 1"])
 
-		wo = make_wo_order_test_record(production_item = fg_item)
+		wo = make_wo_order_test_record(production_item=fg_item)
 		ste = frappe.get_doc(make_stock_entry(wo.name, "Material Transfer for Manufacture", 1))
 		ste.insert()
 		ste.submit()
@@ -499,39 +551,42 @@
 		rm1 = "Test Batch Size Item RM 1 For BOM"
 
 		for item in ["Test Batch Size Item For BOM", "Test Batch Size Item RM 1 For BOM"]:
-			make_item(item, {
-				"include_item_in_manufacturing": 1,
-				"is_stock_item": 1
-			})
+			make_item(item, {"include_item_in_manufacturing": 1, "is_stock_item": 1})
 
-		bom_name = frappe.db.get_value("BOM",
-			{"item": fg_item, "is_active": 1, "with_operations": 1}, "name")
+		bom_name = frappe.db.get_value(
+			"BOM", {"item": fg_item, "is_active": 1, "with_operations": 1}, "name"
+		)
 
 		if not bom_name:
-			bom = make_bom(item=fg_item, rate=1000, raw_materials = [rm1], do_not_save=True)
+			bom = make_bom(item=fg_item, rate=1000, raw_materials=[rm1], do_not_save=True)
 			bom.with_operations = 1
-			bom.append("operations", {
-				"operation": "_Test Operation 1",
-				"workstation": "_Test Workstation 1",
-				"description": "Test Data",
-				"operating_cost": 100,
-				"time_in_mins": 40,
-				"batch_size": 5
-			})
+			bom.append(
+				"operations",
+				{
+					"operation": "_Test Operation 1",
+					"workstation": "_Test Workstation 1",
+					"description": "Test Data",
+					"operating_cost": 100,
+					"time_in_mins": 40,
+					"batch_size": 5,
+				},
+			)
 
 			bom.save()
 			bom.submit()
 			bom_name = bom.name
 
-		work_order = make_wo_order_test_record(item=fg_item,
-			planned_start_date=now(), qty=1, do_not_save=True)
+		work_order = make_wo_order_test_record(
+			item=fg_item, planned_start_date=now(), qty=1, do_not_save=True
+		)
 
 		work_order.set_work_order_operations()
 		work_order.save()
 		self.assertEqual(work_order.operations[0].time_in_mins, 8.0)
 
-		work_order1 = make_wo_order_test_record(item=fg_item,
-			planned_start_date=now(), qty=5, do_not_save=True)
+		work_order1 = make_wo_order_test_record(
+			item=fg_item, planned_start_date=now(), qty=5, do_not_save=True
+		)
 
 		work_order1.set_work_order_operations()
 		work_order1.save()
@@ -541,65 +596,73 @@
 		fg_item = "Test Batch Size Item For BOM 3"
 		rm1 = "Test Batch Size Item RM 1 For BOM 3"
 
-		frappe.db.set_value('Manufacturing Settings', None, 'make_serial_no_batch_from_work_order', 0)
+		frappe.db.set_value("Manufacturing Settings", None, "make_serial_no_batch_from_work_order", 0)
 		for item in ["Test Batch Size Item For BOM 3", "Test Batch Size Item RM 1 For BOM 3"]:
-			item_args = {
-				"include_item_in_manufacturing": 1,
-				"is_stock_item": 1
-			}
+			item_args = {"include_item_in_manufacturing": 1, "is_stock_item": 1}
 
 			if item == fg_item:
-				item_args['has_batch_no'] = 1
-				item_args['create_new_batch'] = 1
-				item_args['batch_number_series'] = 'TBSI3.#####'
+				item_args["has_batch_no"] = 1
+				item_args["create_new_batch"] = 1
+				item_args["batch_number_series"] = "TBSI3.#####"
 
 			make_item(item, item_args)
 
-		bom_name = frappe.db.get_value("BOM",
-			{"item": fg_item, "is_active": 1, "with_operations": 1}, "name")
+		bom_name = frappe.db.get_value(
+			"BOM", {"item": fg_item, "is_active": 1, "with_operations": 1}, "name"
+		)
 
 		if not bom_name:
-			bom = make_bom(item=fg_item, rate=1000, raw_materials = [rm1], do_not_save=True)
+			bom = make_bom(item=fg_item, rate=1000, raw_materials=[rm1], do_not_save=True)
 			bom.save()
 			bom.submit()
 			bom_name = bom.name
 
-		work_order = make_wo_order_test_record(item=fg_item, skip_transfer=True, planned_start_date=now(), qty=1)
+		work_order = make_wo_order_test_record(
+			item=fg_item, skip_transfer=True, planned_start_date=now(), qty=1
+		)
 		ste1 = frappe.get_doc(make_stock_entry(work_order.name, "Manufacture", 1))
-		for row in ste1.get('items'):
+		for row in ste1.get("items"):
 			if row.is_finished_item:
 				self.assertEqual(row.item_code, fg_item)
 
-		work_order = make_wo_order_test_record(item=fg_item, skip_transfer=True, planned_start_date=now(), qty=1)
-		frappe.db.set_value('Manufacturing Settings', None, 'make_serial_no_batch_from_work_order', 1)
+		work_order = make_wo_order_test_record(
+			item=fg_item, skip_transfer=True, planned_start_date=now(), qty=1
+		)
+		frappe.db.set_value("Manufacturing Settings", None, "make_serial_no_batch_from_work_order", 1)
 		ste1 = frappe.get_doc(make_stock_entry(work_order.name, "Manufacture", 1))
-		for row in ste1.get('items'):
+		for row in ste1.get("items"):
 			if row.is_finished_item:
 				self.assertEqual(row.item_code, fg_item)
 
-		work_order = make_wo_order_test_record(item=fg_item, skip_transfer=True, planned_start_date=now(),
-			qty=30, do_not_save = True)
+		work_order = make_wo_order_test_record(
+			item=fg_item, skip_transfer=True, planned_start_date=now(), qty=30, do_not_save=True
+		)
 		work_order.batch_size = 10
 		work_order.insert()
 		work_order.submit()
 		self.assertEqual(work_order.has_batch_no, 1)
 		ste1 = frappe.get_doc(make_stock_entry(work_order.name, "Manufacture", 30))
-		for row in ste1.get('items'):
+		for row in ste1.get("items"):
 			if row.is_finished_item:
 				self.assertEqual(row.item_code, fg_item)
 				self.assertEqual(row.qty, 10)
 
-		frappe.db.set_value('Manufacturing Settings', None, 'make_serial_no_batch_from_work_order', 0)
+		frappe.db.set_value("Manufacturing Settings", None, "make_serial_no_batch_from_work_order", 0)
 
 	def test_partial_material_consumption(self):
 		frappe.db.set_value("Manufacturing Settings", None, "material_consumption", 1)
 		wo_order = make_wo_order_test_record(planned_start_date=now(), qty=4)
 
 		ste_cancel_list = []
-		ste1 = test_stock_entry.make_stock_entry(item_code="_Test Item",
-			target="_Test Warehouse - _TC", qty=20, basic_rate=5000.0)
-		ste2 = test_stock_entry.make_stock_entry(item_code="_Test Item Home Desktop 100",
-			target="_Test Warehouse - _TC", qty=20, basic_rate=1000.0)
+		ste1 = test_stock_entry.make_stock_entry(
+			item_code="_Test Item", target="_Test Warehouse - _TC", qty=20, basic_rate=5000.0
+		)
+		ste2 = test_stock_entry.make_stock_entry(
+			item_code="_Test Item Home Desktop 100",
+			target="_Test Warehouse - _TC",
+			qty=20,
+			basic_rate=1000.0,
+		)
 
 		ste_cancel_list.extend([ste1, ste2])
 
@@ -625,16 +688,25 @@
 
 	def test_extra_material_transfer(self):
 		frappe.db.set_value("Manufacturing Settings", None, "material_consumption", 0)
-		frappe.db.set_value("Manufacturing Settings", None, "backflush_raw_materials_based_on",
-			"Material Transferred for Manufacture")
+		frappe.db.set_value(
+			"Manufacturing Settings",
+			None,
+			"backflush_raw_materials_based_on",
+			"Material Transferred for Manufacture",
+		)
 
 		wo_order = make_wo_order_test_record(planned_start_date=now(), qty=4)
 
 		ste_cancel_list = []
-		ste1 = test_stock_entry.make_stock_entry(item_code="_Test Item",
-			target="_Test Warehouse - _TC", qty=20, basic_rate=5000.0)
-		ste2 = test_stock_entry.make_stock_entry(item_code="_Test Item Home Desktop 100",
-			target="_Test Warehouse - _TC", qty=20, basic_rate=1000.0)
+		ste1 = test_stock_entry.make_stock_entry(
+			item_code="_Test Item", target="_Test Warehouse - _TC", qty=20, basic_rate=5000.0
+		)
+		ste2 = test_stock_entry.make_stock_entry(
+			item_code="_Test Item Home Desktop 100",
+			target="_Test Warehouse - _TC",
+			qty=20,
+			basic_rate=1000.0,
+		)
 
 		ste_cancel_list.extend([ste1, ste2])
 
@@ -666,30 +738,31 @@
 		frappe.db.set_value("Manufacturing Settings", None, "backflush_raw_materials_based_on", "BOM")
 
 	def test_make_stock_entry_for_customer_provided_item(self):
-		finished_item = 'Test Item for Make Stock Entry 1'
-		make_item(finished_item, {
+		finished_item = "Test Item for Make Stock Entry 1"
+		make_item(finished_item, {"include_item_in_manufacturing": 1, "is_stock_item": 1})
+
+		customer_provided_item = "CUST-0987"
+		make_item(
+			customer_provided_item,
+			{
+				"is_purchase_item": 0,
+				"is_customer_provided_item": 1,
+				"is_stock_item": 1,
 				"include_item_in_manufacturing": 1,
-				"is_stock_item": 1
-			})
+				"customer": "_Test Customer",
+			},
+		)
 
-		customer_provided_item = 'CUST-0987'
-		make_item(customer_provided_item, {
-			'is_purchase_item': 0,
-			'is_customer_provided_item': 1,
-			"is_stock_item": 1,
-			"include_item_in_manufacturing": 1,
-			'customer': '_Test Customer'
-		})
-
-		if not frappe.db.exists('BOM', {'item': finished_item}):
+		if not frappe.db.exists("BOM", {"item": finished_item}):
 			make_bom(item=finished_item, raw_materials=[customer_provided_item], rm_qty=1)
 
 		company = "_Test Company with perpetual inventory"
 		customer_warehouse = create_warehouse("Test Customer Provided Warehouse", company=company)
-		wo = make_wo_order_test_record(item=finished_item, qty=1, source_warehouse=customer_warehouse,
-			company=company)
+		wo = make_wo_order_test_record(
+			item=finished_item, qty=1, source_warehouse=customer_warehouse, company=company
+		)
 
-		ste = frappe.get_doc(make_stock_entry(wo.name, purpose='Material Transfer for Manufacture'))
+		ste = frappe.get_doc(make_stock_entry(wo.name, purpose="Material Transfer for Manufacture"))
 		ste.insert()
 
 		self.assertEqual(len(ste.items), 1)
@@ -698,26 +771,33 @@
 			self.assertEqual(item.valuation_rate, 0)
 
 	def test_valuation_rate_missing_on_make_stock_entry(self):
-		item_name = 'Test Valuation Rate Missing'
-		rm_item = '_Test raw material item'
-		make_item(item_name, {
-			"is_stock_item": 1,
-			"include_item_in_manufacturing": 1,
-		})
-		make_item('_Test raw material item', {
-			"is_stock_item": 1,
-			"include_item_in_manufacturing": 1,
-		})
+		item_name = "Test Valuation Rate Missing"
+		rm_item = "_Test raw material item"
+		make_item(
+			item_name,
+			{
+				"is_stock_item": 1,
+				"include_item_in_manufacturing": 1,
+			},
+		)
+		make_item(
+			"_Test raw material item",
+			{
+				"is_stock_item": 1,
+				"include_item_in_manufacturing": 1,
+			},
+		)
 
-		if not frappe.db.get_value('BOM', {'item': item_name}):
+		if not frappe.db.get_value("BOM", {"item": item_name}):
 			make_bom(item=item_name, raw_materials=[rm_item], rm_qty=1)
 
 		company = "_Test Company with perpetual inventory"
 		source_warehouse = create_warehouse("Test Valuation Rate Missing Warehouse", company=company)
-		wo = make_wo_order_test_record(item=item_name, qty=1, source_warehouse=source_warehouse,
-			company=company)
+		wo = make_wo_order_test_record(
+			item=item_name, qty=1, source_warehouse=source_warehouse, company=company
+		)
 
-		stock_entry = frappe.get_doc(make_stock_entry(wo.name, 'Material Transfer for Manufacture'))
+		stock_entry = frappe.get_doc(make_stock_entry(wo.name, "Material Transfer for Manufacture"))
 		self.assertRaises(frappe.ValidationError, stock_entry.save)
 
 	def test_wo_completion_with_pl_bom(self):
@@ -727,19 +807,19 @@
 		)
 
 		qty = 4
-		scrap_qty = 0.25 # bom item qty = 1, consider as 25% of FG
+		scrap_qty = 0.25  # bom item qty = 1, consider as 25% of FG
 		source_warehouse = "Stores - _TC"
 		wip_warehouse = "_Test Warehouse - _TC"
 		fg_item_non_whole, _, bom_item = create_process_loss_bom_items()
 
-		test_stock_entry.make_stock_entry(item_code=bom_item.item_code,
-			target=source_warehouse, qty=4, basic_rate=100)
+		test_stock_entry.make_stock_entry(
+			item_code=bom_item.item_code, target=source_warehouse, qty=4, basic_rate=100
+		)
 
 		bom_no = f"BOM-{fg_item_non_whole.item_code}-001"
 		if not frappe.db.exists("BOM", bom_no):
 			bom_doc = create_bom_with_process_loss_item(
-				fg_item_non_whole, bom_item, scrap_qty=scrap_qty,
-				scrap_rate=0, fg_qty=1, is_process_loss=1
+				fg_item_non_whole, bom_item, scrap_qty=scrap_qty, scrap_rate=0, fg_qty=1, is_process_loss=1
 			)
 			bom_doc.submit()
 
@@ -752,16 +832,12 @@
 			stock_uom=fg_item_non_whole.stock_uom,
 		)
 
-		se = frappe.get_doc(
-			make_stock_entry(wo.name, "Material Transfer for Manufacture", qty)
-		)
+		se = frappe.get_doc(make_stock_entry(wo.name, "Material Transfer for Manufacture", qty))
 		se.get("items")[0].s_warehouse = "Stores - _TC"
 		se.insert()
 		se.submit()
 
-		se = frappe.get_doc(
-			make_stock_entry(wo.name, "Manufacture", qty)
-		)
+		se = frappe.get_doc(make_stock_entry(wo.name, "Manufacture", qty))
 		se.insert()
 		se.submit()
 
@@ -778,41 +854,52 @@
 		self.assertEqual(fg_item.qty, actual_fg_qty)
 
 		# Testing Work Order values
-		self.assertEqual(
-			frappe.db.get_value("Work Order", wo.name, "produced_qty"),
-			qty
-		)
-		self.assertEqual(
-			frappe.db.get_value("Work Order", wo.name, "process_loss_qty"),
-			total_pl_qty
-		)
+		self.assertEqual(frappe.db.get_value("Work Order", wo.name, "produced_qty"), qty)
+		self.assertEqual(frappe.db.get_value("Work Order", wo.name, "process_loss_qty"), total_pl_qty)
 
 	@timeout(seconds=60)
 	def test_job_card_scrap_item(self):
-		items = ['Test FG Item for Scrap Item Test', 'Test RM Item 1 for Scrap Item Test',
-			'Test RM Item 2 for Scrap Item Test']
+		items = [
+			"Test FG Item for Scrap Item Test",
+			"Test RM Item 1 for Scrap Item Test",
+			"Test RM Item 2 for Scrap Item Test",
+		]
 
-		company = '_Test Company with perpetual inventory'
+		company = "_Test Company with perpetual inventory"
 		for item_code in items:
-			create_item(item_code = item_code, is_stock_item = 1,
-				is_purchase_item=1, opening_stock=100, valuation_rate=10, company=company, warehouse='Stores - TCP1')
+			create_item(
+				item_code=item_code,
+				is_stock_item=1,
+				is_purchase_item=1,
+				opening_stock=100,
+				valuation_rate=10,
+				company=company,
+				warehouse="Stores - TCP1",
+			)
 
-		item = 'Test FG Item for Scrap Item Test'
-		raw_materials = ['Test RM Item 1 for Scrap Item Test', 'Test RM Item 2 for Scrap Item Test']
-		if not frappe.db.get_value('BOM', {'item': item}):
-			bom = make_bom(item=item, source_warehouse='Stores - TCP1', raw_materials=raw_materials, do_not_save=True)
+		item = "Test FG Item for Scrap Item Test"
+		raw_materials = ["Test RM Item 1 for Scrap Item Test", "Test RM Item 2 for Scrap Item Test"]
+		if not frappe.db.get_value("BOM", {"item": item}):
+			bom = make_bom(
+				item=item, source_warehouse="Stores - TCP1", raw_materials=raw_materials, do_not_save=True
+			)
 			bom.with_operations = 1
-			bom.append('operations', {
-				'operation': '_Test Operation 1',
-				'workstation': '_Test Workstation 1',
-				'hour_rate': 20,
-				'time_in_mins': 60
-			})
+			bom.append(
+				"operations",
+				{
+					"operation": "_Test Operation 1",
+					"workstation": "_Test Workstation 1",
+					"hour_rate": 20,
+					"time_in_mins": 60,
+				},
+			)
 
 			bom.submit()
 
-		wo_order = make_wo_order_test_record(item=item, company=company, planned_start_date=now(), qty=20, skip_transfer=1)
-		job_card = frappe.db.get_value('Job Card', {'work_order': wo_order.name}, 'name')
+		wo_order = make_wo_order_test_record(
+			item=item, company=company, planned_start_date=now(), qty=20, skip_transfer=1
+		)
+		job_card = frappe.db.get_value("Job Card", {"work_order": wo_order.name}, "name")
 		update_job_card(job_card)
 
 		stock_entry = frappe.get_doc(make_stock_entry(wo_order.name, "Manufacture", 10))
@@ -821,8 +908,10 @@
 				self.assertEqual(row.qty, 1)
 
 		# Partial Job Card 1 with qty 10
-		wo_order = make_wo_order_test_record(item=item, company=company, planned_start_date=add_days(now(), 60), qty=20, skip_transfer=1)
-		job_card = frappe.db.get_value('Job Card', {'work_order': wo_order.name}, 'name')
+		wo_order = make_wo_order_test_record(
+			item=item, company=company, planned_start_date=add_days(now(), 60), qty=20, skip_transfer=1
+		)
+		job_card = frappe.db.get_value("Job Card", {"work_order": wo_order.name}, "name")
 		update_job_card(job_card, 10)
 
 		stock_entry = frappe.get_doc(make_stock_entry(wo_order.name, "Manufacture", 10))
@@ -835,12 +924,12 @@
 		wo_order.load_from_db()
 		for row in wo_order.operations:
 			n_dict = row.as_dict()
-			n_dict['qty'] = 10
-			n_dict['pending_qty'] = 10
+			n_dict["qty"] = 10
+			n_dict["pending_qty"] = 10
 			operations.append(n_dict)
 
 		make_job_card(wo_order.name, operations)
-		job_card = frappe.db.get_value('Job Card', {'work_order': wo_order.name, 'docstatus': 0}, 'name')
+		job_card = frappe.db.get_value("Job Card", {"work_order": wo_order.name, "docstatus": 0}, "name")
 		update_job_card(job_card, 10)
 
 		stock_entry = frappe.get_doc(make_stock_entry(wo_order.name, "Manufacture", 10))
@@ -849,131 +938,160 @@
 				self.assertEqual(row.qty, 2)
 
 	def test_close_work_order(self):
-		items = ['Test FG Item for Closed WO', 'Test RM Item 1 for Closed WO',
-			'Test RM Item 2 for Closed WO']
+		items = [
+			"Test FG Item for Closed WO",
+			"Test RM Item 1 for Closed WO",
+			"Test RM Item 2 for Closed WO",
+		]
 
-		company = '_Test Company with perpetual inventory'
+		company = "_Test Company with perpetual inventory"
 		for item_code in items:
-			create_item(item_code = item_code, is_stock_item = 1,
-				is_purchase_item=1, opening_stock=100, valuation_rate=10, company=company, warehouse='Stores - TCP1')
+			create_item(
+				item_code=item_code,
+				is_stock_item=1,
+				is_purchase_item=1,
+				opening_stock=100,
+				valuation_rate=10,
+				company=company,
+				warehouse="Stores - TCP1",
+			)
 
-		item = 'Test FG Item for Closed WO'
-		raw_materials = ['Test RM Item 1 for Closed WO', 'Test RM Item 2 for Closed WO']
-		if not frappe.db.get_value('BOM', {'item': item}):
-			bom = make_bom(item=item, source_warehouse='Stores - TCP1', raw_materials=raw_materials, do_not_save=True)
+		item = "Test FG Item for Closed WO"
+		raw_materials = ["Test RM Item 1 for Closed WO", "Test RM Item 2 for Closed WO"]
+		if not frappe.db.get_value("BOM", {"item": item}):
+			bom = make_bom(
+				item=item, source_warehouse="Stores - TCP1", raw_materials=raw_materials, do_not_save=True
+			)
 			bom.with_operations = 1
-			bom.append('operations', {
-				'operation': '_Test Operation 1',
-				'workstation': '_Test Workstation 1',
-				'hour_rate': 20,
-				'time_in_mins': 60
-			})
+			bom.append(
+				"operations",
+				{
+					"operation": "_Test Operation 1",
+					"workstation": "_Test Workstation 1",
+					"hour_rate": 20,
+					"time_in_mins": 60,
+				},
+			)
 
 			bom.submit()
 
-		wo_order = make_wo_order_test_record(item=item, company=company, planned_start_date=now(), qty=20, skip_transfer=1)
-		job_cards = frappe.db.get_value('Job Card', {'work_order': wo_order.name}, 'name')
+		wo_order = make_wo_order_test_record(
+			item=item, company=company, planned_start_date=now(), qty=20, skip_transfer=1
+		)
+		job_cards = frappe.db.get_value("Job Card", {"work_order": wo_order.name}, "name")
 
 		if len(job_cards) == len(bom.operations):
 			for jc in job_cards:
-				job_card_doc = frappe.get_doc('Job Card', jc)
-				job_card_doc.append('time_logs', {
-					'from_time': now(),
-					'time_in_mins': 60,
-					'completed_qty': job_card_doc.for_quantity
-				})
+				job_card_doc = frappe.get_doc("Job Card", jc)
+				job_card_doc.append(
+					"time_logs",
+					{"from_time": now(), "time_in_mins": 60, "completed_qty": job_card_doc.for_quantity},
+				)
 
 				job_card_doc.submit()
 
 			close_work_order(wo_order, "Closed")
-			self.assertEqual(wo_order.get('status'), "Closed")
+			self.assertEqual(wo_order.get("status"), "Closed")
 
 	def test_fix_time_operations(self):
-		bom = frappe.get_doc({
-			"doctype": "BOM",
-			"item": "_Test FG Item 2",
-			"is_active": 1,
-			"is_default": 1,
-			"quantity": 1.0,
-			"with_operations": 1,
-			"operations": [
-				{
-					"operation": "_Test Operation 1",
-					"description": "_Test",
-					"workstation": "_Test Workstation 1",
-					"time_in_mins": 60,
-					"operating_cost": 140,
-					"fixed_time": 1
-				}
-			],
-			"items": [
-				{
-					"amount": 5000.0,
-					"doctype": "BOM Item",
-					"item_code": "_Test Item",
-					"parentfield": "items",
-					"qty": 1.0,
-					"rate": 5000.0,
-				},
-			],
-		})
+		bom = frappe.get_doc(
+			{
+				"doctype": "BOM",
+				"item": "_Test FG Item 2",
+				"is_active": 1,
+				"is_default": 1,
+				"quantity": 1.0,
+				"with_operations": 1,
+				"operations": [
+					{
+						"operation": "_Test Operation 1",
+						"description": "_Test",
+						"workstation": "_Test Workstation 1",
+						"time_in_mins": 60,
+						"operating_cost": 140,
+						"fixed_time": 1,
+					}
+				],
+				"items": [
+					{
+						"amount": 5000.0,
+						"doctype": "BOM Item",
+						"item_code": "_Test Item",
+						"parentfield": "items",
+						"qty": 1.0,
+						"rate": 5000.0,
+					},
+				],
+			}
+		)
 		bom.save()
 		bom.submit()
 
-
-		wo1 = make_wo_order_test_record(item=bom.item, bom_no=bom.name, qty=1, skip_transfer=1, do_not_submit=1)
-		wo2 = make_wo_order_test_record(item=bom.item, bom_no=bom.name, qty=2, skip_transfer=1, do_not_submit=1)
+		wo1 = make_wo_order_test_record(
+			item=bom.item, bom_no=bom.name, qty=1, skip_transfer=1, do_not_submit=1
+		)
+		wo2 = make_wo_order_test_record(
+			item=bom.item, bom_no=bom.name, qty=2, skip_transfer=1, do_not_submit=1
+		)
 
 		self.assertEqual(wo1.operations[0].time_in_mins, wo2.operations[0].time_in_mins)
 
 	def test_partial_manufacture_entries(self):
 		cancel_stock_entry = []
 
-		frappe.db.set_value("Manufacturing Settings", None,
-			"backflush_raw_materials_based_on", "Material Transferred for Manufacture")
+		frappe.db.set_value(
+			"Manufacturing Settings",
+			None,
+			"backflush_raw_materials_based_on",
+			"Material Transferred for Manufacture",
+		)
 
 		wo_order = make_wo_order_test_record(planned_start_date=now(), qty=100)
-		ste1 = test_stock_entry.make_stock_entry(item_code="_Test Item",
-			target="_Test Warehouse - _TC", qty=120, basic_rate=5000.0)
-		ste2 = test_stock_entry.make_stock_entry(item_code="_Test Item Home Desktop 100",
-			target="_Test Warehouse - _TC", qty=240, basic_rate=1000.0)
+		ste1 = test_stock_entry.make_stock_entry(
+			item_code="_Test Item", target="_Test Warehouse - _TC", qty=120, basic_rate=5000.0
+		)
+		ste2 = test_stock_entry.make_stock_entry(
+			item_code="_Test Item Home Desktop 100",
+			target="_Test Warehouse - _TC",
+			qty=240,
+			basic_rate=1000.0,
+		)
 
 		cancel_stock_entry.extend([ste1.name, ste2.name])
 
 		sm = frappe.get_doc(make_stock_entry(wo_order.name, "Material Transfer for Manufacture", 100))
-		for row in sm.get('items'):
-			if row.get('item_code') == '_Test Item':
+		for row in sm.get("items"):
+			if row.get("item_code") == "_Test Item":
 				row.qty = 110
 
 		sm.submit()
 		cancel_stock_entry.append(sm.name)
 
 		s = frappe.get_doc(make_stock_entry(wo_order.name, "Manufacture", 90))
-		for row in s.get('items'):
-			if row.get('item_code') == '_Test Item':
-				self.assertEqual(row.get('qty'), 100)
+		for row in s.get("items"):
+			if row.get("item_code") == "_Test Item":
+				self.assertEqual(row.get("qty"), 100)
 		s.submit()
 		cancel_stock_entry.append(s.name)
 
 		s1 = frappe.get_doc(make_stock_entry(wo_order.name, "Manufacture", 5))
-		for row in s1.get('items'):
-			if row.get('item_code') == '_Test Item':
-				self.assertEqual(row.get('qty'), 5)
+		for row in s1.get("items"):
+			if row.get("item_code") == "_Test Item":
+				self.assertEqual(row.get("qty"), 5)
 		s1.submit()
 		cancel_stock_entry.append(s1.name)
 
 		s2 = frappe.get_doc(make_stock_entry(wo_order.name, "Manufacture", 5))
-		for row in s2.get('items'):
-			if row.get('item_code') == '_Test Item':
-				self.assertEqual(row.get('qty'), 5)
+		for row in s2.get("items"):
+			if row.get("item_code") == "_Test Item":
+				self.assertEqual(row.get("qty"), 5)
 
 		cancel_stock_entry.reverse()
 		for ste in cancel_stock_entry:
 			doc = frappe.get_doc("Stock Entry", ste)
 			doc.cancel()
 
-		frappe.db.set_value("Manufacturing Settings", None,
-			"backflush_raw_materials_based_on", "BOM")
+		frappe.db.set_value("Manufacturing Settings", None, "backflush_raw_materials_based_on", "BOM")
 
 	@change_settings("Manufacturing Settings", {"make_serial_no_batch_from_work_order": 1})
 	def test_auto_batch_creation(self):
@@ -982,7 +1100,7 @@
 		fg_item = frappe.generate_hash(length=20)
 		child_item = frappe.generate_hash(length=20)
 
-		bom_tree =  {fg_item: {child_item: {}}}
+		bom_tree = {fg_item: {child_item: {}}}
 
 		create_nested_bom(bom_tree, prefix="")
 
@@ -998,54 +1116,55 @@
 
 
 def update_job_card(job_card, jc_qty=None):
-	employee = frappe.db.get_value('Employee', {'status': 'Active'}, 'name')
-	job_card_doc = frappe.get_doc('Job Card', job_card)
-	job_card_doc.set('scrap_items', [
-		{
-			'item_code': 'Test RM Item 1 for Scrap Item Test',
-			'stock_qty': 2
-		},
-		{
-			'item_code': 'Test RM Item 2 for Scrap Item Test',
-			'stock_qty': 2
-		},
-	])
+	employee = frappe.db.get_value("Employee", {"status": "Active"}, "name")
+	job_card_doc = frappe.get_doc("Job Card", job_card)
+	job_card_doc.set(
+		"scrap_items",
+		[
+			{"item_code": "Test RM Item 1 for Scrap Item Test", "stock_qty": 2},
+			{"item_code": "Test RM Item 2 for Scrap Item Test", "stock_qty": 2},
+		],
+	)
 
 	if jc_qty:
 		job_card_doc.for_quantity = jc_qty
 
-	job_card_doc.append('time_logs', {
-		'from_time': now(),
-		'employee': employee,
-		'time_in_mins': 60,
-		'completed_qty': job_card_doc.for_quantity
-	})
+	job_card_doc.append(
+		"time_logs",
+		{
+			"from_time": now(),
+			"employee": employee,
+			"time_in_mins": 60,
+			"completed_qty": job_card_doc.for_quantity,
+		},
+	)
 
 	job_card_doc.submit()
 
 
 def get_scrap_item_details(bom_no):
 	scrap_items = {}
-	for item in frappe.db.sql("""select item_code, stock_qty from `tabBOM Scrap Item`
-		where parent = %s""", bom_no, as_dict=1):
+	for item in frappe.db.sql(
+		"""select item_code, stock_qty from `tabBOM Scrap Item`
+		where parent = %s""",
+		bom_no,
+		as_dict=1,
+	):
 		scrap_items[item.item_code] = item.stock_qty
 
 	return scrap_items
 
+
 def allow_overproduction(fieldname, percentage):
 	doc = frappe.get_doc("Manufacturing Settings")
-	doc.update({
-		fieldname: percentage
-	})
+	doc.update({fieldname: percentage})
 	doc.save()
 
+
 def make_wo_order_test_record(**args):
 	args = frappe._dict(args)
 	if args.company and args.company != "_Test Company":
-		warehouse_map = {
-			"fg_warehouse": "_Test FG Warehouse",
-			"wip_warehouse": "_Test WIP Warehouse"
-		}
+		warehouse_map = {"fg_warehouse": "_Test FG Warehouse", "wip_warehouse": "_Test WIP Warehouse"}
 
 		for attr, wh_name in warehouse_map.items():
 			if not args.get(attr):
@@ -1053,16 +1172,17 @@
 
 	wo_order = frappe.new_doc("Work Order")
 	wo_order.production_item = args.production_item or args.item or args.item_code or "_Test FG Item"
-	wo_order.bom_no = args.bom_no or frappe.db.get_value("BOM", {"item": wo_order.production_item,
-		"is_active": 1, "is_default": 1})
+	wo_order.bom_no = args.bom_no or frappe.db.get_value(
+		"BOM", {"item": wo_order.production_item, "is_active": 1, "is_default": 1}
+	)
 	wo_order.qty = args.qty or 10
 	wo_order.wip_warehouse = args.wip_warehouse or "_Test Warehouse - _TC"
 	wo_order.fg_warehouse = args.fg_warehouse or "_Test Warehouse 1 - _TC"
 	wo_order.scrap_warehouse = args.fg_warehouse or "_Test Scrap Warehouse - _TC"
 	wo_order.company = args.company or "_Test Company"
 	wo_order.stock_uom = args.stock_uom or "_Test UOM"
-	wo_order.use_multi_level_bom= args.use_multi_level_bom or 0
-	wo_order.skip_transfer=args.skip_transfer or 0
+	wo_order.use_multi_level_bom = args.use_multi_level_bom or 0
+	wo_order.skip_transfer = args.skip_transfer or 0
 	wo_order.get_items_and_operations_from_bom()
 	wo_order.sales_order = args.sales_order or None
 	wo_order.planned_start_date = args.planned_start_date or now()
@@ -1079,4 +1199,5 @@
 			wo_order.submit()
 	return wo_order
 
-test_records = frappe.get_test_records('Work Order')
+
+test_records = frappe.get_test_records("Work Order")
diff --git a/erpnext/manufacturing/doctype/work_order/work_order.py b/erpnext/manufacturing/doctype/work_order/work_order.py
index e832ac9..c8c2f9a 100644
--- a/erpnext/manufacturing/doctype/work_order/work_order.py
+++ b/erpnext/manufacturing/doctype/work_order/work_order.py
@@ -42,11 +42,26 @@
 from erpnext.utilities.transaction_base import validate_uom_is_integer
 
 
-class OverProductionError(frappe.ValidationError): pass
-class CapacityError(frappe.ValidationError): pass
-class StockOverProductionError(frappe.ValidationError): pass
-class OperationTooLongError(frappe.ValidationError): pass
-class ItemHasVariantError(frappe.ValidationError): pass
+class OverProductionError(frappe.ValidationError):
+	pass
+
+
+class CapacityError(frappe.ValidationError):
+	pass
+
+
+class StockOverProductionError(frappe.ValidationError):
+	pass
+
+
+class OperationTooLongError(frappe.ValidationError):
+	pass
+
+
+class ItemHasVariantError(frappe.ValidationError):
+	pass
+
+
 class SerialNoQtyError(frappe.ValidationError):
 	pass
 
@@ -74,12 +89,13 @@
 
 		validate_uom_is_integer(self, "stock_uom", ["qty", "produced_qty"])
 
-		self.set_required_items(reset_only_qty = len(self.get("required_items")))
+		self.set_required_items(reset_only_qty=len(self.get("required_items")))
 
 	def validate_sales_order(self):
 		if self.sales_order:
 			self.check_sales_order_on_hold_or_close()
-			so = frappe.db.sql("""
+			so = frappe.db.sql(
+				"""
 				select so.name, so_item.delivery_date, so.project
 				from `tabSales Order` so
 				inner join `tabSales Order Item` so_item on so_item.parent = so.name
@@ -88,10 +104,14 @@
 					and so.skip_delivery_note  = 0 and (
 					so_item.item_code=%s or
 					pk_item.item_code=%s )
-			""", (self.sales_order, self.production_item, self.production_item), as_dict=1)
+			""",
+				(self.sales_order, self.production_item, self.production_item),
+				as_dict=1,
+			)
 
 			if not so:
-				so = frappe.db.sql("""
+				so = frappe.db.sql(
+					"""
 					select
 						so.name, so_item.delivery_date, so.project
 					from
@@ -102,7 +122,10 @@
 						and so.skip_delivery_note = 0
 						and so_item.item_code = packed_item.parent_item
 						and so.docstatus = 1 and packed_item.item_code=%s
-				""", (self.sales_order, self.production_item), as_dict=1)
+				""",
+					(self.sales_order, self.production_item),
+					as_dict=1,
+				)
 
 			if len(so):
 				if not self.expected_delivery_date:
@@ -123,7 +146,9 @@
 
 	def set_default_warehouse(self):
 		if not self.wip_warehouse:
-			self.wip_warehouse = frappe.db.get_single_value("Manufacturing Settings", "default_wip_warehouse")
+			self.wip_warehouse = frappe.db.get_single_value(
+				"Manufacturing Settings", "default_wip_warehouse"
+			)
 		if not self.fg_warehouse:
 			self.fg_warehouse = frappe.db.get_single_value("Manufacturing Settings", "default_fg_warehouse")
 
@@ -145,40 +170,55 @@
 			self.planned_operating_cost += flt(d.planned_operating_cost)
 			self.actual_operating_cost += flt(d.actual_operating_cost)
 
-		variable_cost = self.actual_operating_cost if self.actual_operating_cost \
-			else self.planned_operating_cost
+		variable_cost = (
+			self.actual_operating_cost if self.actual_operating_cost else self.planned_operating_cost
+		)
 
-		self.total_operating_cost = (flt(self.additional_operating_cost)
-			+ flt(variable_cost) + flt(self.corrective_operation_cost))
+		self.total_operating_cost = (
+			flt(self.additional_operating_cost) + flt(variable_cost) + flt(self.corrective_operation_cost)
+		)
 
 	def validate_work_order_against_so(self):
 		# already ordered qty
-		ordered_qty_against_so = frappe.db.sql("""select sum(qty) from `tabWork Order`
+		ordered_qty_against_so = frappe.db.sql(
+			"""select sum(qty) from `tabWork Order`
 			where production_item = %s and sales_order = %s and docstatus < 2 and name != %s""",
-			(self.production_item, self.sales_order, self.name))[0][0]
+			(self.production_item, self.sales_order, self.name),
+		)[0][0]
 
 		total_qty = flt(ordered_qty_against_so) + flt(self.qty)
 
 		# get qty from Sales Order Item table
-		so_item_qty = frappe.db.sql("""select sum(stock_qty) from `tabSales Order Item`
+		so_item_qty = frappe.db.sql(
+			"""select sum(stock_qty) from `tabSales Order Item`
 			where parent = %s and item_code = %s""",
-			(self.sales_order, self.production_item))[0][0]
+			(self.sales_order, self.production_item),
+		)[0][0]
 		# get qty from Packing Item table
-		dnpi_qty = frappe.db.sql("""select sum(qty) from `tabPacked Item`
+		dnpi_qty = frappe.db.sql(
+			"""select sum(qty) from `tabPacked Item`
 			where parent = %s and parenttype = 'Sales Order' and item_code = %s""",
-			(self.sales_order, self.production_item))[0][0]
+			(self.sales_order, self.production_item),
+		)[0][0]
 		# total qty in SO
 		so_qty = flt(so_item_qty) + flt(dnpi_qty)
 
-		allowance_percentage = flt(frappe.db.get_single_value("Manufacturing Settings",
-			"overproduction_percentage_for_sales_order"))
+		allowance_percentage = flt(
+			frappe.db.get_single_value(
+				"Manufacturing Settings", "overproduction_percentage_for_sales_order"
+			)
+		)
 
-		if total_qty > so_qty + (allowance_percentage/100 * so_qty):
-			frappe.throw(_("Cannot produce more Item {0} than Sales Order quantity {1}")
-				.format(self.production_item, so_qty), OverProductionError)
+		if total_qty > so_qty + (allowance_percentage / 100 * so_qty):
+			frappe.throw(
+				_("Cannot produce more Item {0} than Sales Order quantity {1}").format(
+					self.production_item, so_qty
+				),
+				OverProductionError,
+			)
 
 	def update_status(self, status=None):
-		'''Update status of work order if unknown'''
+		"""Update status of work order if unknown"""
 		if status != "Stopped" and status != "Closed":
 			status = self.get_status(status)
 
@@ -190,17 +230,22 @@
 		return status
 
 	def get_status(self, status=None):
-		'''Return the status based on stock entries against this work order'''
+		"""Return the status based on stock entries against this work order"""
 		if not status:
 			status = self.status
 
-		if self.docstatus==0:
-			status = 'Draft'
-		elif self.docstatus==1:
-			if status != 'Stopped':
-				stock_entries = frappe._dict(frappe.db.sql("""select purpose, sum(fg_completed_qty)
+		if self.docstatus == 0:
+			status = "Draft"
+		elif self.docstatus == 1:
+			if status != "Stopped":
+				stock_entries = frappe._dict(
+					frappe.db.sql(
+						"""select purpose, sum(fg_completed_qty)
 					from `tabStock Entry` where work_order=%s and docstatus=1
-					group by purpose""", self.name))
+					group by purpose""",
+						self.name,
+					)
+				)
 
 				status = "Not Started"
 				if stock_entries:
@@ -209,31 +254,46 @@
 					if flt(produced_qty) >= flt(self.qty):
 						status = "Completed"
 		else:
-			status = 'Cancelled'
+			status = "Cancelled"
 
 		return status
 
 	def update_work_order_qty(self):
 		"""Update **Manufactured Qty** and **Material Transferred for Qty** in Work Order
-			based on Stock Entry"""
+		based on Stock Entry"""
 
-		allowance_percentage = flt(frappe.db.get_single_value("Manufacturing Settings",
-			"overproduction_percentage_for_work_order"))
+		allowance_percentage = flt(
+			frappe.db.get_single_value("Manufacturing Settings", "overproduction_percentage_for_work_order")
+		)
 
-		for purpose, fieldname in (("Manufacture", "produced_qty"),
-			("Material Transfer for Manufacture", "material_transferred_for_manufacturing")):
-			if (purpose == 'Material Transfer for Manufacture' and
-				self.operations and self.transfer_material_against == 'Job Card'):
+		for purpose, fieldname in (
+			("Manufacture", "produced_qty"),
+			("Material Transfer for Manufacture", "material_transferred_for_manufacturing"),
+		):
+			if (
+				purpose == "Material Transfer for Manufacture"
+				and self.operations
+				and self.transfer_material_against == "Job Card"
+			):
 				continue
 
-			qty = flt(frappe.db.sql("""select sum(fg_completed_qty)
+			qty = flt(
+				frappe.db.sql(
+					"""select sum(fg_completed_qty)
 				from `tabStock Entry` where work_order=%s and docstatus=1
-				and purpose=%s""", (self.name, purpose))[0][0])
+				and purpose=%s""",
+					(self.name, purpose),
+				)[0][0]
+			)
 
-			completed_qty = self.qty + (allowance_percentage/100 * self.qty)
+			completed_qty = self.qty + (allowance_percentage / 100 * self.qty)
 			if qty > completed_qty:
-				frappe.throw(_("{0} ({1}) cannot be greater than planned quantity ({2}) in Work Order {3}").format(\
-					self.meta.get_label(fieldname), qty, completed_qty, self.name), StockOverProductionError)
+				frappe.throw(
+					_("{0} ({1}) cannot be greater than planned quantity ({2}) in Work Order {3}").format(
+						self.meta.get_label(fieldname), qty, completed_qty, self.name
+					),
+					StockOverProductionError,
+				)
 
 			self.db_set(fieldname, qty)
 			self.set_process_loss_qty()
@@ -247,7 +307,9 @@
 			self.update_production_plan_status()
 
 	def set_process_loss_qty(self):
-		process_loss_qty = flt(frappe.db.sql("""
+		process_loss_qty = flt(
+			frappe.db.sql(
+				"""
 				SELECT sum(qty) FROM `tabStock Entry Detail`
 				WHERE
 					is_process_loss=1
@@ -258,21 +320,33 @@
 							AND purpose='Manufacture'
 							AND docstatus=1
 					)
-			""", (self.name, ))[0][0])
+			""",
+				(self.name,),
+			)[0][0]
+		)
 		if process_loss_qty is not None:
-			self.db_set('process_loss_qty', process_loss_qty)
+			self.db_set("process_loss_qty", process_loss_qty)
 
 	def update_production_plan_status(self):
-		production_plan = frappe.get_doc('Production Plan', self.production_plan)
+		production_plan = frappe.get_doc("Production Plan", self.production_plan)
 		produced_qty = 0
 		if self.production_plan_item:
-			total_qty = frappe.get_all("Work Order", fields = "sum(produced_qty) as produced_qty",
-				filters = {'docstatus': 1, 'production_plan': self.production_plan,
-					'production_plan_item': self.production_plan_item}, as_list=1)
+			total_qty = frappe.get_all(
+				"Work Order",
+				fields="sum(produced_qty) as produced_qty",
+				filters={
+					"docstatus": 1,
+					"production_plan": self.production_plan,
+					"production_plan_item": self.production_plan_item,
+				},
+				as_list=1,
+			)
 
 			produced_qty = total_qty[0][0] if total_qty else 0
 
-		production_plan.run_method("update_produced_pending_qty", produced_qty, self.production_plan_item)
+		production_plan.run_method(
+			"update_produced_pending_qty", produced_qty, self.production_plan_item
+		)
 
 	def before_submit(self):
 		self.create_serial_no_batch_no()
@@ -283,7 +357,9 @@
 		if not self.fg_warehouse:
 			frappe.throw(_("For Warehouse is required before Submit"))
 
-		if self.production_plan and frappe.db.exists('Production Plan Item Reference',{'parent':self.production_plan}):
+		if self.production_plan and frappe.db.exists(
+			"Production Plan Item Reference", {"parent": self.production_plan}
+		):
 			self.update_work_order_qty_in_combined_so()
 		else:
 			self.update_work_order_qty_in_so()
@@ -296,9 +372,11 @@
 
 	def on_cancel(self):
 		self.validate_cancel()
-		frappe.db.set(self,'status', 'Cancelled')
+		frappe.db.set(self, "status", "Cancelled")
 
-		if self.production_plan and frappe.db.exists('Production Plan Item Reference',{'parent':self.production_plan}):
+		if self.production_plan and frappe.db.exists(
+			"Production Plan Item Reference", {"parent": self.production_plan}
+		):
 			self.update_work_order_qty_in_combined_so()
 		else:
 			self.update_work_order_qty_in_so()
@@ -314,16 +392,15 @@
 		if not (self.has_serial_no or self.has_batch_no):
 			return
 
-		if not cint(frappe.db.get_single_value("Manufacturing Settings", "make_serial_no_batch_from_work_order")):
+		if not cint(
+			frappe.db.get_single_value("Manufacturing Settings", "make_serial_no_batch_from_work_order")
+		):
 			return
 
 		if self.has_batch_no:
 			self.create_batch_for_finished_good()
 
-		args = {
-			"item_code": self.production_item,
-			"work_order": self.name
-		}
+		args = {"item_code": self.production_item, "work_order": self.name}
 
 		if self.has_serial_no:
 			self.make_serial_nos(args)
@@ -336,9 +413,12 @@
 		batch_auto_creation = frappe.get_cached_value("Item", self.production_item, "create_new_batch")
 		if not batch_auto_creation:
 			frappe.msgprint(
-				_("Batch not created for item {} since it does not have a batch series.")
-					.format(frappe.bold(self.production_item)),
-				alert=True, indicator="orange")
+				_("Batch not created for item {} since it does not have a batch series.").format(
+					frappe.bold(self.production_item)
+				),
+				alert=True,
+				indicator="orange",
+			)
 			return
 
 		while total_qty > 0:
@@ -352,19 +432,23 @@
 				qty = total_qty
 				total_qty = 0
 
-			make_batch(frappe._dict({
-				"item": self.production_item,
-				"qty_to_produce": qty,
-				"reference_doctype": self.doctype,
-				"reference_name": self.name
-			}))
+			make_batch(
+				frappe._dict(
+					{
+						"item": self.production_item,
+						"qty_to_produce": qty,
+						"reference_doctype": self.doctype,
+						"reference_name": self.name,
+					}
+				)
+			)
 
 	def delete_auto_created_batch_and_serial_no(self):
-		for row in frappe.get_all("Serial No", filters = {"work_order": self.name}):
+		for row in frappe.get_all("Serial No", filters={"work_order": self.name}):
 			frappe.delete_doc("Serial No", row.name)
 			self.db_set("serial_no", "")
 
-		for row in frappe.get_all("Batch", filters = {"reference_name": self.name}):
+		for row in frappe.get_all("Batch", filters={"reference_name": self.name}):
 			frappe.delete_doc("Batch", row.name)
 
 	def make_serial_nos(self, args):
@@ -379,8 +463,12 @@
 
 		serial_nos_length = len(get_serial_nos(self.serial_no))
 		if serial_nos_length != self.qty:
-			frappe.throw(_("{0} Serial Numbers required for Item {1}. You have provided {2}.")
-				.format(self.qty, self.production_item, serial_nos_length), SerialNoQtyError)
+			frappe.throw(
+				_("{0} Serial Numbers required for Item {1}. You have provided {2}.").format(
+					self.qty, self.production_item, serial_nos_length
+				),
+				SerialNoQtyError,
+			)
 
 	def create_job_card(self):
 		manufacturing_settings_doc = frappe.get_doc("Manufacturing Settings")
@@ -393,8 +481,7 @@
 			while qty > 0:
 				qty = split_qty_based_on_batch_size(self, row, qty)
 				if row.job_card_qty > 0:
-					self.prepare_data_for_job_card(row, index,
-						plan_days, enable_capacity_planning)
+					self.prepare_data_for_job_card(row, index, plan_days, enable_capacity_planning)
 
 		planned_end_date = self.operations and self.operations[-1].planned_end_time
 		if planned_end_date:
@@ -404,12 +491,14 @@
 		self.set_operation_start_end_time(index, row)
 
 		if not row.workstation:
-			frappe.throw(_("Row {0}: select the workstation against the operation {1}")
-				.format(row.idx, row.operation))
+			frappe.throw(
+				_("Row {0}: select the workstation against the operation {1}").format(row.idx, row.operation)
+			)
 
 		original_start_time = row.planned_start_time
-		job_card_doc = create_job_card(self, row, auto_create=True,
-			enable_capacity_planning=enable_capacity_planning)
+		job_card_doc = create_job_card(
+			self, row, auto_create=True, enable_capacity_planning=enable_capacity_planning
+		)
 
 		if enable_capacity_planning and job_card_doc:
 			row.planned_start_time = job_card_doc.time_logs[-1].from_time
@@ -417,22 +506,29 @@
 
 			if date_diff(row.planned_start_time, original_start_time) > plan_days:
 				frappe.message_log.pop()
-				frappe.throw(_("Unable to find the time slot in the next {0} days for the operation {1}.")
-					.format(plan_days, row.operation), CapacityError)
+				frappe.throw(
+					_("Unable to find the time slot in the next {0} days for the operation {1}.").format(
+						plan_days, row.operation
+					),
+					CapacityError,
+				)
 
 			row.db_update()
 
 	def set_operation_start_end_time(self, idx, row):
 		"""Set start and end time for given operation. If first operation, set start as
 		`planned_start_date`, else add time diff to end time of earlier operation."""
-		if idx==0:
+		if idx == 0:
 			# first operation at planned_start date
 			row.planned_start_time = self.planned_start_date
 		else:
-			row.planned_start_time = get_datetime(self.operations[idx-1].planned_end_time)\
-				+ get_mins_between_operations()
+			row.planned_start_time = (
+				get_datetime(self.operations[idx - 1].planned_end_time) + get_mins_between_operations()
+			)
 
-		row.planned_end_time = get_datetime(row.planned_start_time) + relativedelta(minutes = row.time_in_mins)
+		row.planned_end_time = get_datetime(row.planned_start_time) + relativedelta(
+			minutes=row.time_in_mins
+		)
 
 		if row.planned_start_time == row.planned_end_time:
 			frappe.throw(_("Capacity Planning Error, planned start time can not be same as end time"))
@@ -442,23 +538,35 @@
 			frappe.throw(_("Stopped Work Order cannot be cancelled, Unstop it first to cancel"))
 
 		# Check whether any stock entry exists against this Work Order
-		stock_entry = frappe.db.sql("""select name from `tabStock Entry`
-			where work_order = %s and docstatus = 1""", self.name)
+		stock_entry = frappe.db.sql(
+			"""select name from `tabStock Entry`
+			where work_order = %s and docstatus = 1""",
+			self.name,
+		)
 		if stock_entry:
-			frappe.throw(_("Cannot cancel because submitted Stock Entry {0} exists").format(frappe.utils.get_link_to_form('Stock Entry', stock_entry[0][0])))
+			frappe.throw(
+				_("Cannot cancel because submitted Stock Entry {0} exists").format(
+					frappe.utils.get_link_to_form("Stock Entry", stock_entry[0][0])
+				)
+			)
 
 	def update_planned_qty(self):
-		update_bin_qty(self.production_item, self.fg_warehouse, {
-			"planned_qty": get_planned_qty(self.production_item, self.fg_warehouse)
-		})
+		update_bin_qty(
+			self.production_item,
+			self.fg_warehouse,
+			{"planned_qty": get_planned_qty(self.production_item, self.fg_warehouse)},
+		)
 
 		if self.material_request:
 			mr_obj = frappe.get_doc("Material Request", self.material_request)
 			mr_obj.update_requested_qty([self.material_request_item])
 
 	def update_ordered_qty(self):
-		if self.production_plan and self.production_plan_item \
-			and not self.production_plan_sub_assembly_item:
+		if (
+			self.production_plan
+			and self.production_plan_item
+			and not self.production_plan_sub_assembly_item
+		):
 			qty = frappe.get_value("Production Plan Item", self.production_plan_item, "ordered_qty") or 0.0
 
 			if self.docstatus == 1:
@@ -466,12 +574,11 @@
 			elif self.docstatus == 2:
 				qty -= self.qty
 
-			frappe.db.set_value('Production Plan Item',
-				self.production_plan_item, 'ordered_qty', qty)
+			frappe.db.set_value("Production Plan Item", self.production_plan_item, "ordered_qty", qty)
 
-			doc = frappe.get_doc('Production Plan', self.production_plan)
+			doc = frappe.get_doc("Production Plan", self.production_plan)
 			doc.set_status()
-			doc.db_set('status', doc.status)
+			doc.db_set("status", doc.status)
 
 	def update_work_order_qty_in_so(self):
 		if not self.sales_order and not self.sales_order_item:
@@ -479,8 +586,11 @@
 
 		total_bundle_qty = 1
 		if self.product_bundle_item:
-			total_bundle_qty = frappe.db.sql(""" select sum(qty) from
-				`tabProduct Bundle Item` where parent = %s""", (frappe.db.escape(self.product_bundle_item)))[0][0]
+			total_bundle_qty = frappe.db.sql(
+				""" select sum(qty) from
+				`tabProduct Bundle Item` where parent = %s""",
+				(frappe.db.escape(self.product_bundle_item)),
+			)[0][0]
 
 			if not total_bundle_qty:
 				# product bundle is 0 (product bundle allows 0 qty for items)
@@ -488,49 +598,78 @@
 
 		cond = "product_bundle_item = %s" if self.product_bundle_item else "production_item = %s"
 
-		qty = frappe.db.sql(""" select sum(qty) from
+		qty = frappe.db.sql(
+			""" select sum(qty) from
 			`tabWork Order` where sales_order = %s and docstatus = 1 and {0}
-			""".format(cond), (self.sales_order, (self.product_bundle_item or self.production_item)), as_list=1)
+			""".format(
+				cond
+			),
+			(self.sales_order, (self.product_bundle_item or self.production_item)),
+			as_list=1,
+		)
 
 		work_order_qty = qty[0][0] if qty and qty[0][0] else 0
-		frappe.db.set_value('Sales Order Item',
-			self.sales_order_item, 'work_order_qty', flt(work_order_qty/total_bundle_qty, 2))
+		frappe.db.set_value(
+			"Sales Order Item",
+			self.sales_order_item,
+			"work_order_qty",
+			flt(work_order_qty / total_bundle_qty, 2),
+		)
 
 	def update_work_order_qty_in_combined_so(self):
 		total_bundle_qty = 1
 		if self.product_bundle_item:
-			total_bundle_qty = frappe.db.sql(""" select sum(qty) from
-				`tabProduct Bundle Item` where parent = %s""", (frappe.db.escape(self.product_bundle_item)))[0][0]
+			total_bundle_qty = frappe.db.sql(
+				""" select sum(qty) from
+				`tabProduct Bundle Item` where parent = %s""",
+				(frappe.db.escape(self.product_bundle_item)),
+			)[0][0]
 
 			if not total_bundle_qty:
 				# product bundle is 0 (product bundle allows 0 qty for items)
 				total_bundle_qty = 1
 
-		prod_plan = frappe.get_doc('Production Plan', self.production_plan)
-		item_reference = frappe.get_value('Production Plan Item', self.production_plan_item, 'sales_order_item')
+		prod_plan = frappe.get_doc("Production Plan", self.production_plan)
+		item_reference = frappe.get_value(
+			"Production Plan Item", self.production_plan_item, "sales_order_item"
+		)
 
 		for plan_reference in prod_plan.prod_plan_references:
 			work_order_qty = 0.0
 			if plan_reference.item_reference == item_reference:
 				if self.docstatus == 1:
 					work_order_qty = flt(plan_reference.qty) / total_bundle_qty
-				frappe.db.set_value('Sales Order Item',
-					plan_reference.sales_order_item, 'work_order_qty', work_order_qty)
+				frappe.db.set_value(
+					"Sales Order Item", plan_reference.sales_order_item, "work_order_qty", work_order_qty
+				)
 
 	def update_completed_qty_in_material_request(self):
 		if self.material_request:
-			frappe.get_doc("Material Request", self.material_request).update_completed_qty([self.material_request_item])
+			frappe.get_doc("Material Request", self.material_request).update_completed_qty(
+				[self.material_request_item]
+			)
 
 	def set_work_order_operations(self):
 		"""Fetch operations from BOM and set in 'Work Order'"""
 
 		def _get_operations(bom_no, qty=1):
-			data = frappe.get_all("BOM Operation",
-					filters={"parent": bom_no},
-					fields=["operation", "description", "workstation", "idx",
-						"base_hour_rate as hour_rate", "time_in_mins", "parent as bom",
-						"batch_size", "sequence_id", "fixed_time"],
-					order_by="idx")
+			data = frappe.get_all(
+				"BOM Operation",
+				filters={"parent": bom_no},
+				fields=[
+					"operation",
+					"description",
+					"workstation",
+					"idx",
+					"base_hour_rate as hour_rate",
+					"time_in_mins",
+					"parent as bom",
+					"batch_size",
+					"sequence_id",
+					"fixed_time",
+				],
+				order_by="idx",
+			)
 
 			for d in data:
 				if not d.fixed_time:
@@ -539,9 +678,8 @@
 
 			return data
 
-
-		self.set('operations', [])
-		if not self.bom_no or not frappe.get_cached_value('BOM', self.bom_no, 'with_operations'):
+		self.set("operations", [])
+		if not self.bom_no or not frappe.get_cached_value("BOM", self.bom_no, "with_operations"):
 			return
 
 		operations = []
@@ -555,12 +693,12 @@
 					operations.extend(_get_operations(node.name, qty=node.exploded_qty))
 
 		bom_qty = frappe.get_cached_value("BOM", self.bom_no, "quantity")
-		operations.extend(_get_operations(self.bom_no, qty=1.0/bom_qty))
+		operations.extend(_get_operations(self.bom_no, qty=1.0 / bom_qty))
 
 		for correct_index, operation in enumerate(operations, start=1):
 			operation.idx = correct_index
 
-		self.set('operations', operations)
+		self.set("operations", operations)
 		self.calculate_time()
 
 	def calculate_time(self):
@@ -576,16 +714,27 @@
 		holidays = {}
 
 		if holiday_list not in holidays:
-			holiday_list_days = [getdate(d[0]) for d in frappe.get_all("Holiday", fields=["holiday_date"],
-				filters={"parent": holiday_list}, order_by="holiday_date", limit_page_length=0, as_list=1)]
+			holiday_list_days = [
+				getdate(d[0])
+				for d in frappe.get_all(
+					"Holiday",
+					fields=["holiday_date"],
+					filters={"parent": holiday_list},
+					order_by="holiday_date",
+					limit_page_length=0,
+					as_list=1,
+				)
+			]
 
 			holidays[holiday_list] = holiday_list_days
 
 		return holidays[holiday_list]
 
 	def update_operation_status(self):
-		allowance_percentage = flt(frappe.db.get_single_value("Manufacturing Settings", "overproduction_percentage_for_work_order"))
-		max_allowed_qty_for_wo = flt(self.qty) + (allowance_percentage/100 * flt(self.qty))
+		allowance_percentage = flt(
+			frappe.db.get_single_value("Manufacturing Settings", "overproduction_percentage_for_work_order")
+		)
+		max_allowed_qty_for_wo = flt(self.qty) + (allowance_percentage / 100 * flt(self.qty))
 
 		for d in self.get("operations"):
 			if not d.completed_qty:
@@ -601,7 +750,9 @@
 
 	def set_actual_dates(self):
 		if self.get("operations"):
-			actual_start_dates = [d.actual_start_time for d in self.get("operations") if d.actual_start_time]
+			actual_start_dates = [
+				d.actual_start_time for d in self.get("operations") if d.actual_start_time
+			]
 			if actual_start_dates:
 				self.actual_start_date = min(actual_start_dates)
 
@@ -609,20 +760,21 @@
 			if actual_end_dates:
 				self.actual_end_date = max(actual_end_dates)
 		else:
-			data = frappe.get_all("Stock Entry",
-				fields = ["timestamp(posting_date, posting_time) as posting_datetime"],
-				filters = {
+			data = frappe.get_all(
+				"Stock Entry",
+				fields=["timestamp(posting_date, posting_time) as posting_datetime"],
+				filters={
 					"work_order": self.name,
-					"purpose": ("in", ["Material Transfer for Manufacture", "Manufacture"])
-				}
+					"purpose": ("in", ["Material Transfer for Manufacture", "Manufacture"]),
+				},
 			)
 
 			if data and len(data):
 				dates = [d.posting_datetime for d in data]
-				self.db_set('actual_start_date', min(dates))
+				self.db_set("actual_start_date", min(dates))
 
 				if self.status == "Completed":
-					self.db_set('actual_end_date', max(dates))
+					self.db_set("actual_end_date", max(dates))
 
 		self.set_lead_time()
 
@@ -645,24 +797,39 @@
 		if not self.qty > 0:
 			frappe.throw(_("Quantity to Manufacture must be greater than 0."))
 
-		if self.production_plan and self.production_plan_item \
-			and not self.production_plan_sub_assembly_item:
-			qty_dict = frappe.db.get_value("Production Plan Item", self.production_plan_item, ["planned_qty", "ordered_qty"], as_dict=1)
+		if (
+			self.production_plan
+			and self.production_plan_item
+			and not self.production_plan_sub_assembly_item
+		):
+			qty_dict = frappe.db.get_value(
+				"Production Plan Item", self.production_plan_item, ["planned_qty", "ordered_qty"], as_dict=1
+			)
 
 			if not qty_dict:
 				return
 
-			allowance_qty = flt(frappe.db.get_single_value("Manufacturing Settings",
-			"overproduction_percentage_for_work_order"))/100 * qty_dict.get("planned_qty", 0)
+			allowance_qty = (
+				flt(
+					frappe.db.get_single_value(
+						"Manufacturing Settings", "overproduction_percentage_for_work_order"
+					)
+				)
+				/ 100
+				* qty_dict.get("planned_qty", 0)
+			)
 
 			max_qty = qty_dict.get("planned_qty", 0) + allowance_qty - qty_dict.get("ordered_qty", 0)
 
 			if not max_qty > 0:
-				frappe.throw(_("Cannot produce more item for {0}")
-				.format(self.production_item), OverProductionError)
+				frappe.throw(
+					_("Cannot produce more item for {0}").format(self.production_item), OverProductionError
+				)
 			elif self.qty > max_qty:
-				frappe.throw(_("Cannot produce more than {0} items for {1}")
-				.format(max_qty, self.production_item), OverProductionError)
+				frappe.throw(
+					_("Cannot produce more than {0} items for {1}").format(max_qty, self.production_item),
+					OverProductionError,
+				)
 
 	def validate_transfer_against(self):
 		if not self.docstatus == 1:
@@ -671,8 +838,10 @@
 		if not self.operations:
 			self.transfer_material_against = "Work Order"
 		if not self.transfer_material_against:
-			frappe.throw(_("Setting {} is required").format(self.meta.get_label("transfer_material_against")), title=_("Missing value"))
-
+			frappe.throw(
+				_("Setting {} is required").format(self.meta.get_label("transfer_material_against")),
+				title=_("Missing value"),
+			)
 
 	def validate_operation_time(self):
 		for d in self.operations:
@@ -680,14 +849,14 @@
 				frappe.throw(_("Operation Time must be greater than 0 for Operation {0}").format(d.operation))
 
 	def update_required_items(self):
-		'''
+		"""
 		update bin reserved_qty_for_production
 		called from Stock Entry for production, after submit, cancel
-		'''
+		"""
 		# calculate consumed qty based on submitted stock entries
 		self.update_consumed_qty_for_required_items()
 
-		if self.docstatus==1:
+		if self.docstatus == 1:
 			# calculate transferred qty based on submitted stock entries
 			self.update_transferred_qty_for_required_items()
 
@@ -695,7 +864,7 @@
 			self.update_reserved_qty_for_production()
 
 	def update_reserved_qty_for_production(self, items=None):
-		'''update reserved_qty_for_production in bins'''
+		"""update reserved_qty_for_production in bins"""
 		for d in self.required_items:
 			if d.source_warehouse:
 				stock_bin = get_bin(d.item_code, d.source_warehouse)
@@ -717,17 +886,18 @@
 				d.available_qty_at_wip_warehouse = get_latest_stock_qty(d.item_code, self.wip_warehouse)
 
 	def set_required_items(self, reset_only_qty=False):
-		'''set required_items for production to keep track of reserved qty'''
+		"""set required_items for production to keep track of reserved qty"""
 		if not reset_only_qty:
 			self.required_items = []
 
 		operation = None
-		if self.get('operations') and len(self.operations) == 1:
+		if self.get("operations") and len(self.operations) == 1:
 			operation = self.operations[0].operation
 
 		if self.bom_no and self.qty:
-			item_dict = get_bom_items_as_dict(self.bom_no, self.company, qty=self.qty,
-				fetch_exploded = self.use_multi_level_bom)
+			item_dict = get_bom_items_as_dict(
+				self.bom_no, self.company, qty=self.qty, fetch_exploded=self.use_multi_level_bom
+			)
 
 			if reset_only_qty:
 				for d in self.get("required_items"):
@@ -737,19 +907,22 @@
 					if not d.operation:
 						d.operation = operation
 			else:
-				for item in sorted(item_dict.values(), key=lambda d: d['idx'] or float('inf')):
-					self.append('required_items', {
-						'rate': item.rate,
-						'amount': item.rate * item.qty,
-						'operation': item.operation or operation,
-						'item_code': item.item_code,
-						'item_name': item.item_name,
-						'description': item.description,
-						'allow_alternative_item': item.allow_alternative_item,
-						'required_qty': item.qty,
-						'source_warehouse': item.source_warehouse or item.default_warehouse,
-						'include_item_in_manufacturing': item.include_item_in_manufacturing
-					})
+				for item in sorted(item_dict.values(), key=lambda d: d["idx"] or float("inf")):
+					self.append(
+						"required_items",
+						{
+							"rate": item.rate,
+							"amount": item.rate * item.qty,
+							"operation": item.operation or operation,
+							"item_code": item.item_code,
+							"item_name": item.item_name,
+							"description": item.description,
+							"allow_alternative_item": item.allow_alternative_item,
+							"required_qty": item.qty,
+							"source_warehouse": item.source_warehouse or item.default_warehouse,
+							"include_item_in_manufacturing": item.include_item_in_manufacturing,
+						},
+					)
 
 					if not self.project:
 						self.project = item.get("project")
@@ -757,32 +930,33 @@
 			self.set_available_qty()
 
 	def update_transferred_qty_for_required_items(self):
-		'''update transferred qty from submitted stock entries for that item against
-			the work order'''
+		"""update transferred qty from submitted stock entries for that item against
+		the work order"""
 
 		for d in self.required_items:
-			transferred_qty = frappe.db.sql('''select sum(qty)
+			transferred_qty = frappe.db.sql(
+				"""select sum(qty)
 				from `tabStock Entry` entry, `tabStock Entry Detail` detail
 				where
 					entry.work_order = %(name)s
 					and entry.purpose = "Material Transfer for Manufacture"
 					and entry.docstatus = 1
 					and detail.parent = entry.name
-					and (detail.item_code = %(item)s or detail.original_item = %(item)s)''', {
-						'name': self.name,
-						'item': d.item_code
-					})[0][0]
+					and (detail.item_code = %(item)s or detail.original_item = %(item)s)""",
+				{"name": self.name, "item": d.item_code},
+			)[0][0]
 
-			d.db_set('transferred_qty', flt(transferred_qty), update_modified = False)
+			d.db_set("transferred_qty", flt(transferred_qty), update_modified=False)
 
 	def update_consumed_qty_for_required_items(self):
-		'''
-			Update consumed qty from submitted stock entries
-			against a work order for each stock item
-		'''
+		"""
+		Update consumed qty from submitted stock entries
+		against a work order for each stock item
+		"""
 
 		for item in self.required_items:
-			consumed_qty = frappe.db.sql('''
+			consumed_qty = frappe.db.sql(
+				"""
 				SELECT
 					SUM(qty)
 				FROM
@@ -797,85 +971,97 @@
 						AND detail.s_warehouse IS NOT null
 						AND (detail.item_code = %(item)s
 							OR detail.original_item = %(item)s)
-				''', {
-					'name': self.name,
-					'item': item.item_code
-				})[0][0]
+				""",
+				{"name": self.name, "item": item.item_code},
+			)[0][0]
 
-			item.db_set('consumed_qty', flt(consumed_qty), update_modified=False)
+			item.db_set("consumed_qty", flt(consumed_qty), update_modified=False)
 
 	@frappe.whitelist()
 	def make_bom(self):
-		data = frappe.db.sql(""" select sed.item_code, sed.qty, sed.s_warehouse
+		data = frappe.db.sql(
+			""" select sed.item_code, sed.qty, sed.s_warehouse
 			from `tabStock Entry Detail` sed, `tabStock Entry` se
 			where se.name = sed.parent and se.purpose = 'Manufacture'
 			and (sed.t_warehouse is null or sed.t_warehouse = '') and se.docstatus = 1
-			and se.work_order = %s""", (self.name), as_dict=1)
+			and se.work_order = %s""",
+			(self.name),
+			as_dict=1,
+		)
 
 		bom = frappe.new_doc("BOM")
 		bom.item = self.production_item
 		bom.conversion_rate = 1
 
 		for d in data:
-			bom.append('items', {
-				'item_code': d.item_code,
-				'qty': d.qty,
-				'source_warehouse': d.s_warehouse
-			})
+			bom.append("items", {"item_code": d.item_code, "qty": d.qty, "source_warehouse": d.s_warehouse})
 
 		if self.operations:
-			bom.set('operations', self.operations)
+			bom.set("operations", self.operations)
 			bom.with_operations = 1
 
 		bom.set_bom_material_details()
 		return bom
 
 	def update_batch_produced_qty(self, stock_entry_doc):
-		if not cint(frappe.db.get_single_value("Manufacturing Settings", "make_serial_no_batch_from_work_order")):
+		if not cint(
+			frappe.db.get_single_value("Manufacturing Settings", "make_serial_no_batch_from_work_order")
+		):
 			return
 
 		for row in stock_entry_doc.items:
 			if row.batch_no and (row.is_finished_item or row.is_scrap_item):
-				qty = frappe.get_all("Stock Entry Detail", filters = {"batch_no": row.batch_no, "docstatus": 1},
-					or_filters= {"is_finished_item": 1, "is_scrap_item": 1}, fields = ["sum(qty)"], as_list=1)[0][0]
+				qty = frappe.get_all(
+					"Stock Entry Detail",
+					filters={"batch_no": row.batch_no, "docstatus": 1},
+					or_filters={"is_finished_item": 1, "is_scrap_item": 1},
+					fields=["sum(qty)"],
+					as_list=1,
+				)[0][0]
 
 				frappe.db.set_value("Batch", row.batch_no, "produced_qty", flt(qty))
 
+
 @frappe.whitelist()
 @frappe.validate_and_sanitize_search_inputs
 def get_bom_operations(doctype, txt, searchfield, start, page_len, filters):
 	if txt:
-		filters['operation'] = ('like', '%%%s%%' % txt)
+		filters["operation"] = ("like", "%%%s%%" % txt)
 
-	return frappe.get_all('BOM Operation',
-		filters = filters, fields = ['operation'], as_list=1)
+	return frappe.get_all("BOM Operation", filters=filters, fields=["operation"], as_list=1)
+
 
 @frappe.whitelist()
-def get_item_details(item, project = None, skip_bom_info=False):
-	res = frappe.db.sql("""
+def get_item_details(item, project=None, skip_bom_info=False):
+	res = frappe.db.sql(
+		"""
 		select stock_uom, description, item_name, allow_alternative_item,
 			include_item_in_manufacturing
 		from `tabItem`
 		where disabled=0
 			and (end_of_life is null or end_of_life='0000-00-00' or end_of_life > %s)
 			and name=%s
-	""", (nowdate(), item), as_dict=1)
+	""",
+		(nowdate(), item),
+		as_dict=1,
+	)
 
 	if not res:
 		return {}
 
 	res = res[0]
-	if skip_bom_info: return res
+	if skip_bom_info:
+		return res
 
 	filters = {"item": item, "is_default": 1, "docstatus": 1}
 
 	if project:
 		filters = {"item": item, "project": project}
 
-	res["bom_no"] = frappe.db.get_value("BOM", filters = filters)
+	res["bom_no"] = frappe.db.get_value("BOM", filters=filters)
 
 	if not res["bom_no"]:
-		variant_of= frappe.db.get_value("Item", item, "variant_of")
+		variant_of = frappe.db.get_value("Item", item, "variant_of")
 
 		if variant_of:
 			res["bom_no"] = frappe.db.get_value("BOM", filters={"item": variant_of, "is_default": 1})
@@ -883,19 +1069,26 @@
 	if not res["bom_no"]:
 		if project:
 			res = get_item_details(item)
-			frappe.msgprint(_("Default BOM not found for Item {0} and Project {1}").format(item, project), alert=1)
+			frappe.msgprint(
+				_("Default BOM not found for Item {0} and Project {1}").format(item, project), alert=1
+			)
 		else:
 			frappe.throw(_("Default BOM for {0} not found").format(item))
 
-	bom_data = frappe.db.get_value('BOM', res['bom_no'],
-		['project', 'allow_alternative_item', 'transfer_material_against', 'item_name'], as_dict=1)
+	bom_data = frappe.db.get_value(
+		"BOM",
+		res["bom_no"],
+		["project", "allow_alternative_item", "transfer_material_against", "item_name"],
+		as_dict=1,
+	)
 
-	res['project'] = project or bom_data.pop("project")
+	res["project"] = project or bom_data.pop("project")
 	res.update(bom_data)
 	res.update(check_if_scrap_warehouse_mandatory(res["bom_no"]))
 
 	return res
 
+
 @frappe.whitelist()
 def make_work_order(bom_no, item, qty=0, project=None, variant_items=None):
 	if not frappe.has_permission("Work Order", "write"):
@@ -917,43 +1110,51 @@
 
 	return wo_doc
 
+
 def add_variant_item(variant_items, wo_doc, bom_no, table_name="items"):
 	if isinstance(variant_items, str):
 		variant_items = json.loads(variant_items)
 
 	for item in variant_items:
-		args = frappe._dict({
-			"item_code": item.get("variant_item_code"),
-			"required_qty": item.get("qty"),
-			"qty": item.get("qty"), # for bom
-			"source_warehouse": item.get("source_warehouse"),
-			"operation": item.get("operation")
-		})
+		args = frappe._dict(
+			{
+				"item_code": item.get("variant_item_code"),
+				"required_qty": item.get("qty"),
+				"qty": item.get("qty"),  # for bom
+				"source_warehouse": item.get("source_warehouse"),
+				"operation": item.get("operation"),
+			}
+		)
 
 		bom_doc = frappe.get_cached_doc("BOM", bom_no)
 		item_data = get_item_details(args.item_code, skip_bom_info=True)
 		args.update(item_data)
 
-		args["rate"] = get_bom_item_rate({
-			"company": wo_doc.company,
-			"item_code": args.get("item_code"),
-			"qty": args.get("required_qty"),
-			"uom": args.get("stock_uom"),
-			"stock_uom": args.get("stock_uom"),
-			"conversion_factor": 1
-		}, bom_doc)
+		args["rate"] = get_bom_item_rate(
+			{
+				"company": wo_doc.company,
+				"item_code": args.get("item_code"),
+				"qty": args.get("required_qty"),
+				"uom": args.get("stock_uom"),
+				"stock_uom": args.get("stock_uom"),
+				"conversion_factor": 1,
+			},
+			bom_doc,
+		)
 
 		if not args.source_warehouse:
-			args["source_warehouse"] = get_item_defaults(item.get("variant_item_code"),
-				wo_doc.company).default_warehouse
+			args["source_warehouse"] = get_item_defaults(
+				item.get("variant_item_code"), wo_doc.company
+			).default_warehouse
 
 		args["amount"] = flt(args.get("required_qty")) * flt(args.get("rate"))
 		args["uom"] = item_data.stock_uom
 		wo_doc.append(table_name, args)
 
+
 @frappe.whitelist()
 def check_if_scrap_warehouse_mandatory(bom_no):
-	res = {"set_scrap_wh_mandatory": False }
+	res = {"set_scrap_wh_mandatory": False}
 	if bom_no:
 		bom = frappe.get_doc("BOM", bom_no)
 
@@ -962,12 +1163,14 @@
 
 	return res
 
+
 @frappe.whitelist()
 def set_work_order_ops(name):
-	po = frappe.get_doc('Work Order', name)
+	po = frappe.get_doc("Work Order", name)
 	po.set_work_order_operations()
 	po.save()
 
+
 @frappe.whitelist()
 def make_stock_entry(work_order_id, purpose, qty=None):
 	work_order = frappe.get_doc("Work Order", work_order_id)
@@ -985,10 +1188,11 @@
 	stock_entry.use_multi_level_bom = work_order.use_multi_level_bom
 	stock_entry.fg_completed_qty = qty or (flt(work_order.qty) - flt(work_order.produced_qty))
 	if work_order.bom_no:
-		stock_entry.inspection_required = frappe.db.get_value('BOM',
-			work_order.bom_no, 'inspection_required')
+		stock_entry.inspection_required = frappe.db.get_value(
+			"BOM", work_order.bom_no, "inspection_required"
+		)
 
-	if purpose=="Material Transfer for Manufacture":
+	if purpose == "Material Transfer for Manufacture":
 		stock_entry.to_warehouse = wip_warehouse
 		stock_entry.project = work_order.project
 	else:
@@ -1001,6 +1205,7 @@
 	stock_entry.set_serial_no_batch_for_finished_good()
 	return stock_entry.as_dict()
 
+
 @frappe.whitelist()
 def get_default_warehouse():
 	doc = frappe.get_cached_doc("Manufacturing Settings")
@@ -1008,12 +1213,13 @@
 	return {
 		"wip_warehouse": doc.default_wip_warehouse,
 		"fg_warehouse": doc.default_fg_warehouse,
-		"scrap_warehouse": doc.default_scrap_warehouse
+		"scrap_warehouse": doc.default_scrap_warehouse,
 	}
 
+
 @frappe.whitelist()
 def stop_unstop(work_order, status):
-	""" Called from client side on Stop/Unstop event"""
+	"""Called from client side on Stop/Unstop event"""
 
 	if not frappe.has_permission("Work Order", "write"):
 		frappe.throw(_("Not permitted"), frappe.PermissionError)
@@ -1030,24 +1236,29 @@
 
 	return pro_order.status
 
+
 @frappe.whitelist()
 def query_sales_order(production_item):
-	out = frappe.db.sql_list("""
+	out = frappe.db.sql_list(
+		"""
 		select distinct so.name from `tabSales Order` so, `tabSales Order Item` so_item
 		where so_item.parent=so.name and so_item.item_code=%s and so.docstatus=1
 	union
 		select distinct so.name from `tabSales Order` so, `tabPacked Item` pi_item
 		where pi_item.parent=so.name and pi_item.item_code=%s and so.docstatus=1
-	""", (production_item, production_item))
+	""",
+		(production_item, production_item),
+	)
 
 	return out
 
+
 @frappe.whitelist()
 def make_job_card(work_order, operations):
 	if isinstance(operations, str):
 		operations = json.loads(operations)
 
-	work_order = frappe.get_doc('Work Order', work_order)
+	work_order = frappe.get_doc("Work Order", work_order)
 	for row in operations:
 		row = frappe._dict(row)
 		validate_operation_data(row)
@@ -1057,6 +1268,7 @@
 			if row.job_card_qty > 0:
 				create_job_card(work_order, row, auto_create=True)
 
+
 @frappe.whitelist()
 def close_work_order(work_order, status):
 	if not frappe.has_permission("Work Order", "write"):
@@ -1064,15 +1276,17 @@
 
 	work_order = frappe.get_doc("Work Order", work_order)
 	if work_order.get("operations"):
-		job_cards = frappe.get_list("Job Card",
-			filters={
-				"work_order": work_order.name,
-				"status": "Work In Progress"
-			}, pluck='name')
+		job_cards = frappe.get_list(
+			"Job Card", filters={"work_order": work_order.name, "status": "Work In Progress"}, pluck="name"
+		)
 
 		if job_cards:
 			job_cards = ", ".join(job_cards)
-			frappe.throw(_("Can not close Work Order. Since {0} Job Cards are in Work In Progress state.").format(job_cards))
+			frappe.throw(
+				_("Can not close Work Order. Since {0} Job Cards are in Work In Progress state.").format(
+					job_cards
+				)
+			)
 
 	work_order.update_status(status)
 	work_order.update_planned_qty()
@@ -1080,9 +1294,11 @@
 	work_order.notify_update()
 	return work_order.status
 
+
 def split_qty_based_on_batch_size(wo_doc, row, qty):
-	if not cint(frappe.db.get_value("Operation",
-		row.operation, "create_job_card_based_on_batch_size")):
+	if not cint(
+		frappe.db.get_value("Operation", row.operation, "create_job_card_based_on_batch_size")
+	):
 		row.batch_size = row.get("qty") or wo_doc.qty
 
 	row.job_card_qty = row.batch_size
@@ -1096,55 +1312,63 @@
 
 	return qty
 
+
 def get_serial_nos_for_job_card(row, wo_doc):
 	if not wo_doc.serial_no:
 		return
 
 	serial_nos = get_serial_nos(wo_doc.serial_no)
 	used_serial_nos = []
-	for d in frappe.get_all('Job Card', fields=['serial_no'],
-		filters={'docstatus': ('<', 2), 'work_order': wo_doc.name, 'operation_id': row.name}):
+	for d in frappe.get_all(
+		"Job Card",
+		fields=["serial_no"],
+		filters={"docstatus": ("<", 2), "work_order": wo_doc.name, "operation_id": row.name},
+	):
 		used_serial_nos.extend(get_serial_nos(d.serial_no))
 
 	serial_nos = sorted(list(set(serial_nos) - set(used_serial_nos)))
-	row.serial_no = '\n'.join(serial_nos[0:row.job_card_qty])
+	row.serial_no = "\n".join(serial_nos[0 : row.job_card_qty])
+
 
 def validate_operation_data(row):
 	if row.get("qty") <= 0:
-		frappe.throw(_("Quantity to Manufacture can not be zero for the operation {0}")
-			.format(
+		frappe.throw(
+			_("Quantity to Manufacture can not be zero for the operation {0}").format(
 				frappe.bold(row.get("operation"))
 			)
 		)
 
 	if row.get("qty") > row.get("pending_qty"):
-		frappe.throw(_("For operation {0}: Quantity ({1}) can not be greter than pending quantity({2})")
-			.format(
+		frappe.throw(
+			_("For operation {0}: Quantity ({1}) can not be greter than pending quantity({2})").format(
 				frappe.bold(row.get("operation")),
 				frappe.bold(row.get("qty")),
-				frappe.bold(row.get("pending_qty"))
+				frappe.bold(row.get("pending_qty")),
 			)
 		)
 
+
 def create_job_card(work_order, row, enable_capacity_planning=False, auto_create=False):
 	doc = frappe.new_doc("Job Card")
-	doc.update({
-		'work_order': work_order.name,
-		'operation': row.get("operation"),
-		'workstation': row.get("workstation"),
-		'posting_date': nowdate(),
-		'for_quantity': row.job_card_qty or work_order.get('qty', 0),
-		'operation_id': row.get("name"),
-		'bom_no': work_order.bom_no,
-		'project': work_order.project,
-		'company': work_order.company,
-		'sequence_id': row.get("sequence_id"),
-		'wip_warehouse': work_order.wip_warehouse,
-		'hour_rate': row.get("hour_rate"),
-		'serial_no': row.get("serial_no")
-	})
+	doc.update(
+		{
+			"work_order": work_order.name,
+			"operation": row.get("operation"),
+			"workstation": row.get("workstation"),
+			"posting_date": nowdate(),
+			"for_quantity": row.job_card_qty or work_order.get("qty", 0),
+			"operation_id": row.get("name"),
+			"bom_no": work_order.bom_no,
+			"project": work_order.project,
+			"company": work_order.company,
+			"sequence_id": row.get("sequence_id"),
+			"wip_warehouse": work_order.wip_warehouse,
+			"hour_rate": row.get("hour_rate"),
+			"serial_no": row.get("serial_no"),
+		}
+	)
 
-	if work_order.transfer_material_against == 'Job Card' and not work_order.skip_transfer:
+	if work_order.transfer_material_against == "Job Card" and not work_order.skip_transfer:
 		doc.get_required_items()
 
 	if auto_create:
@@ -1153,7 +1377,9 @@
 			doc.schedule_time_logs(row)
 
 		doc.insert()
-		frappe.msgprint(_("Job card {0} created").format(get_link_to_form("Job Card", doc.name)), alert=True)
+		frappe.msgprint(
+			_("Job card {0} created").format(get_link_to_form("Job Card", doc.name)), alert=True
+		)
 
 	if enable_capacity_planning:
 		# automatically added scheduling rows shouldn't change status to WIP
@@ -1161,15 +1387,18 @@
 
 	return doc
 
+
 def get_work_order_operation_data(work_order, operation, workstation):
 	for d in work_order.operations:
 		if d.operation == operation and d.workstation == workstation:
 			return d
 
+
 @frappe.whitelist()
 def create_pick_list(source_name, target_doc=None, for_qty=None):
-	for_qty = for_qty or json.loads(target_doc).get('for_qty')
-	max_finished_goods_qty = frappe.db.get_value('Work Order', source_name, 'qty')
+	for_qty = for_qty or json.loads(target_doc).get("for_qty")
+	max_finished_goods_qty = frappe.db.get_value("Work Order", source_name, "qty")
+
 	def update_item_quantity(source, target, source_parent):
 		pending_to_issue = flt(source.required_qty) - flt(source.transferred_qty)
 		desire_to_transfer = flt(source.required_qty) / max_finished_goods_qty * flt(for_qty)
@@ -1183,25 +1412,25 @@
 		if qty:
 			target.qty = qty
 			target.stock_qty = qty
-			target.uom = frappe.get_value('Item', source.item_code, 'stock_uom')
+			target.uom = frappe.get_value("Item", source.item_code, "stock_uom")
 			target.stock_uom = target.uom
 			target.conversion_factor = 1
 		else:
 			target.delete()
 
-	doc = get_mapped_doc('Work Order', source_name, {
-		'Work Order': {
-			'doctype': 'Pick List',
-			'validation': {
-				'docstatus': ['=', 1]
-			}
+	doc = get_mapped_doc(
+		"Work Order",
+		source_name,
+		{
+			"Work Order": {"doctype": "Pick List", "validation": {"docstatus": ["=", 1]}},
+			"Work Order Item": {
+				"doctype": "Pick List Item",
+				"postprocess": update_item_quantity,
+				"condition": lambda doc: abs(doc.transferred_qty) < abs(doc.required_qty),
+			},
 		},
-		'Work Order Item': {
-			'doctype': 'Pick List Item',
-			'postprocess': update_item_quantity,
-			'condition': lambda doc: abs(doc.transferred_qty) < abs(doc.required_qty)
-		},
-	}, target_doc)
+		target_doc,
+	)
 
 	doc.for_qty = for_qty
 
@@ -1209,26 +1438,31 @@
 
 	return doc
 
+
 def get_reserved_qty_for_production(item_code: str, warehouse: str) -> float:
 	"""Get total reserved quantity for any item in specified warehouse"""
 	wo = frappe.qb.DocType("Work Order")
 	wo_item = frappe.qb.DocType("Work Order Item")
 
 	return (
-	frappe.qb
-		.from_(wo)
+		frappe.qb.from_(wo)
 		.from_(wo_item)
-		.select(Sum(Case()
+		.select(
+			Sum(
+				Case()
 				.when(wo.skip_transfer == 0, wo_item.required_qty - wo_item.transferred_qty)
-				.else_(wo_item.required_qty - wo_item.consumed_qty))
+				.else_(wo_item.required_qty - wo_item.consumed_qty)
 			)
+		)
 		.where(
 			(wo_item.item_code == item_code)
 			& (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))
+			& (
+				(wo_item.required_qty > wo_item.transferred_qty)
+				| (wo_item.required_qty > wo_item.consumed_qty)
+			)
 		)
 	).run()[0][0] or 0.0
diff --git a/erpnext/manufacturing/doctype/work_order/work_order_dashboard.py b/erpnext/manufacturing/doctype/work_order/work_order_dashboard.py
index 37dd11a..465460f 100644
--- a/erpnext/manufacturing/doctype/work_order/work_order_dashboard.py
+++ b/erpnext/manufacturing/doctype/work_order/work_order_dashboard.py
@@ -3,18 +3,10 @@
 
 def get_data():
 	return {
-		'fieldname': 'work_order',
-		'non_standard_fieldnames': {
-			'Batch': 'reference_name'
-		},
-		'transactions': [
-			{
-				'label': _('Transactions'),
-				'items': ['Stock Entry', 'Job Card', 'Pick List']
-			},
-			{
-				'label': _('Reference'),
-				'items': ['Serial No', 'Batch']
-			}
-		]
+		"fieldname": "work_order",
+		"non_standard_fieldnames": {"Batch": "reference_name"},
+		"transactions": [
+			{"label": _("Transactions"), "items": ["Stock Entry", "Job Card", "Pick List"]},
+			{"label": _("Reference"), "items": ["Serial No", "Batch"]},
+		],
 	}
diff --git a/erpnext/manufacturing/doctype/work_order_item/work_order_item.py b/erpnext/manufacturing/doctype/work_order_item/work_order_item.py
index 4311d3b..1792747 100644
--- a/erpnext/manufacturing/doctype/work_order_item/work_order_item.py
+++ b/erpnext/manufacturing/doctype/work_order_item/work_order_item.py
@@ -9,5 +9,6 @@
 class WorkOrderItem(Document):
 	pass
 
+
 def on_doctype_update():
 	frappe.db.add_index("Work Order Item", ["item_code", "source_warehouse"])
diff --git a/erpnext/manufacturing/doctype/workstation/test_workstation.py b/erpnext/manufacturing/doctype/workstation/test_workstation.py
index dd51017..6db985c 100644
--- a/erpnext/manufacturing/doctype/workstation/test_workstation.py
+++ b/erpnext/manufacturing/doctype/workstation/test_workstation.py
@@ -13,19 +13,42 @@
 )
 
 test_dependencies = ["Warehouse"]
-test_records = frappe.get_test_records('Workstation')
-make_test_records('Workstation')
+test_records = frappe.get_test_records("Workstation")
+make_test_records("Workstation")
+
 
 class TestWorkstation(FrappeTestCase):
 	def test_validate_timings(self):
-		check_if_within_operating_hours("_Test Workstation 1", "Operation 1", "2013-02-02 11:00:00", "2013-02-02 19:00:00")
-		check_if_within_operating_hours("_Test Workstation 1", "Operation 1", "2013-02-02 10:00:00", "2013-02-02 20:00:00")
-		self.assertRaises(NotInWorkingHoursError, check_if_within_operating_hours,
-			"_Test Workstation 1", "Operation 1", "2013-02-02 05:00:00", "2013-02-02 20:00:00")
-		self.assertRaises(NotInWorkingHoursError, check_if_within_operating_hours,
-			"_Test Workstation 1", "Operation 1", "2013-02-02 05:00:00", "2013-02-02 20:00:00")
-		self.assertRaises(WorkstationHolidayError, check_if_within_operating_hours,
-			"_Test Workstation 1", "Operation 1", "2013-02-01 10:00:00", "2013-02-02 20:00:00")
+		check_if_within_operating_hours(
+			"_Test Workstation 1", "Operation 1", "2013-02-02 11:00:00", "2013-02-02 19:00:00"
+		)
+		check_if_within_operating_hours(
+			"_Test Workstation 1", "Operation 1", "2013-02-02 10:00:00", "2013-02-02 20:00:00"
+		)
+		self.assertRaises(
+			NotInWorkingHoursError,
+			check_if_within_operating_hours,
+			"_Test Workstation 1",
+			"Operation 1",
+			"2013-02-02 05:00:00",
+			"2013-02-02 20:00:00",
+		)
+		self.assertRaises(
+			NotInWorkingHoursError,
+			check_if_within_operating_hours,
+			"_Test Workstation 1",
+			"Operation 1",
+			"2013-02-02 05:00:00",
+			"2013-02-02 20:00:00",
+		)
+		self.assertRaises(
+			WorkstationHolidayError,
+			check_if_within_operating_hours,
+			"_Test Workstation 1",
+			"Operation 1",
+			"2013-02-01 10:00:00",
+			"2013-02-02 20:00:00",
+		)
 
 	def test_update_bom_operation_rate(self):
 		operations = [
@@ -33,14 +56,14 @@
 				"operation": "Test Operation A",
 				"workstation": "_Test Workstation A",
 				"hour_rate_rent": 300,
-				"time_in_mins": 60
+				"time_in_mins": 60,
 			},
 			{
 				"operation": "Test Operation B",
 				"workstation": "_Test Workstation B",
 				"hour_rate_rent": 1000,
-				"time_in_mins": 60
-			}
+				"time_in_mins": 60,
+			},
 		]
 
 		for row in operations:
@@ -48,21 +71,13 @@
 			make_operation(row)
 
 		test_routing_operations = [
-			{
-				"operation": "Test Operation A",
-				"workstation": "_Test Workstation A",
-				"time_in_mins": 60
-			},
-			{
-				"operation": "Test Operation B",
-				"workstation": "_Test Workstation A",
-				"time_in_mins": 60
-			}
+			{"operation": "Test Operation A", "workstation": "_Test Workstation A", "time_in_mins": 60},
+			{"operation": "Test Operation B", "workstation": "_Test Workstation A", "time_in_mins": 60},
 		]
-		routing_doc = create_routing(routing_name = "Routing Test", operations=test_routing_operations)
+		routing_doc = create_routing(routing_name="Routing Test", operations=test_routing_operations)
 		bom_doc = setup_bom(item_code="_Testing Item", routing=routing_doc.name, currency="INR")
 		w1 = frappe.get_doc("Workstation", "_Test Workstation A")
-		#resets values
+		# resets values
 		w1.hour_rate_rent = 300
 		w1.hour_rate_labour = 0
 		w1.save()
@@ -72,13 +87,14 @@
 		self.assertEqual(bom_doc.operations[0].hour_rate, 300)
 		w1.hour_rate_rent = 250
 		w1.save()
-		#updating after setting new rates in workstations
+		# updating after setting new rates in workstations
 		bom_doc.update_cost()
 		bom_doc.reload()
 		self.assertEqual(w1.hour_rate, 250)
 		self.assertEqual(bom_doc.operations[0].hour_rate, 250)
 		self.assertEqual(bom_doc.operations[1].hour_rate, 250)
 
+
 def make_workstation(*args, **kwargs):
 	args = args if args else kwargs
 	if isinstance(args, tuple):
@@ -88,10 +104,7 @@
 
 	workstation_name = args.workstation_name or args.workstation
 	if not frappe.db.exists("Workstation", workstation_name):
-		doc = frappe.get_doc({
-			"doctype": "Workstation",
-			"workstation_name": workstation_name
-		})
+		doc = frappe.get_doc({"doctype": "Workstation", "workstation_name": workstation_name})
 		doc.hour_rate_rent = args.get("hour_rate_rent")
 		doc.hour_rate_labour = args.get("hour_rate_labour")
 		doc.insert()
diff --git a/erpnext/manufacturing/doctype/workstation/workstation.py b/erpnext/manufacturing/doctype/workstation/workstation.py
index 4cfd410..59e5318 100644
--- a/erpnext/manufacturing/doctype/workstation/workstation.py
+++ b/erpnext/manufacturing/doctype/workstation/workstation.py
@@ -19,14 +19,26 @@
 from erpnext.support.doctype.issue.issue import get_holidays
 
 
-class WorkstationHolidayError(frappe.ValidationError): pass
-class NotInWorkingHoursError(frappe.ValidationError): pass
-class OverlapError(frappe.ValidationError): pass
+class WorkstationHolidayError(frappe.ValidationError):
+	pass
+
+
+class NotInWorkingHoursError(frappe.ValidationError):
+	pass
+
+
+class OverlapError(frappe.ValidationError):
+	pass
+
 
 class Workstation(Document):
 	def validate(self):
-		self.hour_rate = (flt(self.hour_rate_labour) + flt(self.hour_rate_electricity) +
-			flt(self.hour_rate_consumable) + flt(self.hour_rate_rent))
+		self.hour_rate = (
+			flt(self.hour_rate_labour)
+			+ flt(self.hour_rate_electricity)
+			+ flt(self.hour_rate_consumable)
+			+ flt(self.hour_rate_rent)
+		)
 
 	def on_update(self):
 		self.validate_overlap_for_operation_timings()
@@ -35,29 +47,41 @@
 	def validate_overlap_for_operation_timings(self):
 		"""Check if there is no overlap in setting Workstation Operating Hours"""
 		for d in self.get("working_hours"):
-			existing = frappe.db.sql_list("""select idx from `tabWorkstation Working Hour`
+			existing = frappe.db.sql_list(
+				"""select idx from `tabWorkstation Working Hour`
 				where parent = %s and name != %s
 					and (
 						(start_time between %s and %s) or
 						(end_time between %s and %s) or
 						(%s between start_time and end_time))
-				""", (self.name, d.name, d.start_time, d.end_time, d.start_time, d.end_time, d.start_time))
+				""",
+				(self.name, d.name, d.start_time, d.end_time, d.start_time, d.end_time, d.start_time),
+			)
 
 			if existing:
-				frappe.throw(_("Row #{0}: Timings conflicts with row {1}").format(d.idx, comma_and(existing)), OverlapError)
+				frappe.throw(
+					_("Row #{0}: Timings conflicts with row {1}").format(d.idx, comma_and(existing)), OverlapError
+				)
 
 	def update_bom_operation(self):
-		bom_list = frappe.db.sql("""select DISTINCT parent from `tabBOM Operation`
-			where workstation = %s and parenttype = 'routing' """, self.name)
+		bom_list = frappe.db.sql(
+			"""select DISTINCT parent from `tabBOM Operation`
+			where workstation = %s and parenttype = 'routing' """,
+			self.name,
+		)
 
 		for bom_no in bom_list:
-			frappe.db.sql("""update `tabBOM Operation` set hour_rate = %s
+			frappe.db.sql(
+				"""update `tabBOM Operation` set hour_rate = %s
 				where parent = %s and workstation = %s""",
-				(self.hour_rate, bom_no[0], self.name))
+				(self.hour_rate, bom_no[0], self.name),
+			)
 
 	def validate_workstation_holiday(self, schedule_date, skip_holiday_list_check=False):
-		if not skip_holiday_list_check and (not self.holiday_list or
-			cint(frappe.db.get_single_value("Manufacturing Settings", "allow_production_on_holidays"))):
+		if not skip_holiday_list_check and (
+			not self.holiday_list
+			or cint(frappe.db.get_single_value("Manufacturing Settings", "allow_production_on_holidays"))
+		):
 			return schedule_date
 
 		if schedule_date in tuple(get_holidays(self.holiday_list)):
@@ -66,18 +90,25 @@
 
 		return schedule_date
 
+
 @frappe.whitelist()
 def get_default_holiday_list():
-	return frappe.get_cached_value('Company',  frappe.defaults.get_user_default("Company"),  "default_holiday_list")
+	return frappe.get_cached_value(
+		"Company", frappe.defaults.get_user_default("Company"), "default_holiday_list"
+	)
+
 
 def check_if_within_operating_hours(workstation, operation, from_datetime, to_datetime):
 	if from_datetime and to_datetime:
-		if not cint(frappe.db.get_value("Manufacturing Settings", "None", "allow_production_on_holidays")):
+		if not cint(
+			frappe.db.get_value("Manufacturing Settings", "None", "allow_production_on_holidays")
+		):
 			check_workstation_for_holiday(workstation, from_datetime, to_datetime)
 
 		if not cint(frappe.db.get_value("Manufacturing Settings", None, "allow_overtime")):
 			is_within_operating_hours(workstation, operation, from_datetime, to_datetime)
 
+
 def is_within_operating_hours(workstation, operation, from_datetime, to_datetime):
 	operation_length = time_diff_in_seconds(to_datetime, from_datetime)
 	workstation = frappe.get_doc("Workstation", workstation)
@@ -87,21 +118,35 @@
 
 	for working_hour in workstation.working_hours:
 		if working_hour.start_time and working_hour.end_time:
-			slot_length = (to_timedelta(working_hour.end_time or "") - to_timedelta(working_hour.start_time or "")).total_seconds()
+			slot_length = (
+				to_timedelta(working_hour.end_time or "") - to_timedelta(working_hour.start_time or "")
+			).total_seconds()
 			if slot_length >= operation_length:
 				return
 
-	frappe.throw(_("Operation {0} longer than any available working hours in workstation {1}, break down the operation into multiple operations").format(operation, workstation.name), NotInWorkingHoursError)
+	frappe.throw(
+		_(
+			"Operation {0} longer than any available working hours in workstation {1}, break down the operation into multiple operations"
+		).format(operation, workstation.name),
+		NotInWorkingHoursError,
+	)
+
 
 def check_workstation_for_holiday(workstation, from_datetime, to_datetime):
 	holiday_list = frappe.db.get_value("Workstation", workstation, "holiday_list")
 	if holiday_list and from_datetime and to_datetime:
 		applicable_holidays = []
-		for d in frappe.db.sql("""select holiday_date from `tabHoliday` where parent = %s
+		for d in frappe.db.sql(
+			"""select holiday_date from `tabHoliday` where parent = %s
 			and holiday_date between %s and %s """,
-			(holiday_list, getdate(from_datetime), getdate(to_datetime))):
-				applicable_holidays.append(formatdate(d[0]))
+			(holiday_list, getdate(from_datetime), getdate(to_datetime)),
+		):
+			applicable_holidays.append(formatdate(d[0]))
 
 		if applicable_holidays:
-			frappe.throw(_("Workstation is closed on the following dates as per Holiday List: {0}")
-				.format(holiday_list) + "\n" + "\n".join(applicable_holidays), WorkstationHolidayError)
+			frappe.throw(
+				_("Workstation is closed on the following dates as per Holiday List: {0}").format(holiday_list)
+				+ "\n"
+				+ "\n".join(applicable_holidays),
+				WorkstationHolidayError,
+			)
diff --git a/erpnext/manufacturing/doctype/workstation/workstation_dashboard.py b/erpnext/manufacturing/doctype/workstation/workstation_dashboard.py
index 1fa1494..6d02221 100644
--- a/erpnext/manufacturing/doctype/workstation/workstation_dashboard.py
+++ b/erpnext/manufacturing/doctype/workstation/workstation_dashboard.py
@@ -3,17 +3,22 @@
 
 def get_data():
 	return {
-		'fieldname': 'workstation',
-		'transactions': [
+		"fieldname": "workstation",
+		"transactions": [
+			{"label": _("Master"), "items": ["BOM", "Routing", "Operation"]},
 			{
-				'label': _('Master'),
-				'items': ['BOM', 'Routing', 'Operation']
+				"label": _("Transaction"),
+				"items": [
+					"Work Order",
+					"Job Card",
+				],
 			},
-			{
-				'label': _('Transaction'),
-				'items': ['Work Order', 'Job Card',]
-			}
 		],
-		'disable_create_buttons': ['BOM', 'Routing', 'Operation',
-			'Work Order', 'Job Card',]
+		"disable_create_buttons": [
+			"BOM",
+			"Routing",
+			"Operation",
+			"Work Order",
+			"Job Card",
+		],
 	}
diff --git a/erpnext/manufacturing/report/bom_explorer/bom_explorer.py b/erpnext/manufacturing/report/bom_explorer/bom_explorer.py
index 19a80ab..c0affd9 100644
--- a/erpnext/manufacturing/report/bom_explorer/bom_explorer.py
+++ b/erpnext/manufacturing/report/bom_explorer/bom_explorer.py
@@ -11,30 +11,37 @@
 	get_data(filters, data)
 	return columns, data
 
+
 def get_data(filters, data):
 	get_exploded_items(filters.bom, data)
 
+
 def get_exploded_items(bom, data, indent=0, qty=1):
-	exploded_items = frappe.get_all("BOM Item",
+	exploded_items = frappe.get_all(
+		"BOM Item",
 		filters={"parent": bom},
-		fields= ['qty','bom_no','qty','scrap','item_code','item_name','description','uom'])
+		fields=["qty", "bom_no", "qty", "scrap", "item_code", "item_name", "description", "uom"],
+	)
 
 	for item in exploded_items:
 		print(item.bom_no, indent)
 		item["indent"] = indent
-		data.append({
-			'item_code': item.item_code,
-			'item_name': item.item_name,
-			'indent': indent,
-			'bom_level': indent,
-			'bom': item.bom_no,
-			'qty': item.qty * qty,
-			'uom': item.uom,
-			'description': item.description,
-			'scrap': item.scrap
-		})
+		data.append(
+			{
+				"item_code": item.item_code,
+				"item_name": item.item_name,
+				"indent": indent,
+				"bom_level": indent,
+				"bom": item.bom_no,
+				"qty": item.qty * qty,
+				"uom": item.uom,
+				"description": item.description,
+				"scrap": item.scrap,
+			}
+		)
 		if item.bom_no:
-			get_exploded_items(item.bom_no, data, indent=indent+1, qty=item.qty)
+			get_exploded_items(item.bom_no, data, indent=indent + 1, qty=item.qty)
+
 
 def get_columns():
 	return [
@@ -43,49 +50,13 @@
 			"fieldtype": "Link",
 			"fieldname": "item_code",
 			"width": 300,
-			"options": "Item"
+			"options": "Item",
 		},
-		{
-			"label": "Item Name",
-			"fieldtype": "data",
-			"fieldname": "item_name",
-			"width": 100
-		},
-		{
-			"label": "BOM",
-			"fieldtype": "Link",
-			"fieldname": "bom",
-			"width": 150,
-			"options": "BOM"
-		},
-		{
-			"label": "Qty",
-			"fieldtype": "data",
-			"fieldname": "qty",
-			"width": 100
-		},
-		{
-			"label": "UOM",
-			"fieldtype": "data",
-			"fieldname": "uom",
-			"width": 100
-		},
-		{
-			"label": "BOM Level",
-			"fieldtype": "Int",
-			"fieldname": "bom_level",
-			"width": 100
-		},
-		{
-			"label": "Standard Description",
-			"fieldtype": "data",
-			"fieldname": "description",
-			"width": 150
-		},
-		{
-			"label": "Scrap",
-			"fieldtype": "data",
-			"fieldname": "scrap",
-			"width": 100
-		},
+		{"label": "Item Name", "fieldtype": "data", "fieldname": "item_name", "width": 100},
+		{"label": "BOM", "fieldtype": "Link", "fieldname": "bom", "width": 150, "options": "BOM"},
+		{"label": "Qty", "fieldtype": "data", "fieldname": "qty", "width": 100},
+		{"label": "UOM", "fieldtype": "data", "fieldname": "uom", "width": 100},
+		{"label": "BOM Level", "fieldtype": "Int", "fieldname": "bom_level", "width": 100},
+		{"label": "Standard Description", "fieldtype": "data", "fieldname": "description", "width": 150},
+		{"label": "Scrap", "fieldtype": "data", "fieldname": "scrap", "width": 100},
 	]
diff --git a/erpnext/manufacturing/report/bom_operations_time/bom_operations_time.py b/erpnext/manufacturing/report/bom_operations_time/bom_operations_time.py
index eda9eb9..92c69cf 100644
--- a/erpnext/manufacturing/report/bom_operations_time/bom_operations_time.py
+++ b/erpnext/manufacturing/report/bom_operations_time/bom_operations_time.py
@@ -11,6 +11,7 @@
 	columns = get_columns(filters)
 	return columns, data
 
+
 def get_data(filters):
 	bom_wise_data = {}
 	bom_data, report_data = [], []
@@ -24,11 +25,9 @@
 			bom_data.append(d.name)
 			row.update(d)
 		else:
-			row.update({
-				"operation": d.operation,
-				"workstation": d.workstation,
-				"time_in_mins": d.time_in_mins
-			})
+			row.update(
+				{"operation": d.operation, "workstation": d.workstation, "time_in_mins": d.time_in_mins}
+			)
 
 		# maintain BOM wise data for grouping such as:
 		# {"BOM A": [{Row1}, {Row2}], "BOM B": ...}
@@ -43,20 +42,25 @@
 
 	return report_data
 
+
 def get_filtered_data(filters):
 	bom = frappe.qb.DocType("BOM")
 	bom_ops = frappe.qb.DocType("BOM Operation")
 
 	bom_ops_query = (
 		frappe.qb.from_(bom)
-		.join(bom_ops).on(bom.name == bom_ops.parent)
+		.join(bom_ops)
+		.on(bom.name == bom_ops.parent)
 		.select(
-			bom.name, bom.item, bom.item_name, bom.uom,
-			bom_ops.operation, bom_ops.workstation, bom_ops.time_in_mins
-		).where(
-			(bom.docstatus == 1)
-			& (bom.is_active == 1)
+			bom.name,
+			bom.item,
+			bom.item_name,
+			bom.uom,
+			bom_ops.operation,
+			bom_ops.workstation,
+			bom_ops.time_in_mins,
 		)
+		.where((bom.docstatus == 1) & (bom.is_active == 1))
 	)
 
 	if filters.get("item_code"):
@@ -66,18 +70,20 @@
 		bom_ops_query = bom_ops_query.where(bom.name.isin(filters.get("bom_id")))
 
 	if filters.get("workstation"):
-		bom_ops_query = bom_ops_query.where(
-			bom_ops.workstation == filters.get("workstation")
-		)
+		bom_ops_query = bom_ops_query.where(bom_ops.workstation == filters.get("workstation"))
 
 	bom_operation_data = bom_ops_query.run(as_dict=True)
 
 	return bom_operation_data
 
+
 def get_bom_count(bom_data):
-	data = frappe.get_all("BOM Item",
+	data = frappe.get_all(
+		"BOM Item",
 		fields=["count(name) as count", "bom_no"],
-		filters= {"bom_no": ("in", bom_data)}, group_by = "bom_no")
+		filters={"bom_no": ("in", bom_data)},
+		group_by="bom_no",
+	)
 
 	bom_count = {}
 	for d in data:
@@ -85,58 +91,42 @@
 
 	return bom_count
 
+
 def get_args():
-	return frappe._dict({
-		"name": "",
-		"item": "",
-		"item_name": "",
-		"uom": ""
-	})
+	return frappe._dict({"name": "", "item": "", "item_name": "", "uom": ""})
+
 
 def get_columns(filters):
-	return [{
-		"label": _("BOM ID"),
-		"options": "BOM",
-		"fieldname": "name",
-		"fieldtype": "Link",
-		"width": 220
-	}, {
-		"label": _("Item Code"),
-		"options": "Item",
-		"fieldname": "item",
-		"fieldtype": "Link",
-		"width": 150
-	}, {
-		"label": _("Item Name"),
-		"fieldname": "item_name",
-		"fieldtype": "Data",
-		"width": 110
-	}, {
-		"label": _("UOM"),
-		"options": "UOM",
-		"fieldname": "uom",
-		"fieldtype": "Link",
-		"width": 100
-	}, {
-		"label": _("Operation"),
-		"options": "Operation",
-		"fieldname": "operation",
-		"fieldtype": "Link",
-		"width": 140
-	}, {
-		"label": _("Workstation"),
-		"options": "Workstation",
-		"fieldname": "workstation",
-		"fieldtype": "Link",
-		"width": 110
-	}, {
-		"label": _("Time (In Mins)"),
-		"fieldname": "time_in_mins",
-		"fieldtype": "Float",
-		"width": 120
-	}, {
-		"label": _("Sub-assembly BOM Count"),
-		"fieldname": "used_as_subassembly_items",
-		"fieldtype": "Int",
-		"width": 200
-	}]
+	return [
+		{"label": _("BOM ID"), "options": "BOM", "fieldname": "name", "fieldtype": "Link", "width": 220},
+		{
+			"label": _("Item Code"),
+			"options": "Item",
+			"fieldname": "item",
+			"fieldtype": "Link",
+			"width": 150,
+		},
+		{"label": _("Item Name"), "fieldname": "item_name", "fieldtype": "Data", "width": 110},
+		{"label": _("UOM"), "options": "UOM", "fieldname": "uom", "fieldtype": "Link", "width": 100},
+		{
+			"label": _("Operation"),
+			"options": "Operation",
+			"fieldname": "operation",
+			"fieldtype": "Link",
+			"width": 140,
+		},
+		{
+			"label": _("Workstation"),
+			"options": "Workstation",
+			"fieldname": "workstation",
+			"fieldtype": "Link",
+			"width": 110,
+		},
+		{"label": _("Time (In Mins)"), "fieldname": "time_in_mins", "fieldtype": "Float", "width": 120},
+		{
+			"label": _("Sub-assembly BOM Count"),
+			"fieldname": "used_as_subassembly_items",
+			"fieldtype": "Int",
+			"width": 200,
+		},
+	]
diff --git a/erpnext/manufacturing/report/bom_stock_calculated/bom_stock_calculated.py b/erpnext/manufacturing/report/bom_stock_calculated/bom_stock_calculated.py
index 2693352..933be3e 100644
--- a/erpnext/manufacturing/report/bom_stock_calculated/bom_stock_calculated.py
+++ b/erpnext/manufacturing/report/bom_stock_calculated/bom_stock_calculated.py
@@ -23,14 +23,24 @@
 		summ_data.append(get_report_data(last_pur_price, reqd_qty, row, manufacture_details))
 	return columns, summ_data
 
+
 def get_report_data(last_pur_price, reqd_qty, row, manufacture_details):
 	to_build = row.to_build if row.to_build > 0 else 0
 	diff_qty = to_build - reqd_qty
-	return [row.item_code, row.description,
-		comma_and(manufacture_details.get(row.item_code, {}).get('manufacturer', []), add_quotes=False),
-		comma_and(manufacture_details.get(row.item_code, {}).get('manufacturer_part', []), add_quotes=False),
-		row.actual_qty, str(to_build),
-		reqd_qty, diff_qty, last_pur_price]
+	return [
+		row.item_code,
+		row.description,
+		comma_and(manufacture_details.get(row.item_code, {}).get("manufacturer", []), add_quotes=False),
+		comma_and(
+			manufacture_details.get(row.item_code, {}).get("manufacturer_part", []), add_quotes=False
+		),
+		row.actual_qty,
+		str(to_build),
+		reqd_qty,
+		diff_qty,
+		last_pur_price,
+	]
+
 
 def get_columns():
 	"""return columns"""
@@ -41,12 +51,13 @@
 		_("Manufacturer Part Number") + "::250",
 		_("Qty") + ":Float:50",
 		_("Stock Qty") + ":Float:100",
-		_("Reqd Qty")+ ":Float:100",
-		_("Diff Qty")+ ":Float:100",
-		_("Last Purchase Price")+ ":Float:100",
+		_("Reqd Qty") + ":Float:100",
+		_("Diff Qty") + ":Float:100",
+		_("Last Purchase Price") + ":Float:100",
 	]
 	return columns
 
+
 def get_bom_stock(filters):
 	conditions = ""
 	bom = filters.get("bom")
@@ -59,18 +70,23 @@
 		qty_field = "stock_qty"
 
 	if filters.get("warehouse"):
-		warehouse_details = frappe.db.get_value("Warehouse", filters.get("warehouse"), ["lft", "rgt"], as_dict=1)
+		warehouse_details = frappe.db.get_value(
+			"Warehouse", filters.get("warehouse"), ["lft", "rgt"], as_dict=1
+		)
 		if warehouse_details:
-			conditions += " and exists (select name from `tabWarehouse` wh \
-				where wh.lft >= %s and wh.rgt <= %s and ledger.warehouse = wh.name)" % (warehouse_details.lft,
-				warehouse_details.rgt)
+			conditions += (
+				" and exists (select name from `tabWarehouse` wh \
+				where wh.lft >= %s and wh.rgt <= %s and ledger.warehouse = wh.name)"
+				% (warehouse_details.lft, warehouse_details.rgt)
+			)
 		else:
 			conditions += " and ledger.warehouse = %s" % frappe.db.escape(filters.get("warehouse"))
 
 	else:
 		conditions += ""
 
-	return frappe.db.sql("""
+	return frappe.db.sql(
+		"""
 			SELECT
 				bom_item.item_code,
 				bom_item.description,
@@ -86,14 +102,21 @@
 			WHERE
 				bom_item.parent = '{bom}' and bom_item.parenttype='BOM'
 
-			GROUP BY bom_item.item_code""".format(qty_field=qty_field, table=table, conditions=conditions, bom=bom), as_dict=1)
+			GROUP BY bom_item.item_code""".format(
+			qty_field=qty_field, table=table, conditions=conditions, bom=bom
+		),
+		as_dict=1,
+	)
+
 
 def get_manufacturer_records():
-	details = frappe.get_all('Item Manufacturer', fields = ["manufacturer", "manufacturer_part_no", "item_code"])
+	details = frappe.get_all(
+		"Item Manufacturer", fields=["manufacturer", "manufacturer_part_no", "item_code"]
+	)
 	manufacture_details = frappe._dict()
 	for detail in details:
-		dic = manufacture_details.setdefault(detail.get('item_code'), {})
-		dic.setdefault('manufacturer', []).append(detail.get('manufacturer'))
-		dic.setdefault('manufacturer_part', []).append(detail.get('manufacturer_part_no'))
+		dic = manufacture_details.setdefault(detail.get("item_code"), {})
+		dic.setdefault("manufacturer", []).append(detail.get("manufacturer"))
+		dic.setdefault("manufacturer_part", []).append(detail.get("manufacturer_part_no"))
 
 	return manufacture_details
diff --git a/erpnext/manufacturing/report/bom_stock_report/bom_stock_report.py b/erpnext/manufacturing/report/bom_stock_report/bom_stock_report.py
index fa94391..34e9826 100644
--- a/erpnext/manufacturing/report/bom_stock_report/bom_stock_report.py
+++ b/erpnext/manufacturing/report/bom_stock_report/bom_stock_report.py
@@ -7,7 +7,8 @@
 
 
 def execute(filters=None):
-	if not filters: filters = {}
+	if not filters:
+		filters = {}
 
 	columns = get_columns()
 
@@ -15,6 +16,7 @@
 
 	return columns, data
 
+
 def get_columns():
 	"""return columns"""
 	columns = [
@@ -29,6 +31,7 @@
 
 	return columns
 
+
 def get_bom_stock(filters):
 	conditions = ""
 	bom = filters.get("bom")
@@ -37,25 +40,30 @@
 	qty_field = "stock_qty"
 
 	qty_to_produce = filters.get("qty_to_produce", 1)
-	if  int(qty_to_produce) <= 0:
+	if int(qty_to_produce) <= 0:
 		frappe.throw(_("Quantity to Produce can not be less than Zero"))
 
 	if filters.get("show_exploded_view"):
 		table = "`tabBOM Explosion Item`"
 
 	if filters.get("warehouse"):
-		warehouse_details = frappe.db.get_value("Warehouse", filters.get("warehouse"), ["lft", "rgt"], as_dict=1)
+		warehouse_details = frappe.db.get_value(
+			"Warehouse", filters.get("warehouse"), ["lft", "rgt"], as_dict=1
+		)
 		if warehouse_details:
-			conditions += " and exists (select name from `tabWarehouse` wh \
-				where wh.lft >= %s and wh.rgt <= %s and ledger.warehouse = wh.name)" % (warehouse_details.lft,
-				warehouse_details.rgt)
+			conditions += (
+				" and exists (select name from `tabWarehouse` wh \
+				where wh.lft >= %s and wh.rgt <= %s and ledger.warehouse = wh.name)"
+				% (warehouse_details.lft, warehouse_details.rgt)
+			)
 		else:
 			conditions += " and ledger.warehouse = %s" % frappe.db.escape(filters.get("warehouse"))
 
 	else:
 		conditions += ""
 
-	return frappe.db.sql("""
+	return frappe.db.sql(
+		"""
 			SELECT
 				bom_item.item_code,
 				bom_item.description ,
@@ -74,9 +82,10 @@
 				bom_item.parent = {bom} and bom_item.parenttype='BOM'
 
 			GROUP BY bom_item.item_code""".format(
-				qty_field=qty_field,
-				table=table,
-				conditions=conditions,
-				bom=frappe.db.escape(bom),
-				qty_to_produce=qty_to_produce or 1)
-			)
+			qty_field=qty_field,
+			table=table,
+			conditions=conditions,
+			bom=frappe.db.escape(bom),
+			qty_to_produce=qty_to_produce or 1,
+		)
+	)
diff --git a/erpnext/manufacturing/report/bom_variance_report/bom_variance_report.py b/erpnext/manufacturing/report/bom_variance_report/bom_variance_report.py
index a5ae43e..3fe2198 100644
--- a/erpnext/manufacturing/report/bom_variance_report/bom_variance_report.py
+++ b/erpnext/manufacturing/report/bom_variance_report/bom_variance_report.py
@@ -12,98 +12,99 @@
 	data = get_data(filters)
 	return columns, data
 
+
 def get_columns(filters):
-	columns = [{
+	columns = [
+		{
 			"label": _("Work Order"),
 			"fieldname": "work_order",
 			"fieldtype": "Link",
 			"options": "Work Order",
-			"width": 120
-		}]
-
-	if not filters.get('bom_no'):
-		columns.extend([
-			{
-				"label": _("BOM No"),
-				"fieldname": "bom_no",
-				"fieldtype": "Link",
-				"options": "BOM",
-				"width": 180
-			}
-		])
-
-	columns.extend([
-		{
-			"label": _("Finished Good"),
-			"fieldname": "production_item",
-			"fieldtype": "Link",
-			"options": "Item",
-			"width": 120
-		},
-		{
-			"label": _("Ordered Qty"),
-			"fieldname": "qty",
-			"fieldtype": "Float",
-			"width": 120
-		},
-		{
-			"label": _("Produced Qty"),
-			"fieldname": "produced_qty",
-			"fieldtype": "Float",
-			"width": 120
-		},
-		{
-			"label": _("Raw Material"),
-			"fieldname": "raw_material_code",
-			"fieldtype": "Link",
-			"options": "Item",
-			"width": 120
-		},
-		{
-			"label": _("Required Qty"),
-			"fieldname": "required_qty",
-			"fieldtype": "Float",
-			"width": 120
-		},
-		{
-			"label": _("Consumed Qty"),
-			"fieldname": "consumed_qty",
-			"fieldtype": "Float",
-			"width": 120
+			"width": 120,
 		}
-	])
+	]
+
+	if not filters.get("bom_no"):
+		columns.extend(
+			[
+				{
+					"label": _("BOM No"),
+					"fieldname": "bom_no",
+					"fieldtype": "Link",
+					"options": "BOM",
+					"width": 180,
+				}
+			]
+		)
+
+	columns.extend(
+		[
+			{
+				"label": _("Finished Good"),
+				"fieldname": "production_item",
+				"fieldtype": "Link",
+				"options": "Item",
+				"width": 120,
+			},
+			{"label": _("Ordered Qty"), "fieldname": "qty", "fieldtype": "Float", "width": 120},
+			{"label": _("Produced Qty"), "fieldname": "produced_qty", "fieldtype": "Float", "width": 120},
+			{
+				"label": _("Raw Material"),
+				"fieldname": "raw_material_code",
+				"fieldtype": "Link",
+				"options": "Item",
+				"width": 120,
+			},
+			{"label": _("Required Qty"), "fieldname": "required_qty", "fieldtype": "Float", "width": 120},
+			{"label": _("Consumed Qty"), "fieldname": "consumed_qty", "fieldtype": "Float", "width": 120},
+		]
+	)
 
 	return columns
 
+
 def get_data(filters):
 	cond = "1=1"
 
-	if filters.get('bom_no') and not filters.get('work_order'):
-		cond += " and bom_no = '%s'" % filters.get('bom_no')
+	if filters.get("bom_no") and not filters.get("work_order"):
+		cond += " and bom_no = '%s'" % filters.get("bom_no")
 
-	if filters.get('work_order'):
-		cond += " and name = '%s'" % filters.get('work_order')
+	if filters.get("work_order"):
+		cond += " and name = '%s'" % filters.get("work_order")
 
 	results = []
-	for d in frappe.db.sql(""" select name as work_order, qty, produced_qty, production_item, bom_no
-		from `tabWork Order` where produced_qty > qty and docstatus = 1 and {0}""".format(cond), as_dict=1):
+	for d in frappe.db.sql(
+		""" select name as work_order, qty, produced_qty, production_item, bom_no
+		from `tabWork Order` where produced_qty > qty and docstatus = 1 and {0}""".format(
+			cond
+		),
+		as_dict=1,
+	):
 		results.append(d)
 
-		for data in frappe.get_all('Work Order Item', fields=["item_code as raw_material_code",
-			"required_qty", "consumed_qty"], filters={'parent': d.work_order, 'parenttype': 'Work Order'}):
+		for data in frappe.get_all(
+			"Work Order Item",
+			fields=["item_code as raw_material_code", "required_qty", "consumed_qty"],
+			filters={"parent": d.work_order, "parenttype": "Work Order"},
+		):
 			results.append(data)
 
 	return results
 
+
 @frappe.whitelist()
 @frappe.validate_and_sanitize_search_inputs
 def get_work_orders(doctype, txt, searchfield, start, page_len, filters):
 	cond = "1=1"
-	if filters.get('bom_no'):
-		cond += " and bom_no = '%s'" % filters.get('bom_no')
+	if filters.get("bom_no"):
+		cond += " and bom_no = '%s'" % filters.get("bom_no")
 
-	return frappe.db.sql("""select name from `tabWork Order`
+	return frappe.db.sql(
+		"""select name from `tabWork Order`
 		where name like %(name)s and {0} and produced_qty > qty and docstatus = 1
-		order by name limit {1}, {2}""".format(cond, start, page_len),{
-			'name': "%%%s%%" % txt
-		}, as_list=1)
+		order by name limit {1}, {2}""".format(
+			cond, start, page_len
+		),
+		{"name": "%%%s%%" % txt},
+		as_list=1,
+	)
diff --git a/erpnext/manufacturing/report/cost_of_poor_quality_report/cost_of_poor_quality_report.py b/erpnext/manufacturing/report/cost_of_poor_quality_report/cost_of_poor_quality_report.py
index 88b2117..481fe51 100644
--- a/erpnext/manufacturing/report/cost_of_poor_quality_report/cost_of_poor_quality_report.py
+++ b/erpnext/manufacturing/report/cost_of_poor_quality_report/cost_of_poor_quality_report.py
@@ -11,58 +11,77 @@
 
 def get_data(report_filters):
 	data = []
-	operations = frappe.get_all("Operation", filters = {"is_corrective_operation": 1})
+	operations = frappe.get_all("Operation", filters={"is_corrective_operation": 1})
 	if operations:
-		if report_filters.get('operation'):
-			operations = [report_filters.get('operation')]
+		if report_filters.get("operation"):
+			operations = [report_filters.get("operation")]
 		else:
 			operations = [d.name for d in operations]
 
 		job_card = frappe.qb.DocType("Job Card")
 
-		operating_cost = ((job_card.hour_rate) * (job_card.total_time_in_mins) / 60.0).as_('operating_cost')
-		item_code = (job_card.production_item).as_('item_code')
+		operating_cost = ((job_card.hour_rate) * (job_card.total_time_in_mins) / 60.0).as_(
+			"operating_cost"
+		)
+		item_code = (job_card.production_item).as_("item_code")
 
-		query = (frappe.qb
-					.from_(job_card)
-					.select(job_card.name, job_card.work_order, item_code, job_card.item_name,
-						job_card.operation, job_card.serial_no, job_card.batch_no,
-						job_card.workstation, job_card.total_time_in_mins, job_card.hour_rate,
-						operating_cost)
-					.where(
-						(job_card.docstatus == 1)
-						& (job_card.is_corrective_job_card == 1))
-					.groupby(job_card.name)
-				)
+		query = (
+			frappe.qb.from_(job_card)
+			.select(
+				job_card.name,
+				job_card.work_order,
+				item_code,
+				job_card.item_name,
+				job_card.operation,
+				job_card.serial_no,
+				job_card.batch_no,
+				job_card.workstation,
+				job_card.total_time_in_mins,
+				job_card.hour_rate,
+				operating_cost,
+			)
+			.where((job_card.docstatus == 1) & (job_card.is_corrective_job_card == 1))
+			.groupby(job_card.name)
+		)
 
 		query = append_filters(query, report_filters, operations, job_card)
 		data = query.run(as_dict=True)
 	return data
 
-def append_filters(query, report_filters, operations, job_card):
-	"""Append optional filters to query builder. """
 
-	for field in ("name", "work_order", "operation", "workstation",
-			"company", "serial_no", "batch_no", "production_item"):
+def append_filters(query, report_filters, operations, job_card):
+	"""Append optional filters to query builder."""
+
+	for field in (
+		"name",
+		"work_order",
+		"operation",
+		"workstation",
+		"company",
+		"serial_no",
+		"batch_no",
+		"production_item",
+	):
 		if report_filters.get(field):
-			if field == 'serial_no':
-				query = query.where(job_card[field].like('%{}%'.format(report_filters.get(field))))
-			elif field == 'operation':
+			if field == "serial_no":
+				query = query.where(job_card[field].like("%{}%".format(report_filters.get(field))))
+			elif field == "operation":
 				query = query.where(job_card[field].isin(operations))
 			else:
 				query = query.where(job_card[field] == report_filters.get(field))
 
-	if report_filters.get('from_date') or report_filters.get('to_date'):
+	if report_filters.get("from_date") or report_filters.get("to_date"):
 		job_card_time_log = frappe.qb.DocType("Job Card Time Log")
 
 		query = query.join(job_card_time_log).on(job_card.name == job_card_time_log.parent)
-		if report_filters.get('from_date'):
-			query = query.where(job_card_time_log.from_time >= report_filters.get('from_date'))
-		if report_filters.get('to_date'):
-			query = query.where(job_card_time_log.to_time <= report_filters.get('to_date'))
+		if report_filters.get("from_date"):
+			query = query.where(job_card_time_log.from_time >= report_filters.get("from_date"))
+		if report_filters.get("to_date"):
+			query = query.where(job_card_time_log.to_time <= report_filters.get("to_date"))
 
 	return query
 
+
 def get_columns(filters):
 	return [
 		{
@@ -70,64 +89,49 @@
 			"fieldtype": "Link",
 			"fieldname": "name",
 			"options": "Job Card",
-			"width": "120"
+			"width": "120",
 		},
 		{
 			"label": _("Work Order"),
 			"fieldtype": "Link",
 			"fieldname": "work_order",
 			"options": "Work Order",
-			"width": "100"
+			"width": "100",
 		},
 		{
 			"label": _("Item Code"),
 			"fieldtype": "Link",
 			"fieldname": "item_code",
 			"options": "Item",
-			"width": "100"
+			"width": "100",
 		},
-		{
-			"label": _("Item Name"),
-			"fieldtype": "Data",
-			"fieldname": "item_name",
-			"width": "100"
-		},
+		{"label": _("Item Name"), "fieldtype": "Data", "fieldname": "item_name", "width": "100"},
 		{
 			"label": _("Operation"),
 			"fieldtype": "Link",
 			"fieldname": "operation",
 			"options": "Operation",
-			"width": "100"
+			"width": "100",
 		},
-		{
-			"label": _("Serial No"),
-			"fieldtype": "Data",
-			"fieldname": "serial_no",
-			"width": "100"
-		},
-		{
-			"label": _("Batch No"),
-			"fieldtype": "Data",
-			"fieldname": "batch_no",
-			"width": "100"
-		},
+		{"label": _("Serial No"), "fieldtype": "Data", "fieldname": "serial_no", "width": "100"},
+		{"label": _("Batch No"), "fieldtype": "Data", "fieldname": "batch_no", "width": "100"},
 		{
 			"label": _("Workstation"),
 			"fieldtype": "Link",
 			"fieldname": "workstation",
 			"options": "Workstation",
-			"width": "100"
+			"width": "100",
 		},
 		{
 			"label": _("Operating Cost"),
 			"fieldtype": "Currency",
 			"fieldname": "operating_cost",
-			"width": "150"
+			"width": "150",
 		},
 		{
 			"label": _("Total Time (in Mins)"),
 			"fieldtype": "Float",
 			"fieldname": "total_time_in_mins",
-			"width": "150"
-		}
+			"width": "150",
+		},
 	]
diff --git a/erpnext/manufacturing/report/downtime_analysis/downtime_analysis.py b/erpnext/manufacturing/report/downtime_analysis/downtime_analysis.py
index 2c515d1..80a1564 100644
--- a/erpnext/manufacturing/report/downtime_analysis/downtime_analysis.py
+++ b/erpnext/manufacturing/report/downtime_analysis/downtime_analysis.py
@@ -14,10 +14,20 @@
 	chart_data = get_chart_data(data, filters)
 	return columns, data, None, chart_data
 
+
 def get_data(filters):
 	query_filters = {}
 
-	fields = ["name", "workstation", "operator", "from_time", "to_time", "downtime", "stop_reason", "remarks"]
+	fields = [
+		"name",
+		"workstation",
+		"operator",
+		"from_time",
+		"to_time",
+		"downtime",
+		"stop_reason",
+		"remarks",
+	]
 
 	query_filters["from_time"] = (">=", filters.get("from_date"))
 	query_filters["to_time"] = ("<=", filters.get("to_date"))
@@ -25,13 +35,14 @@
 	if filters.get("workstation"):
 		query_filters["workstation"] = filters.get("workstation")
 
-	data = frappe.get_all("Downtime Entry", fields= fields, filters=query_filters) or []
+	data = frappe.get_all("Downtime Entry", fields=fields, filters=query_filters) or []
 	for d in data:
 		if d.downtime:
 			d.downtime = d.downtime / 60
 
 	return data
 
+
 def get_chart_data(data, columns):
 	labels = sorted(list(set([d.workstation for d in data])))
 
@@ -47,17 +58,13 @@
 		datasets.append(workstation_wise_data.get(label, 0))
 
 	chart = {
-		"data": {
-			"labels": labels,
-			"datasets": [
-				{"name": "Machine Downtime", "values": datasets}
-			]
-		},
-		"type": "bar"
+		"data": {"labels": labels, "datasets": [{"name": "Machine Downtime", "values": datasets}]},
+		"type": "bar",
 	}
 
 	return chart
 
+
 def get_columns(filters):
 	return [
 		{
@@ -65,50 +72,25 @@
 			"fieldname": "name",
 			"fieldtype": "Link",
 			"options": "Downtime Entry",
-			"width": 100
+			"width": 100,
 		},
 		{
 			"label": _("Machine"),
 			"fieldname": "workstation",
 			"fieldtype": "Link",
 			"options": "Workstation",
-			"width": 100
+			"width": 100,
 		},
 		{
 			"label": _("Operator"),
 			"fieldname": "operator",
 			"fieldtype": "Link",
 			"options": "Employee",
-			"width": 130
+			"width": 130,
 		},
-		{
-			"label": _("From Time"),
-			"fieldname": "from_time",
-			"fieldtype": "Datetime",
-			"width": 160
-		},
-		{
-			"label": _("To Time"),
-			"fieldname": "to_time",
-			"fieldtype": "Datetime",
-			"width": 160
-		},
-		{
-			"label": _("Downtime (In Hours)"),
-			"fieldname": "downtime",
-			"fieldtype": "Float",
-			"width": 150
-		},
-		{
-			"label": _("Stop Reason"),
-			"fieldname": "stop_reason",
-			"fieldtype": "Data",
-			"width": 220
-		},
-		{
-			"label": _("Remarks"),
-			"fieldname": "remarks",
-			"fieldtype": "Text",
-			"width": 100
-		}
+		{"label": _("From Time"), "fieldname": "from_time", "fieldtype": "Datetime", "width": 160},
+		{"label": _("To Time"), "fieldname": "to_time", "fieldtype": "Datetime", "width": 160},
+		{"label": _("Downtime (In Hours)"), "fieldname": "downtime", "fieldtype": "Float", "width": 150},
+		{"label": _("Stop Reason"), "fieldname": "stop_reason", "fieldtype": "Data", "width": 220},
+		{"label": _("Remarks"), "fieldname": "remarks", "fieldtype": "Text", "width": 100},
 	]
diff --git a/erpnext/manufacturing/report/exponential_smoothing_forecasting/exponential_smoothing_forecasting.py b/erpnext/manufacturing/report/exponential_smoothing_forecasting/exponential_smoothing_forecasting.py
index 26b3359..7500744 100644
--- a/erpnext/manufacturing/report/exponential_smoothing_forecasting/exponential_smoothing_forecasting.py
+++ b/erpnext/manufacturing/report/exponential_smoothing_forecasting/exponential_smoothing_forecasting.py
@@ -14,6 +14,7 @@
 def execute(filters=None):
 	return ForecastingReport(filters).execute_report()
 
+
 class ExponentialSmoothingForecast(object):
 	def forecast_future_data(self):
 		for key, value in self.period_wise_data.items():
@@ -26,24 +27,22 @@
 
 				elif forecast_data:
 					previous_period_data = forecast_data[-1]
-					value[forecast_key] = (previous_period_data[1] +
-						flt(self.filters.smoothing_constant) * (
-							flt(previous_period_data[0]) - flt(previous_period_data[1])
-						)
+					value[forecast_key] = previous_period_data[1] + flt(self.filters.smoothing_constant) * (
+						flt(previous_period_data[0]) - flt(previous_period_data[1])
 					)
 
 				if value.get(forecast_key):
 					# will be use to forecaset next period
 					forecast_data.append([value.get(period.key), value.get(forecast_key)])
 
+
 class ForecastingReport(ExponentialSmoothingForecast):
 	def __init__(self, filters=None):
 		self.filters = frappe._dict(filters or {})
 		self.data = []
 		self.doctype = self.filters.based_on_document
 		self.child_doctype = self.doctype + " Item"
-		self.based_on_field = ("qty"
-			if self.filters.based_on_field == "Qty" else "amount")
+		self.based_on_field = "qty" if self.filters.based_on_field == "Qty" else "amount"
 		self.fieldtype = "Float" if self.based_on_field == "qty" else "Currency"
 		self.company_currency = erpnext.get_company_currency(self.filters.company)
 
@@ -63,8 +62,15 @@
 		self.period_wise_data = {}
 
 		from_date = add_years(self.filters.from_date, cint(self.filters.no_of_years) * -1)
-		self.period_list = get_period_list(from_date, self.filters.to_date,
-			from_date, self.filters.to_date, "Date Range", self.filters.periodicity, ignore_fiscal_year=True)
+		self.period_list = get_period_list(
+			from_date,
+			self.filters.to_date,
+			from_date,
+			self.filters.to_date,
+			"Date Range",
+			self.filters.periodicity,
+			ignore_fiscal_year=True,
+		)
 
 		order_data = self.get_data_for_forecast() or []
 
@@ -76,8 +82,10 @@
 			period_data = self.period_wise_data[key]
 			for period in self.period_list:
 				# check if posting date is within the period
-				if (entry.posting_date >= period.from_date and entry.posting_date <= period.to_date):
-					period_data[period.key] = period_data.get(period.key, 0.0) + flt(entry.get(self.based_on_field))
+				if entry.posting_date >= period.from_date and entry.posting_date <= period.to_date:
+					period_data[period.key] = period_data.get(period.key, 0.0) + flt(
+						entry.get(self.based_on_field)
+					)
 
 		for key, value in self.period_wise_data.items():
 			list_of_period_value = [value.get(p.key, 0) for p in self.period_list]
@@ -90,12 +98,12 @@
 	def get_data_for_forecast(self):
 		cond = ""
 		if self.filters.item_code:
-			cond = " AND soi.item_code = %s" %(frappe.db.escape(self.filters.item_code))
+			cond = " AND soi.item_code = %s" % (frappe.db.escape(self.filters.item_code))
 
 		warehouses = []
 		if self.filters.warehouse:
 			warehouses = get_child_warehouses(self.filters.warehouse)
-			cond += " AND soi.warehouse in ({})".format(','.join(['%s'] * len(warehouses)))
+			cond += " AND soi.warehouse in ({})".format(",".join(["%s"] * len(warehouses)))
 
 		input_data = [self.filters.from_date, self.filters.company]
 		if warehouses:
@@ -103,7 +111,8 @@
 
 		date_field = "posting_date" if self.doctype == "Delivery Note" else "transaction_date"
 
-		return frappe.db.sql("""
+		return frappe.db.sql(
+			"""
 			SELECT
 				so.{date_field} as posting_date, soi.item_code, soi.warehouse,
 				soi.item_name, soi.stock_qty as qty, soi.base_amount as amount
@@ -112,23 +121,27 @@
 			WHERE
 				so.docstatus = 1 AND so.name = soi.parent AND
 				so.{date_field} < %s AND so.company = %s {cond}
-		""".format(doc=self.doctype, child_doc=self.child_doctype, date_field=date_field, cond=cond),
-			tuple(input_data), as_dict=1)
+		""".format(
+				doc=self.doctype, child_doc=self.child_doctype, date_field=date_field, cond=cond
+			),
+			tuple(input_data),
+			as_dict=1,
+		)
 
 	def prepare_final_data(self):
 		self.data = []
 
-		if not self.period_wise_data: return
+		if not self.period_wise_data:
+			return
 
 		for key in self.period_wise_data:
 			self.data.append(self.period_wise_data.get(key))
 
 	def add_total(self):
-		if not self.data: return
+		if not self.data:
+			return
 
-		total_row = {
-			"item_code": _(frappe.bold("Total Quantity"))
-		}
+		total_row = {"item_code": _(frappe.bold("Total Quantity"))}
 
 		for value in self.data:
 			for period in self.period_list:
@@ -145,43 +158,52 @@
 		self.data.append(total_row)
 
 	def get_columns(self):
-		columns = [{
-			"label": _("Item Code"),
-			"options": "Item",
-			"fieldname": "item_code",
-			"fieldtype": "Link",
-			"width": 130
-		}, {
-			"label": _("Warehouse"),
-			"options": "Warehouse",
-			"fieldname": "warehouse",
-			"fieldtype": "Link",
-			"width": 130
-		}]
+		columns = [
+			{
+				"label": _("Item Code"),
+				"options": "Item",
+				"fieldname": "item_code",
+				"fieldtype": "Link",
+				"width": 130,
+			},
+			{
+				"label": _("Warehouse"),
+				"options": "Warehouse",
+				"fieldname": "warehouse",
+				"fieldtype": "Link",
+				"width": 130,
+			},
+		]
 
-		width = 180 if self.filters.periodicity in ['Yearly', "Half-Yearly", "Quarterly"] else 100
+		width = 180 if self.filters.periodicity in ["Yearly", "Half-Yearly", "Quarterly"] else 100
 		for period in self.period_list:
-			if (self.filters.periodicity in ['Yearly', "Half-Yearly", "Quarterly"]
-				or period.from_date >= getdate(self.filters.from_date)):
+			if self.filters.periodicity in [
+				"Yearly",
+				"Half-Yearly",
+				"Quarterly",
+			] or period.from_date >= getdate(self.filters.from_date):
 
 				forecast_key = period.key
 				label = _(period.label)
 				if period.from_date >= getdate(self.filters.from_date):
-					forecast_key = 'forecast_' + period.key
+					forecast_key = "forecast_" + period.key
 					label = _(period.label) + " " + _("(Forecast)")
 
-				columns.append({
-					"label": label,
-					"fieldname": forecast_key,
-					"fieldtype": self.fieldtype,
-					"width": width,
-					"default": 0.0
-				})
+				columns.append(
+					{
+						"label": label,
+						"fieldname": forecast_key,
+						"fieldtype": self.fieldtype,
+						"width": width,
+						"default": 0.0,
+					}
+				)
 
 		return columns
 
 	def get_chart_data(self):
-		if not self.data: return
+		if not self.data:
+			return
 
 		labels = []
 		self.total_demand = []
@@ -206,40 +228,35 @@
 			"data": {
 				"labels": labels,
 				"datasets": [
-					{
-						"name": "Demand",
-						"values": self.total_demand
-					},
-					{
-						"name": "Forecast",
-						"values": self.total_forecast
-					}
-				]
+					{"name": "Demand", "values": self.total_demand},
+					{"name": "Forecast", "values": self.total_forecast},
+				],
 			},
-			"type": "line"
+			"type": "line",
 		}
 
 	def get_summary_data(self):
-		if not self.data: return
+		if not self.data:
+			return
 
 		return [
 			{
 				"value": sum(self.total_demand),
 				"label": _("Total Demand (Past Data)"),
 				"currency": self.company_currency,
-				"datatype": self.fieldtype
+				"datatype": self.fieldtype,
 			},
 			{
 				"value": sum(self.total_history_forecast),
 				"label": _("Total Forecast (Past Data)"),
 				"currency": self.company_currency,
-				"datatype": self.fieldtype
+				"datatype": self.fieldtype,
 			},
 			{
 				"value": sum(self.total_future_forecast),
 				"indicator": "Green",
 				"label": _("Total Forecast (Future Data)"),
 				"currency": self.company_currency,
-				"datatype": self.fieldtype
-			}
+				"datatype": self.fieldtype,
+			},
 		]
diff --git a/erpnext/manufacturing/report/job_card_summary/job_card_summary.py b/erpnext/manufacturing/report/job_card_summary/job_card_summary.py
index 4046bb1..a86c7a4 100644
--- a/erpnext/manufacturing/report/job_card_summary/job_card_summary.py
+++ b/erpnext/manufacturing/report/job_card_summary/job_card_summary.py
@@ -16,23 +16,34 @@
 	chart_data = get_chart_data(data, filters)
 	return columns, data, None, chart_data
 
+
 def get_data(filters):
 	query_filters = {
 		"docstatus": ("<", 2),
-		"posting_date": ("between", [filters.from_date, filters.to_date])
+		"posting_date": ("between", [filters.from_date, filters.to_date]),
 	}
 
-	fields = ["name", "status", "work_order", "production_item", "item_name", "posting_date",
-		"total_completed_qty", "workstation", "operation", "total_time_in_mins"]
+	fields = [
+		"name",
+		"status",
+		"work_order",
+		"production_item",
+		"item_name",
+		"posting_date",
+		"total_completed_qty",
+		"workstation",
+		"operation",
+		"total_time_in_mins",
+	]
 
 	for field in ["work_order", "workstation", "operation", "company"]:
 		if filters.get(field):
 			query_filters[field] = ("in", filters.get(field))
 
-	data = frappe.get_all("Job Card",
-		fields= fields, filters=query_filters)
+	data = frappe.get_all("Job Card", fields=fields, filters=query_filters)
 
-	if not data: return []
+	if not data:
+		return []
 
 	job_cards = [d.name for d in data]
 
@@ -42,9 +53,12 @@
 	}
 
 	job_card_time_details = {}
-	for job_card_data in frappe.get_all("Job Card Time Log",
+	for job_card_data in frappe.get_all(
+		"Job Card Time Log",
 		fields=["min(from_time) as from_time", "max(to_time) as to_time", "parent"],
-		filters=job_card_time_filter, group_by="parent"):
+		filters=job_card_time_filter,
+		group_by="parent",
+	):
 		job_card_time_details[job_card_data.parent] = job_card_data
 
 	res = []
@@ -60,6 +74,7 @@
 
 	return res
 
+
 def get_chart_data(job_card_details, filters):
 	labels, periodic_data = prepare_chart_data(job_card_details, filters)
 
@@ -73,23 +88,15 @@
 	datasets.append({"name": "Open", "values": open_job_cards})
 	datasets.append({"name": "Completed", "values": completed})
 
-	chart = {
-		"data": {
-			'labels': labels,
-			'datasets': datasets
-		},
-		"type": "bar"
-	}
+	chart = {"data": {"labels": labels, "datasets": datasets}, "type": "bar"}
 
 	return chart
 
+
 def prepare_chart_data(job_card_details, filters):
 	labels = []
 
-	periodic_data = {
-		"Open": {},
-		"Completed": {}
-	}
+	periodic_data = {"Open": {}, "Completed": {}}
 
 	filters.range = "Monthly"
 
@@ -110,6 +117,7 @@
 
 	return labels, periodic_data
 
+
 def get_columns(filters):
 	columns = [
 		{
@@ -117,84 +125,62 @@
 			"fieldname": "name",
 			"fieldtype": "Link",
 			"options": "Job Card",
-			"width": 100
+			"width": 100,
 		},
-		{
-			"label": _("Posting Date"),
-			"fieldname": "posting_date",
-			"fieldtype": "Date",
-			"width": 100
-		},
+		{"label": _("Posting Date"), "fieldname": "posting_date", "fieldtype": "Date", "width": 100},
 	]
 
 	if not filters.get("status"):
 		columns.append(
-			{
-				"label": _("Status"),
-				"fieldname": "status",
-				"width": 100
-			},
+			{"label": _("Status"), "fieldname": "status", "width": 100},
 		)
 
-	columns.extend([
-		{
-			"label": _("Work Order"),
-			"fieldname": "work_order",
-			"fieldtype": "Link",
-			"options": "Work Order",
-			"width": 100
-		},
-		{
-			"label": _("Production Item"),
-			"fieldname": "production_item",
-			"fieldtype": "Link",
-			"options": "Item",
-			"width": 110
-		},
-		{
-			"label": _("Item Name"),
-			"fieldname": "item_name",
-			"fieldtype": "Data",
-			"width": 100
-		},
-		{
-			"label": _("Workstation"),
-			"fieldname": "workstation",
-			"fieldtype": "Link",
-			"options": "Workstation",
-			"width": 110
-		},
-		{
-			"label": _("Operation"),
-			"fieldname": "operation",
-			"fieldtype": "Link",
-			"options": "Operation",
-			"width": 110
-		},
-		{
-			"label": _("Total Completed Qty"),
-			"fieldname": "total_completed_qty",
-			"fieldtype": "Float",
-			"width": 120
-		},
-		{
-			"label": _("From Time"),
-			"fieldname": "from_time",
-			"fieldtype": "Datetime",
-			"width": 120
-		},
-		{
-			"label": _("To Time"),
-			"fieldname": "to_time",
-			"fieldtype": "Datetime",
-			"width": 120
-		},
-		{
-			"label": _("Time Required (In Mins)"),
-			"fieldname": "total_time_in_mins",
-			"fieldtype": "Float",
-			"width": 100
-		}
-	])
+	columns.extend(
+		[
+			{
+				"label": _("Work Order"),
+				"fieldname": "work_order",
+				"fieldtype": "Link",
+				"options": "Work Order",
+				"width": 100,
+			},
+			{
+				"label": _("Production Item"),
+				"fieldname": "production_item",
+				"fieldtype": "Link",
+				"options": "Item",
+				"width": 110,
+			},
+			{"label": _("Item Name"), "fieldname": "item_name", "fieldtype": "Data", "width": 100},
+			{
+				"label": _("Workstation"),
+				"fieldname": "workstation",
+				"fieldtype": "Link",
+				"options": "Workstation",
+				"width": 110,
+			},
+			{
+				"label": _("Operation"),
+				"fieldname": "operation",
+				"fieldtype": "Link",
+				"options": "Operation",
+				"width": 110,
+			},
+			{
+				"label": _("Total Completed Qty"),
+				"fieldname": "total_completed_qty",
+				"fieldtype": "Float",
+				"width": 120,
+			},
+			{"label": _("From Time"), "fieldname": "from_time", "fieldtype": "Datetime", "width": 120},
+			{"label": _("To Time"), "fieldname": "to_time", "fieldtype": "Datetime", "width": 120},
+			{
+				"label": _("Time Required (In Mins)"),
+				"fieldname": "total_time_in_mins",
+				"fieldtype": "Float",
+				"width": 100,
+			},
+		]
+	)
 
 	return columns
diff --git a/erpnext/manufacturing/report/process_loss_report/process_loss_report.py b/erpnext/manufacturing/report/process_loss_report/process_loss_report.py
index 9b544da..b10e643 100644
--- a/erpnext/manufacturing/report/process_loss_report/process_loss_report.py
+++ b/erpnext/manufacturing/report/process_loss_report/process_loss_report.py
@@ -12,87 +12,71 @@
 Columns = List[Dict[str, str]]
 QueryArgs = Dict[str, str]
 
+
 def execute(filters: Filters) -> Tuple[Columns, Data]:
 	columns = get_columns()
 	data = get_data(filters)
 	return columns, data
 
+
 def get_data(filters: Filters) -> Data:
 	query_args = get_query_args(filters)
 	data = run_query(query_args)
 	update_data_with_total_pl_value(data)
 	return data
 
+
 def get_columns() -> Columns:
 	return [
 		{
-			'label': _('Work Order'),
-			'fieldname': 'name',
-			'fieldtype': 'Link',
-			'options': 'Work Order',
-			'width': '200'
+			"label": _("Work Order"),
+			"fieldname": "name",
+			"fieldtype": "Link",
+			"options": "Work Order",
+			"width": "200",
 		},
 		{
-			'label': _('Item'),
-			'fieldname': 'production_item',
-			'fieldtype': 'Link',
-			'options': 'Item',
-			'width': '100'
+			"label": _("Item"),
+			"fieldname": "production_item",
+			"fieldtype": "Link",
+			"options": "Item",
+			"width": "100",
 		},
+		{"label": _("Status"), "fieldname": "status", "fieldtype": "Data", "width": "100"},
 		{
-			'label': _('Status'),
-			'fieldname': 'status',
-			'fieldtype': 'Data',
-			'width': '100'
+			"label": _("Manufactured Qty"),
+			"fieldname": "produced_qty",
+			"fieldtype": "Float",
+			"width": "150",
 		},
+		{"label": _("Loss Qty"), "fieldname": "process_loss_qty", "fieldtype": "Float", "width": "150"},
 		{
-			'label': _('Manufactured Qty'),
-			'fieldname': 'produced_qty',
-			'fieldtype': 'Float',
-			'width': '150'
+			"label": _("Actual Manufactured Qty"),
+			"fieldname": "actual_produced_qty",
+			"fieldtype": "Float",
+			"width": "150",
 		},
+		{"label": _("Loss Value"), "fieldname": "total_pl_value", "fieldtype": "Float", "width": "150"},
+		{"label": _("FG Value"), "fieldname": "total_fg_value", "fieldtype": "Float", "width": "150"},
 		{
-			'label': _('Loss Qty'),
-			'fieldname': 'process_loss_qty',
-			'fieldtype': 'Float',
-			'width': '150'
+			"label": _("Raw Material Value"),
+			"fieldname": "total_rm_value",
+			"fieldtype": "Float",
+			"width": "150",
 		},
-		{
-			'label': _('Actual Manufactured Qty'),
-			'fieldname': 'actual_produced_qty',
-			'fieldtype': 'Float',
-			'width': '150'
-		},
-		{
-			'label': _('Loss Value'),
-			'fieldname': 'total_pl_value',
-			'fieldtype': 'Float',
-			'width': '150'
-		},
-		{
-			'label': _('FG Value'),
-			'fieldname': 'total_fg_value',
-			'fieldtype': 'Float',
-			'width': '150'
-		},
-		{
-			'label': _('Raw Material Value'),
-			'fieldname': 'total_rm_value',
-			'fieldtype': 'Float',
-			'width': '150'
-		}
 	]
 
+
 def get_query_args(filters: Filters) -> QueryArgs:
 	query_args = {}
 	query_args.update(filters)
-	query_args.update(
-		get_filter_conditions(filters)
-	)
+	query_args.update(get_filter_conditions(filters))
 	return query_args
 
+
 def run_query(query_args: QueryArgs) -> Data:
-	return frappe.db.sql("""
+	return frappe.db.sql(
+		"""
 		SELECT
 			wo.name, wo.status, wo.production_item, wo.qty,
 			wo.produced_qty, wo.process_loss_qty,
@@ -111,23 +95,26 @@
 			{work_order_filter}
 		GROUP BY
 			se.work_order
-	""".format(**query_args), query_args, as_dict=1)
+	""".format(
+			**query_args
+		),
+		query_args,
+		as_dict=1,
+	)
+
 
 def update_data_with_total_pl_value(data: Data) -> None:
 	for row in data:
-		value_per_unit_fg = row['total_fg_value'] / row['actual_produced_qty']
-		row['total_pl_value'] = row['process_loss_qty'] * value_per_unit_fg
+		value_per_unit_fg = row["total_fg_value"] / row["actual_produced_qty"]
+		row["total_pl_value"] = row["process_loss_qty"] * value_per_unit_fg
+
 
 def get_filter_conditions(filters: Filters) -> QueryArgs:
 	filter_conditions = dict(item_filter="", work_order_filter="")
 	if "item" in filters:
 		production_item = filters.get("item")
-		filter_conditions.update(
-			{"item_filter": f"AND wo.production_item='{production_item}'"}
-		)
+		filter_conditions.update({"item_filter": f"AND wo.production_item='{production_item}'"})
 	if "work_order" in filters:
 		work_order_name = filters.get("work_order")
-		filter_conditions.update(
-			{"work_order_filter": f"AND wo.name='{work_order_name}'"}
-		)
+		filter_conditions.update({"work_order_filter": f"AND wo.name='{work_order_name}'"})
 	return filter_conditions
diff --git a/erpnext/manufacturing/report/production_analytics/production_analytics.py b/erpnext/manufacturing/report/production_analytics/production_analytics.py
index d4743d3..12b5d19 100644
--- a/erpnext/manufacturing/report/production_analytics/production_analytics.py
+++ b/erpnext/manufacturing/report/production_analytics/production_analytics.py
@@ -12,16 +12,11 @@
 def execute(filters=None):
 	columns = get_columns(filters)
 	data, chart = get_data(filters, columns)
-	return columns, data, None , chart
+	return columns, data, None, chart
+
 
 def get_columns(filters):
-	columns =[
-		{
-			"label": _("Status"),
-			"fieldname": "Status",
-			"fieldtype": "Data",
-			"width": 140
-		}]
+	columns = [{"label": _("Status"), "fieldname": "Status", "fieldtype": "Data", "width": 140}]
 
 	ranges = get_period_date_ranges(filters)
 
@@ -29,22 +24,20 @@
 
 		period = get_period(end_date, filters)
 
-		columns.append({
-			"label": _(period),
-			"fieldname": scrub(period),
-			"fieldtype": "Float",
-			"width": 120
-		})
+		columns.append(
+			{"label": _(period), "fieldname": scrub(period), "fieldtype": "Float", "width": 120}
+		)
 
 	return columns
 
+
 def get_periodic_data(filters, entry):
 	periodic_data = {
 		"All Work Orders": {},
 		"Not Started": {},
 		"Overdue": {},
 		"Pending": {},
-		"Completed": {}
+		"Completed": {},
 	}
 
 	ranges = get_period_date_ranges(filters)
@@ -52,34 +45,37 @@
 	for from_date, end_date in ranges:
 		period = get_period(end_date, filters)
 		for d in entry:
-			if getdate(d.creation) <= getdate(from_date) or getdate(d.creation) <= getdate(end_date) :
+			if getdate(d.creation) <= getdate(from_date) or getdate(d.creation) <= getdate(end_date):
 				periodic_data = update_periodic_data(periodic_data, "All Work Orders", period)
-				if d.status == 'Completed':
-					if getdate(d.actual_end_date) < getdate(from_date) or getdate(d.modified) < getdate(from_date):
+				if d.status == "Completed":
+					if getdate(d.actual_end_date) < getdate(from_date) or getdate(d.modified) < getdate(
+						from_date
+					):
 						periodic_data = update_periodic_data(periodic_data, "Completed", period)
-					elif getdate(d.actual_start_date) < getdate(from_date) :
+					elif getdate(d.actual_start_date) < getdate(from_date):
 						periodic_data = update_periodic_data(periodic_data, "Pending", period)
-					elif getdate(d.planned_start_date) < getdate(from_date) :
+					elif getdate(d.planned_start_date) < getdate(from_date):
 						periodic_data = update_periodic_data(periodic_data, "Overdue", period)
 					else:
 						periodic_data = update_periodic_data(periodic_data, "Not Started", period)
 
-				elif d.status == 'In Process':
-					if getdate(d.actual_start_date) < getdate(from_date) :
+				elif d.status == "In Process":
+					if getdate(d.actual_start_date) < getdate(from_date):
 						periodic_data = update_periodic_data(periodic_data, "Pending", period)
-					elif getdate(d.planned_start_date) < getdate(from_date) :
+					elif getdate(d.planned_start_date) < getdate(from_date):
 						periodic_data = update_periodic_data(periodic_data, "Overdue", period)
 					else:
 						periodic_data = update_periodic_data(periodic_data, "Not Started", period)
 
-				elif d.status == 'Not Started':
-					if getdate(d.planned_start_date) < getdate(from_date) :
+				elif d.status == "Not Started":
+					if getdate(d.planned_start_date) < getdate(from_date):
 						periodic_data = update_periodic_data(periodic_data, "Overdue", period)
 					else:
 						periodic_data = update_periodic_data(periodic_data, "Not Started", period)
 
 	return periodic_data
 
+
 def update_periodic_data(periodic_data, status, period):
 	if periodic_data.get(status).get(period):
 		periodic_data[status][period] += 1
@@ -88,22 +84,33 @@
 
 	return periodic_data
 
+
 def get_data(filters, columns):
 	data = []
-	entry = frappe.get_all("Work Order",
-		fields=["creation", "modified", "actual_start_date", "actual_end_date", "planned_start_date", "planned_end_date", "status"],
-		filters={"docstatus": 1, "company": filters["company"] })
+	entry = frappe.get_all(
+		"Work Order",
+		fields=[
+			"creation",
+			"modified",
+			"actual_start_date",
+			"actual_end_date",
+			"planned_start_date",
+			"planned_end_date",
+			"status",
+		],
+		filters={"docstatus": 1, "company": filters["company"]},
+	)
 
-	periodic_data = get_periodic_data(filters,entry)
+	periodic_data = get_periodic_data(filters, entry)
 
 	labels = ["All Work Orders", "Not Started", "Overdue", "Pending", "Completed"]
-	chart_data = get_chart_data(periodic_data,columns)
+	chart_data = get_chart_data(periodic_data, columns)
 	ranges = get_period_date_ranges(filters)
 
 	for label in labels:
 		work = {}
 		work["Status"] = label
-		for dummy,end_date in ranges:
+		for dummy, end_date in ranges:
 			period = get_period(end_date, filters)
 			if periodic_data.get(label).get(period):
 				work[scrub(period)] = periodic_data.get(label).get(period)
@@ -113,10 +120,11 @@
 
 	return data, chart_data
 
+
 def get_chart_data(periodic_data, columns):
 	labels = [d.get("label") for d in columns[1:]]
 
-	all_data, not_start, overdue, pending, completed = [], [], [] , [], []
+	all_data, not_start, overdue, pending, completed = [], [], [], [], []
 	datasets = []
 
 	for d in labels:
@@ -126,18 +134,13 @@
 		pending.append(periodic_data.get("Pending").get(d))
 		completed.append(periodic_data.get("Completed").get(d))
 
-	datasets.append({'name':'All Work Orders', 'values': all_data})
-	datasets.append({'name':'Not Started', 'values': not_start})
-	datasets.append({'name':'Overdue', 'values': overdue})
-	datasets.append({'name':'Pending', 'values': pending})
-	datasets.append({'name':'Completed', 'values': completed})
+	datasets.append({"name": "All Work Orders", "values": all_data})
+	datasets.append({"name": "Not Started", "values": not_start})
+	datasets.append({"name": "Overdue", "values": overdue})
+	datasets.append({"name": "Pending", "values": pending})
+	datasets.append({"name": "Completed", "values": completed})
 
-	chart = {
-		"data": {
-			'labels': labels,
-			'datasets': datasets
-		}
-	}
+	chart = {"data": {"labels": labels, "datasets": datasets}}
 	chart["type"] = "line"
 
 	return chart
diff --git a/erpnext/manufacturing/report/production_plan_summary/production_plan_summary.py b/erpnext/manufacturing/report/production_plan_summary/production_plan_summary.py
index aaa2314..17f7f5e 100644
--- a/erpnext/manufacturing/report/production_plan_summary/production_plan_summary.py
+++ b/erpnext/manufacturing/report/production_plan_summary/production_plan_summary.py
@@ -13,6 +13,7 @@
 
 	return columns, data
 
+
 def get_data(filters):
 	data = []
 
@@ -23,6 +24,7 @@
 
 	return data
 
+
 def get_production_plan_item_details(filters, data, order_details):
 	itemwise_indent = {}
 
@@ -30,77 +32,85 @@
 	for row in production_plan_doc.po_items:
 		work_order = frappe.get_value(
 			"Work Order",
-			{
-				"production_plan_item": row.name,
-				"bom_no": row.bom_no,
-				"production_item": row.item_code
-			},
-			"name"
+			{"production_plan_item": row.name, "bom_no": row.bom_no, "production_item": row.item_code},
+			"name",
 		)
 
 		if row.item_code not in itemwise_indent:
 			itemwise_indent.setdefault(row.item_code, {})
 
-		data.append({
-			"indent": 0,
-			"item_code": row.item_code,
-			"item_name": frappe.get_cached_value("Item", row.item_code, "item_name"),
-			"qty": row.planned_qty,
-			"document_type": "Work Order",
-			"document_name": work_order or "",
-			"bom_level": 0,
-			"produced_qty": order_details.get((work_order, row.item_code), {}).get("produced_qty", 0),
-			"pending_qty": flt(row.planned_qty) - flt(order_details.get((work_order, row.item_code), {}).get("produced_qty", 0))
-		})
+		data.append(
+			{
+				"indent": 0,
+				"item_code": row.item_code,
+				"item_name": frappe.get_cached_value("Item", row.item_code, "item_name"),
+				"qty": row.planned_qty,
+				"document_type": "Work Order",
+				"document_name": work_order or "",
+				"bom_level": 0,
+				"produced_qty": order_details.get((work_order, row.item_code), {}).get("produced_qty", 0),
+				"pending_qty": flt(row.planned_qty)
+				- flt(order_details.get((work_order, row.item_code), {}).get("produced_qty", 0)),
+			}
+		)
 
-		get_production_plan_sub_assembly_item_details(filters, row, production_plan_doc, data, order_details)
+		get_production_plan_sub_assembly_item_details(
+			filters, row, production_plan_doc, data, order_details
+		)
 
-def get_production_plan_sub_assembly_item_details(filters, row, production_plan_doc, data, order_details):
+
+def get_production_plan_sub_assembly_item_details(
+	filters, row, production_plan_doc, data, order_details
+):
 	for item in production_plan_doc.sub_assembly_items:
 		if row.name == item.production_plan_item:
-			subcontracted_item = (item.type_of_manufacturing == 'Subcontract')
+			subcontracted_item = item.type_of_manufacturing == "Subcontract"
 
 			if subcontracted_item:
 				docname = frappe.get_value(
 					"Purchase Order Item",
-					{
-						"production_plan_sub_assembly_item": item.name,
-						"docstatus": ("<", 2)
-					},
-					"parent"
+					{"production_plan_sub_assembly_item": item.name, "docstatus": ("<", 2)},
+					"parent",
 				)
 			else:
 				docname = frappe.get_value(
-					"Work Order",
-					{
-						"production_plan_sub_assembly_item": item.name,
-						"docstatus": ("<", 2)
-					},
-					"name"
+					"Work Order", {"production_plan_sub_assembly_item": item.name, "docstatus": ("<", 2)}, "name"
 				)
 
-			data.append({
-				"indent": 1,
-				"item_code": item.production_item,
-				"item_name": item.item_name,
-				"qty": item.qty,
-				"document_type": "Work Order" if not subcontracted_item else "Purchase Order",
-				"document_name": docname or "",
-				"bom_level": item.bom_level,
-				"produced_qty": order_details.get((docname, item.production_item), {}).get("produced_qty", 0),
-				"pending_qty": flt(item.qty) - flt(order_details.get((docname, item.production_item), {}).get("produced_qty", 0))
-			})
+			data.append(
+				{
+					"indent": 1,
+					"item_code": item.production_item,
+					"item_name": item.item_name,
+					"qty": item.qty,
+					"document_type": "Work Order" if not subcontracted_item else "Purchase Order",
+					"document_name": docname or "",
+					"bom_level": item.bom_level,
+					"produced_qty": order_details.get((docname, item.production_item), {}).get("produced_qty", 0),
+					"pending_qty": flt(item.qty)
+					- flt(order_details.get((docname, item.production_item), {}).get("produced_qty", 0)),
+				}
+			)
+
 
 def get_work_order_details(filters, order_details):
-	for row in frappe.get_all("Work Order", filters = {"production_plan": filters.get("production_plan")},
-		fields=["name", "produced_qty", "production_plan", "production_item"]):
+	for row in frappe.get_all(
+		"Work Order",
+		filters={"production_plan": filters.get("production_plan")},
+		fields=["name", "produced_qty", "production_plan", "production_item"],
+	):
 		order_details.setdefault((row.name, row.production_item), row)
 
+
 def get_purchase_order_details(filters, order_details):
-	for row in frappe.get_all("Purchase Order Item", filters = {"production_plan": filters.get("production_plan")},
-		fields=["parent", "received_qty as produced_qty", "item_code"]):
+	for row in frappe.get_all(
+		"Purchase Order Item",
+		filters={"production_plan": filters.get("production_plan")},
+		fields=["parent", "received_qty as produced_qty", "item_code"],
+	):
 		order_details.setdefault((row.parent, row.item_code), row)
 
+
 def get_column(filters):
 	return [
 		{
@@ -108,49 +118,24 @@
 			"fieldtype": "Link",
 			"fieldname": "item_code",
 			"width": 300,
-			"options": "Item"
+			"options": "Item",
 		},
-		{
-			"label": "Item Name",
-			"fieldtype": "data",
-			"fieldname": "item_name",
-			"width": 100
-		},
+		{"label": "Item Name", "fieldtype": "data", "fieldname": "item_name", "width": 100},
 		{
 			"label": "Document Type",
 			"fieldtype": "Link",
 			"fieldname": "document_type",
 			"width": 150,
-			"options": "DocType"
+			"options": "DocType",
 		},
 		{
 			"label": "Document Name",
 			"fieldtype": "Dynamic Link",
 			"fieldname": "document_name",
-			"width": 150
+			"width": 150,
 		},
-		{
-			"label": "BOM Level",
-			"fieldtype": "Int",
-			"fieldname": "bom_level",
-			"width": 100
-		},
-		{
-			"label": "Order Qty",
-			"fieldtype": "Float",
-			"fieldname": "qty",
-			"width": 120
-		},
-		{
-			"label": "Received Qty",
-			"fieldtype": "Float",
-			"fieldname": "produced_qty",
-			"width": 160
-		},
-		{
-			"label": "Pending Qty",
-			"fieldtype": "Float",
-			"fieldname": "pending_qty",
-			"width": 110
-		}
+		{"label": "BOM Level", "fieldtype": "Int", "fieldname": "bom_level", "width": 100},
+		{"label": "Order Qty", "fieldtype": "Float", "fieldname": "qty", "width": 120},
+		{"label": "Received Qty", "fieldtype": "Float", "fieldname": "produced_qty", "width": 160},
+		{"label": "Pending Qty", "fieldtype": "Float", "fieldname": "pending_qty", "width": 110},
 	]
diff --git a/erpnext/manufacturing/report/production_planning_report/production_planning_report.py b/erpnext/manufacturing/report/production_planning_report/production_planning_report.py
index e1e7225..1404888 100644
--- a/erpnext/manufacturing/report/production_planning_report/production_planning_report.py
+++ b/erpnext/manufacturing/report/production_planning_report/production_planning_report.py
@@ -15,38 +15,36 @@
 			stock_qty as qty_to_manufacture, `tabSales Order Item`.parent as name, bom_no, warehouse,
 			`tabSales Order Item`.delivery_date, `tabSales Order`.base_grand_total """,
 		"filters": """`tabSales Order Item`.docstatus = 1 and stock_qty > produced_qty
-			and `tabSales Order`.per_delivered < 100.0"""
+			and `tabSales Order`.per_delivered < 100.0""",
 	},
 	"Material Request": {
 		"fields": """ item_code as production_item, item_name as production_item_name, stock_uom,
 			stock_qty as qty_to_manufacture, `tabMaterial Request Item`.parent as name, bom_no, warehouse,
 			`tabMaterial Request Item`.schedule_date """,
 		"filters": """`tabMaterial Request`.docstatus = 1 and `tabMaterial Request`.per_ordered < 100
-			and `tabMaterial Request`.material_request_type = 'Manufacture' """
+			and `tabMaterial Request`.material_request_type = 'Manufacture' """,
 	},
 	"Work Order": {
 		"fields": """ production_item, item_name as production_item_name, planned_start_date,
 			stock_uom, qty as qty_to_manufacture, name, bom_no, fg_warehouse as warehouse """,
-		"filters": "docstatus = 1 and status not in ('Completed', 'Stopped')"
+		"filters": "docstatus = 1 and status not in ('Completed', 'Stopped')",
 	},
 }
 
 order_mapper = {
 	"Sales Order": {
 		"Delivery Date": "`tabSales Order Item`.delivery_date asc",
-		"Total Amount": "`tabSales Order`.base_grand_total desc"
+		"Total Amount": "`tabSales Order`.base_grand_total desc",
 	},
-	"Material Request": {
-		"Required Date": "`tabMaterial Request Item`.schedule_date asc"
-	},
-	"Work Order": {
-		"Planned Start Date": "planned_start_date asc"
-	}
+	"Material Request": {"Required Date": "`tabMaterial Request Item`.schedule_date asc"},
+	"Work Order": {"Planned Start Date": "planned_start_date asc"},
 }
 
+
 def execute(filters=None):
 	return ProductionPlanReport(filters).execute_report()
 
+
 class ProductionPlanReport(object):
 	def __init__(self, filters=None):
 		self.filters = frappe._dict(filters or {})
@@ -65,46 +63,64 @@
 		return self.columns, self.data
 
 	def get_open_orders(self):
-		doctype = ("`tabWork Order`" if self.filters.based_on == "Work Order"
-			else "`tab{doc}`, `tab{doc} Item`".format(doc=self.filters.based_on))
+		doctype = (
+			"`tabWork Order`"
+			if self.filters.based_on == "Work Order"
+			else "`tab{doc}`, `tab{doc} Item`".format(doc=self.filters.based_on)
+		)
 
 		filters = mapper.get(self.filters.based_on)["filters"]
 		filters = self.prepare_other_conditions(filters, self.filters.based_on)
 		order_by = " ORDER BY %s" % (order_mapper[self.filters.based_on][self.filters.order_by])
 
-		self.orders = frappe.db.sql(""" SELECT {fields} from {doctype}
+		self.orders = frappe.db.sql(
+			""" SELECT {fields} from {doctype}
 			WHERE {filters} {order_by}""".format(
-				doctype = doctype,
-				filters = filters,
-				order_by = order_by,
-				fields = mapper.get(self.filters.based_on)["fields"]
-			), tuple(self.filters.docnames), as_dict=1)
+				doctype=doctype,
+				filters=filters,
+				order_by=order_by,
+				fields=mapper.get(self.filters.based_on)["fields"],
+			),
+			tuple(self.filters.docnames),
+			as_dict=1,
+		)
 
 	def prepare_other_conditions(self, filters, doctype):
 		if self.filters.docnames:
 			field = "name" if doctype == "Work Order" else "`tab{} Item`.parent".format(doctype)
-			filters += " and %s in (%s)" % (field, ','.join(['%s'] * len(self.filters.docnames)))
+			filters += " and %s in (%s)" % (field, ",".join(["%s"] * len(self.filters.docnames)))
 
 		if doctype != "Work Order":
 			filters += " and `tab{doc}`.name = `tab{doc} Item`.parent".format(doc=doctype)
 
 		if self.filters.company:
-			filters += " and `tab%s`.company = %s" %(doctype, frappe.db.escape(self.filters.company))
+			filters += " and `tab%s`.company = %s" % (doctype, frappe.db.escape(self.filters.company))
 
 		return filters
 
 	def get_raw_materials(self):
-		if not self.orders: return
+		if not self.orders:
+			return
 		self.warehouses = [d.warehouse for d in self.orders]
 		self.item_codes = [d.production_item for d in self.orders]
 
 		if self.filters.based_on == "Work Order":
 			work_orders = [d.name for d in self.orders]
 
-			raw_materials = frappe.get_all("Work Order Item",
-				fields=["parent", "item_code", "item_name as raw_material_name",
-					"source_warehouse as warehouse", "required_qty"],
-				filters = {"docstatus": 1, "parent": ("in", work_orders), "source_warehouse": ("!=", "")}) or []
+			raw_materials = (
+				frappe.get_all(
+					"Work Order Item",
+					fields=[
+						"parent",
+						"item_code",
+						"item_name as raw_material_name",
+						"source_warehouse as warehouse",
+						"required_qty",
+					],
+					filters={"docstatus": 1, "parent": ("in", work_orders), "source_warehouse": ("!=", "")},
+				)
+				or []
+			)
 			self.warehouses.extend([d.source_warehouse for d in raw_materials])
 
 		else:
@@ -118,21 +134,32 @@
 
 				bom_nos.append(bom_no)
 
-			bom_doctype = ("BOM Explosion Item"
-				if self.filters.include_subassembly_raw_materials else "BOM Item")
+			bom_doctype = (
+				"BOM Explosion Item" if self.filters.include_subassembly_raw_materials else "BOM Item"
+			)
 
-			qty_field = ("qty_consumed_per_unit"
-				if self.filters.include_subassembly_raw_materials else "(bom_item.qty / bom.quantity)")
+			qty_field = (
+				"qty_consumed_per_unit"
+				if self.filters.include_subassembly_raw_materials
+				else "(bom_item.qty / bom.quantity)"
+			)
 
-			raw_materials = frappe.db.sql(""" SELECT bom_item.parent, bom_item.item_code,
+			raw_materials = frappe.db.sql(
+				""" SELECT bom_item.parent, bom_item.item_code,
 					bom_item.item_name as raw_material_name, {0} as required_qty_per_unit
 				FROM
 					`tabBOM` as bom, `tab{1}` as bom_item
 				WHERE
 					bom_item.parent in ({2}) and bom_item.parent = bom.name and bom.docstatus = 1
-			""".format(qty_field, bom_doctype, ','.join(["%s"] * len(bom_nos))), tuple(bom_nos), as_dict=1)
+			""".format(
+					qty_field, bom_doctype, ",".join(["%s"] * len(bom_nos))
+				),
+				tuple(bom_nos),
+				as_dict=1,
+			)
 
-		if not raw_materials: return
+		if not raw_materials:
+			return
 
 		self.item_codes.extend([d.item_code for d in raw_materials])
 
@@ -144,15 +171,20 @@
 			rows.append(d)
 
 	def get_item_details(self):
-		if not (self.orders and self.item_codes): return
+		if not (self.orders and self.item_codes):
+			return
 
 		self.item_details = {}
-		for d in frappe.get_all("Item Default", fields = ["parent", "default_warehouse"],
-			filters = {"company": self.filters.company, "parent": ("in", self.item_codes)}):
+		for d in frappe.get_all(
+			"Item Default",
+			fields=["parent", "default_warehouse"],
+			filters={"company": self.filters.company, "parent": ("in", self.item_codes)},
+		):
 			self.item_details[d.parent] = d
 
 	def get_bin_details(self):
-		if not (self.orders and self.raw_materials_dict): return
+		if not (self.orders and self.raw_materials_dict):
+			return
 
 		self.bin_details = {}
 		self.mrp_warehouses = []
@@ -160,48 +192,55 @@
 			self.mrp_warehouses.extend(get_child_warehouses(self.filters.raw_material_warehouse))
 			self.warehouses.extend(self.mrp_warehouses)
 
-		for d in frappe.get_all("Bin",
+		for d in frappe.get_all(
+			"Bin",
 			fields=["warehouse", "item_code", "actual_qty", "ordered_qty", "projected_qty"],
-			filters = {"item_code": ("in", self.item_codes), "warehouse": ("in", self.warehouses)}):
+			filters={"item_code": ("in", self.item_codes), "warehouse": ("in", self.warehouses)},
+		):
 			key = (d.item_code, d.warehouse)
 			if key not in self.bin_details:
 				self.bin_details.setdefault(key, d)
 
 	def get_purchase_details(self):
-		if not (self.orders and self.raw_materials_dict): return
+		if not (self.orders and self.raw_materials_dict):
+			return
 
 		self.purchase_details = {}
 
-		purchased_items = frappe.get_all("Purchase Order Item",
+		purchased_items = frappe.get_all(
+			"Purchase Order Item",
 			fields=["item_code", "min(schedule_date) as arrival_date", "qty as arrival_qty", "warehouse"],
 			filters={
 				"item_code": ("in", self.item_codes),
 				"warehouse": ("in", self.warehouses),
 				"docstatus": 1,
 			},
-			group_by = "item_code, warehouse")
+			group_by="item_code, warehouse",
+		)
 		for d in purchased_items:
 			key = (d.item_code, d.warehouse)
 			if key not in self.purchase_details:
 				self.purchase_details.setdefault(key, d)
 
 	def prepare_data(self):
-		if not self.orders: return
+		if not self.orders:
+			return
 
 		for d in self.orders:
 			key = d.name if self.filters.based_on == "Work Order" else d.bom_no
 
-			if not self.raw_materials_dict.get(key): continue
+			if not self.raw_materials_dict.get(key):
+				continue
 
 			bin_data = self.bin_details.get((d.production_item, d.warehouse)) or {}
-			d.update({
-				"for_warehouse": d.warehouse,
-				"available_qty": 0
-			})
+			d.update({"for_warehouse": d.warehouse, "available_qty": 0})
 
 			if bin_data and bin_data.get("actual_qty") > 0 and d.qty_to_manufacture:
-				d.available_qty = (bin_data.get("actual_qty")
-					if (d.qty_to_manufacture > bin_data.get("actual_qty")) else d.qty_to_manufacture)
+				d.available_qty = (
+					bin_data.get("actual_qty")
+					if (d.qty_to_manufacture > bin_data.get("actual_qty"))
+					else d.qty_to_manufacture
+				)
 
 				bin_data["actual_qty"] -= d.available_qty
 
@@ -232,8 +271,9 @@
 			d.remaining_qty = d.required_qty
 			self.pick_materials_from_warehouses(d, data, warehouses)
 
-			if (d.remaining_qty and self.filters.raw_material_warehouse
-				and d.remaining_qty != d.required_qty):
+			if (
+				d.remaining_qty and self.filters.raw_material_warehouse and d.remaining_qty != d.required_qty
+			):
 				row = self.get_args()
 				d.warehouse = self.filters.raw_material_warehouse
 				d.required_qty = d.remaining_qty
@@ -243,7 +283,8 @@
 
 	def pick_materials_from_warehouses(self, args, order_data, warehouses):
 		for index, warehouse in enumerate(warehouses):
-			if not args.remaining_qty: return
+			if not args.remaining_qty:
+				return
 
 			row = self.get_args()
 
@@ -255,14 +296,18 @@
 
 			args.allotted_qty = 0
 			if bin_data and bin_data.get("actual_qty") > 0:
-				args.allotted_qty = (bin_data.get("actual_qty")
-					if (args.required_qty > bin_data.get("actual_qty")) else args.required_qty)
+				args.allotted_qty = (
+					bin_data.get("actual_qty")
+					if (args.required_qty > bin_data.get("actual_qty"))
+					else args.required_qty
+				)
 
 				args.remaining_qty -= args.allotted_qty
 				bin_data["actual_qty"] -= args.allotted_qty
 
-			if ((self.mrp_warehouses and (args.allotted_qty or index == len(warehouses) - 1))
-				or not self.mrp_warehouses):
+			if (
+				self.mrp_warehouses and (args.allotted_qty or index == len(warehouses) - 1)
+			) or not self.mrp_warehouses:
 				if not self.index:
 					row.update(order_data)
 					self.index += 1
@@ -275,52 +320,45 @@
 				self.data.append(row)
 
 	def get_args(self):
-		return frappe._dict({
-			"work_order": "",
-			"sales_order": "",
-			"production_item": "",
-			"production_item_name": "",
-			"qty_to_manufacture": "",
-			"produced_qty": ""
-		})
+		return frappe._dict(
+			{
+				"work_order": "",
+				"sales_order": "",
+				"production_item": "",
+				"production_item_name": "",
+				"qty_to_manufacture": "",
+				"produced_qty": "",
+			}
+		)
 
 	def get_columns(self):
 		based_on = self.filters.based_on
 
-		self.columns = [{
-			"label": _("ID"),
-			"options": based_on,
-			"fieldname": "name",
-			"fieldtype": "Link",
-			"width": 100
-		}, {
-			"label": _("Item Code"),
-			"fieldname": "production_item",
-			"fieldtype": "Link",
-			"options": "Item",
-			"width": 120
-		}, {
-			"label": _("Item Name"),
-			"fieldname": "production_item_name",
-			"fieldtype": "Data",
-			"width": 130
-		}, {
-			"label": _("Warehouse"),
-			"options": "Warehouse",
-			"fieldname": "for_warehouse",
-			"fieldtype": "Link",
-			"width": 100
-		}, {
-			"label": _("Order Qty"),
-			"fieldname": "qty_to_manufacture",
-			"fieldtype": "Float",
-			"width": 80
-		}, {
-			"label": _("Available"),
-			"fieldname": "available_qty",
-			"fieldtype": "Float",
-			"width": 80
-		}]
+		self.columns = [
+			{"label": _("ID"), "options": based_on, "fieldname": "name", "fieldtype": "Link", "width": 100},
+			{
+				"label": _("Item Code"),
+				"fieldname": "production_item",
+				"fieldtype": "Link",
+				"options": "Item",
+				"width": 120,
+			},
+			{
+				"label": _("Item Name"),
+				"fieldname": "production_item_name",
+				"fieldtype": "Data",
+				"width": 130,
+			},
+			{
+				"label": _("Warehouse"),
+				"options": "Warehouse",
+				"fieldname": "for_warehouse",
+				"fieldtype": "Link",
+				"width": 100,
+			},
+			{"label": _("Order Qty"), "fieldname": "qty_to_manufacture", "fieldtype": "Float", "width": 80},
+			{"label": _("Available"), "fieldname": "available_qty", "fieldtype": "Float", "width": 80},
+		]
 
 		fieldname, fieldtype = "delivery_date", "Date"
 		if self.filters.based_on == "Sales Order" and self.filters.order_by == "Total Amount":
@@ -330,48 +368,50 @@
 		elif self.filters.based_on == "Work Order":
 			fieldname = "planned_start_date"
 
-		self.columns.append({
-			"label": _(self.filters.order_by),
-			"fieldname": fieldname,
-			"fieldtype": fieldtype,
-			"width": 100
-		})
+		self.columns.append(
+			{
+				"label": _(self.filters.order_by),
+				"fieldname": fieldname,
+				"fieldtype": fieldtype,
+				"width": 100,
+			}
+		)
 
-		self.columns.extend([{
-			"label": _("Raw Material Code"),
-			"fieldname": "item_code",
-			"fieldtype": "Link",
-			"options": "Item",
-			"width": 120
-		}, {
-			"label": _("Raw Material Name"),
-			"fieldname": "raw_material_name",
-			"fieldtype": "Data",
-			"width": 130
-		}, {
-			"label": _("Warehouse"),
-			"options": "Warehouse",
-			"fieldname": "warehouse",
-			"fieldtype": "Link",
-			"width": 110
-		}, {
-			"label": _("Required Qty"),
-			"fieldname": "required_qty",
-			"fieldtype": "Float",
-			"width": 100
-		}, {
-			"label": _("Allotted Qty"),
-			"fieldname": "allotted_qty",
-			"fieldtype": "Float",
-			"width": 100
-		}, {
-			"label": _("Expected Arrival Date"),
-			"fieldname": "arrival_date",
-			"fieldtype": "Date",
-			"width": 160
-		}, {
-			"label": _("Arrival Quantity"),
-			"fieldname": "arrival_qty",
-			"fieldtype": "Float",
-			"width": 140
-		}])
+		self.columns.extend(
+			[
+				{
+					"label": _("Raw Material Code"),
+					"fieldname": "item_code",
+					"fieldtype": "Link",
+					"options": "Item",
+					"width": 120,
+				},
+				{
+					"label": _("Raw Material Name"),
+					"fieldname": "raw_material_name",
+					"fieldtype": "Data",
+					"width": 130,
+				},
+				{
+					"label": _("Warehouse"),
+					"options": "Warehouse",
+					"fieldname": "warehouse",
+					"fieldtype": "Link",
+					"width": 110,
+				},
+				{"label": _("Required Qty"), "fieldname": "required_qty", "fieldtype": "Float", "width": 100},
+				{"label": _("Allotted Qty"), "fieldname": "allotted_qty", "fieldtype": "Float", "width": 100},
+				{
+					"label": _("Expected Arrival Date"),
+					"fieldname": "arrival_date",
+					"fieldtype": "Date",
+					"width": 160,
+				},
+				{
+					"label": _("Arrival Quantity"),
+					"fieldname": "arrival_qty",
+					"fieldtype": "Float",
+					"width": 140,
+				},
+			]
+		)
diff --git a/erpnext/manufacturing/report/quality_inspection_summary/quality_inspection_summary.py b/erpnext/manufacturing/report/quality_inspection_summary/quality_inspection_summary.py
index a0c4a43..0a79130 100644
--- a/erpnext/manufacturing/report/quality_inspection_summary/quality_inspection_summary.py
+++ b/erpnext/manufacturing/report/quality_inspection_summary/quality_inspection_summary.py
@@ -11,13 +11,24 @@
 	data = get_data(filters)
 	columns = get_columns(filters)
 	chart_data = get_chart_data(data, filters)
-	return columns, data , None, chart_data
+	return columns, data, None, chart_data
+
 
 def get_data(filters):
 	query_filters = {"docstatus": ("<", 2)}
 
-	fields = ["name", "status", "report_date", "item_code", "item_name", "sample_size",
-		"inspection_type", "reference_type", "reference_name", "inspected_by"]
+	fields = [
+		"name",
+		"status",
+		"report_date",
+		"item_code",
+		"item_name",
+		"sample_size",
+		"inspection_type",
+		"reference_type",
+		"reference_name",
+		"inspected_by",
+	]
 
 	for field in ["status", "item_code", "status", "inspected_by"]:
 		if filters.get(field):
@@ -26,36 +37,33 @@
 	query_filters["report_date"] = (">=", filters.get("from_date"))
 	query_filters["report_date"] = ("<=", filters.get("to_date"))
 
-	return frappe.get_all("Quality Inspection",
-		fields= fields, filters=query_filters, order_by="report_date asc")
+	return frappe.get_all(
+		"Quality Inspection", fields=fields, filters=query_filters, order_by="report_date asc"
+	)
+
 
 def get_chart_data(periodic_data, columns):
 	labels = ["Rejected", "Accepted"]
 
-	status_wise_data = {
-		"Accepted": 0,
-		"Rejected": 0
-	}
+	status_wise_data = {"Accepted": 0, "Rejected": 0}
 
 	datasets = []
 
 	for d in periodic_data:
 		status_wise_data[d.status] += 1
 
-	datasets.append({'name':'Qty Wise Chart',
-		'values': [status_wise_data.get("Rejected"), status_wise_data.get("Accepted")]})
+	datasets.append(
+		{
+			"name": "Qty Wise Chart",
+			"values": [status_wise_data.get("Rejected"), status_wise_data.get("Accepted")],
+		}
+	)
 
-	chart = {
-		"data": {
-			'labels': labels,
-			'datasets': datasets
-		},
-		"type": "donut",
-		"height": 300
-	}
+	chart = {"data": {"labels": labels, "datasets": datasets}, "type": "donut", "height": 300}
 
 	return chart
 
+
 def get_columns(filters):
 	columns = [
 		{
@@ -63,71 +71,49 @@
 			"fieldname": "name",
 			"fieldtype": "Link",
 			"options": "Work Order",
-			"width": 100
+			"width": 100,
 		},
-		{
-			"label": _("Report Date"),
-			"fieldname": "report_date",
-			"fieldtype": "Date",
-			"width": 150
-		}
+		{"label": _("Report Date"), "fieldname": "report_date", "fieldtype": "Date", "width": 150},
 	]
 
 	if not filters.get("status"):
 		columns.append(
-			{
-				"label": _("Status"),
-				"fieldname": "status",
-				"width": 100
-			},
+			{"label": _("Status"), "fieldname": "status", "width": 100},
 		)
 
-	columns.extend([
-		{
-			"label": _("Item Code"),
-			"fieldname": "item_code",
-			"fieldtype": "Link",
-			"options": "Item",
-			"width": 130
-		},
-		{
-			"label": _("Item Name"),
-			"fieldname": "item_name",
-			"fieldtype": "Data",
-			"width": 130
-		},
-		{
-			"label": _("Sample Size"),
-			"fieldname": "sample_size",
-			"fieldtype": "Float",
-			"width": 110
-		},
-		{
-			"label": _("Inspection Type"),
-			"fieldname": "inspection_type",
-			"fieldtype": "Data",
-			"width": 110
-		},
-		{
-			"label": _("Document Type"),
-			"fieldname": "reference_type",
-			"fieldtype": "Data",
-			"width": 90
-		},
-		{
-			"label": _("Document Name"),
-			"fieldname": "reference_name",
-			"fieldtype": "Dynamic Link",
-			"options": "reference_type",
-			"width": 150
-		},
-		{
-			"label": _("Inspected By"),
-			"fieldname": "inspected_by",
-			"fieldtype": "Link",
-			"options": "User",
-			"width": 150
-		}
-	])
+	columns.extend(
+		[
+			{
+				"label": _("Item Code"),
+				"fieldname": "item_code",
+				"fieldtype": "Link",
+				"options": "Item",
+				"width": 130,
+			},
+			{"label": _("Item Name"), "fieldname": "item_name", "fieldtype": "Data", "width": 130},
+			{"label": _("Sample Size"), "fieldname": "sample_size", "fieldtype": "Float", "width": 110},
+			{
+				"label": _("Inspection Type"),
+				"fieldname": "inspection_type",
+				"fieldtype": "Data",
+				"width": 110,
+			},
+			{"label": _("Document Type"), "fieldname": "reference_type", "fieldtype": "Data", "width": 90},
+			{
+				"label": _("Document Name"),
+				"fieldname": "reference_name",
+				"fieldtype": "Dynamic Link",
+				"options": "reference_type",
+				"width": 150,
+			},
+			{
+				"label": _("Inspected By"),
+				"fieldname": "inspected_by",
+				"fieldtype": "Link",
+				"options": "User",
+				"width": 150,
+			},
+		]
+	)
 
 	return columns
diff --git a/erpnext/manufacturing/report/work_order_consumed_materials/work_order_consumed_materials.py b/erpnext/manufacturing/report/work_order_consumed_materials/work_order_consumed_materials.py
index 0528348..8158bc9 100644
--- a/erpnext/manufacturing/report/work_order_consumed_materials/work_order_consumed_materials.py
+++ b/erpnext/manufacturing/report/work_order_consumed_materials/work_order_consumed_materials.py
@@ -12,12 +12,13 @@
 
 	return columns, data
 
+
 def get_data(report_filters):
 	fields = get_fields()
 	filters = get_filter_condition(report_filters)
 
 	wo_items = {}
-	for d in frappe.get_all("Work Order", filters = filters, fields=fields):
+	for d in frappe.get_all("Work Order", filters=filters, fields=fields):
 		d.extra_consumed_qty = 0.0
 		if d.consumed_qty and d.consumed_qty > d.required_qty:
 			d.extra_consumed_qty = d.consumed_qty - d.required_qty
@@ -29,7 +30,7 @@
 	for key, wo_data in wo_items.items():
 		for index, row in enumerate(wo_data):
 			if index != 0:
-				#If one work order has multiple raw materials then show parent data in the first row only
+				# If one work order has multiple raw materials then show parent data in the first row only
 				for field in ["name", "status", "production_item", "qty", "produced_qty"]:
 					row[field] = ""
 
@@ -37,17 +38,28 @@
 
 	return data
 
+
 def get_fields():
-	return ["`tabWork Order Item`.`parent`", "`tabWork Order Item`.`item_code` as raw_material_item_code",
-		"`tabWork Order Item`.`item_name` as raw_material_name", "`tabWork Order Item`.`required_qty`",
-		"`tabWork Order Item`.`transferred_qty`", "`tabWork Order Item`.`consumed_qty`", "`tabWork Order`.`status`",
-		"`tabWork Order`.`name`", "`tabWork Order`.`production_item`", "`tabWork Order`.`qty`",
-		"`tabWork Order`.`produced_qty`"]
+	return [
+		"`tabWork Order Item`.`parent`",
+		"`tabWork Order Item`.`item_code` as raw_material_item_code",
+		"`tabWork Order Item`.`item_name` as raw_material_name",
+		"`tabWork Order Item`.`required_qty`",
+		"`tabWork Order Item`.`transferred_qty`",
+		"`tabWork Order Item`.`consumed_qty`",
+		"`tabWork Order`.`status`",
+		"`tabWork Order`.`name`",
+		"`tabWork Order`.`production_item`",
+		"`tabWork Order`.`qty`",
+		"`tabWork Order`.`produced_qty`",
+	]
+
 
 def get_filter_condition(report_filters):
 	filters = {
-		"docstatus": 1, "status": ("in", ["In Process", "Completed", "Stopped"]),
-		"creation": ("between", [report_filters.from_date, report_filters.to_date])
+		"docstatus": 1,
+		"status": ("in", ["In Process", "Completed", "Stopped"]),
+		"creation": ("between", [report_filters.from_date, report_filters.to_date]),
 	}
 
 	for field in ["name", "production_item", "company", "status"]:
@@ -58,6 +70,7 @@
 
 	return filters
 
+
 def get_columns():
 	return [
 		{
@@ -65,67 +78,38 @@
 			"fieldname": "name",
 			"fieldtype": "Link",
 			"options": "Work Order",
-			"width": 80
+			"width": 80,
 		},
-		{
-			"label": _("Status"),
-			"fieldname": "status",
-			"fieldtype": "Data",
-			"width": 80
-		},
+		{"label": _("Status"), "fieldname": "status", "fieldtype": "Data", "width": 80},
 		{
 			"label": _("Production Item"),
 			"fieldname": "production_item",
 			"fieldtype": "Link",
 			"options": "Item",
-			"width": 130
+			"width": 130,
 		},
-		{
-			"label": _("Qty to Produce"),
-			"fieldname": "qty",
-			"fieldtype": "Float",
-			"width": 120
-		},
-		{
-			"label": _("Produced Qty"),
-			"fieldname": "produced_qty",
-			"fieldtype": "Float",
-			"width": 110
-		},
+		{"label": _("Qty to Produce"), "fieldname": "qty", "fieldtype": "Float", "width": 120},
+		{"label": _("Produced Qty"), "fieldname": "produced_qty", "fieldtype": "Float", "width": 110},
 		{
 			"label": _("Raw Material Item"),
 			"fieldname": "raw_material_item_code",
 			"fieldtype": "Link",
 			"options": "Item",
-			"width": 150
+			"width": 150,
 		},
-		{
-			"label": _("Item Name"),
-			"fieldname": "raw_material_name",
-			"width": 130
-		},
-		{
-			"label": _("Required Qty"),
-			"fieldname": "required_qty",
-			"fieldtype": "Float",
-			"width": 100
-		},
+		{"label": _("Item Name"), "fieldname": "raw_material_name", "width": 130},
+		{"label": _("Required Qty"), "fieldname": "required_qty", "fieldtype": "Float", "width": 100},
 		{
 			"label": _("Transferred Qty"),
 			"fieldname": "transferred_qty",
 			"fieldtype": "Float",
-			"width": 100
+			"width": 100,
 		},
-		{
-			"label": _("Consumed Qty"),
-			"fieldname": "consumed_qty",
-			"fieldtype": "Float",
-			"width": 100
-		},
+		{"label": _("Consumed Qty"), "fieldname": "consumed_qty", "fieldtype": "Float", "width": 100},
 		{
 			"label": _("Extra Consumed Qty"),
 			"fieldname": "extra_consumed_qty",
 			"fieldtype": "Float",
-			"width": 100
-		}
+			"width": 100,
+		},
 	]
diff --git a/erpnext/manufacturing/report/work_order_stock_report/work_order_stock_report.py b/erpnext/manufacturing/report/work_order_stock_report/work_order_stock_report.py
index db0b239..c6b7e58 100644
--- a/erpnext/manufacturing/report/work_order_stock_report/work_order_stock_report.py
+++ b/erpnext/manufacturing/report/work_order_stock_report/work_order_stock_report.py
@@ -12,17 +12,20 @@
 	columns = get_columns()
 	return columns, data
 
+
 def get_item_list(wo_list, filters):
 	out = []
 
-	#Add a row for each item/qty
+	# Add a row for each item/qty
 	for wo_details in wo_list:
 		desc = frappe.db.get_value("BOM", wo_details.bom_no, "description")
 
-		for wo_item_details in frappe.db.get_values("Work Order Item",
-			{"parent": wo_details.name}, ["item_code", "source_warehouse"], as_dict=1):
+		for wo_item_details in frappe.db.get_values(
+			"Work Order Item", {"parent": wo_details.name}, ["item_code", "source_warehouse"], as_dict=1
+		):
 
-			item_list = frappe.db.sql("""SELECT
+			item_list = frappe.db.sql(
+				"""SELECT
 					bom_item.item_code as item_code,
 					ifnull(ledger.actual_qty*bom.quantity/bom_item.stock_qty,0) as build_qty
 				FROM
@@ -36,8 +39,14 @@
 					and bom.name = %(bom)s
 				GROUP BY
 					bom_item.item_code""",
-			{"bom": wo_details.bom_no, "warehouse": wo_item_details.source_warehouse,
-				"filterhouse": filters.warehouse, "item_code": wo_item_details.item_code}, as_dict=1)
+				{
+					"bom": wo_details.bom_no,
+					"warehouse": wo_item_details.source_warehouse,
+					"filterhouse": filters.warehouse,
+					"item_code": wo_item_details.item_code,
+				},
+				as_dict=1,
+			)
 
 			stock_qty = 0
 			count = 0
@@ -54,97 +63,99 @@
 			else:
 				build = "N"
 
-			row = frappe._dict({
-				"work_order": wo_details.name,
-				"status": wo_details.status,
-				"req_items": cint(count),
-				"instock": stock_qty,
-				"description": desc,
-				"source_warehouse": wo_item_details.source_warehouse,
-				"item_code": wo_item_details.item_code,
-				"bom_no": wo_details.bom_no,
-				"qty": wo_details.qty,
-				"buildable_qty": buildable_qty,
-				"ready_to_build": build
-			})
+			row = frappe._dict(
+				{
+					"work_order": wo_details.name,
+					"status": wo_details.status,
+					"req_items": cint(count),
+					"instock": stock_qty,
+					"description": desc,
+					"source_warehouse": wo_item_details.source_warehouse,
+					"item_code": wo_item_details.item_code,
+					"bom_no": wo_details.bom_no,
+					"qty": wo_details.qty,
+					"buildable_qty": buildable_qty,
+					"ready_to_build": build,
+				}
+			)
 
 			out.append(row)
 
 	return out
 
+
 def get_work_orders():
-	out =  frappe.get_all("Work Order", filters={"docstatus": 1, "status": ( "!=","Completed")},
-		fields=["name","status", "bom_no", "qty", "produced_qty"], order_by='name')
+	out = frappe.get_all(
+		"Work Order",
+		filters={"docstatus": 1, "status": ("!=", "Completed")},
+		fields=["name", "status", "bom_no", "qty", "produced_qty"],
+		order_by="name",
+	)
 
 	return out
 
+
 def get_columns():
-	columns = [{
-		"fieldname": "work_order",
-		"label": "Work Order",
-		"fieldtype": "Link",
-		"options": "Work Order",
-		"width": 110
-	}, {
-		"fieldname": "bom_no",
-		"label": "BOM",
-		"fieldtype": "Link",
-		"options": "BOM",
-		"width": 120
-	}, {
-		"fieldname": "description",
-		"label": "Description",
-		"fieldtype": "Data",
-		"options": "",
-		"width": 230
-	}, {
-		"fieldname": "item_code",
-		"label": "Item Code",
-		"fieldtype": "Link",
-		"options": "Item",
-		"width": 110
-	},{
-		"fieldname": "source_warehouse",
-		"label": "Source Warehouse",
-		"fieldtype": "Link",
-		"options": "Warehouse",
-		"width": 110
-	},{
-		"fieldname": "qty",
-		"label": "Qty to Build",
-		"fieldtype": "Data",
-		"options": "",
-		"width": 110
-	}, {
-		"fieldname": "status",
-		"label": "Status",
-		"fieldtype": "Data",
-		"options": "",
-		"width": 100
-	}, {
-		"fieldname": "req_items",
-		"label": "# Req'd Items",
-		"fieldtype": "Data",
-		"options": "",
-		"width": 105
-	}, {
-		"fieldname": "instock",
-		"label": "# In Stock",
-		"fieldtype": "Data",
-		"options": "",
-		"width": 105
-	}, {
-		"fieldname": "buildable_qty",
-		"label": "Buildable Qty",
-		"fieldtype": "Data",
-		"options": "",
-		"width": 100
-	}, {
-		"fieldname": "ready_to_build",
-		"label": "Build All?",
-		"fieldtype": "Data",
-		"options": "",
-		"width": 90
-	}]
+	columns = [
+		{
+			"fieldname": "work_order",
+			"label": "Work Order",
+			"fieldtype": "Link",
+			"options": "Work Order",
+			"width": 110,
+		},
+		{"fieldname": "bom_no", "label": "BOM", "fieldtype": "Link", "options": "BOM", "width": 120},
+		{
+			"fieldname": "description",
+			"label": "Description",
+			"fieldtype": "Data",
+			"options": "",
+			"width": 230,
+		},
+		{
+			"fieldname": "item_code",
+			"label": "Item Code",
+			"fieldtype": "Link",
+			"options": "Item",
+			"width": 110,
+		},
+		{
+			"fieldname": "source_warehouse",
+			"label": "Source Warehouse",
+			"fieldtype": "Link",
+			"options": "Warehouse",
+			"width": 110,
+		},
+		{"fieldname": "qty", "label": "Qty to Build", "fieldtype": "Data", "options": "", "width": 110},
+		{"fieldname": "status", "label": "Status", "fieldtype": "Data", "options": "", "width": 100},
+		{
+			"fieldname": "req_items",
+			"label": "# Req'd Items",
+			"fieldtype": "Data",
+			"options": "",
+			"width": 105,
+		},
+		{
+			"fieldname": "instock",
+			"label": "# In Stock",
+			"fieldtype": "Data",
+			"options": "",
+			"width": 105,
+		},
+		{
+			"fieldname": "buildable_qty",
+			"label": "Buildable Qty",
+			"fieldtype": "Data",
+			"options": "",
+			"width": 100,
+		},
+		{
+			"fieldname": "ready_to_build",
+			"label": "Build All?",
+			"fieldtype": "Data",
+			"options": "",
+			"width": 90,
+		},
+	]
 
 	return columns
diff --git a/erpnext/manufacturing/report/work_order_summary/work_order_summary.py b/erpnext/manufacturing/report/work_order_summary/work_order_summary.py
index d7469dd..2368bfd 100644
--- a/erpnext/manufacturing/report/work_order_summary/work_order_summary.py
+++ b/erpnext/manufacturing/report/work_order_summary/work_order_summary.py
@@ -21,11 +21,23 @@
 	chart_data = get_chart_data(data, filters)
 	return columns, data, None, chart_data
 
+
 def get_data(filters):
 	query_filters = {"docstatus": ("<", 2)}
 
-	fields = ["name", "status", "sales_order", "production_item", "qty", "produced_qty",
-		"planned_start_date", "planned_end_date", "actual_start_date", "actual_end_date", "lead_time"]
+	fields = [
+		"name",
+		"status",
+		"sales_order",
+		"production_item",
+		"qty",
+		"produced_qty",
+		"planned_start_date",
+		"planned_end_date",
+		"actual_start_date",
+		"actual_end_date",
+		"lead_time",
+	]
 
 	for field in ["sales_order", "production_item", "status", "company"]:
 		if filters.get(field):
@@ -34,15 +46,16 @@
 	query_filters["planned_start_date"] = (">=", filters.get("from_date"))
 	query_filters["planned_end_date"] = ("<=", filters.get("to_date"))
 
-	data = frappe.get_all("Work Order",
-		fields= fields, filters=query_filters, order_by="planned_start_date asc")
+	data = frappe.get_all(
+		"Work Order", fields=fields, filters=query_filters, order_by="planned_start_date asc"
+	)
 
 	res = []
 	for d in data:
 		start_date = d.actual_start_date or d.planned_start_date
 		d.age = 0
 
-		if d.status != 'Completed':
+		if d.status != "Completed":
 			d.age = date_diff(today(), start_date)
 
 		if filters.get("age") <= d.age:
@@ -50,6 +63,7 @@
 
 	return res
 
+
 def get_chart_data(data, filters):
 	if filters.get("charts_based_on") == "Status":
 		return get_chart_based_on_status(data)
@@ -58,6 +72,7 @@
 	else:
 		return get_chart_based_on_qty(data, filters)
 
+
 def get_chart_based_on_status(data):
 	labels = frappe.get_meta("Work Order").get_options("status").split("\n")
 	if "" in labels:
@@ -71,25 +86,18 @@
 	values = [status_wise_data[label] for label in labels]
 
 	chart = {
-		"data": {
-			'labels': labels,
-			'datasets': [{'name':'Qty Wise Chart', 'values': values}]
-		},
+		"data": {"labels": labels, "datasets": [{"name": "Qty Wise Chart", "values": values}]},
 		"type": "donut",
-		"height": 300
+		"height": 300,
 	}
 
 	return chart
 
+
 def get_chart_based_on_age(data):
 	labels = ["0-30 Days", "30-60 Days", "60-90 Days", "90 Above"]
 
-	age_wise_data = {
-		"0-30 Days": 0,
-		"30-60 Days": 0,
-		"60-90 Days": 0,
-		"90 Above": 0
-	}
+	age_wise_data = {"0-30 Days": 0, "30-60 Days": 0, "60-90 Days": 0, "90 Above": 0}
 
 	for d in data:
 		if d.age > 0 and d.age <= 30:
@@ -101,20 +109,22 @@
 		else:
 			age_wise_data["90 Above"] += 1
 
-	values = [age_wise_data["0-30 Days"], age_wise_data["30-60 Days"],
-		age_wise_data["60-90 Days"], age_wise_data["90 Above"]]
+	values = [
+		age_wise_data["0-30 Days"],
+		age_wise_data["30-60 Days"],
+		age_wise_data["60-90 Days"],
+		age_wise_data["90 Above"],
+	]
 
 	chart = {
-		"data": {
-			'labels': labels,
-			'datasets': [{'name':'Qty Wise Chart', 'values': values}]
-		},
+		"data": {"labels": labels, "datasets": [{"name": "Qty Wise Chart", "values": values}]},
 		"type": "donut",
-		"height": 300
+		"height": 300,
 	}
 
 	return chart
 
+
 def get_chart_based_on_qty(data, filters):
 	labels, periodic_data = prepare_chart_data(data, filters)
 
@@ -129,25 +139,18 @@
 	datasets.append({"name": "Completed", "values": completed})
 
 	chart = {
-		"data": {
-			'labels': labels,
-			'datasets': datasets
-		},
+		"data": {"labels": labels, "datasets": datasets},
 		"type": "bar",
-		"barOptions": {
-			"stacked": 1
-		}
+		"barOptions": {"stacked": 1},
 	}
 
 	return chart
 
+
 def prepare_chart_data(data, filters):
 	labels = []
 
-	periodic_data = {
-		"Pending": {},
-		"Completed": {}
-	}
+	periodic_data = {"Pending": {}, "Completed": {}}
 
 	filters.range = "Monthly"
 
@@ -165,11 +168,12 @@
 
 		for d in data:
 			if getdate(d.planned_start_date) >= from_date and getdate(d.planned_start_date) <= end_date:
-				periodic_data["Pending"][period] += (flt(d.qty) - flt(d.produced_qty))
+				periodic_data["Pending"][period] += flt(d.qty) - flt(d.produced_qty)
 				periodic_data["Completed"][period] += flt(d.produced_qty)
 
 	return labels, periodic_data
 
+
 def get_columns(filters):
 	columns = [
 		{
@@ -177,90 +181,77 @@
 			"fieldname": "name",
 			"fieldtype": "Link",
 			"options": "Work Order",
-			"width": 100
+			"width": 100,
 		},
 	]
 
 	if not filters.get("status"):
 		columns.append(
-			{
-				"label": _("Status"),
-				"fieldname": "status",
-				"width": 100
-			},
+			{"label": _("Status"), "fieldname": "status", "width": 100},
 		)
 
-	columns.extend([
-		{
-			"label": _("Production Item"),
-			"fieldname": "production_item",
-			"fieldtype": "Link",
-			"options": "Item",
-			"width": 130
-		},
-		{
-			"label": _("Produce Qty"),
-			"fieldname": "qty",
-			"fieldtype": "Float",
-			"width": 110
-		},
-		{
-			"label": _("Produced Qty"),
-			"fieldname": "produced_qty",
-			"fieldtype": "Float",
-			"width": 110
-		},
-		{
-			"label": _("Sales Order"),
-			"fieldname": "sales_order",
-			"fieldtype": "Link",
-			"options": "Sales Order",
-			"width": 90
-		},
-		{
-			"label": _("Planned Start Date"),
-			"fieldname": "planned_start_date",
-			"fieldtype": "Date",
-			"width": 150
-		},
-		{
-			"label": _("Planned End Date"),
-			"fieldname": "planned_end_date",
-			"fieldtype": "Date",
-			"width": 150
-		}
-	])
-
-	if filters.get("status") != 'Not Started':
-		columns.extend([
+	columns.extend(
+		[
 			{
-				"label": _("Actual Start Date"),
-				"fieldname": "actual_start_date",
+				"label": _("Production Item"),
+				"fieldname": "production_item",
+				"fieldtype": "Link",
+				"options": "Item",
+				"width": 130,
+			},
+			{"label": _("Produce Qty"), "fieldname": "qty", "fieldtype": "Float", "width": 110},
+			{"label": _("Produced Qty"), "fieldname": "produced_qty", "fieldtype": "Float", "width": 110},
+			{
+				"label": _("Sales Order"),
+				"fieldname": "sales_order",
+				"fieldtype": "Link",
+				"options": "Sales Order",
+				"width": 90,
+			},
+			{
+				"label": _("Planned Start Date"),
+				"fieldname": "planned_start_date",
 				"fieldtype": "Date",
-				"width": 100
+				"width": 150,
 			},
 			{
-				"label": _("Actual End Date"),
-				"fieldname": "actual_end_date",
+				"label": _("Planned End Date"),
+				"fieldname": "planned_end_date",
 				"fieldtype": "Date",
-				"width": 100
+				"width": 150,
 			},
-			{
-				"label": _("Age"),
-				"fieldname": "age",
-				"fieldtype": "Float",
-				"width": 110
-			},
-		])
+		]
+	)
 
-	if filters.get("status") == 'Completed':
-		columns.extend([
-			{
-				"label": _("Lead Time (in mins)"),
-				"fieldname": "lead_time",
-				"fieldtype": "Float",
-				"width": 110
-			},
-		])
+	if filters.get("status") != "Not Started":
+		columns.extend(
+			[
+				{
+					"label": _("Actual Start Date"),
+					"fieldname": "actual_start_date",
+					"fieldtype": "Date",
+					"width": 100,
+				},
+				{
+					"label": _("Actual End Date"),
+					"fieldname": "actual_end_date",
+					"fieldtype": "Date",
+					"width": 100,
+				},
+				{"label": _("Age"), "fieldname": "age", "fieldtype": "Float", "width": 110},
+			]
+		)
+
+	if filters.get("status") == "Completed":
+		columns.extend(
+			[
+				{
+					"label": _("Lead Time (in mins)"),
+					"fieldname": "lead_time",
+					"fieldtype": "Float",
+					"width": 110,
+				},
+			]
+		)
 
 	return columns