code cleanup
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index 89be499..6d15d54 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -653,3 +653,4 @@
 erpnext.patches.v12_0.set_against_blanket_order_in_sales_and_purchase_order
 erpnext.patches.v12_0.set_cost_center_in_child_table_of_expense_claim
 erpnext.patches.v12_0.set_lead_title_field
+erpnext.patches.v12_0.set_permission_einvoicing
diff --git a/erpnext/patches/v12_0/set_permission_einvoicing.py b/erpnext/patches/v12_0/set_permission_einvoicing.py
index c01f34a..1095c8c 100644
--- a/erpnext/patches/v12_0/set_permission_einvoicing.py
+++ b/erpnext/patches/v12_0/set_permission_einvoicing.py
@@ -1,4 +1,5 @@
 import frappe
+from erpnext.regional.italy.setup import make_custom_fields
 from frappe.permissions import add_permission, update_permission_property
 
 def execute():
@@ -7,6 +8,8 @@
 	if not company:
 		return
 
+	make_custom_fields()
+
 	add_permission('Import Supplier Invoice', 'Accounts Manager', 0)
 	update_permission_property('Import Supplier Invoice', 'Accounts Manager', 0, 'write', 1)
 	update_permission_property('Import Supplier Invoice', 'Accounts Manager', 0, 'create', 1)
