Merge pull request #28605 from deepeshgarg007/ksa-e-invoice-new

refactor(KSA VAT): QR Code as per ZATKA specification
diff --git a/erpnext/__init__.py b/erpnext/__init__.py
index 9d99ebb..a5de50f 100644
--- a/erpnext/__init__.py
+++ b/erpnext/__init__.py
@@ -4,7 +4,7 @@
 
 from erpnext.hooks import regional_overrides
 
-__version__ = '13.9.0'
+__version__ = '14.0.0-dev'
 
 def get_default_company(user=None):
 	'''Get default company for user'''
diff --git a/erpnext/accounts/doctype/bank_reconciliation_tool/bank_reconciliation_tool.py b/erpnext/accounts/doctype/bank_reconciliation_tool/bank_reconciliation_tool.py
index 5cbf00b..e7371fb 100644
--- a/erpnext/accounts/doctype/bank_reconciliation_tool/bank_reconciliation_tool.py
+++ b/erpnext/accounts/doctype/bank_reconciliation_tool/bank_reconciliation_tool.py
@@ -434,7 +434,7 @@
 
 def get_ec_matching_query(bank_account, company, amount_condition):
 	# get matching Expense Claim query
-	mode_of_payments = [x["parent"] for x in frappe.db.get_list("Mode of Payment Account",
+	mode_of_payments = [x["parent"] for x in frappe.db.get_all("Mode of Payment Account",
 			filters={"default_account": bank_account}, fields=["parent"])]
 	mode_of_payments = '(\'' + '\', \''.join(mode_of_payments) + '\' )'
 	company_currency = get_company_currency(company)
diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.py b/erpnext/accounts/doctype/payment_entry/payment_entry.py
index 7aeb872..c1b056b 100644
--- a/erpnext/accounts/doctype/payment_entry/payment_entry.py
+++ b/erpnext/accounts/doctype/payment_entry/payment_entry.py
@@ -339,7 +339,7 @@
 		for k, v in no_oustanding_refs.items():
 			frappe.msgprint(
 				_("{} - {} now have {} as they had no outstanding amount left before submitting the Payment Entry.")
-					.format(k, frappe.bold(", ".join(d.reference_name for d in v)), frappe.bold("negative outstanding amount"))
+					.format(_(k), frappe.bold(", ".join(d.reference_name for d in v)), frappe.bold(_("negative outstanding amount")))
 				+ "<br><br>" + _("If this is undesirable please cancel the corresponding Payment Entry."),
 				title=_("Warning"), indicator="orange")
 
@@ -611,7 +611,7 @@
 
 			if not total_negative_outstanding:
 				frappe.throw(_("Cannot {0} {1} {2} without any negative outstanding invoice")
-					.format(self.payment_type, ("to" if self.party_type=="Customer" else "from"),
+					.format(_(self.payment_type), (_("to") if self.party_type=="Customer" else _("from")),
 						self.party_type), InvalidPaymentEntry)
 
 			elif paid_amount - additional_charges > total_negative_outstanding:
@@ -1092,7 +1092,7 @@
 
 	if not data:
 		frappe.msgprint(_("No outstanding invoices found for the {0} {1} which qualify the filters you have specified.")
-			.format(args.get("party_type").lower(), frappe.bold(args.get("party"))))
+			.format(_(args.get("party_type")).lower(), frappe.bold(args.get("party"))))
 
 	return data
 
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
index 516133a..48b5cb9 100644
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
@@ -728,7 +728,7 @@
 									"account": self.stock_received_but_not_billed,
 									"against": self.supplier,
 									"debit": flt(item.item_tax_amount, item.precision("item_tax_amount")),
-									"remarks": self.remarks or "Accounting Entry for Stock",
+									"remarks": self.remarks or _("Accounting Entry for Stock"),
 									"cost_center": self.cost_center,
 									"project": item.project or self.project
 								}, item=item)
@@ -936,7 +936,7 @@
 							"cost_center": tax.cost_center,
 							"against": self.supplier,
 							"credit": valuation_tax[tax.name],
