style: format code with black
diff --git a/erpnext/controllers/buying_controller.py b/erpnext/controllers/buying_controller.py
index b740476..4789207 100644
--- a/erpnext/controllers/buying_controller.py
+++ b/erpnext/controllers/buying_controller.py
@@ -20,12 +20,11 @@
 class QtyMismatchError(ValidationError):
 	pass
 
-class BuyingController(StockController, Subcontracting):
 
+class BuyingController(StockController, Subcontracting):
 	def get_feed(self):
 		if self.get("supplier_name"):
-			return _("From {0} | {1} {2}").format(self.supplier_name, self.currency,
-				self.grand_total)
+			return _("From {0} | {1} {2}").format(self.supplier_name, self.currency, self.grand_total)
 
 	def validate(self):
 		super(BuyingController, self).validate()
@@ -40,16 +39,18 @@
 		self.set_supplier_address()
 		self.validate_asset_return()
 
-		if self.doctype=="Purchase Invoice":
+		if self.doctype == "Purchase Invoice":
 			self.validate_purchase_receipt_if_update_stock()
 
-		if self.doctype=="Purchase Receipt" or (self.doctype=="Purchase Invoice" and self.update_stock):
+		if self.doctype == "Purchase Receipt" or (
+			self.doctype == "Purchase Invoice" and self.update_stock
+		):
 			# self.validate_purchase_return()
 			self.validate_rejected_warehouse()
 			self.validate_accepted_rejected_qty()
 			validate_for_items(self)
 
-			#sub-contracting
+			# sub-contracting
 			self.validate_for_subcontracting()
 			self.create_raw_materials_supplied("supplied_items")
 			self.set_landed_cost_voucher_amount()
@@ -59,8 +60,12 @@
 
 	def onload(self):
 		super(BuyingController, self).onload()
-		self.set_onload("backflush_based_on", frappe.db.get_single_value('Buying Settings',
-			'backflush_raw_materials_of_subcontract_based_on'))
+		self.set_onload(
+			"backflush_based_on",
+			frappe.db.get_single_value(
+				"Buying Settings", "backflush_raw_materials_of_subcontract_based_on"
+			),
+		)
 
 	def set_missing_values(self, for_validate=False):
 		super(BuyingController, self).set_missing_values(for_validate)
@@ -77,9 +82,9 @@
 					doctype=self.doctype,
 					company=self.company,
 					party_address=self.get("supplier_address"),
-					shipping_address=self.get('shipping_address'),
-					fetch_payment_terms_template= not self.get('ignore_default_payment_terms_template'),
-					ignore_permissions=self.flags.ignore_permissions
+					shipping_address=self.get("shipping_address"),
+					fetch_payment_terms_template=not self.get("ignore_default_payment_terms_template"),
+					ignore_permissions=self.flags.ignore_permissions,
 				)
 			)
 
@@ -88,14 +93,16 @@
 	def set_supplier_from_item_default(self):
 		if self.meta.get_field("supplier") and not self.supplier:
 			for d in self.get("items"):
-				supplier = frappe.db.get_value("Item Default",
-					{"parent": d.item_code, "company": self.company}, "default_supplier")
+				supplier = frappe.db.get_value(
+					"Item Default", {"parent": d.item_code, "company": self.company}, "default_supplier"
+				)
 				if supplier:
 					self.supplier = supplier
 				else:
 					item_group = frappe.db.get_value("Item", d.item_code, "item_group")
-					supplier = frappe.db.get_value("Item Default",
-					{"parent": item_group, "company": self.company}, "default_supplier")
+					supplier = frappe.db.get_value(
+						"Item Default", {"parent": item_group, "company": self.company}, "default_supplier"
+					)
 					if supplier:
 						self.supplier = supplier
 					break
@@ -106,55 +113,71 @@
 			self.update_tax_category(msg)
 
 	def update_tax_category(self, msg):
-		tax_for_valuation = [d for d in self.get("taxes")
-				if d.category in ["Valuation", "Valuation and Total"]]
+		tax_for_valuation = [
+			d for d in self.get("taxes") if d.category in ["Valuation", "Valuation and Total"]
+		]
 
 		if tax_for_valuation:
 			for d in tax_for_valuation:
-				d.category = 'Total'
+				d.category = "Total"
 
 			msgprint(msg)
 
 	def validate_asset_return(self):
-		if self.doctype not in ['Purchase Receipt', 'Purchase Invoice'] or not self.is_return:
+		if self.doctype not in ["Purchase Receipt", "Purchase Invoice"] or not self.is_return:
 			return
 
-		purchase_doc_field = 'purchase_receipt' if self.doctype == 'Purchase Receipt' else 'purchase_invoice'
-		not_cancelled_asset = [d.name for d in frappe.db.get_all("Asset", {
-			purchase_doc_field: self.return_against,
-			"docstatus": 1
-		})]
+		purchase_doc_field = (
+			"purchase_receipt" if self.doctype == "Purchase Receipt" else "purchase_invoice"
+		)
+		not_cancelled_asset = [
+			d.name
+			for d in frappe.db.get_all("Asset", {purchase_doc_field: self.return_against, "docstatus": 1})
+		]
 		if self.is_return and len(not_cancelled_asset):