\ No newline at end of file
diff --git a/erpnext/regional/doctype/import_supplier_invoice/import_supplier_invoice.js b/erpnext/regional/doctype/import_supplier_invoice/import_supplier_invoice.js
index bbc0f92..9f1a092 100644
--- a/erpnext/regional/doctype/import_supplier_invoice/import_supplier_invoice.js
+++ b/erpnext/regional/doctype/import_supplier_invoice/import_supplier_invoice.js
@@ -11,9 +11,20 @@
 		});
 	},
 	setup: function(frm) {
-		frm.set_query("tax_account", function() {
+		frm.set_query("tax_account", function(doc) {
 			return {
-				filters: { account_type: 'Tax' }
+				filters: {
+					account_type: 'Tax',
+					company: doc.company
+				}
+			};
+		});
+
+		frm.set_query("default_buying_price_list", function(doc) {
+			return {
+				filters: {
+					currency: frappe.get_doc(":Company", doc.company).default_currency
+				}
 			};
 		});
 	}
diff --git a/erpnext/regional/doctype/import_supplier_invoice/import_supplier_invoice.json b/erpnext/regional/doctype/import_supplier_invoice/import_supplier_invoice.json
index aabf9de..59e955c 100644
--- a/erpnext/regional/doctype/import_supplier_invoice/import_supplier_invoice.json
+++ b/erpnext/regional/doctype/import_supplier_invoice/import_supplier_invoice.json
@@ -1,4 +1,5 @@
 {
+ "actions": [],
  "creation": "2019-10-15 12:33:21.845329",
  "doctype": "DocType",
  "editable_grid": 1,
@@ -7,9 +8,11 @@
   "invoice_series",
   "company",
   "item_code",
+  "column_break_5",
   "supplier_group",
   "tax_account",
-  "column_break_5",
+  "default_buying_price_list",
+  "upload_xml_invoices_section",
   "zip_file",
   "import_invoices",
   "status"
@@ -75,9 +78,22 @@
    "label": "Invoice Series",
    "options": "ACC-PINV-.YYYY.-",
    "reqd": 1
+  },
+  {
+   "fieldname": "default_buying_price_list",
+   "fieldtype": "Link",
+   "label": "Default Buying Price List",
+   "options": "Price List",
+   "reqd": 1
+  },
+  {
+   "fieldname": "upload_xml_invoices_section",
+   "fieldtype": "Section Break",
+   "label": "Upload XML Invoices"
   }
  ],
- "modified": "2019-10-19 00:15:11.404733",
+ "links": [],
+ "modified": "2019-12-10 16:37:26.793398",
  "modified_by": "Administrator",
  "module": "Regional",
  "name": "Import Supplier Invoice",
diff --git a/erpnext/regional/doctype/import_supplier_invoice/import_supplier_invoice.py b/erpnext/regional/doctype/import_supplier_invoice/import_supplier_invoice.py
index 15e6344..1d21d39 100644
--- a/erpnext/regional/doctype/import_supplier_invoice/import_supplier_invoice.py
+++ b/erpnext/regional/doctype/import_supplier_invoice/import_supplier_invoice.py
@@ -8,13 +8,13 @@
 import re
 import traceback
 import zipfile
-import frappe
+import frappe, erpnext
 from frappe import _
 from frappe.model.document import Document
 from frappe.custom.doctype.custom_field.custom_field import create_custom_field
 from frappe.utils.data import format_datetime
 from bs4 import BeautifulSoup as bs
-from frappe.utils import cint, flt, today, nowdate, add_days, get_files_path
+from frappe.utils import cint, flt, today, nowdate, add_days, get_files_path, get_datetime_str
 import dateutil
 from frappe.utils.file_manager import save_file
 
@@ -28,61 +28,20 @@
 			self.name = "Import Invoice on " + format_datetime(self.creation)
 
 	def import_xml_data(self):
-		pi_count = 0
 		import_file = frappe.get_doc("File", {"file_url": self.zip_file})
 		self.publish("File Import", _("Processing XML Files"), 1, 3)
 
+		self.file_count = 0
+		self.purchase_invoices_count = 0
+		self.default_uom = frappe.db.get_value("Stock Settings", fieldname="stock_uom")
+
 		with zipfile.ZipFile(get_full_path(self.zip_file)) as zf:
-			file_count = 0
 			for file_name in zf.namelist():
-				items = []
-				taxes = []
-				terms = []
-				encoded_content = zf.read(file_name)
-
-				try:
-					content = encoded_content.decode("utf-8-sig")
-				except UnicodeDecodeError:
-					try:
-						content = encoded_content.decode("utf-16")
-					except UnicodeDecodeError as e:
-						frappe.log_error(message=e, title="UTF-16 encoding error for File Name: " + file_name)
-
+				content = get_file_content(file_name, zf)
 				file_content = bs(content, "xml")
+				self.prepare_data_for_import(file_content, file_name, content)
 
-				for line in file_content.find_all("DatiGeneraliDocumento"):
-					document_type = line.TipoDocumento.text
-					bill_date = dateutil.parser.parse(line.Data.text).strftime("%Y-%m-%d")
-					invoice_no = line.Numero.text
-					if len(invoice_no) != 0:
-						total_discount = 0
-
-						supp_dict = get_supplier_info_from_file(file_content)
-						destination_code = get_destination_code_from_file(file_content)
-						items, return_invoice, total_discount = get_item_from_file(file_content, self.item_code)
-						taxes = get_taxes_from_file(file_content, self.tax_account)
-						terms = get_payment_terms_from_file(file_content)
-
-						supplier_name = create_supplier(supplier = supp_dict.get('supplier'), supplier_group = self.supplier_group, 
-											tax_id = supp_dict.get('tax_id'), fiscal_code = supp_dict.get('fiscal_code'),
-											fiscal_regime = supp_dict.get('fiscal_regime'))
-
-						address = create_address(supplier_name = supplier_name, address_line1 = supp_dict.get('address_line1'), 
-									city = supp_dict.get('city'), province = supp_dict.get('province'), 
-									pin_code = supp_dict.get('pin_code'), country = supp_dict.get('country'))
-
-						pi_name = create_purchase_invoice(company = self.company, naming_series = self.invoice_series,
-									supplier_name = supplier_name, bill_no = invoice_no,document_type = document_type, 
-									bill_date = bill_date,is_return = return_invoice, destination_code = destination_code,
-									total_discount = total_discount, items = items,taxes = taxes, terms = terms,
-									file_name = file_name)
-
-						file_count += 1
-						if pi_name:
-							pi_count += 1
-							file_save = save_file(file_name, encoded_content, "Purchase Invoice", pi_name, folder=None, decode=False, is_private=0, df=None)
-
-		if pi_count == file_count:
+		if self.purchase_invoices_count == self.file_count:
 			self.status = "File Import Completed"
 			self.publish("File Import", _("XML Files Processed"), 2, 3)
 		else:
@@ -92,6 +51,78 @@
 		self.save()
 		self.publish("File Import", _("XML Files Processed"), 3, 3)
 
+	def prepare_data_for_import(self, file_content, file_name, encoded_content):
+		for line in file_content.find_all("DatiGeneraliDocumento"):
+			invoices_args = {
+				"company": self.company,
+				"naming_series": self.invoice_series,
+				"document_type": line.TipoDocumento.text,
+				"bill_date": get_datetime_str(line.Data.text),
+				"invoice_no": line.Numero.text,
+				"total_discount": 0,
+				"items": [],
+				"buying_price_list": self.default_buying_price_list
+			}
+
+			if not invoices_args.get("invoice_no", ''): return
+
+			supp_dict = get_supplier_details(file_content)
+			invoices_args["destination_code"] = get_destination_code_from_file(file_content)
+			invoices_args["taxes"] = get_taxes_from_file(file_content, self.tax_account)
+			invoices_args["terms"] = get_payment_terms_from_file(file_content)
+			self.prepare_items_for_invoice(file_content, invoices_args)
+
+			supplier_name = create_supplier(self.supplier_group, supp_dict)
+			address = create_address(supplier_name, supp_dict)
+			pi_name = create_purchase_invoice(supplier_name, file_name, invoices_args)
+
+			self.file_count += 1
+			if pi_name:
+				self.purchase_invoices_count += 1
+				file_save = save_file(file_name, encoded_content, "Purchase Invoice",
+					pi_name, folder=None, decode=False, is_private=0, df=None)
+
+	def prepare_items_for_invoice(self, file_content, invoices_args):
+		qty = 1
+		rate, tax_rate = [0 ,0]
+		uom = self.default_uom
+
+		#read file for item information
+		for line in file_content.find_all("DettaglioLinee"):
+			if line.find("PrezzoUnitario") and line.find("PrezzoTotale"):
+				rate = flt(line.PrezzoUnitario.text) or 0
+				line_total = flt(line.PrezzoTotale.text) or 0
+
+				if rate and flt(line_total) / rate != 1.0 and line.find("Quantita"):
+					qty = flt(line.Quantita.text) or 0
+					if line.find("UnitaMisura"):
+						uom = create_uom(line.UnitaMisura.text)
+
+				if (rate < 0 and line_total < 0):
+					qty *= -1
+					invoices_args["return_invoice"] = 1
+
+				if line.find("AliquotaIVA"):
+					tax_rate = flt(line.AliquotaIVA.text)
+
+				line_str = re.sub('[^A-Za-z0-9]+', '-', line.Descrizione.text)
+				item_name = line_str[0:140]
+
+				invoices_args['items'].append({
+					"item_code": self.item_code,
+					"item_name": item_name,
+					"description": line_str,
+					"qty": qty,
+					"uom": uom,
+					"rate": abs(rate),
+					"conversion_factor": 1.0,
+					"tax_rate": tax_rate
+				})
+
+				for disc_line in line.find_all("ScontoMaggiorazione"):
+					if disc_line.find("Percentuale"):
+						invoices_args["total_discount"] += flt((flt(disc_line.Percentuale.text) / 100) * (rate * qty))
+
 	def process_file_data(self):
 		self.status = "Processing File Data"
 		self.save()
@@ -100,100 +131,47 @@
 	def publish(self, title, message, count, total):
 		frappe.publish_realtime("import_invoice_update", {"title": title, "message": message, "count": count, "total": total})
 
-def get_supplier_info_from_file(file_content):
+def get_file_content(file_name, zip_file_object):
+	content = ''
+	encoded_content = zip_file_object.read(file_name)
+
+	try:
+		content = encoded_content.decode("utf-8-sig")
+	except UnicodeDecodeError:
+		try:
+			content = encoded_content.decode("utf-16")
+		except UnicodeDecodeError as e:
+			frappe.log_error(message=e, title="UTF-16 encoding error for File Name: " + file_name)
+
+	return content
+
+def get_supplier_details(file_content):
 	supplier_info = {}
 	for line in file_content.find_all("CedentePrestatore"):
-		tax_id = line.DatiAnagrafici.IdPaese.text + line.DatiAnagrafici.IdCodice.text
+		supplier_info['tax_id'] = line.DatiAnagrafici.IdPaese.text + line.DatiAnagrafici.IdCodice.text
 		if line.find("CodiceFiscale"):
-			fiscal_code = line.DatiAnagrafici.CodiceFiscale.text
-		else:
-			fiscal_code = ""
+			supplier_info['fiscal_code'] = line.DatiAnagrafici.CodiceFiscale.text
+
 		if line.find("RegimeFiscale"):
-			fiscal_regime = line.DatiAnagrafici.RegimeFiscale.text
-		else:
-			fiscal_regime = ""
+			supplier_info['fiscal_regime'] = line.DatiAnagrafici.RegimeFiscale.text
+
 		if line.find("Denominazione"):
-			supplier = line.DatiAnagrafici.Anagrafica.Denominazione.text
+			supplier_info['supplier'] = line.DatiAnagrafici.Anagrafica.Denominazione.text
+
 		if line.find("Nome"):
-			supplier = line.DatiAnagrafici.Anagrafica.Nome.text + " " + line.DatiAnagrafici.Anagrafica.Cognome.text
-		address_line1 = line.Sede.Indirizzo.text
-		city = line.Sede.Comune.text
+			supplier_info['supplier'] = (line.DatiAnagrafici.Anagrafica.Nome.text
+				+ " " + line.DatiAnagrafici.Anagrafica.Cognome.text)
+
+		supplier_info['address_line1'] = line.Sede.Indirizzo.text
+		supplier_info['city'] = line.Sede.Comune.text
 		if line.find("Provincia"):
-			province = line.Sede.Provincia.text
-		else:
-			province = ""
-		pin_code = line.Sede.CAP.text
-		country = get_country(line.Sede.Nazione.text)
-		#set the dict values
-		supplier_info['tax_id'] = tax_id
-		supplier_info['fiscal_code'] = fiscal_code
-		supplier_info['fiscal_regime'] = fiscal_regime
-		supplier_info['supplier'] = supplier
-		supplier_info['address_line1'] = address_line1
-		supplier_info['city'] = city
-		supplier_info['province'] = province
-		supplier_info['pin_code'] = pin_code
-		supplier_info['country'] = country
+			supplier_info['province'] = line.Sede.Provincia.text
+
+		supplier_info['pin_code'] = line.Sede.CAP.text
+		supplier_info['country'] = get_country(line.Sede.Nazione.text)
 
 		return supplier_info
 
-def get_item_from_file(file_content, item_code):
-	items = []
-	total_discount = 0
-	default_uom = frappe.db.get_value("Stock Settings", fieldname="stock_uom")
-	#read file for item information
-	for line in file_content.find_all("DettaglioLinee"):
-		if line.find("PrezzoUnitario") and line.find("PrezzoTotale"):
-			unit_rate = flt(line.PrezzoUnitario.text) or 0
-			line_total = flt(line.PrezzoTotale.text) or 0
-
-			if (unit_rate == 0.0):
-				qty = 1.0
-				uom = default_uom
-				rate = tax_rate = 0
-			else:
-				if (line_total / unit_rate) == 1.0:
-					qty = 1.0
-					uom = default_uom
-				else:
-					if line.find("Quantita"):
-						qty = flt(line.Quantita.text) or 0
-						if line.find("UnitaMisura"):
-							uom = create_uom(line.UnitaMisura.text)
-						else:
-							uom = default_uom
-
-				if (unit_rate < 0 and line_total < 0):
-					qty *= -1
-					return_invoice = 1
-					unit_rate *= -1
-				else:
-					return_invoice = 0
-
-				rate = unit_rate
-				if line.find("AliquotaIVA"):
-					tax_rate = flt(line.AliquotaIVA.text)
-
-			line_str = re.sub('[^A-Za-z0-9]+', '-', line.Descrizione.text)
-			item_name = line_str[0:140]
-			items.append({
-							"item_code": item_code,
-							"item_name": item_name,
-							"description": line_str,
-							"qty": qty,
-							"uom": uom,
-							"rate": rate,
-							"conversion_factor": 1.0,
-							"tax_rate": tax_rate
-						})
-
-			for disc_line in line.find_all("ScontoMaggiorazione"):
-				if disc_line.find("Percentuale"):
-					discount = flt(disc_line.Percentuale.text) or 0
-					total_discount += flt((discount / 100) * (rate * qty))
-
-	return items, return_invoice, total_discount
-
 def get_taxes_from_file(file_content, tax_account):
 	taxes = []
 	#read file for taxes information
@@ -227,22 +205,24 @@
 		else:
 			due_date = today()
 		terms.append({
-						"mode_of_payment_code": mop_code,
-						"bank_account_iban": line.IBAN.text if line.find("IBAN") else "",
-						"due_date": due_date,
-						"payment_amount": line.ImportoPagamento.text
+			"mode_of_payment_code": mop_code,
+			"bank_account_iban": line.IBAN.text if line.find("IBAN") else "",
+			"due_date": due_date,
+			"payment_amount": line.ImportoPagamento.text
 		})
 
 	return terms
 
 def get_destination_code_from_file(file_content):
+	destination_code = ''
 	for line in file_content.find_all("DatiTrasmissione"):
 		destination_code = line.CodiceDestinatario.text
 
 	return destination_code
 
-def create_supplier(**args):
+def create_supplier(supplier_group, args):
 	args = frappe._dict(args)
+
 	existing_supplier_name = frappe.db.get_value("Supplier",
 				filters={"tax_id": args.tax_id}, fieldname="name")
 	if existing_supplier_name:
@@ -258,11 +238,7 @@
 				["Dynamic Link", "parenttype", "=", "Contact"]
 			]
 