-							"remarks": self.remarks or "Accounting Entry for Stock"
+							"remarks": self.remarks or _("Accounting Entry for Stock")
 						}, item=tax))
 
 	@property
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
index a1f3ee4..4538675 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
@@ -978,7 +978,7 @@
 		}
 
 		if (frm.doc.is_debit_note) {
-			frm.set_df_property('return_against', 'label', 'Adjustment Against');
+			frm.set_df_property('return_against', 'label', __('Adjustment Against'));
 		}
 
 		if (frappe.boot.active_domains.includes("Healthcare")) {
@@ -988,10 +988,10 @@
 			if (cint(frm.doc.docstatus==0) && cur_frm.page.current_view_name!=="pos" && !frm.doc.is_return) {
 				frm.add_custom_button(__('Healthcare Services'), function() {
 					get_healthcare_services_to_invoice(frm);
-				},"Get Items From");
+				},__("Get Items From"));
 				frm.add_custom_button(__('Prescriptions'), function() {
 					get_drugs_to_invoice(frm);
-				},"Get Items From");
+				},__("Get Items From"));
 			}
 		}
 		else {
diff --git a/erpnext/controllers/stock_controller.py b/erpnext/controllers/stock_controller.py
index ae17094..7073e32 100644
--- a/erpnext/controllers/stock_controller.py
+++ b/erpnext/controllers/stock_controller.py
@@ -134,7 +134,7 @@
 							"against": expense_account,
 							"cost_center": item_row.cost_center,
 							"project": item_row.project or self.get('project'),
-							"remarks": self.get("remarks") or "Accounting Entry for Stock",
+							"remarks": self.get("remarks") or _("Accounting Entry for Stock"),
 							"debit": flt(sle.stock_value_difference, precision),
 							"is_opening": item_row.get("is_opening") or self.get("is_opening") or "No",
 						}, warehouse_account[sle.warehouse]["account_currency"], item=item_row))
@@ -143,7 +143,7 @@
 							"account": expense_account,
 							"against": warehouse_account[sle.warehouse]["account"],
 							"cost_center": item_row.cost_center,
-							"remarks": self.get("remarks") or "Accounting Entry for Stock",
+							"remarks": self.get("remarks") or _("Accounting Entry for Stock"),
 							"credit": flt(sle.stock_value_difference, precision),
 							"project": item_row.get("project") or self.get("project"),
 							"is_opening": item_row.get("is_opening") or self.get("is_opening") or "No"
diff --git a/erpnext/hr/doctype/employee_advance/employee_advance.py b/erpnext/hr/doctype/employee_advance/employee_advance.py
index 8a8e8db..7aac2b6 100644
--- a/erpnext/hr/doctype/employee_advance/employee_advance.py
+++ b/erpnext/hr/doctype/employee_advance/employee_advance.py
@@ -5,6 +5,7 @@
 import frappe
 from frappe import _
 from frappe.model.document import Document
+from frappe.query_builder.functions import Sum
 from frappe.utils import flt, nowdate
 
 import erpnext
@@ -41,24 +42,34 @@
 			self.status = "Cancelled"
 
 	def set_total_advance_paid(self):
-		paid_amount = frappe.db.sql("""
-			select ifnull(sum(debit), 0) as paid_amount
-			from `tabGL Entry`
-			where against_voucher_type = 'Employee Advance'
-				and against_voucher = %s
-				and party_type = 'Employee'
-				and party = %s
-		""", (self.name, self.employee), as_dict=1)[0].paid_amount
+		gle = frappe.qb.DocType("GL Entry")
 
-		return_amount = frappe.db.sql("""
-			select ifnull(sum(credit), 0) as return_amount
-			from `tabGL Entry`
-			where against_voucher_type = 'Employee Advance'
-				and voucher_type != 'Expense Claim'
-				and against_voucher = %s
-				and party_type = 'Employee'
-				and party = %s
-		""", (self.name, self.employee), as_dict=1)[0].return_amount
+		paid_amount = (
+			frappe.qb.from_(gle)
+				.select(Sum(gle.debit).as_("paid_amount"))
+				.where(
+					(gle.against_voucher_type == 'Employee Advance')
+					& (gle.against_voucher == self.name)
+					& (gle.party_type == 'Employee')
+					& (gle.party == self.employee)
+					& (gle.docstatus == 1)
+					& (gle.is_cancelled == 0)
+				)
+			).run(as_dict=True)[0].paid_amount or 0
+
+		return_amount = (
+			frappe.qb.from_(gle)
+				.select(Sum(gle.credit).as_("return_amount"))
+				.where(
+					(gle.against_voucher_type == 'Employee Advance')
+					& (gle.voucher_type != 'Expense Claim')
+					& (gle.against_voucher == self.name)
+					& (gle.party_type == 'Employee')
+					& (gle.party == self.employee)
+					& (gle.docstatus == 1)
+					& (gle.is_cancelled == 0)
+				)
+			).run(as_dict=True)[0].return_amount or 0
 
 		if paid_amount != 0:
 			paid_amount = flt(paid_amount) / flt(self.exchange_rate)