-			frappe.throw(_("{} has submitted assets linked to it. You need to cancel the assets to create purchase return.")
-				.format(self.return_against), title=_("Not Allowed"))
+			frappe.throw(
+				_(
+					"{} has submitted assets linked to it. You need to cancel the assets to create purchase return."
+				).format(self.return_against),
+				title=_("Not Allowed"),
+			)
 
 	def get_asset_items(self):
-		if self.doctype not in ['Purchase Order', 'Purchase Invoice', 'Purchase Receipt']:
+		if self.doctype not in ["Purchase Order", "Purchase Invoice", "Purchase Receipt"]:
 			return []
 
 		return [d.item_code for d in self.items if d.is_fixed_asset]
 
 	def set_landed_cost_voucher_amount(self):
 		for d in self.get("items"):
-			lc_voucher_data = frappe.db.sql("""select sum(applicable_charges), cost_center
+			lc_voucher_data = frappe.db.sql(
+				"""select sum(applicable_charges), cost_center
 				from `tabLanded Cost Item`
-				where docstatus = 1 and purchase_receipt_item = %s""", d.name)
+				where docstatus = 1 and purchase_receipt_item = %s""",
+				d.name,
+			)
 			d.landed_cost_voucher_amount = lc_voucher_data[0][0] if lc_voucher_data else 0.0
 			if not d.cost_center and lc_voucher_data and lc_voucher_data[0][1]:
-				d.db_set('cost_center', lc_voucher_data[0][1])
+				d.db_set("cost_center", lc_voucher_data[0][1])
 
 	def validate_from_warehouse(self):
-		for item in self.get('items'):
-			if item.get('from_warehouse') and (item.get('from_warehouse') == item.get('warehouse')):
-				frappe.throw(_("Row #{0}: Accepted Warehouse and Supplier Warehouse cannot be same").format(item.idx))
+		for item in self.get("items"):
+			if item.get("from_warehouse") and (item.get("from_warehouse") == item.get("warehouse")):
+				frappe.throw(
+					_("Row #{0}: Accepted Warehouse and Supplier Warehouse cannot be same").format(item.idx)
+				)
 
-			if item.get('from_warehouse') and self.get('is_subcontracted') == 'Yes':
-				frappe.throw(_("Row #{0}: Cannot select Supplier Warehouse while suppling raw materials to subcontractor").format(item.idx))
+			if item.get("from_warehouse") and self.get("is_subcontracted") == "Yes":
+				frappe.throw(
+					_(
+						"Row #{0}: Cannot select Supplier Warehouse while suppling raw materials to subcontractor"
+					).format(item.idx)
+				)
 
 	def set_supplier_address(self):
 		address_dict = {
-			'supplier_address': 'address_display',
-			'shipping_address': 'shipping_address_display'
+			"supplier_address": "address_display",
+			"shipping_address": "shipping_address_display",
 		}
 
 		for address_field, address_display_field in address_dict.items():
@@ -163,6 +186,7 @@
 
 	def set_total_in_words(self):
 		from frappe.utils import money_in_words
+
 		if self.meta.get_field("base_in_words"):
 			if self.meta.get_field("base_rounded_total") and not self.is_rounded_total_disabled():
 				amount = self.base_rounded_total
@@ -181,10 +205,10 @@
 	# update valuation rate
 	def update_valuation_rate(self, reset_outgoing_rate=True):
 		"""
-			item_tax_amount is the total tax amount applied on that item
-			stored for valuation
+		item_tax_amount is the total tax amount applied on that item
+		stored for valuation
 
-			TODO: rename item_tax_amount to valuation_tax_amount
+		TODO: rename item_tax_amount to valuation_tax_amount
 		"""
 		stock_and_asset_items = []
 		stock_and_asset_items = self.get_stock_items() + self.get_asset_items()
@@ -192,36 +216,50 @@
 		stock_and_asset_items_qty, stock_and_asset_items_amount = 0, 0
 		last_item_idx = 1
 		for d in self.get("items"):
-			if (d.item_code and d.item_code in stock_and_asset_items):
+			if d.item_code and d.item_code in stock_and_asset_items:
 				stock_and_asset_items_qty += flt(d.qty)
 				stock_and_asset_items_amount += flt(d.base_net_amount)
 				last_item_idx = d.idx
 
-		total_valuation_amount = sum(flt(d.base_tax_amount_after_discount_amount) for d in self.get("taxes")
-			if d.category in ["Valuation", "Valuation and Total"])
+		total_valuation_amount = sum(
+			flt(d.base_tax_amount_after_discount_amount)
+			for d in self.get("taxes")
+			if d.category in ["Valuation", "Valuation and Total"]
+		)
 
 		valuation_amount_adjustment = total_valuation_amount
 		for i, item in enumerate(self.get("items")):
 			if item.item_code and item.qty and item.item_code in stock_and_asset_items:
-				item_proportion = flt(item.base_net_amount) / stock_and_asset_items_amount if stock_and_asset_items_amount \
+				item_proportion = (
+					flt(item.base_net_amount) / stock_and_asset_items_amount
+					if stock_and_asset_items_amount
 					else flt(item.qty) / stock_and_asset_items_qty
+				)
 
 				if i == (last_item_idx - 1):
