feat: Tax Category based on Address
diff --git a/erpnext/accounts/party.py b/erpnext/accounts/party.py
index 90fc3d1..b22d3d4 100644
--- a/erpnext/accounts/party.py
+++ b/erpnext/accounts/party.py
@@ -8,7 +8,7 @@
 from frappe.defaults import get_user_permissions
 from frappe.model.utils import get_fetch_values
 from frappe.utils import (add_days, getdate, formatdate, date_diff,
-	add_years, get_timestamp, nowdate, flt, add_months, get_last_day)
+	add_years, get_timestamp, nowdate, flt, cstr, add_months, get_last_day)
 from frappe.contacts.doctype.address.address import (get_address_display,
 	get_default_address, get_company_address)
 from frappe.contacts.doctype.contact.contact import get_contact_details, get_default_contact
@@ -16,7 +16,7 @@
 from erpnext.accounts.utils import get_fiscal_year
 from erpnext import get_default_currency, get_company_currency
 
-from six import iteritems
+from six import iteritems, string_types
 
 class DuplicatePartyAccountError(frappe.ValidationError): pass
 
@@ -49,7 +49,8 @@
 	set_other_values(out, party, party_type)
 	set_price_list(out, party, party_type, price_list)
 
-	out["tax_category"] = get_tax_category(party, party_address, shipping_address)
+	out["tax_category"] = get_address_tax_category(party.get("tax_category"),
+		party_address, shipping_address if party_type != "Supplier" else party_address)
 	out["taxes_and_charges"] = set_taxes(party.name, party_type, posting_date, company, out.customer_group,
 		out.supplier_group, out.tax_category, party_address, shipping_address)
 
@@ -355,8 +356,17 @@
 				frappe.throw(_("Due / Reference Date cannot be after {0}")
 					.format(formatdate(default_due_date)))
 
-def get_tax_category(party, billing_address, shipping_address):
-	return party.get("tax_category")
+@frappe.whitelist()
+def get_address_tax_category(tax_category, billing_address=None, shipping_address=None):
+	addr_tax_category_from = frappe.db.get_single_value("Accounts Settings", "determine_address_tax_category_from")
+	if addr_tax_category_from == "Shipping Address":
+		if shipping_address:
+			tax_category = frappe.db.get_value("Address", shipping_address, "tax_category") or tax_category
+	else:
+		if billing_address:
+			tax_category = frappe.db.get_value("Address", billing_address, "tax_category") or tax_category
+
+	return cstr(tax_category)
 
 @frappe.whitelist()
 def set_taxes(party, party_type, posting_date, company, customer_group=None, supplier_group=None, tax_category=None,