diff --git a/erpnext/hr/doctype/employee_advance/test_employee_advance.py b/erpnext/hr/doctype/employee_advance/test_employee_advance.py
index 4ecfa60..5f2e720 100644
--- a/erpnext/hr/doctype/employee_advance/test_employee_advance.py
+++ b/erpnext/hr/doctype/employee_advance/test_employee_advance.py
@@ -34,6 +34,24 @@
 		journal_entry1 = make_payment_entry(advance)
 		self.assertRaises(EmployeeAdvanceOverPayment, journal_entry1.submit)
 
+	def test_paid_amount_on_pe_cancellation(self):
+		employee_name = make_employee("_T@employe.advance")
+		advance = make_employee_advance(employee_name)
+
+		pe = make_payment_entry(advance)
+		pe.submit()
+
+		advance.reload()
+
+		self.assertEqual(advance.paid_amount, 1000)
+		self.assertEqual(advance.status, "Paid")
+
+		pe.cancel()
+		advance.reload()
+
+		self.assertEqual(advance.paid_amount, 0)
+		self.assertEqual(advance.status, "Unpaid")
+
 	def test_repay_unclaimed_amount_from_salary(self):
 		employee_name = make_employee("_T@employe.advance")
 		advance = make_employee_advance(employee_name, {"repay_unclaimed_amount_from_salary": 1})
diff --git a/erpnext/hr/doctype/expense_claim_detail/expense_claim_detail.json b/erpnext/hr/doctype/expense_claim_detail/expense_claim_detail.json
index 70a48f9..6edbcb5c 100644
--- a/erpnext/hr/doctype/expense_claim_detail/expense_claim_detail.json
+++ b/erpnext/hr/doctype/expense_claim_detail/expense_claim_detail.json
@@ -94,7 +94,6 @@
    "fieldtype": "Currency",
    "in_list_view": 1,
    "label": "Sanctioned Amount",
-   "no_copy": 1,
    "oldfieldname": "sanctioned_amount",
    "oldfieldtype": "Currency",
    "options": "Company:company:default_currency",
@@ -120,7 +119,7 @@
  "idx": 1,
  "istable": 1,
  "links": [],
- "modified": "2020-09-18 17:26:09.703215",
+ "modified": "2021-11-26 14:23:45.539922",
  "modified_by": "Administrator",
  "module": "HR",
  "name": "Expense Claim Detail",
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 cf19cbf..090a3e7 100644
--- a/erpnext/manufacturing/report/bom_stock_calculated/bom_stock_calculated.py
+++ b/erpnext/manufacturing/report/bom_stock_calculated/bom_stock_calculated.py
@@ -89,7 +89,7 @@
 			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_list('Item Manufacturer', fields = ["manufacturer", "manufacturer_part_no", "parent"])
+	details = frappe.get_all('Item Manufacturer', fields = ["manufacturer", "manufacturer_part_no", "parent"])
 	manufacture_details = frappe._dict()
 	for detail in details:
 		dic = manufacture_details.setdefault(detail.get('parent'), {})
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index e475229..897e70c 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -287,7 +287,7 @@
 erpnext.patches.v13_0.custom_fields_for_taxjar_integration          #08-11-2021
 erpnext.patches.v13_0.set_operation_time_based_on_operating_cost
 erpnext.patches.v13_0.validate_options_for_data_field
