[fix] test-case, warehouse mandatory for mix type product bundle
diff --git a/erpnext/selling/doctype/product_bundle/product_bundle.py b/erpnext/selling/doctype/product_bundle/product_bundle.py
index fdf6b76..2949c5c 100644
--- a/erpnext/selling/doctype/product_bundle/product_bundle.py
+++ b/erpnext/selling/doctype/product_bundle/product_bundle.py
@@ -13,9 +13,15 @@
 		self.name = self.new_item_code
 
 	def validate(self):
+		self.validate_main_item()
 		from erpnext.utilities.transaction_base import validate_uom_is_integer
 		validate_uom_is_integer(self, "uom", "qty")
 
+	def validate_main_item(self):
+		"""Validates, main Item is not a stock item"""
+		if frappe.db.get_value("Item", self.new_item_code, "is_stock_item"):
+			frappe.throw(_("Parent Item {0} must not be a Stock Item").format(self.new_item_code))
+
 	def get_item_details(self, name):
 		det = frappe.db.sql("""select description, stock_uom from `tabItem`
 			where name = %s""", name)
@@ -28,7 +34,7 @@
 	from erpnext.controllers.queries import get_match_cond
 
 	return frappe.db.sql("""select name, item_name, description from tabItem
-		where name not in (select name from `tabProduct Bundle`)
+		where is_stock_item=0 and name not in (select name from `tabProduct Bundle`)
 		and %s like %s %s limit %s, %s""" % (searchfield, "%s",
 		get_match_cond(doctype),"%s", "%s"),
 		("%%%s%%" % txt, start, page_len))
diff --git a/erpnext/selling/doctype/product_bundle/test_product_bundle.py b/erpnext/selling/doctype/product_bundle/test_product_bundle.py
index 39b17f3..85a2b20 100644
--- a/erpnext/selling/doctype/product_bundle/test_product_bundle.py
+++ b/erpnext/selling/doctype/product_bundle/test_product_bundle.py
@@ -13,7 +13,6 @@
 
 	product_bundle = frappe.get_doc({
 		"doctype": "Product Bundle",
-		"parent_item": parent,
 		"new_item_code": parent
 	})
 
diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py
index 109034d..1c05715 100644
--- a/erpnext/selling/doctype/sales_order/sales_order.py
+++ b/erpnext/selling/doctype/sales_order/sales_order.py
@@ -15,6 +15,8 @@
 	"items": "templates/form_grid/item_grid.html"
 }
 
+class WarehouseRequired(frappe.ValidationError): pass
+
 class SalesOrder(SellingController):
 	def validate_mandatory(self):
 		# validate transaction date v/s delivery date
@@ -39,8 +41,11 @@
 		for d in self.get('items'):
 			check_list.append(cstr(d.item_code))
 
-			if frappe.db.get_value("Item", d.item_code, "is_stock_item") and not d.warehouse:
-					frappe.throw(_("Delivery warehouse required for stock item {0}").format(d.item_code))
+			if (frappe.db.get_value("Item", d.item_code, "is_stock_item")==1 or
+				(self.has_product_bundle(d.item_code) and self.product_bundle_has_stock_item(d.item_code))) \
+				and not d.warehouse:
+				frappe.throw(_("Delivery warehouse required for stock item {0}").format(d.item_code),
+					WarehouseRequired)
 
 			# used for production plan
 			d.transaction_date = self.transaction_date
@@ -52,6 +57,12 @@
 		if len(unique_chk_list) != len(check_list):
 			frappe.msgprint(_("Warning: Same item has been entered multiple times."))
 
+	def product_bundle_has_stock_item(self, product_bundle):
+		"""Returns true if product bundle has stock item"""
+		ret = len(frappe.db.sql("""select i.name from tabItem i, `tabProduct Bundle Item` pbi
+			where pbi.parent = %s and pbi.item_code = i.name and i.is_stock_item = 1""", product_bundle))
+		return ret
+
 	def validate_sales_mntc_quotation(self):
 		for d in self.get('items'):
 			if d.prevdoc_docname:
diff --git a/erpnext/selling/doctype/sales_order/test_sales_order.py b/erpnext/selling/doctype/sales_order/test_sales_order.py
index 1ceda12..8841202 100644
--- a/erpnext/selling/doctype/sales_order/test_sales_order.py
+++ b/erpnext/selling/doctype/sales_order/test_sales_order.py
@@ -6,7 +6,7 @@
 import frappe.permissions
 import unittest
 from erpnext.selling.doctype.sales_order.sales_order \
-	import make_material_request, make_delivery_note, make_sales_invoice
+	import make_material_request, make_delivery_note, make_sales_invoice, WarehouseRequired
 
 class TestSalesOrder(unittest.TestCase):
 	def tearDown(self):
@@ -235,11 +235,24 @@
 		make_product_bundle("_Test Service Product Bundle",
 			["_Test Service Product Bundle Item 1", "_Test Service Product Bundle Item 2"])
 
-		so = make_sales_order(item_code = "_Test Service Product Bundle")
+		so = make_sales_order(item_code = "_Test Service Product Bundle", warehouse=None)
 
 		self.assertTrue("_Test Service Product Bundle Item 1" in [d.item_code for d in so.packed_items])
 		self.assertTrue("_Test Service Product Bundle Item 2" in [d.item_code for d in so.packed_items])
 
+	def test_mix_type_product_bundle(self):
+		from erpnext.stock.doctype.item.test_item import make_item
+		from erpnext.selling.doctype.product_bundle.test_product_bundle import make_product_bundle
+
+		make_item("_Test Mix Product Bundle", {"is_stock_item": 0, "is_sales_item": 1})
+		make_item("_Test Mix Product Bundle Item 1", {"is_stock_item": 1, "is_sales_item": 1})
+		make_item("_Test Mix Product Bundle Item 2", {"is_stock_item": 0, "is_sales_item": 1})
+
+		make_product_bundle("_Test Mix Product Bundle",
+			["_Test Mix Product Bundle Item 1", "_Test Mix Product Bundle Item 2"])
+
+		self.assertRaises(WarehouseRequired, make_sales_order, item_code = "_Test Mix Product Bundle", warehouse="")
+
 	def test_auto_insert_price(self):
 		from erpnext.stock.doctype.item.test_item import make_item
 		make_item("_Test Item for Auto Price List", {"is_stock_item": 0, "is_sales_item": 1})
@@ -284,13 +297,17 @@
 	if args.selling_price_list:
 		so.selling_price_list = args.selling_price_list
 
+	if "warehouse" not in args:
+		args.warehouse = "_Test Warehouse - _TC"
+
 	so.append("items", {
 		"item_code": args.item or args.item_code or "_Test Item",
-		"warehouse": args.warehouse or "_Test Warehouse - _TC",
+		"warehouse": args.warehouse,
 		"qty": args.qty or 10,
 		"rate": args.rate or 100,
 		"conversion_factor": 1.0,
 	})
+
 	if not args.do_not_save:
 		so.insert()
 		if not args.do_not_submit:
diff --git a/erpnext/setup/doctype/company/company.py b/erpnext/setup/doctype/company/company.py
index f1f7cc4..5660d89 100644
--- a/erpnext/setup/doctype/company/company.py
+++ b/erpnext/setup/doctype/company/company.py
@@ -30,7 +30,7 @@
 		self.abbr = self.abbr.strip()
 		if self.get('__islocal') and len(self.abbr) > 5:
 			frappe.throw(_("Abbreviation cannot have more than 5 characters"))
-			
+
 		if not self.abbr.strip():
 			frappe.throw(_("Abbr can not be blank or space"))
 
@@ -70,7 +70,8 @@
 		frappe.clear_cache()
 
 	def install_country_fixtures(self):