-					item.item_tax_amount = flt(valuation_amount_adjustment,
-						self.precision("item_tax_amount", item))
+					item.item_tax_amount = flt(
+						valuation_amount_adjustment, self.precision("item_tax_amount", item)
+					)
 				else:
-					item.item_tax_amount = flt(item_proportion * total_valuation_amount,
-						self.precision("item_tax_amount", item))
+					item.item_tax_amount = flt(
+						item_proportion * total_valuation_amount, self.precision("item_tax_amount", item)
+					)
 					valuation_amount_adjustment -= item.item_tax_amount
 
 				self.round_floats_in(item)
-				if flt(item.conversion_factor)==0.0:
-					item.conversion_factor = get_conversion_factor(item.item_code, item.uom).get("conversion_factor") or 1.0
+				if flt(item.conversion_factor) == 0.0:
+					item.conversion_factor = (
+						get_conversion_factor(item.item_code, item.uom).get("conversion_factor") or 1.0
+					)
 
 				qty_in_stock_uom = flt(item.qty * item.conversion_factor)
 				item.rm_supp_cost = self.get_supplied_items_cost(item.name, reset_outgoing_rate)
-				item.valuation_rate = ((item.base_net_amount + item.item_tax_amount + item.rm_supp_cost
-					 + flt(item.landed_cost_voucher_amount)) / qty_in_stock_uom)
+				item.valuation_rate = (
+					item.base_net_amount
+					+ item.item_tax_amount
+					+ item.rm_supp_cost
+					+ flt(item.landed_cost_voucher_amount)
+				) / qty_in_stock_uom
 			else:
 				item.valuation_rate = 0.0
 
@@ -242,46 +280,55 @@
 				# Get outgoing rate based on original item cost based on valuation method
 
 				if not d.get(frappe.scrub(ref_doctype)):
-					outgoing_rate = get_incoming_rate({
-						"item_code": d.item_code,
-						"warehouse": d.get('from_warehouse'),
-						"posting_date": self.get('posting_date') or self.get('transation_date'),
-						"posting_time": self.get('posting_time'),
-						"qty": -1 * flt(d.get('stock_qty')),
-						"serial_no": d.get('serial_no'),
-						"batch_no": d.get("batch_no"),
-						"company": self.company,
-						"voucher_type": self.doctype,
-						"voucher_no": self.name,
-						"allow_zero_valuation": d.get("allow_zero_valuation")
-					}, raise_error_if_no_rate=False)
+					outgoing_rate = get_incoming_rate(
+						{
+							"item_code": d.item_code,
+							"warehouse": d.get("from_warehouse"),
+							"posting_date": self.get("posting_date") or self.get("transation_date"),
+							"posting_time": self.get("posting_time"),
+							"qty": -1 * flt(d.get("stock_qty")),
+							"serial_no": d.get("serial_no"),
+							"batch_no": d.get("batch_no"),
+							"company": self.company,
+							"voucher_type": self.doctype,
+							"voucher_no": self.name,
+							"allow_zero_valuation": d.get("allow_zero_valuation"),
+						},
+						raise_error_if_no_rate=False,
+					)
 
-					rate = flt(outgoing_rate * d.conversion_factor, d.precision('rate'))
+					rate = flt(outgoing_rate * d.conversion_factor, d.precision("rate"))
 				else:
-					rate = frappe.db.get_value(ref_doctype, d.get(frappe.scrub(ref_doctype)), 'rate')
+					rate = frappe.db.get_value(ref_doctype, d.get(frappe.scrub(ref_doctype)), "rate")
 
 				if self.is_internal_transfer():
 					if rate != d.rate:
 						d.rate = rate
 						d.discount_percentage = 0
 						d.discount_amount = 0
-						frappe.msgprint(_("Row {0}: Item rate has been updated as per valuation rate since its an internal stock transfer")
-							.format(d.idx), alert=1)
+						frappe.msgprint(
+							_(
+								"Row {0}: Item rate has been updated as per valuation rate since its an internal stock transfer"
+							).format(d.idx),
+							alert=1,
+						)
 
 	def get_supplied_items_cost(self, item_row_id, reset_outgoing_rate=True):
 		supplied_items_cost = 0.0
 		for d in self.get("supplied_items"):
 			if d.reference_name == item_row_id:
-				if reset_outgoing_rate and frappe.get_cached_value('Item', d.rm_item_code, 'is_stock_item'):
-					rate = get_incoming_rate({
-						"item_code": d.rm_item_code,
-						"warehouse": self.supplier_warehouse,
-						"posting_date": self.posting_date,
-						"posting_time": self.posting_time,
-						"qty": -1 * d.consumed_qty,
-						"serial_no": d.serial_no,
-						"batch_no": d.batch_no,
-					})
+				if reset_outgoing_rate and frappe.get_cached_value("Item", d.rm_item_code, "is_stock_item"):
+					rate = get_incoming_rate(
+						{
+							"item_code": d.rm_item_code,
+							"warehouse": self.supplier_warehouse,
+							"posting_date": self.posting_date,
+							"posting_time": self.posting_time,
+							"qty": -1 * d.consumed_qty,
+							"serial_no": d.serial_no,
+							"batch_no": d.batch_no,
+						}
+					)
 
 					if rate > 0:
 						d.rate = rate