-erpnext.patches.v13_0.create_gst_payment_entry_fields
+erpnext.patches.v13_0.create_gst_payment_entry_fields #27-11-2021
 erpnext.patches.v14_0.delete_shopify_doctypes
 erpnext.patches.v13_0.fix_invoice_statuses
 erpnext.patches.v13_0.replace_supplier_item_group_with_party_specific_item
diff --git a/erpnext/patches/v13_0/create_gst_payment_entry_fields.py b/erpnext/patches/v13_0/create_gst_payment_entry_fields.py
index 7e6d67c..4166945 100644
--- a/erpnext/patches/v13_0/create_gst_payment_entry_fields.py
+++ b/erpnext/patches/v13_0/create_gst_payment_entry_fields.py
@@ -9,24 +9,29 @@
 	frappe.reload_doc('accounts', 'doctype', 'advance_taxes_and_charges')
 	frappe.reload_doc('accounts', 'doctype', 'payment_entry')
 
-	custom_fields = {
-		'Payment Entry': [
-			dict(fieldname='gst_section', label='GST Details', fieldtype='Section Break', insert_after='deductions',
-				print_hide=1, collapsible=1),
-			dict(fieldname='company_address', label='Company Address', fieldtype='Link', insert_after='gst_section',
-				print_hide=1, options='Address'),
-			dict(fieldname='company_gstin', label='Company GSTIN',
-				fieldtype='Data', insert_after='company_address',
-				fetch_from='company_address.gstin', print_hide=1, read_only=1),
-			dict(fieldname='place_of_supply', label='Place of Supply',
-				fieldtype='Data', insert_after='company_gstin',
-				print_hide=1, read_only=1),
-			dict(fieldname='customer_address', label='Customer Address', fieldtype='Link', insert_after='place_of_supply',
-				print_hide=1, options='Address', depends_on = 'eval:doc.party_type == "Customer"'),
-			dict(fieldname='customer_gstin', label='Customer GSTIN',
-				fieldtype='Data', insert_after='customer_address',
-				fetch_from='customer_address.gstin', print_hide=1, read_only=1)
-		]
-	}
+	if frappe.db.exists('Company', {'country': 'India'}):
+		custom_fields = {
+			'Payment Entry': [
+				dict(fieldname='gst_section', label='GST Details', fieldtype='Section Break', insert_after='deductions',
+					print_hide=1, collapsible=1),
+				dict(fieldname='company_address', label='Company Address', fieldtype='Link', insert_after='gst_section',
+					print_hide=1, options='Address'),
+				dict(fieldname='company_gstin', label='Company GSTIN',
+					fieldtype='Data', insert_after='company_address',
+					fetch_from='company_address.gstin', print_hide=1, read_only=1),
+				dict(fieldname='place_of_supply', label='Place of Supply',
+					fieldtype='Data', insert_after='company_gstin',
+					print_hide=1, read_only=1),
+				dict(fieldname='customer_address', label='Customer Address', fieldtype='Link', insert_after='place_of_supply',
+					print_hide=1, options='Address', depends_on = 'eval:doc.party_type == "Customer"'),
+				dict(fieldname='customer_gstin', label='Customer GSTIN',
+					fieldtype='Data', insert_after='customer_address',
+					fetch_from='customer_address.gstin', print_hide=1, read_only=1)
+			]
+		}
 
-	create_custom_fields(custom_fields, update=True)
\ No newline at end of file
+		create_custom_fields(custom_fields, update=True)
+	else:
+		fields = ['gst_section', 'company_address', 'company_gstin', 'place_of_supply', 'customer_address', 'customer_gstin']
+		for field in fields:
+			frappe.delete_doc_if_exists("Custom Field", f"Payment Entry-{field}")
\ No newline at end of file
diff --git a/erpnext/regional/report/eway_bill/eway_bill.py b/erpnext/regional/report/eway_bill/eway_bill.py
index 91a4767..f3fe5e8 100644
--- a/erpnext/regional/report/eway_bill/eway_bill.py
+++ b/erpnext/regional/report/eway_bill/eway_bill.py
@@ -106,14 +106,14 @@
 		row.update({'ship_to_state': row.to_state})
 
 def set_taxes(row, filters):