-		existing_contacts = frappe.get_list("Contact", filters)
-
-		if existing_contacts:
-			pass
-		else:
+		if not frappe.get_list("Contact", filters):
 			new_contact = frappe.new_doc("Contact")
 			new_contact.first_name = args.supplier
 			new_contact.append('links', {
@@ -276,7 +252,7 @@
 		
 		new_supplier = frappe.new_doc("Supplier")
 		new_supplier.supplier_name = args.supplier
-		new_supplier.supplier_group = args.supplier_group
+		new_supplier.supplier_group = supplier_group
 		new_supplier.tax_id = args.tax_id
 		new_supplier.fiscal_code = args.fiscal_code
 		new_supplier.fiscal_regime = args.fiscal_regime
@@ -293,11 +269,12 @@
 
 		return new_supplier.name
 
-def create_address(**args):
+def create_address(supplier_name, args):
 	args = frappe._dict(args)
+
 	filters = [
 			["Dynamic Link", "link_doctype", "=", "Supplier"],
-			["Dynamic Link", "link_name", "=", args.supplier_name],
+			["Dynamic Link", "link_name", "=", supplier_name],
 			["Dynamic Link", "parenttype", "=", "Address"]
 		]
 
@@ -324,7 +301,7 @@
 
 		new_address_doc.append("links", {
 			"link_doctype": "Supplier",
-			"link_name": args.supplier_name
+			"link_name": supplier_name
 		})
 		new_address_doc.address_type = "Billing"
 		new_address_doc.insert(ignore_mandatory=True)
@@ -332,26 +309,29 @@
 	else:
 		return None
 
-def create_purchase_invoice(**args):
+def create_purchase_invoice(supplier_name, file_name, args):
 	args = frappe._dict(args)
 	pi = frappe.get_doc({
-			"doctype": "Purchase Invoice",
-			"company": args.company,
-			"naming_series": args.naming_series,
-			"supplier": args.supplier_name,
-			"is_return": args.is_return,
-			"posting_date": today(),
-			"bill_no": args.bill_no,
-			"bill_date": args.bill_date,
-			"destination_code": args.destination_code,
-			"document_type": args.document_type,
-			"items": args["items"],
-			"taxes": args["taxes"]
-		})
+		"doctype": "Purchase Invoice",
+		"company": args.company,
+		"currency": erpnext.get_company_currency(args.company),
+		"naming_series": args.naming_series,
+		"supplier": supplier_name,
+		"is_return": args.is_return,
+		"posting_date": today(),
+		"bill_no": args.bill_no,
+		"buying_price_list": args.buying_price_list,
+		"bill_date": args.bill_date,
+		"destination_code": args.destination_code,
+		"document_type": args.document_type,
+		"items": args["items"],
+		"taxes": args["taxes"]
+	})
 
 	try:
 		pi.set_missing_values()
 		pi.insert(ignore_mandatory=True)
+
 		#if discount exists in file, apply any discount on grand total
 		if args.total_discount > 0:
 			pi.apply_discount_on = "Grand Total"
@@ -375,7 +355,8 @@
 		pi.save()
 		return pi.name
 	except Exception as e:
-		frappe.log_error(message=e, title="Create Purchase Invoice: " + args.bill_no + "File Name: " + args.file_name)
+		frappe.log_error(message=e,
+			title="Create Purchase Invoice: " + args.bill_no + "File Name: " + file_name)
 		return None
 
 def get_country(code):