Defaults in Item Group (#14874)

* Add Defaults table in Item Group

* Fetch defaults from Item group if not found in Item

* Add patch

* Remove default fields from Item Group

* Set query for defaults

* Fix Codacy

* Modify test records

* Modify budget.py and sales_order.py

* Remove join from query

* Else condition to avoid error if no defaults found

* refrain from making item test records before item_group

* default cost center fetch correction

* Remove tab item group from query
diff --git a/erpnext/accounts/doctype/budget/budget.py b/erpnext/accounts/doctype/budget/budget.py
index 421d756..771ec8d 100644
--- a/erpnext/accounts/doctype/budget/budget.py
+++ b/erpnext/accounts/doctype/budget/budget.py
@@ -298,8 +298,7 @@
 
 	if not (cost_center and expense_account):
 		for doctype in ['Item Group', 'Company']:
-			data = get_expense_cost_center(doctype,
-				args.get(frappe.scrub(doctype)))
+			data = get_expense_cost_center(doctype, args)
 
 			if not cost_center and data:
 				cost_center = data[0]
@@ -312,8 +311,11 @@
 
 	return cost_center, expense_account
 
-def get_expense_cost_center(doctype, value):
-	fields = (['default_cost_center', 'default_expense_account']
-		if doctype == 'Item Group' else ['cost_center', 'default_expense_account'])
-
-	return frappe.db.get_value(doctype, value, fields)
+def get_expense_cost_center(doctype, args):
+	if doctype == 'Item Group':
+		return frappe.db.get_value('Item Default',
+			{'parent': args.get(frappe.scrub(doctype)), 'company': args.get('company')},
+			['buying_cost_center', 'expense_account'])
+	else:
+		return frappe.db.get_value(doctype, args.get(frappe.scrub(doctype)),\
+			['cost_center', 'default_expense_account'])
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.py b/erpnext/buying/doctype/purchase_order/purchase_order.py
index 5af3078..5b8204a 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.py
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.py
@@ -15,6 +15,7 @@
 from erpnext.stock.utils import get_bin
 from six import string_types
 from erpnext.stock.doctype.item.item import get_item_defaults
+from erpnext.setup.doctype.item_group.item_group import get_item_group_defaults
 
 form_grid_templates = {
 	"items": "templates/form_grid/item_grid.html"
@@ -390,9 +391,10 @@
 		target.qty = target.amount / flt(obj.rate) if (flt(obj.rate) and flt(obj.billed_amt)) else flt(obj.qty)
 
 		item = get_item_defaults(target.item_code, source_parent.company)
+		item_group = get_item_group_defaults(target.item_code, source_parent.company)
 		target.cost_center = frappe.db.get_value("Project", obj.project, "cost_center") \
 			or item.get("buying_cost_center") \
-			or frappe.db.get_value("Item Group", item.item_group, "default_cost_center")
+			or item_group.get("buying_cost_center")
 
 	doc = get_mapped_doc("Purchase Order", source_name,	{
 		"Purchase Order": {
diff --git a/erpnext/controllers/buying_controller.py b/erpnext/controllers/buying_controller.py
index a22a9ec..70a0773 100644
--- a/erpnext/controllers/buying_controller.py
+++ b/erpnext/controllers/buying_controller.py
@@ -79,6 +79,12 @@
 					{"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")
+					if supplier:
+						self.supplier = supplier
 					break
 
 	def validate_stock_or_nonstock_items(self):
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index 507f9f5..f66f2a2 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -559,3 +559,4 @@
 erpnext.patches.v11_0.set_department_for_doctypes
 erpnext.patches.v11_0.update_allow_transfer_for_manufacture
 erpnext.patches.v11_0.rename_healthcare_doctype_and_fields
+erpnext.patches.v11_0.add_item_group_defaults
diff --git a/erpnext/patches/v11_0/add_item_group_defaults.py b/erpnext/patches/v11_0/add_item_group_defaults.py
new file mode 100644
index 0000000..2a15ad1
--- /dev/null
+++ b/erpnext/patches/v11_0/add_item_group_defaults.py
@@ -0,0 +1,73 @@
+# Copyright (c) 2018, Frappe and Contributors
+# License: GNU General Public License v3. See license.txt
+
+from __future__ import unicode_literals
+import frappe
+
+def execute():
+	'''
+
+	Fields to move from item group to item defaults child table
+	[ default_cost_center, default_expense_account, default_income_account ]
+
+	'''
+
+	frappe.reload_doc('stock', 'doctype', 'item_default')
+	frappe.reload_doc('setup', 'doctype', 'item_group')
+
+	companies = frappe.get_all("Company")
+	item_groups = frappe.db.sql("""select name, default_income_account, default_expense_account,\
+		default_cost_center from `tabItem Group`""", as_dict=True)
+
+	if len(companies) == 1:
+		for item_group in item_groups:
+			doc = frappe.get_doc("Item Group", item_group.get("name"))
+			item_group_defaults = []
+			item_group_defaults.append({
+				"company": companies[0].name,
+				"income_account": item_group.get("default_income_account"),
+				"expense_account": item_group.get("default_expense_account"),
+				"buying_cost_center": item_group.get("default_cost_center"),
+				"selling_cost_center": item_group.get("default_cost_center")
+			})
+			doc.extend("item_group_defaults", item_group_defaults)
+			for child_doc in doc.item_group_defaults:
+				child_doc.db_insert()
+	else:
+		item_group_dict = {
+			"default_expense_account": ["expense_account"],
+			"default_income_account": ["income_account"],
+			"default_cost_center": ["buying_cost_center", "selling_cost_center"]
+		}
+		for item_group in item_groups:
+			item_group_defaults = []
+			def insert_into_item_defaults(doc_field_name, doc_field_value, company):
+				for d in item_group_defaults:
+					if d.get("company") == company:
+						d[doc_field_name[0]] = doc_field_value
+						if len(doc_field_name) > 1:
+							d[doc_field_name[1]] = doc_field_value
+						return
+
+				item_group_defaults.append({
+					"company": company,
+					doc_field_name[0]: doc_field_value
+				})
+
+				if(len(doc_field_name) > 1):
+					item_group_defaults[len(item_group_defaults)-1][doc_field_name[1]] = doc_field_value
+
+			for d in [
+					["default_expense_account", "Account"], ["default_income_account", "Account"],
+					["default_cost_center", "Cost Center"]
+				]:
+				if item_group.get(d[0]):
+					company = frappe.get_value(d[1], item_group.get(d[0]), "company", cache=True)
+					doc_field_name = item_group_dict.get(d[0])
+
+					insert_into_item_defaults(doc_field_name, item_group.get(d[0]), company)
+
+			doc = frappe.get_doc("Item Group", item_group.get("name"))
+			doc.extend("item_group_defaults", item_group_defaults)
+			for child_doc in doc.item_group_defaults:
+				child_doc.db_insert()
diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py
index 8d47416..3ec4a23 100755
--- a/erpnext/selling/doctype/sales_order/sales_order.py
+++ b/erpnext/selling/doctype/sales_order/sales_order.py
@@ -16,7 +16,7 @@
 from frappe.desk.doctype.auto_repeat.auto_repeat import get_next_schedule_date
 from erpnext.selling.doctype.customer.customer import check_credit_limit
 from erpnext.stock.doctype.item.item import get_item_defaults
-
+from erpnext.setup.doctype.item_group.item_group import get_item_group_defaults
 
 form_grid_templates = {
 	"items": "templates/form_grid/item_grid.html"
@@ -513,11 +513,12 @@
 		target.qty = flt(source.qty) - flt(source.delivered_qty)
 
 		item = get_item_defaults(target.item_code, source_parent.company)
+		item_group = get_item_group_defaults(target.item_code, source_parent.company)
 
 		if item:
 			target.cost_center = frappe.db.get_value("Project", source_parent.project, "cost_center") \
 				or item.get("selling_cost_center") \
-				or frappe.db.get_value("Item Group", item.item_group, "default_cost_center")
+				or item_group.get("selling_cost_center")
 
 	target_doc = get_mapped_doc("Sales Order", source_name, {
 		"Sales Order": {
@@ -581,8 +582,9 @@
 			target.cost_center = frappe.db.get_value("Project", source_parent.project, "cost_center")
 		if not target.cost_center and target.item_code:
 			item = get_item_defaults(target.item_code, target.company)
+			item_group = get_item_group_defaults(target.item_code, target.company)
 			target.cost_center = item.get("selling_cost_center") \
-				or frappe.db.get_value("Item Group", item.item_group, "default_cost_center")
+				or item_group.get("selling_cost_center")
 
 	doclist = get_mapped_doc("Sales Order", source_name, {
 		"Sales Order": {
diff --git a/erpnext/setup/doctype/item_group/item_group.js b/erpnext/setup/doctype/item_group/item_group.js
index c55c7cb..df22231 100644
--- a/erpnext/setup/doctype/item_group/item_group.js
+++ b/erpnext/setup/doctype/item_group/item_group.js
@@ -14,6 +14,40 @@
 				]
 			}
 		}
+		frm.fields_dict["item_group_defaults"].grid.get_field("expense_account").get_query = function(doc, cdt, cdn) {
+			const row = locals[cdt][cdn];
+			return {
+				query: "erpnext.controllers.queries.get_expense_account",
+				filters: { company: row.company }
+			}
+		}
+		frm.fields_dict["item_group_defaults"].grid.get_field("income_account").get_query = function(doc, cdt, cdn) {
+			const row = locals[cdt][cdn];
+			return {
+				query: "erpnext.controllers.queries.get_income_account",
+				filters: { company: row.company }
+			}
+		}
+
+		frm.fields_dict["item_group_defaults"].grid.get_field("buying_cost_center").get_query = function(doc, cdt, cdn) {
+			const row = locals[cdt][cdn];
+			return {
+				filters: {
+					"is_group": 0,
+					"company": row.company
+				}
+			}
+		}
+
+		frm.fields_dict["item_group_defaults"].grid.get_field("selling_cost_center").get_query = function(doc, cdt, cdn) {
+			const row = locals[cdt][cdn];
+			return {
+				filters: {
+					"is_group": 0,
+					"company": row.company
+				}
+			}
+		}
 	},
 
 	refresh: function(frm) {
diff --git a/erpnext/setup/doctype/item_group/item_group.json b/erpnext/setup/doctype/item_group/item_group.json
index 29486b2..0a16a29 100644
--- a/erpnext/setup/doctype/item_group/item_group.json
+++ b/erpnext/setup/doctype/item_group/item_group.json
@@ -1,5 +1,6 @@
 {
  "allow_copy": 0, 
+ "allow_guest_to_view": 0, 
  "allow_import": 1, 
  "allow_rename": 1, 
  "autoname": "field:item_group_name", 
@@ -13,6 +14,8 @@
  "editable_grid": 0, 
  "fields": [
   {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -38,9 +41,12 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -68,9 +74,12 @@
    "reqd": 1, 
    "search_index": 0, 
    "set_only_once": 0, 
-   "unique": 0
+   "translatable": 0, 
+   "unique": 1
   }, 
   {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 1, 
    "collapsible": 0, 
@@ -100,9 +109,12 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 1, 
    "collapsible": 0, 
@@ -132,9 +144,12 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -159,15 +174,18 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
-   "fieldname": "default_income_account", 
-   "fieldtype": "Link", 
+   "fieldname": "defaults", 
+   "fieldtype": "Section Break", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
@@ -175,11 +193,11 @@
    "in_global_search": 0, 
    "in_list_view": 0, 
    "in_standard_filter": 0, 
-   "label": "Default Income Account", 
+   "label": "Defaults", 
    "length": 0, 
    "no_copy": 0, 
-   "options": "Account", 
    "permlevel": 0, 
+   "precision": "", 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
@@ -188,15 +206,18 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
-   "fieldname": "default_expense_account", 
-   "fieldtype": "Link", 
+   "fieldname": "item_group_defaults", 
+   "fieldtype": "Table", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
@@ -204,11 +225,12 @@
    "in_global_search": 0, 
    "in_list_view": 0, 
    "in_standard_filter": 0, 
-   "label": "Default Expense Account", 
+   "label": "Item Group Defaults", 
    "length": 0, 
    "no_copy": 0, 
-   "options": "Account", 
+   "options": "Item Default", 
    "permlevel": 0, 
+   "precision": "", 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
@@ -217,38 +239,12 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "default_cost_center", 
-   "fieldtype": "Link", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Default Cost Center", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Cost Center", 
-   "permlevel": 0, 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0
-  }, 
-  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -274,9 +270,12 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -303,9 +302,12 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -333,9 +335,12 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 1
   }, 
   {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -364,9 +369,12 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -394,9 +402,12 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -424,9 +435,12 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -454,9 +468,12 @@
    "reqd": 0, 
    "search_index": 1, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -484,9 +501,12 @@
    "reqd": 0, 
    "search_index": 1, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -516,21 +536,22 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }
  ], 
+ "has_web_view": 0, 
  "hide_heading": 0, 
  "hide_toolbar": 0, 
  "icon": "fa fa-sitemap", 
  "idx": 1, 
  "image_view": 0, 
  "in_create": 0, 
-
  "is_submittable": 0, 
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 3, 
- "modified": "2017-02-20 13:24:59.364873", 
+ "modified": "2018-07-11 16:07:56.050363", 
  "modified_by": "Administrator", 
  "module": "Setup", 
  "name": "Item Group", 
@@ -539,7 +560,6 @@
  "permissions": [
   {
    "amend": 0, 
-   "apply_user_permissions": 0, 
    "cancel": 0, 
    "create": 0, 
    "delete": 0, 
@@ -559,7 +579,6 @@
   }, 
   {
    "amend": 0, 
-   "apply_user_permissions": 0, 
    "cancel": 0, 
    "create": 0, 
    "delete": 0, 
@@ -579,7 +598,6 @@
   }, 
   {
    "amend": 0, 
-   "apply_user_permissions": 0, 
    "cancel": 0, 
    "create": 1, 
    "delete": 1, 
@@ -599,7 +617,6 @@
   }, 
   {
    "amend": 0, 
-   "apply_user_permissions": 0, 
    "cancel": 0, 
    "create": 0, 
    "delete": 0, 
@@ -619,7 +636,6 @@
   }, 
   {
    "amend": 0, 
-   "apply_user_permissions": 0, 
    "cancel": 0, 
    "create": 0, 
    "delete": 0, 
@@ -639,7 +655,6 @@
   }, 
   {
    "amend": 0, 
-   "apply_user_permissions": 0, 
    "cancel": 0, 
    "create": 0, 
    "delete": 0, 
@@ -665,5 +680,6 @@
  "show_name_in_global_search": 1, 
  "sort_order": "DESC", 
  "track_changes": 0, 
- "track_seen": 0
+ "track_seen": 0, 
+ "track_views": 0
 }
\ No newline at end of file
diff --git a/erpnext/setup/doctype/item_group/item_group.py b/erpnext/setup/doctype/item_group/item_group.py
index 230b740..d4f16be 100644
--- a/erpnext/setup/doctype/item_group/item_group.py
+++ b/erpnext/setup/doctype/item_group/item_group.py
@@ -173,3 +173,19 @@
 		item_group_name = frappe.db.get_value("Item Group", d.get('name'))
 		if item_group_name:
 			clear_cache(frappe.db.get_value('Item Group', item_group_name, 'route'))
+
+def get_item_group_defaults(item, company):
+	item_group = frappe.db.get_value("Item", item, "item_group")
+	item_group_defaults = frappe.db.sql('''
+		select
+			expense_account, income_account, buying_cost_center, default_warehouse,
+			selling_cost_center, default_supplier
+		from
+			`tabItem Default` where company = %s and parent = %s and parenttype = 'Item Group' 
+	''', (company, item_group), as_dict=1)
+
+	if item_group_defaults:
+		return item_group_defaults[0]
+	else:
+		return frappe.db.get_value("Item", item, ["name", "item_name", "description", "stock_uom",
+			"is_stock_item", "item_code", "item_group"], as_dict=1)
\ No newline at end of file
diff --git a/erpnext/setup/doctype/item_group/test_item_group.js b/erpnext/setup/doctype/item_group/test_item_group.js
new file mode 100644
index 0000000..ea322e2
--- /dev/null
+++ b/erpnext/setup/doctype/item_group/test_item_group.js
@@ -0,0 +1,23 @@
+/* eslint-disable */
+// rename this file from _test_[name] to test_[name] to activate
+// and remove above this line
+
+QUnit.test("test: Item Group", function (assert) {
+	let done = assert.async();
+
+	// number of asserts
+	assert.expect(1);
+
+	frappe.run_serially([
+		// insert a new Item Group
+		() => frappe.tests.make('Item Group', [
+			// values to be set
+			{key: 'value'}
+		]),
+		() => {
+			assert.equal(cur_frm.doc.key, 'value');
+		},
+		() => done()
+	]);
+
+});
diff --git a/erpnext/setup/doctype/item_group/test_records.json b/erpnext/setup/doctype/item_group/test_records.json
index 74f4641..436535e 100644
--- a/erpnext/setup/doctype/item_group/test_records.json
+++ b/erpnext/setup/doctype/item_group/test_records.json
@@ -4,7 +4,11 @@
   "is_group": 0, 
   "item_group_name": "_Test Item Group", 
   "parent_item_group": "All Item Groups",
-  "default_cost_center": "_Test Cost Center 2 - _TC"
+  "item_group_defaults": [{
+		"company": "_Test Company",
+		"buying_cost_center": "_Test Cost Center 2 - _TC",
+		"selling_cost_center": "_Test Cost Center 2 - _TC"
+	}]
  }, 
  {
   "doctype": "Item Group", 
diff --git a/erpnext/setup/doctype/sales_partner/test_sales_partner.py b/erpnext/setup/doctype/sales_partner/test_sales_partner.py
index a4ae807..4548a4e 100644
--- a/erpnext/setup/doctype/sales_partner/test_sales_partner.py
+++ b/erpnext/setup/doctype/sales_partner/test_sales_partner.py
@@ -4,4 +4,6 @@
 
 
 import frappe
-test_records = frappe.get_test_records('Sales Partner')
\ No newline at end of file
+test_records = frappe.get_test_records('Sales Partner')
+
+test_ignore = ["Item Group"]
diff --git a/erpnext/setup/doctype/sales_person/test_sales_person.py b/erpnext/setup/doctype/sales_person/test_sales_person.py
index 10b5f7c..8313cb4 100644
--- a/erpnext/setup/doctype/sales_person/test_sales_person.py
+++ b/erpnext/setup/doctype/sales_person/test_sales_person.py
@@ -5,4 +5,6 @@
 test_dependencies = ["Employee"]
 
 import frappe
-test_records = frappe.get_test_records('Sales Person')
\ No newline at end of file
+test_records = frappe.get_test_records('Sales Person')
+
+test_ignore = ["Item Group"]
diff --git a/erpnext/setup/doctype/territory/test_territory.py b/erpnext/setup/doctype/territory/test_territory.py
index 5ec8e4a..efe00c5 100644
--- a/erpnext/setup/doctype/territory/test_territory.py
+++ b/erpnext/setup/doctype/territory/test_territory.py
@@ -4,4 +4,6 @@
 
 
 import frappe
-test_records = frappe.get_test_records('Territory')
\ No newline at end of file
+test_records = frappe.get_test_records('Territory')
+
+test_ignore = ["Item Group"]
diff --git a/erpnext/stock/doctype/item/test_item.py b/erpnext/stock/doctype/item/test_item.py
index 5c35bec..7ef4f8c 100644
--- a/erpnext/stock/doctype/item/test_item.py
+++ b/erpnext/stock/doctype/item/test_item.py
@@ -17,7 +17,7 @@
 from six import iteritems
 
 test_ignore = ["BOM"]
-test_dependencies = ["Warehouse"]
+test_dependencies = ["Warehouse", "Item Group"]
 
 def make_item(item_code, properties=None):
 	if frappe.db.exists("Item", item_code):
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py
index 011df70..89f90bf 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.py
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.py
@@ -9,6 +9,7 @@
 from erpnext.stock.utils import get_incoming_rate
 from erpnext.stock.stock_ledger import get_previous_sle, NegativeStockError, get_valuation_rate
 from erpnext.stock.get_item_details import get_bin_details, get_default_cost_center, get_conversion_factor
+from erpnext.setup.doctype.item_group.item_group import get_item_group_defaults
 from erpnext.stock.doctype.batch.batch import get_batch_no, set_batch_nos, get_batch_qty
 from erpnext.stock.doctype.item.item import get_item_defaults
 from erpnext.manufacturing.doctype.bom.bom import validate_bom_no, add_additional_cost
@@ -579,7 +580,7 @@
 					pro_doc.run_method("update_planned_qty")
 
 	def get_item_details(self, args=None, for_update=False):
-		item = frappe.db.sql("""select i.stock_uom, i.description, i.image, i.item_name, i.item_group,
+		item = frappe.db.sql("""select i.name, i.stock_uom, i.description, i.image, i.item_name, i.item_group,
 				i.has_batch_no, i.sample_quantity, i.has_serial_no,
 				id.expense_account, id.buying_cost_center
 			from `tabItem` i LEFT JOIN `tabItem Default` id ON i.name=id.parent and id.company=%s
@@ -592,6 +593,7 @@
 			frappe.throw(_("Item {0} is not active or end of life has been reached").format(args.get("item_code")))
 
 		item = item[0]
+		item_group_defaults = get_item_group_defaults(item.name, self.company)
 
 		ret = frappe._dict({
 			'uom'			      	: item.stock_uom,
@@ -600,7 +602,7 @@
 			'image'					: item.image,
 			'item_name' 		  	: item.item_name,
 			'expense_account'		: args.get("expense_account"),
-			'cost_center'			: get_default_cost_center(args, item),
+			'cost_center'			: get_default_cost_center(args, item, item_group_defaults),
 			'qty'					: 0,
 			'transfer_qty'			: 0,
 			'conversion_factor'		: 1,
diff --git a/erpnext/stock/get_item_details.py b/erpnext/stock/get_item_details.py
index 6d89187..f1afd1c 100644
--- a/erpnext/stock/get_item_details.py
+++ b/erpnext/stock/get_item_details.py
@@ -12,7 +12,7 @@
 from erpnext.stock.doctype.batch.batch import get_batch_no
 from erpnext import get_company_currency
 from erpnext.stock.doctype.item.item import get_item_defaults
-
+from erpnext.setup.doctype.item_group.item_group import get_item_group_defaults
 
 from six import string_types, iteritems
 
@@ -208,7 +208,10 @@
 		if len(user_default_warehouse_list) == 1 else ""
 
 	item_defaults = get_item_defaults(item.name, args.company)
-	warehouse = user_default_warehouse or item_defaults.get("default_warehouse") or args.warehouse
+	item_group_defaults = get_item_group_defaults(item.name, args.company)
+
+	warehouse = user_default_warehouse or item_defaults.get("default_warehouse") or\
+		item_group_defaults.get("default_warehouse") or args.warehouse
 
 	material_request_type = ''
 	if args.get('doctype') == "Material Request" and not args.get('material_request_type'):
@@ -231,9 +234,9 @@
 		"description": cstr(item.description).strip(),
 		"image": cstr(item.image).strip(),
 		"warehouse": warehouse,
-		"income_account": get_default_income_account(args, item_defaults),
-		"expense_account": get_default_expense_account(args, item_defaults),
-		"cost_center": get_default_cost_center(args, item_defaults),
+		"income_account": get_default_income_account(args, item_defaults, item_group_defaults),
+		"expense_account": get_default_expense_account(args, item_defaults, item_group_defaults),
+		"cost_center": get_default_cost_center(args, item_defaults, item_group_defaults),
 		'has_serial_no': item.has_serial_no,
 		'has_batch_no': item.has_batch_no,
 		"batch_no": None,
@@ -252,7 +255,7 @@
 		"net_rate": 0.0,
 		"net_amount": 0.0,
 		"discount_percentage": 0.0,
-		"supplier": item_defaults.get("default_supplier"),
+		"supplier": get_default_supplier(args, item_defaults, item_group_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,
 		"is_fixed_asset": item.is_fixed_asset,
@@ -299,15 +302,15 @@
 	return out
 
 
-def get_default_income_account(args, item):
+def get_default_income_account(args, item, item_group):
 	return (item.get("income_account")
-		or args.income_account
-		or frappe.db.get_value("Item Group", item.item_group, "default_income_account"))
+		or item_group.get("income_account")
+		or args.income_account)
 
-def get_default_expense_account(args, item):
+def get_default_expense_account(args, item, item_group):
 	return (item.get("expense_account")
-		or args.expense_account
-		or frappe.db.get_value("Item Group", item.item_group, "default_expense_account"))
+		or item_group.get("expense_account")
+		or args.expense_account)
 
 def get_default_deferred_revenue_account(args, item):
 	if item.enable_deferred_revenue:
@@ -317,12 +320,16 @@
 	else:
 		return None
 
-def get_default_cost_center(args, item):
+def get_default_cost_center(args, item, item_group):
 	return (frappe.db.get_value("Project", args.get("project"), "cost_center")
 		or (item.get("selling_cost_center") if args.get("customer") else item.get("buying_cost_center"))
-		or frappe.db.get_value("Item Group", item.item_group, "default_cost_center")
+		or (item_group.get("selling_cost_center") if args.get("customer") else item_group.get("buying_cost_center"))
 		or args.get("cost_center"))
 
+def get_default_supplier(args, item, item_group):
+	return (item.get("default_supplier")
+		or item_group.get("default_supplier"))
+
 def get_price_list_rate(args, item_doc, out):
 	meta = frappe.get_meta(args.parenttype or args.doctype)
 
@@ -686,10 +693,11 @@
 
 def get_valuation_rate(item_code, company, warehouse=None):
 	item = get_item_defaults(item_code, company)
+	item_group = get_item_group_defaults(item_code, company)
 	# item = frappe.get_doc("Item", item_code)
 	if item.get("is_stock_item"):
 		if not warehouse:
-			warehouse = item.get("default_warehouse")
+			warehouse = item.get("default_warehouse") or item_group.get("default_warehouse")
 
 		return frappe.db.get_value("Bin", {"item_code": item_code, "warehouse": warehouse},
 			["valuation_rate"], as_dict=True) or {"valuation_rate": 0}