-	taxes = frappe.get_list("Sales Taxes and Charges",
+	taxes = frappe.get_all("Sales Taxes and Charges",
 				filters={
 					'parent': row.dn_id
 				},
 				fields=('item_wise_tax_detail', 'account_head'))
 
 	account_list = ["cgst_account", "sgst_account", "igst_account", "cess_account"]
-	taxes_list = frappe.get_list("GST Account",
+	taxes_list = frappe.get_all("GST Account",
 		filters={
 			"parent": "GST Settings",
 			"company": filters.company
diff --git a/erpnext/regional/report/vat_audit_report/vat_audit_report.py b/erpnext/regional/report/vat_audit_report/vat_audit_report.py
index 5a281a4..17e5064 100644
--- a/erpnext/regional/report/vat_audit_report/vat_audit_report.py
+++ b/erpnext/regional/report/vat_audit_report/vat_audit_report.py
@@ -41,7 +41,7 @@
 		return self.columns, self.data
 
 	def get_sa_vat_accounts(self):
-		self.sa_vat_accounts = frappe.get_list("South Africa VAT Account",
+		self.sa_vat_accounts = frappe.get_all("South Africa VAT Account",
 			filters = {"parent": self.filters.company}, pluck="account")
 		if not self.sa_vat_accounts and not frappe.flags.in_test and not frappe.flags.in_migrate:
 			link_to_settings = get_link_to_form("South Africa VAT Settings", "", label="South Africa VAT Settings")
diff --git a/erpnext/stock/doctype/bin/bin.py b/erpnext/stock/doctype/bin/bin.py
index 48b1cc5..da9c66d 100644
--- a/erpnext/stock/doctype/bin/bin.py
+++ b/erpnext/stock/doctype/bin/bin.py
@@ -4,6 +4,8 @@
 
 import frappe
 from frappe.model.document import Document
+from frappe.query_builder import Case
+from frappe.query_builder.functions import Coalesce, Sum
 from frappe.utils import flt, nowdate
 
 
@@ -19,34 +21,42 @@
 			- flt(self.reserved_qty_for_production) - flt(self.reserved_qty_for_sub_contract))
 
 	def get_first_sle(self):
-		sle = frappe.db.sql("""
-			select * from `tabStock Ledger Entry`
-			where item_code = %s
-			and warehouse = %s
-			order by timestamp(posting_date, posting_time) asc, creation asc
-			limit 1
-		""", (self.item_code, self.warehouse), as_dict=1)
-		return sle and sle[0] or None
+		sle = frappe.qb.DocType("Stock Ledger Entry")
+		first_sle = (
+				frappe.qb.from_(sle)
+					.select("*")
+					.where((sle.item_code == self.item_code) & (sle.warehouse == self.warehouse))
+					.orderby(sle.posting_date, sle.posting_time, sle.creation)
+					.limit(1)
+				).run(as_dict=True)
+
+		return first_sle and first_sle[0] or None
 
 	def update_reserved_qty_for_production(self):
 		'''Update qty reserved for production from Production Item tables
 			in open work orders'''
-		self.reserved_qty_for_production = frappe.db.sql('''
-			SELECT
-				CASE WHEN ifnull(skip_transfer, 0) = 0 THEN
-					SUM(item.required_qty - item.transferred_qty)
-				ELSE
-					SUM(item.required_qty - item.consumed_qty)
-				END
-			FROM `tabWork Order` pro, `tabWork Order Item` item
-			WHERE
-				item.item_code = %s
-				and item.parent = pro.name
-				and pro.docstatus = 1
-				and item.source_warehouse = %s
-				and pro.status not in ("Stopped", "Completed")
-				and (item.required_qty > item.transferred_qty or item.required_qty > item.consumed_qty)
-		''', (self.item_code, self.warehouse))[0][0]
+
+		wo = frappe.qb.DocType("Work Order")
+		wo_item = frappe.qb.DocType("Work Order Item")
+
+		self.reserved_qty_for_production = (
+				frappe.qb
+					.from_(wo)
+					.from_(wo_item)
+					.select(Case()
+							.when(wo.skip_transfer == 0, Sum(wo_item.required_qty - wo_item.transferred_qty))
+							.else_(Sum(wo_item.required_qty - wo_item.consumed_qty))
+						)
+					.where(
+						(wo_item.item_code == self.item_code)
+						& (wo_item.parent == wo.name)
+						& (wo.docstatus == 1)
+						& (wo_item.source_warehouse == self.warehouse)
+						& (wo.status.notin(["Stopped", "Completed"]))
+						& ((wo_item.required_qty > wo_item.transferred_qty)
+							| (wo_item.required_qty > wo_item.consumed_qty))
+					)
+		).run()[0][0] or 0.0
 
 		self.set_projected_qty()
 
@@ -55,36 +65,53 @@
 
 	def update_reserved_qty_for_sub_contracting(self):
 		#reserved qty
-		reserved_qty_for_sub_contract = frappe.db.sql('''
-			select ifnull(sum(itemsup.required_qty),0)
-			from `tabPurchase Order` po, `tabPurchase Order Item Supplied` itemsup
-			where
-				itemsup.rm_item_code = %s
-				and itemsup.parent = po.name
-				and po.docstatus = 1
-				and po.is_subcontracted = 'Yes'
-				and po.status != 'Closed'
-				and po.per_received < 100
-				and itemsup.reserve_warehouse = %s''', (self.item_code, self.warehouse))[0][0]
 
-		#Get Transferred Entries
-		materials_transferred = frappe.db.sql("""
-			select
-				ifnull(sum(CASE WHEN se.is_return = 1 THEN (transfer_qty * -1) ELSE transfer_qty END),0)
-			from
-				`tabStock Entry` se, `tabStock Entry Detail` sed, `tabPurchase Order` po
-			where
-				se.docstatus=1
-				and se.purpose='Send to Subcontractor'
-				and ifnull(se.purchase_order, '') !=''
-				and (sed.item_code = %(item)s or sed.original_item = %(item)s)
-				and se.name = sed.parent
-				and se.purchase_order = po.name
-				and po.docstatus = 1
-				and po.is_subcontracted = 'Yes'
-				and po.status != 'Closed'
-				and po.per_received < 100
-		""", {'item': self.item_code})[0][0]
+		po = frappe.qb.DocType("Purchase Order")
+		supplied_item = frappe.qb.DocType("Purchase Order Item Supplied")
+
+		reserved_qty_for_sub_contract = (
+				frappe.qb
+					.from_(po)
+					.from_(supplied_item)
+					.select(Sum(Coalesce(supplied_item.required_qty, 0)))
+					.where(
+						(supplied_item.rm_item_code == self.item_code)
+						& (po.name == supplied_item.parent)
+						& (po.docstatus == 1)
+						& (po.is_subcontracted == "Yes")
+						& (po.status != "Closed")
+						& (po.per_received < 100)
+						& (supplied_item.reserve_warehouse == self.warehouse)
+					)
+				).run()[0][0] or 0.0
+
+		se = frappe.qb.DocType("Stock Entry")
+		se_item = frappe.qb.DocType("Stock Entry Detail")
+
+		materials_transferred = (
+				frappe.qb
+					.from_(se)
+					.from_(se_item)
+					.from_(po)
+					.select(Sum(
+						Case()
+							.when(se.is_return == 1, se_item.transfer_qty * -1)
+							.else_(se_item.transfer_qty)
+						))
+					.where(
+						(se.docstatus == 1)
+						& (se.purpose == "Send to Subcontractor")
+						& (Coalesce(se.purchase_order, "") != "")
+						& ((se_item.item_code == self.item_code)
+							| (se_item.original_item == self.item_code))
+						& (se.name == se_item.parent)
+						& (po.name == se.purchase_order)
+						& (po.docstatus == 1)
+						& (po.is_subcontracted == "Yes")
+						& (po.status != "Closed")
+						& (po.per_received < 100)
+					)
+				).run()[0][0] or 0.0
 
 		if reserved_qty_for_sub_contract > materials_transferred:
 			reserved_qty_for_sub_contract = reserved_qty_for_sub_contract - materials_transferred
@@ -160,4 +187,4 @@
 		'indented_qty': indented_qty,
 		'planned_qty': planned_qty,
 		'projected_qty': projected_qty
-	})
\ No newline at end of file
+	})
diff --git a/erpnext/stock/doctype/item/item.py b/erpnext/stock/doctype/item/item.py
index 5daabe8..c9b8a37 100644
--- a/erpnext/stock/doctype/item/item.py
+++ b/erpnext/stock/doctype/item/item.py
@@ -222,10 +222,11 @@
 					'route')) + '/' + self.scrub((self.item_name or self.item_code) + '-' + random_string(5))
 
 	def validate_website_image(self):