@@ -316,7 +363,7 @@
 					item.bom = None
 
 	def create_raw_materials_supplied(self, raw_material_table):
-		if self.is_subcontracted=="Yes":
+		if self.is_subcontracted == "Yes":
 			self.set_materials_for_subcontracted_items(raw_material_table)
 
 		elif self.doctype in ["Purchase Receipt", "Purchase Invoice"]:
@@ -324,19 +371,17 @@
 				item.rm_supp_cost = 0.0
 
 		if self.is_subcontracted == "No" and self.get("supplied_items"):
-			self.set('supplied_items', [])
+			self.set("supplied_items", [])
 
 	@property
 	def sub_contracted_items(self):
 		if not hasattr(self, "_sub_contracted_items"):
 			self._sub_contracted_items = []
-			item_codes = list(set(item.item_code for item in
-				self.get("items")))
+			item_codes = list(set(item.item_code for item in self.get("items")))
 			if item_codes:
-				items = frappe.get_all('Item', filters={
-					'name': ['in', item_codes],
-					'is_sub_contracted_item': 1
-				})
+				items = frappe.get_all(
+					"Item", filters={"name": ["in", item_codes], "is_sub_contracted_item": 1}
+				)
 				self._sub_contracted_items = [item.name for item in items]
 
 		return self._sub_contracted_items
@@ -350,9 +395,11 @@
 					frappe.throw(_("Row {0}: Conversion Factor is mandatory").format(d.idx))
 				d.stock_qty = flt(d.qty) * flt(d.conversion_factor)
 
-				if self.doctype=="Purchase Receipt" and d.meta.get_field("received_stock_qty"):
+				if self.doctype == "Purchase Receipt" and d.meta.get_field("received_stock_qty"):
 					# Set Received Qty in Stock UOM
-					d.received_stock_qty = flt(d.received_qty) * flt(d.conversion_factor, d.precision("conversion_factor"))
+					d.received_stock_qty = flt(d.received_qty) * flt(
+						d.conversion_factor, d.precision("conversion_factor")
+					)
 
 	def validate_purchase_return(self):
 		for d in self.get("items"):
@@ -368,20 +415,26 @@
 					d.rejected_warehouse = self.rejected_warehouse
 
 				if not d.rejected_warehouse:
-					frappe.throw(_("Row #{0}: Rejected Warehouse is mandatory against rejected Item {1}").format(d.idx, d.item_code))
+					frappe.throw(
+						_("Row #{0}: Rejected Warehouse is mandatory against rejected Item {1}").format(
+							d.idx, d.item_code
+						)
+					)
 
 	# validate accepted and rejected qty
 	def validate_accepted_rejected_qty(self):
 		for d in self.get("items"):
-			self.validate_negative_quantity(d, ["received_qty","qty", "rejected_qty"])
+			self.validate_negative_quantity(d, ["received_qty", "qty", "rejected_qty"])
 
 			if not flt(d.received_qty) and (flt(d.qty) or flt(d.rejected_qty)):
 				d.received_qty = flt(d.qty) + flt(d.rejected_qty)
 
 			# Check Received Qty = Accepted Qty + Rejected Qty
 			val = flt(d.qty) + flt(d.rejected_qty)
-			if (flt(val, d.precision("received_qty")) != flt(d.received_qty, d.precision("received_qty"))):
-				message = _("Row #{0}: Received Qty must be equal to Accepted + Rejected Qty for Item {1}").format(d.idx, d.item_code)
+			if flt(val, d.precision("received_qty")) != flt(d.received_qty, d.precision("received_qty")):
+				message = _(
+					"Row #{0}: Received Qty must be equal to Accepted + Rejected Qty for Item {1}"
+				).format(d.idx, d.item_code)
 				frappe.throw(msg=message, title=_("Mismatch"), exc=QtyMismatchError)
 
 	def validate_negative_quantity(self, item_row, field_list):
@@ -391,15 +444,20 @@
 		item_row = item_row.as_dict()
 		for fieldname in field_list:
 			if flt(item_row[fieldname]) < 0:
-				frappe.throw(_("Row #{0}: {1} can not be negative for item {2}").format(item_row['idx'],
-					frappe.get_meta(item_row.doctype).get_label(fieldname), item_row['item_code']))
+				frappe.throw(
+					_("Row #{0}: {1} can not be negative for item {2}").format(
+						item_row["idx"],
+						frappe.get_meta(item_row.doctype).get_label(fieldname),
+						item_row["item_code"],
+					)
+				)
 
 	def check_for_on_hold_or_closed_status(self, ref_doctype, ref_fieldname):
 		for d in self.get("items"):
 			if d.get(ref_fieldname):
 				status = frappe.db.get_value(ref_doctype, d.get(ref_fieldname), "status")
 				if status in ("Closed", "On Hold"):
-					frappe.throw(_("{0} {1} is {2}").format(ref_doctype,d.get(ref_fieldname), status))
+					frappe.throw(_("{0} {1} is {2}").format(ref_doctype, d.get(ref_fieldname), status))
 
 	def update_stock_ledger(self, allow_negative_stock=False, via_landed_cost_voucher=False):
 		self.update_ordered_and_reserved_qty()
@@ -407,76 +465,88 @@
 		sl_entries = []
 		stock_items = self.get_stock_items()
 