-		if os.path.exists(os.path.join(os.path.dirname(__file__), "fixtures", self.country.lower())):
+		path = os.path.join(os.path.dirname(__file__), "fixtures", self.country.lower())
+		if os.path.exists(path.encode("utf-8")):
 			frappe.get_attr("erpnext.setup.doctype.company.fixtures.{0}.install".format(self.country.lower()))(self)
 
 	def create_default_warehouses(self):
@@ -183,7 +184,7 @@
 		accounts = frappe.db.sql_list("select name from tabAccount where company=%s", self.name)
 		cost_centers = frappe.db.sql_list("select name from `tabCost Center` where company=%s", self.name)
 		warehouses = frappe.db.sql_list("select name from tabWarehouse where company=%s", self.name)
-		
+
 		rec = frappe.db.sql("SELECT name from `tabGL Entry` where company = %s", self.name)
 		if not rec:
 			# delete Account
@@ -202,21 +203,21 @@
 			frappe.db.sql("""delete from `tabWarehouse` where company=%s""", self.name)
 
 		frappe.defaults.clear_default("company", value=self.name)
-		
+
 		# clear default accounts, warehouses from item
 		for f in ["default_warehouse", "website_warehouse"]:
-			frappe.db.sql("""update tabItem set %s=NULL where %s in (%s)""" 
+			frappe.db.sql("""update tabItem set %s=NULL where %s in (%s)"""
 				% (f, f, ', '.join(['%s']*len(warehouses))), tuple(warehouses))
-				
-		frappe.db.sql("""delete from `tabItem Reorder` where warehouse in (%s)""" 
+
+		frappe.db.sql("""delete from `tabItem Reorder` where warehouse in (%s)"""
 			% ', '.join(['%s']*len(warehouses)), tuple(warehouses))
-				
+
 		for f in ["income_account", "expense_account"]:
-			frappe.db.sql("""update tabItem set %s=NULL where %s in (%s)""" 
+			frappe.db.sql("""update tabItem set %s=NULL where %s in (%s)"""
 				% (f, f, ', '.join(['%s']*len(accounts))), tuple(accounts))
-				
+
 		for f in ["selling_cost_center", "buying_cost_center"]:
-			frappe.db.sql("""update tabItem set %s=NULL where %s in (%s)""" 
+			frappe.db.sql("""update tabItem set %s=NULL where %s in (%s)"""
 				% (f, f, ', '.join(['%s']*len(cost_centers))), tuple(cost_centers))
 
 		# reset default company
@@ -229,7 +230,7 @@
 	new = new.strip()
 	if not new:
 		frappe.throw(_("Abbr can not be blank or space"))
-		
+
 	frappe.only_for("System Manager")
 
 	frappe.db.set_value("Company", company, "abbr", new)
diff --git a/erpnext/setup/utils.py b/erpnext/setup/utils.py
index f661edb..5480613 100644
--- a/erpnext/setup/utils.py
+++ b/erpnext/setup/utils.py
@@ -56,6 +56,9 @@
 	frappe.db.sql("delete from `tabLeave Application`")
 	frappe.db.sql("delete from `tabSalary Slip`")
 	frappe.db.sql("delete from `tabItem Price`")
+
+	frappe.db.set_value("Stock Settings", None, "auto_insert_price_list_rate_if_missing", 0)
+
 	frappe.db.commit()
 
 @frappe.whitelist()
diff --git a/erpnext/stock/doctype/item/test_item.py b/erpnext/stock/doctype/item/test_item.py
index 0fb01ac..510c0d1 100644
--- a/erpnext/stock/doctype/item/test_item.py
+++ b/erpnext/stock/doctype/item/test_item.py
@@ -26,7 +26,13 @@
 
 	if properties:
 		item.update(properties)
-		item.insert()
+
+
+	if item.is_stock_item and not item.default_warehouse:
+		item.default_warehouse = "_Test Warehouse - _TC"
+
+	item.insert()
+
 	return item
 
 class TestItem(unittest.TestCase):