+		"""Validate if the website image is a public file"""
+
 		if frappe.flags.in_import:
 			return
 
-		"""Validate if the website image is a public file"""
 		auto_set_website_image = False
 		if not self.website_image and self.image:
 			auto_set_website_image = True
@@ -255,10 +256,11 @@
 			self.website_image = None
 
 	def make_thumbnail(self):
+		"""Make a thumbnail of `website_image`"""
+
 		if frappe.flags.in_import:
 			return
 
-		"""Make a thumbnail of `website_image`"""
 		import requests.exceptions
 
 		if not self.is_new() and self.website_image != frappe.db.get_value(self.doctype, self.name, "website_image"):
diff --git a/erpnext/stock/doctype/item/test_item.py b/erpnext/stock/doctype/item/test_item.py
index 7237178..8b1224b 100644
--- a/erpnext/stock/doctype/item/test_item.py
+++ b/erpnext/stock/doctype/item/test_item.py
@@ -488,7 +488,7 @@
 			item_doc.save()
 
 		# Check values saved correctly
-		barcodes = frappe.get_list(
+		barcodes = frappe.get_all(
 			'Item Barcode',
 			fields=['barcode', 'barcode_type'],
 			filters={'parent': item_code})
diff --git a/erpnext/stock/get_item_details.py b/erpnext/stock/get_item_details.py
index e00382b..cd180a4 100644
--- a/erpnext/stock/get_item_details.py
+++ b/erpnext/stock/get_item_details.py
@@ -299,7 +299,7 @@
 		"warehouse": warehouse,
 		"income_account": get_default_income_account(args, item_defaults, item_group_defaults, brand_defaults),
 		"expense_account": expense_account or get_default_expense_account(args, item_defaults, item_group_defaults, brand_defaults) ,
-		"discount_account": None or get_default_discount_account(args, item_defaults),
+		"discount_account": get_default_discount_account(args, item_defaults),
 		"cost_center": get_default_cost_center(args, item_defaults, item_group_defaults, brand_defaults),
 		'has_serial_no': item.has_serial_no,
 		'has_batch_no': item.has_batch_no,
@@ -317,6 +317,7 @@
 		"net_rate": 0.0,
 		"net_amount": 0.0,
 		"discount_percentage": 0.0,
+		"discount_amount": 0.0,
 		"supplier": get_default_supplier(args, item_defaults, item_group_defaults, brand_defaults),
 		"update_stock": args.get("update_stock") if args.get('doctype') in ['Sales Invoice', 'Purchase Invoice'] else 0,
 		"delivered_by_supplier": item.delivered_by_supplier if args.get("doctype") in ["Sales Order", "Sales Invoice"] else 0,
diff --git a/erpnext/stock/report/warehouse_wise_item_balance_age_and_value/warehouse_wise_item_balance_age_and_value.py b/erpnext/stock/report/warehouse_wise_item_balance_age_and_value/warehouse_wise_item_balance_age_and_value.py
index d3af5f6..4d1491b 100644
--- a/erpnext/stock/report/warehouse_wise_item_balance_age_and_value/warehouse_wise_item_balance_age_and_value.py
+++ b/erpnext/stock/report/warehouse_wise_item_balance_age_and_value/warehouse_wise_item_balance_age_and_value.py
@@ -46,8 +46,8 @@
 		item_balance.setdefault((item, item_map[item]["item_group"]), [])
 		total_stock_value = 0.00
 		for wh in warehouse_list:
-			row += [qty_dict.bal_qty] if wh.name in warehouse else [0.00]
-			total_stock_value += qty_dict.bal_val if wh.name in warehouse else 0.00
+			row += [qty_dict.bal_qty] if wh.name == warehouse else [0.00]
+			total_stock_value += qty_dict.bal_val if wh.name == warehouse else 0.00
 
 		item_balance[(item, item_map[item]["item_group"])].append(row)
 		item_value.setdefault((item, item_map[item]["item_group"]),[])