-		for d in self.get('items'):
+		for d in self.get("items"):
 			if d.item_code in stock_items and d.warehouse:
 				pr_qty = flt(d.qty) * flt(d.conversion_factor)
 
 				if pr_qty:
 
-					if d.from_warehouse and ((not cint(self.is_return) and self.docstatus==1)
-						or (cint(self.is_return) and self.docstatus==2)):
-						from_warehouse_sle = self.get_sl_entries(d, {
-							"actual_qty": -1 * pr_qty,
-							"warehouse": d.from_warehouse,
-							"outgoing_rate": d.rate,
-							"recalculate_rate": 1,
-							"dependant_sle_voucher_detail_no": d.name
-						})
+					if d.from_warehouse and (
+						(not cint(self.is_return) and self.docstatus == 1)
+						or (cint(self.is_return) and self.docstatus == 2)
+					):
+						from_warehouse_sle = self.get_sl_entries(
+							d,
+							{
+								"actual_qty": -1 * pr_qty,
+								"warehouse": d.from_warehouse,
+								"outgoing_rate": d.rate,
+								"recalculate_rate": 1,
+								"dependant_sle_voucher_detail_no": d.name,
+							},
+						)
 
 						sl_entries.append(from_warehouse_sle)
 
-					sle = self.get_sl_entries(d, {
-						"actual_qty": flt(pr_qty),
-						"serial_no": cstr(d.serial_no).strip()
-					})
+					sle = self.get_sl_entries(
+						d, {"actual_qty": flt(pr_qty), "serial_no": cstr(d.serial_no).strip()}
+					)
 					if self.is_return:
-						outgoing_rate = get_rate_for_return(self.doctype, self.name, d.item_code, self.return_against, item_row=d)
+						outgoing_rate = get_rate_for_return(
+							self.doctype, self.name, d.item_code, self.return_against, item_row=d
+						)
 
-						sle.update({
-							"outgoing_rate": outgoing_rate,
-							"recalculate_rate": 1
-						})
+						sle.update({"outgoing_rate": outgoing_rate, "recalculate_rate": 1})
 						if d.from_warehouse:
 							sle.dependant_sle_voucher_detail_no = d.name
 					else:
 						val_rate_db_precision = 6 if cint(self.precision("valuation_rate", d)) <= 6 else 9
 						incoming_rate = flt(d.valuation_rate, val_rate_db_precision)
-						sle.update({
-							"incoming_rate": incoming_rate,
-							"recalculate_rate": 1 if (self.is_subcontracted and d.bom) or d.from_warehouse else 0
-						})
+						sle.update(
+							{
+								"incoming_rate": incoming_rate,
+								"recalculate_rate": 1 if (self.is_subcontracted and d.bom) or d.from_warehouse else 0,
+							}
+						)
 					sl_entries.append(sle)
 
-					if d.from_warehouse and ((not cint(self.is_return) and self.docstatus==2)
-						or (cint(self.is_return) and self.docstatus==1)):
-						from_warehouse_sle = self.get_sl_entries(d, {
-							"actual_qty": -1 * pr_qty,
-							"warehouse": d.from_warehouse,
-							"recalculate_rate": 1
-						})
+					if d.from_warehouse and (
+						(not cint(self.is_return) and self.docstatus == 2)
+						or (cint(self.is_return) and self.docstatus == 1)
+					):
+						from_warehouse_sle = self.get_sl_entries(
+							d, {"actual_qty": -1 * pr_qty, "warehouse": d.from_warehouse, "recalculate_rate": 1}
+						)
 
 						sl_entries.append(from_warehouse_sle)
 
 				if flt(d.rejected_qty) != 0:
-					sl_entries.append(self.get_sl_entries(d, {
-						"warehouse": d.rejected_warehouse,
-						"actual_qty": flt(d.rejected_qty) * flt(d.conversion_factor),
-						"serial_no": cstr(d.rejected_serial_no).strip(),
-						"incoming_rate": 0.0
-					}))
+					sl_entries.append(
+						self.get_sl_entries(
+							d,
+							{
+								"warehouse": d.rejected_warehouse,
+								"actual_qty": flt(d.rejected_qty) * flt(d.conversion_factor),
+								"serial_no": cstr(d.rejected_serial_no).strip(),
+								"incoming_rate": 0.0,
+							},
+						)
+					)
 
 		self.make_sl_entries_for_supplier_warehouse(sl_entries)
-		self.make_sl_entries(sl_entries, allow_negative_stock=allow_negative_stock,
-			via_landed_cost_voucher=via_landed_cost_voucher)
+		self.make_sl_entries(
+			sl_entries,
+			allow_negative_stock=allow_negative_stock,
+			via_landed_cost_voucher=via_landed_cost_voucher,
+		)
 
 	def update_ordered_and_reserved_qty(self):
 		po_map = {}
 		for d in self.get("items"):
-			if self.doctype=="Purchase Receipt" \
-				and d.purchase_order:
-					po_map.setdefault(d.purchase_order, []).append(d.purchase_order_item)
+			if self.doctype == "Purchase Receipt" and d.purchase_order:
+				po_map.setdefault(d.purchase_order, []).append(d.purchase_order_item)
 
-			elif self.doctype=="Purchase Invoice" and d.purchase_order and d.po_detail:
+			elif self.doctype == "Purchase Invoice" and d.purchase_order and d.po_detail:
 				po_map.setdefault(d.purchase_order, []).append(d.po_detail)
 
 		for po, po_item_rows in po_map.items():
@@ -484,68 +554,78 @@
 				po_obj = frappe.get_doc("Purchase Order", po)
 
 				if po_obj.status in ["Closed", "Cancelled"]:
-					frappe.throw(_("{0} {1} is cancelled or closed").format(_("Purchase Order"), po),
-						frappe.InvalidStatusError)
+					frappe.throw(
+						_("{0} {1} is cancelled or closed").format(_("Purchase Order"), po),
+						frappe.InvalidStatusError,
+					)
 
 				po_obj.update_ordered_qty(po_item_rows)
 				if self.is_subcontracted:
 					po_obj.update_reserved_qty_for_subcontract()
 
 	def make_sl_entries_for_supplier_warehouse(self, sl_entries):
-		if hasattr(self, 'supplied_items'):
-			for d in self.get('supplied_items'):
+		if hasattr(self, "supplied_items"):
+			for d in self.get("supplied_items"):
 				# negative quantity is passed, as raw material qty has to be decreased
 				# when PR is submitted and it has to be increased when PR is cancelled
-				sl_entries.append(self.get_sl_entries(d, {
-					"item_code": d.rm_item_code,
-					"warehouse": self.supplier_warehouse,
-					"actual_qty": -1*flt(d.consumed_qty),
-					"dependant_sle_voucher_detail_no": d.reference_name
-				}))
+				sl_entries.append(
+					self.get_sl_entries(
+						d,
+						{
+							"item_code": d.rm_item_code,
+							"warehouse": self.supplier_warehouse,
+							"actual_qty": -1 * flt(d.consumed_qty),
+							"dependant_sle_voucher_detail_no": d.reference_name,
+						},
+					)
+				)
 
 	def on_submit(self):
-		if self.get('is_return'):
+		if self.get("is_return"):
 			return
 
-		if self.doctype in ['Purchase Receipt', 'Purchase Invoice']:
-			field = 'purchase_invoice' if self.doctype == 'Purchase Invoice' else 'purchase_receipt'
+		if self.doctype in ["Purchase Receipt", "Purchase Invoice"]:
+			field = "purchase_invoice" if self.doctype == "Purchase Invoice" else "purchase_receipt"
 
 			self.process_fixed_asset()
 			self.update_fixed_asset(field)
 
-		if self.doctype in ['Purchase Order', 'Purchase Receipt']:
-			update_last_purchase_rate(self, is_submit = 1)
+		if self.doctype in ["Purchase Order", "Purchase Receipt"]:
+			update_last_purchase_rate(self, is_submit=1)
 
 	def on_cancel(self):
 		super(BuyingController, self).on_cancel()
 
-		if self.get('is_return'):
+		if self.get("is_return"):
 			return
 
-		if self.doctype in ['Purchase Order', 'Purchase Receipt']:
-			update_last_purchase_rate(self, is_submit = 0)
+		if self.doctype in ["Purchase Order", "Purchase Receipt"]:
+			update_last_purchase_rate(self, is_submit=0)
 
-		if self.doctype in ['Purchase Receipt', 'Purchase Invoice']:
-			field = 'purchase_invoice' if self.doctype == 'Purchase Invoice' else 'purchase_receipt'
+		if self.doctype in ["Purchase Receipt", "Purchase Invoice"]:
+			field = "purchase_invoice" if self.doctype == "Purchase Invoice" else "purchase_receipt"
 
 			self.delete_linked_asset()
 			self.update_fixed_asset(field, delete_asset=True)
 
 	def validate_budget(self):
 		if self.docstatus == 1:
-			for data in self.get('items'):
+			for data in self.get("items"):
 				args = data.as_dict()
-				args.update({
-					'doctype': self.doctype,
-					'company': self.company,
-					'posting_date': (self.schedule_date
-						if self.doctype == 'Material Request' else self.transaction_date)
-				})
+				args.update(
+					{
+						"doctype": self.doctype,
+						"company": self.company,
+						"posting_date": (
+							self.schedule_date if self.doctype == "Material Request" else self.transaction_date
+						),
+					}
+				)
 
 				validate_expense_against_budget(args)
 
 	def process_fixed_asset(self):
-		if self.doctype == 'Purchase Invoice' and not self.update_stock:
+		if self.doctype == "Purchase Invoice" and not self.update_stock:
 			return
 
 		asset_items = self.get_asset_items()
@@ -560,12 +640,12 @@
 			if d.is_fixed_asset:
 				item_data = items_data.get(d.item_code)
 
-				if item_data.get('auto_create_assets'):
+				if item_data.get("auto_create_assets"):
 					# If asset has to be auto created
 					# Check for asset naming series
-					if item_data.get('asset_naming_series'):
+					if item_data.get("asset_naming_series"):
 						created_assets = []
-						if item_data.get('is_grouped_asset'):
+						if item_data.get("is_grouped_asset"):
 							asset = self.make_asset(d, is_grouped_asset=True)
 							created_assets.append(asset)
 						else:
@@ -575,21 +655,31 @@
 
 						if len(created_assets) > 5:
 							# dont show asset form links if more than 5 assets are created
-							messages.append(_('{} Assets created for {}').format(len(created_assets), frappe.bold(d.item_code)))
-						else:
-							assets_link = list(map(lambda d: frappe.utils.get_link_to_form('Asset', d), created_assets))
-							assets_link = frappe.bold(','.join(assets_link))
-
-							is_plural = 's' if len(created_assets) != 1 else ''
 							messages.append(
-								_('Asset{} {assets_link} created for {}').format(is_plural, frappe.bold(d.item_code), assets_link=assets_link)
+								_("{} Assets created for {}").format(len(created_assets), frappe.bold(d.item_code))
+							)
+						else:
+							assets_link = list(map(lambda d: frappe.utils.get_link_to_form("Asset", d), created_assets))
+							assets_link = frappe.bold(",".join(assets_link))
+
+							is_plural = "s" if len(created_assets) != 1 else ""
+							messages.append(
+								_("Asset{} {assets_link} created for {}").format(
+									is_plural, frappe.bold(d.item_code), assets_link=assets_link
+								)
 							)
 					else:
-						frappe.throw(_("Row {}: Asset Naming Series is mandatory for the auto creation for item {}")
-							.format(d.idx, frappe.bold(d.item_code)))
+						frappe.throw(
+							_("Row {}: Asset Naming Series is mandatory for the auto creation for item {}").format(
+								d.idx, frappe.bold(d.item_code)
+							)
+						)
 				else:
-					messages.append(_("Assets not created for {0}. You will have to create asset manually.")
-						.format(frappe.bold(d.item_code)))
+					messages.append(
+						_("Assets not created for {0}. You will have to create asset manually.").format(
+							frappe.bold(d.item_code)
+						)
+					)
 
 		for message in messages:
 			frappe.msgprint(message, title="Success", indicator="green")
@@ -598,31 +688,34 @@
 		if not row.asset_location:
 			frappe.throw(_("Row {0}: Enter location for the asset item {1}").format(row.idx, row.item_code))
 
-		item_data = frappe.db.get_value('Item',
-			row.item_code, ['asset_naming_series', 'asset_category'], as_dict=1)
+		item_data = frappe.db.get_value(
+			"Item", row.item_code, ["asset_naming_series", "asset_category"], as_dict=1
+		)
 
 		if is_grouped_asset:
 			purchase_amount = flt(row.base_amount + row.item_tax_amount)
 		else:
 			purchase_amount = flt(row.base_rate + row.item_tax_amount)
 
-		asset = frappe.get_doc({
-			'doctype': 'Asset',
-			'item_code': row.item_code,
-			'asset_name': row.item_name,
-			'naming_series': item_data.get('asset_naming_series') or 'AST',
-			'asset_category': item_data.get('asset_category'),
-			'location': row.asset_location,
-			'company': self.company,
-			'supplier': self.supplier,
-			'purchase_date': self.posting_date,
-			'calculate_depreciation': 1,
-			'purchase_receipt_amount': purchase_amount,
-			'gross_purchase_amount': purchase_amount,
-			'asset_quantity': row.qty if is_grouped_asset else 0,
-			'purchase_receipt': self.name if self.doctype == 'Purchase Receipt' else None,
-			'purchase_invoice': self.name if self.doctype == 'Purchase Invoice' else None
-		})
+		asset = frappe.get_doc(
+			{
+				"doctype": "Asset",
+				"item_code": row.item_code,
+				"asset_name": row.item_name,
+				"naming_series": item_data.get("asset_naming_series") or "AST",
+				"asset_category": item_data.get("asset_category"),
+				"location": row.asset_location,
+				"company": self.company,
+				"supplier": self.supplier,
+				"purchase_date": self.posting_date,
+				"calculate_depreciation": 1,
+				"purchase_receipt_amount": purchase_amount,
+				"gross_purchase_amount": purchase_amount,
+				"asset_quantity": row.qty if is_grouped_asset else 0,
+				"purchase_receipt": self.name if self.doctype == "Purchase Receipt" else None,
+				"purchase_invoice": self.name if self.doctype == "Purchase Invoice" else None,
+			}
+		)
 
 		asset.flags.ignore_validate = True
 		asset.flags.ignore_mandatory = True
@@ -631,22 +724,25 @@
 
 		return asset.name
 
-	def update_fixed_asset(self, field, delete_asset = False):
+	def update_fixed_asset(self, field, delete_asset=False):
 		for d in self.get("items"):
 			if d.is_fixed_asset:
-				is_auto_create_enabled = frappe.db.get_value('Item', d.item_code, 'auto_create_assets')
-				assets = frappe.db.get_all('Asset', filters={ field : self.name, 'item_code' : d.item_code })
+				is_auto_create_enabled = frappe.db.get_value("Item", d.item_code, "auto_create_assets")
+				assets = frappe.db.get_all("Asset", filters={field: self.name, "item_code": d.item_code})
 
 				for asset in assets:
-					asset = frappe.get_doc('Asset', asset.name)
+					asset = frappe.get_doc("Asset", asset.name)
 					if delete_asset and is_auto_create_enabled:
 						# need to delete movements to delete assets otherwise throws link exists error
 						movements = frappe.db.sql(
 							"""SELECT asm.name
 							FROM `tabAsset Movement` asm, `tabAsset Movement Item` asm_item
-							WHERE asm_item.parent=asm.name and asm_item.asset=%s""", asset.name, as_dict=1)
+							WHERE asm_item.parent=asm.name and asm_item.asset=%s""",
+							asset.name,
+							as_dict=1,
+						)
 						for movement in movements:
-							frappe.delete_doc('Asset Movement', movement.name, force=1)
+							frappe.delete_doc("Asset Movement", movement.name, force=1)
 						frappe.delete_doc("Asset", asset.name, force=1)
 						continue
 
@@ -659,8 +755,11 @@
 							asset.set(field, None)
 							asset.supplier = None
 						if asset.docstatus == 1 and delete_asset:
-							frappe.throw(_('Cannot cancel this document as it is linked with submitted asset {0}. Please cancel it to continue.')
-								.format(frappe.utils.get_link_to_form('Asset', asset.name)))
+							frappe.throw(
+								_(
+									"Cannot cancel this document as it is linked with submitted asset {0}. Please cancel it to continue."
+								).format(frappe.utils.get_link_to_form("Asset", asset.name))
+							)
 
 					asset.flags.ignore_validate_update_after_submit = True
 					asset.flags.ignore_mandatory = True
@@ -670,7 +769,7 @@
 					asset.save()
 
 	def delete_linked_asset(self):
-		if self.doctype == 'Purchase Invoice' and not self.get('update_stock'):
+		if self.doctype == "Purchase Invoice" and not self.get("update_stock"):
 			return
 
 		frappe.db.sql("delete from `tabAsset Movement` where reference_name=%s", self.name)
@@ -681,37 +780,47 @@
 
 		if any(d.schedule_date for d in self.get("items")):
 			# Select earliest schedule_date.
-			self.schedule_date = min(d.schedule_date for d in self.get("items")
-							if d.schedule_date is not None)
+			self.schedule_date = min(
+				d.schedule_date for d in self.get("items") if d.schedule_date is not None
+			)
 
 		if self.schedule_date:
-			for d in self.get('items'):
+			for d in self.get("items"):
 				if not d.schedule_date:
 					d.schedule_date = self.schedule_date
 
-				if (d.schedule_date and self.transaction_date and
-					getdate(d.schedule_date) < getdate(self.transaction_date)):
+				if (
+					d.schedule_date
+					and self.transaction_date
+					and getdate(d.schedule_date) < getdate(self.transaction_date)
+				):
 					frappe.throw(_("Row #{0}: Reqd by Date cannot be before Transaction Date").format(d.idx))
 		else:
 			frappe.throw(_("Please enter Reqd by Date"))
 
 	def validate_items(self):
 		# validate items to see if they have is_purchase_item or is_subcontracted_item enabled
-		if self.doctype=="Material Request": return
+		if self.doctype == "Material Request":
+			return
 
-		if hasattr(self, "is_subcontracted") and self.is_subcontracted == 'Yes':
+		if hasattr(self, "is_subcontracted") and self.is_subcontracted == "Yes":
 			validate_item_type(self, "is_sub_contracted_item", "subcontracted")
 		else:
 			validate_item_type(self, "is_purchase_item", "purchase")
 
+
 def get_asset_item_details(asset_items):
 	asset_items_data = {}
-	for d in frappe.get_all('Item', fields = ["name", "auto_create_assets", "asset_naming_series", "is_grouped_asset"],
-		filters = {'name': ('in', asset_items)}):
+	for d in frappe.get_all(
+		"Item",
+		fields=["name", "auto_create_assets", "asset_naming_series", "is_grouped_asset"],
+		filters={"name": ("in", asset_items)},
+	):
 		asset_items_data.setdefault(d.name, d)
 
 	return asset_items_data
 
+
 def validate_item_type(doc, fieldname, message):
 	# iterate through items and check if they are valid sales or purchase items
 	items = [d.item_code for d in doc.items if d.item_code]
@@ -722,16 +831,28 @@
 
 	item_list = ", ".join(["%s" % frappe.db.escape(d) for d in items])
 
-	invalid_items = [d[0] for d in frappe.db.sql("""
+	invalid_items = [
+		d[0]
+		for d in frappe.db.sql(
+			"""
 		select item_code from tabItem where name in ({0}) and {1}=0
-		""".format(item_list, fieldname), as_list=True)]
+		""".format(
+				item_list, fieldname
+			),
+			as_list=True,
+		)
+	]
 
 	if invalid_items:
 		items = ", ".join([d for d in invalid_items])
 
 		if len(invalid_items) > 1:
-			error_message = _("Following items {0} are not marked as {1} item. You can enable them as {1} item from its Item master").format(items, message)
+			error_message = _(
+				"Following items {0} are not marked as {1} item. You can enable them as {1} item from its Item master"
+			).format(items, message)
 		else:
-			error_message = _("Following item {0} is not marked as {1} item. You can enable them as {1} item from its Item master").format(items, message)
+			error_message = _(
+				"Following item {0} is not marked as {1} item. You can enable them as {1} item from its Item master"
+			).format(items, message)
 
 		frappe.throw(error_message)