Merge pull request #3712 from rmehta/setup-wizard-fix

[fix] contact name in setup wizard
diff --git a/erpnext/accounts/doctype/account/account.py b/erpnext/accounts/doctype/account/account.py
index 683734b..f1d822a 100644
--- a/erpnext/accounts/doctype/account/account.py
+++ b/erpnext/accounts/doctype/account/account.py
@@ -49,7 +49,7 @@
 				self.root_type = par.root_type
 
 	def validate_root_details(self):
-		#does not exists parent
+		# does not exists parent
 		if frappe.db.exists("Account", self.name):
 			if not frappe.db.get_value("Account", self.name, "parent_account"):
 				throw(_("Root cannot be edited."))
diff --git a/erpnext/accounts/doctype/purchase_taxes_and_charges_template/purchase_taxes_and_charges_template.py b/erpnext/accounts/doctype/purchase_taxes_and_charges_template/purchase_taxes_and_charges_template.py
index a2ba72d..bffa8e6 100644
--- a/erpnext/accounts/doctype/purchase_taxes_and_charges_template/purchase_taxes_and_charges_template.py
+++ b/erpnext/accounts/doctype/purchase_taxes_and_charges_template/purchase_taxes_and_charges_template.py
@@ -4,10 +4,9 @@
 
 from __future__ import unicode_literals
 from frappe.model.document import Document
-from erpnext.controllers.accounts_controller import validate_taxes_and_charges, validate_inclusive_tax
+from erpnext.accounts.doctype.sales_taxes_and_charges_template.sales_taxes_and_charges_template \
+	import valdiate_taxes_and_charges_template
 
 class PurchaseTaxesandChargesTemplate(Document):
 	def validate(self):
-		for tax in self.get("taxes"):
-			validate_taxes_and_charges(tax)
-			validate_inclusive_tax(tax, self)
+		valdiate_taxes_and_charges_template(self)
diff --git a/erpnext/accounts/doctype/sales_taxes_and_charges_template/sales_taxes_and_charges_template.py b/erpnext/accounts/doctype/sales_taxes_and_charges_template/sales_taxes_and_charges_template.py
index 6721bd8..b36287b 100644
--- a/erpnext/accounts/doctype/sales_taxes_and_charges_template/sales_taxes_and_charges_template.py
+++ b/erpnext/accounts/doctype/sales_taxes_and_charges_template/sales_taxes_and_charges_template.py
@@ -5,21 +5,25 @@
 import frappe
 from frappe.model.document import Document
 from erpnext.controllers.accounts_controller import validate_taxes_and_charges, validate_inclusive_tax
+from frappe.utils.nestedset import get_root_of
 
 class SalesTaxesandChargesTemplate(Document):
 	def validate(self):
-		if self.is_default == 1:
-			frappe.db.sql("""update `tabSales Taxes and Charges Template`
-				set is_default = 0
-				where ifnull(is_default,0) = 1
-				and name != %s and company = %s""",
-				(self.name, self.company))
+		valdiate_taxes_and_charges_template(self)
 
-		# at least one territory
-		self.validate_table_has_rows("territories")
+def valdiate_taxes_and_charges_template(doc):
+	if not doc.is_default and not frappe.get_all(doc.doctype, filters={"is_default": 1}):
+		doc.is_default = 1
 
-		for tax in self.get("taxes"):
-			validate_taxes_and_charges(tax)
-			validate_inclusive_tax(tax, self)
+	if doc.is_default == 1:
+		frappe.db.sql("""update `tab{0}` set is_default = 0
+			where ifnull(is_default,0) = 1 and name != %s and company = %s""".format(doc.doctype),
+			(doc.name, doc.company))
 
+	if doc.meta.get_field("territories"):
+		if not doc.territories:
+			doc.append("territories", {"territory": get_root_of("Territory") })
 
+	for tax in doc.get("taxes"):
+		validate_taxes_and_charges(tax)
+		validate_inclusive_tax(tax, doc)
diff --git a/erpnext/change_log/current/sms.md b/erpnext/change_log/current/sms.md
new file mode 100644
index 0000000..bac293f
--- /dev/null
+++ b/erpnext/change_log/current/sms.md
@@ -0,0 +1 @@
+- Now system will give SMS delivery message and maintain a log
\ No newline at end of file
diff --git a/erpnext/config/crm.py b/erpnext/config/crm.py
index 3a7ab18..d7a6b2e 100644
--- a/erpnext/config/crm.py
+++ b/erpnext/config/crm.py
@@ -42,6 +42,11 @@
 					"name": "SMS Center",
 					"description":_("Send mass SMS to your contacts"),
 				},
+				{
+					"type": "doctype",
+					"name": "SMS Log",
+					"description":_("Logs for maintaining sms delivery status"),
+				}
 			]
 		},
 		{
diff --git a/erpnext/config/selling.py b/erpnext/config/selling.py
index 5433964..62dfe23 100644
--- a/erpnext/config/selling.py
+++ b/erpnext/config/selling.py
@@ -50,6 +50,11 @@
 				},
 				{
 					"type": "doctype",
+					"name": "SMS Log",
+					"description":_("Logs for maintaining sms delivery status"),
+				},
+				{
+					"type": "doctype",
 					"name": "Newsletter",
 					"description": _("Newsletters to contacts, leads."),
 				},
diff --git a/erpnext/contacts/__init__.py b/erpnext/contacts/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/contacts/__init__.py
+++ /dev/null
diff --git a/erpnext/contacts/doctype/__init__.py b/erpnext/contacts/doctype/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/contacts/doctype/__init__.py
+++ /dev/null
diff --git a/erpnext/contacts/doctype/party_type/__init__.py b/erpnext/contacts/doctype/party_type/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/contacts/doctype/party_type/__init__.py
+++ /dev/null
diff --git a/erpnext/contacts/doctype/party_type/party_type.json b/erpnext/contacts/doctype/party_type/party_type.json
deleted file mode 100644
index 19ffefb..0000000
--- a/erpnext/contacts/doctype/party_type/party_type.json
+++ /dev/null
@@ -1,92 +0,0 @@
-{
- "allow_rename": 1, 
- "autoname": "field:party_type_name", 
- "creation": "2014-04-07 12:32:18.010384", 
- "docstatus": 0, 
- "doctype": "DocType", 
- "document_type": "Master", 
- "fields": [
-  {
-   "fieldname": "party_type_name", 
-   "fieldtype": "Data", 
-   "in_list_view": 1, 
-   "label": "Party Type Name", 
-   "permlevel": 0, 
-   "reqd": 1
-  }, 
-  {
-   "fieldname": "parent_party_type", 
-   "fieldtype": "Link", 
-   "label": "Parent Party Type", 
-   "options": "Party Type", 
-   "permlevel": 0
-  }, 
-  {
-   "default": "Yes", 
-   "fieldname": "allow_children", 
-   "fieldtype": "Select", 
-   "label": "Allow Children", 
-   "options": "Yes\nNo", 
-   "permlevel": 0
-  }, 
-  {
-   "fieldname": "default_price_list", 
-   "fieldtype": "Link", 
-   "ignore_user_permissions": 1, 
-   "label": "Default Price List", 
-   "options": "Price List", 
-   "permlevel": 0
-  }, 
-  {
-   "fieldname": "lft", 
-   "fieldtype": "Int", 
-   "hidden": 1, 
-   "label": "LFT", 
-   "permlevel": 0, 
-   "read_only": 1, 
-   "search_index": 1
-  }, 
-  {
-   "fieldname": "rgt", 
-   "fieldtype": "Int", 
-   "hidden": 1, 
-   "label": "RGT", 
-   "permlevel": 0, 
-   "read_only": 1, 
-   "search_index": 1
-  }, 
-  {
-   "fieldname": "old_parent", 
-   "fieldtype": "Data", 
-   "hidden": 1, 
-   "label": "Old Parent", 
-   "permlevel": 0, 
-   "read_only": 1
-  }
- ], 
- "modified": "2015-02-05 05:11:42.046004", 
- "modified_by": "Administrator", 
- "module": "Contacts", 
- "name": "Party Type", 
- "owner": "Administrator", 
- "permissions": [
-  {
-   "apply_user_permissions": 1, 
-   "create": 1, 
-   "permlevel": 0, 
-   "read": 1, 
-   "role": "Sales User", 
-   "share": 1, 
-   "write": 1
-  }, 
-  {
-   "apply_user_permissions": 1, 
-   "create": 1, 
-   "permlevel": 0, 
-   "read": 1, 
-   "role": "Purchase User", 
-   "share": 1, 
-   "write": 1
-  }
- ]
-}
\ No newline at end of file
diff --git a/erpnext/contacts/doctype/party_type/party_type.py b/erpnext/contacts/doctype/party_type/party_type.py
deleted file mode 100644
index d21216f..0000000
--- a/erpnext/contacts/doctype/party_type/party_type.py
+++ /dev/null
@@ -1,9 +0,0 @@
-# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
-# For license information, please see license.txt
-
-from __future__ import unicode_literals
-import frappe
-from frappe.utils.nestedset import NestedSet
-
-class PartyType(NestedSet):
-	nsm_parent_field = 'parent_party_type';
diff --git a/erpnext/modules.txt b/erpnext/modules.txt
index 67c856d..dfca2f2 100644
--- a/erpnext/modules.txt
+++ b/erpnext/modules.txt
@@ -9,6 +9,5 @@
 Stock
 Support
 Utilities
-Contacts
 Shopping Cart
 Hub Node
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index 269dcba..c735507 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -177,3 +177,4 @@
 execute:frappe.rename_doc("DocType", "Salary Manager", "Process Payroll", force=True)
 erpnext.patches.v5_1.rename_roles
 erpnext.patches.v5_1.default_bom
+execute:frappe.delete_doc("DocType", "Party Type")
\ No newline at end of file
diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py
index e8a772a..d45fbba 100644
--- a/erpnext/selling/doctype/sales_order/sales_order.py
+++ b/erpnext/selling/doctype/sales_order/sales_order.py
@@ -272,6 +272,10 @@
 	def postprocess(source, doc):
 		doc.material_request_type = "Purchase"
 
+	so = frappe.get_doc("Sales Order", source_name)
+	
+	item_table = "Packed Item" if so.packed_items else "Sales Order Item"
+	
 	doc = get_mapped_doc("Sales Order", source_name, {
 		"Sales Order": {
 			"doctype": "Material Request",
@@ -279,7 +283,7 @@
 				"docstatus": ["=", 1]
 			}
 		},
-		"Sales Order Item": {
+		item_table: {
 			"doctype": "Material Request Item",
 			"field_map": {
 				"parent": "sales_order_no",
diff --git a/erpnext/setup/doctype/sms_settings/sms_settings.py b/erpnext/setup/doctype/sms_settings/sms_settings.py
index 1403ee5..9099863 100644
--- a/erpnext/setup/doctype/sms_settings/sms_settings.py
+++ b/erpnext/setup/doctype/sms_settings/sms_settings.py
@@ -5,7 +5,7 @@
 import frappe
 
 from frappe import _, throw, msgprint
-from frappe.utils import cstr, nowdate
+from frappe.utils import nowdate
 
 from frappe.model.document import Document
 
@@ -63,8 +63,7 @@
 	}
 
 	if frappe.db.get_value('SMS Settings', None, 'sms_gateway_url'):
-		ret = send_via_gateway(arg)
-		msgprint(ret)
+		send_via_gateway(arg)
 	else:
 		msgprint(_("Please Update SMS Settings"))
 
@@ -74,12 +73,17 @@
 	for d in ss.get("parameters"):
 		args[d.parameter] = d.value
 
-	resp = []
+	success_list = []
 	for d in arg.get('receiver_list'):
 		args[ss.receiver_parameter] = d
-		resp.append(send_request(ss.sms_gateway_url, args))
+		status = send_request(ss.sms_gateway_url, args)
+		if status == 200:
+			success_list.append(d)
 
-	return resp
+	if len(success_list) > 0:
+		args.update(arg)
+		create_sms_log(args, success_list)
+		frappe.msgprint(_("SMS sent to following numbers: {0}").format("\n" + "\n".join(success_list)))
 
 # Send Request
 # =========================================================
@@ -90,11 +94,8 @@
 	headers = {}
 	headers['Accept'] = "text/plain, text/html, */*"
 	conn.request('GET', api_url + urllib.urlencode(args), headers = headers)    # send request
-	resp = conn.getresponse()     # get response
-	resp = resp.read()
-	if resp.status==200:
-		create_sms_log()
-	return resp
+	resp = conn.getresponse()     # get response		
+	return resp.status
 
 # Split gateway url to server and api url
 # =========================================================
@@ -109,12 +110,13 @@
 
 # Create SMS Log
 # =========================================================
-def create_sms_log(arg, sent_sms):
-	sl = frappe.get_doc('SMS Log')
-	sl.sender_name = arg['sender_name']
+def create_sms_log(args, sent_to):
+	sl = frappe.new_doc('SMS Log')
+	sl.sender_name = args['sender_name']
 	sl.sent_on = nowdate()
-	sl.receiver_list = cstr(arg['receiver_list'])
-	sl.message = arg['message']
-	sl.no_of_requested_sms = len(arg['receiver_list'])
-	sl.no_of_sent_sms = sent_sms
+	sl.message = args['message']
+	sl.no_of_requested_sms = len(args['receiver_list'])
+	sl.requested_numbers = "\n".join(args['receiver_list'])
+	sl.no_of_sent_sms = len(sent_to)
+	sl.sent_to = "\n".join(sent_to)
 	sl.save()
diff --git a/erpnext/setup/page/setup_wizard/install_fixtures.py b/erpnext/setup/page/setup_wizard/install_fixtures.py
index 629c06f..6265e4a 100644
--- a/erpnext/setup/page/setup_wizard/install_fixtures.py
+++ b/erpnext/setup/page/setup_wizard/install_fixtures.py
@@ -183,4 +183,4 @@
 		parent_link_field = ("parent_" + scrub(doc.doctype))
 		if doc.meta.get_field(parent_link_field) and not doc.get(parent_link_field):
 			doc.flags.ignore_mandatory = True
-		doc.insert()
+		doc.insert(ignore_permissions=True)
diff --git a/erpnext/setup/page/setup_wizard/sample_data.py b/erpnext/setup/page/setup_wizard/sample_data.py
new file mode 100644
index 0000000..f7fb73b
--- /dev/null
+++ b/erpnext/setup/page/setup_wizard/sample_data.py
@@ -0,0 +1,117 @@
+# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
+# License: GNU General Public License v3. See license.txt
+
+from __future__ import unicode_literals
+
+import frappe
+from frappe.utils.make_random import add_random_children, get_random
+import frappe.utils
+
+def make_sample_data():
+	"""Create a few opportunities, quotes, material requests, issues, todos, projects
+	to help the user get started"""
+
+	selling_items = frappe.get_all("Item", filters = {"is_sales_item": "Yes"})
+	buying_items = frappe.get_all("Item", filters = {"is_sales_item": "No"})
+
+	if selling_items:
+		for i in range(3):
+			make_opportunity(selling_items)
+			make_quote(selling_items)
+
+	make_projects()
+
+	if buying_items:
+		make_material_request(buying_items)
+
+	frappe.db.commit()
+
+def make_opportunity(selling_items):
+	b = frappe.get_doc({
+		"doctype": "Opportunity",
+		"enquiry_from": "Customer",
+		"customer": get_random("Customer"),
+		"enquiry_type": "Sales",
+		"with_items": 1
+	})
+
+	add_random_children(b, "items", rows=len(selling_items), randomize = {
+		"qty": (1, 5),
+		"item_code": ("Item", {"is_sales_item": "Yes"})
+	}, unique="item_code")
+
+	b.insert(ignore_permissions=True)
+
+	b.add_comment("This is a dummy record")
+
+def make_quote(selling_items):
+	qtn = frappe.get_doc({
+		"doctype": "Quotation",
+		"quotation_to": "Customer",
+		"customer": get_random("Customer"),
+		"order_type": "Sales"
+	})
+
+	add_random_children(qtn, "items", rows=len(selling_items), randomize = {
+		"qty": (1, 5),
+		"item_code": ("Item", {"is_sales_item": "Yes"})
+	}, unique="item_code")
+
+	qtn.insert(ignore_permissions=True)
+
+	qtn.add_comment("This is a dummy record")
+
+def make_material_request(buying_items):
+	for i in buying_items:
+		mr = frappe.get_doc({
+			"doctype": "Material Request",
+			"material_request_type": "Purchase",
+			"items": [{
+				"schedule_date": frappe.utils.add_days(frappe.utils.nowdate(), 7),
+				"item_code": i.name,
+				"qty": 10
+			}]
+		})
+		mr.insert()
+		mr.submit()
+
+		mr.add_comment("This is a dummy record")
+
+
+def make_issue():
+	pass
+
+def make_projects():
+	project = frappe.get_doc({
+		"doctype": "Project",
+		"project_name": "ERPNext Implementation",
+	})
+	current_date = frappe.utils.nowdate()
+	project.set("tasks", [
+			{
+				"title": "Explore ERPNext",
+				"start_date": frappe.utils.add_days(current_date, 1),
+				"end_date": frappe.utils.add_days(current_date, 2)
+			},
+			{
+				"title": "Run Sales Cycle",
+				"start_date": frappe.utils.add_days(current_date, 2),
+				"end_date": frappe.utils.add_days(current_date, 3)
+			},
+			{
+				"title": "Run Billing Cycle",
+				"start_date": frappe.utils.add_days(current_date, 3),
+				"end_date": frappe.utils.add_days(current_date, 4)
+			},
+			{
+				"title": "Run Purchase Cycle",
+				"start_date": frappe.utils.add_days(current_date, 4),
+				"end_date": frappe.utils.add_days(current_date, 5)
+			},
+			{
+				"title": "Go Live!",
+				"start_date": frappe.utils.add_days(current_date, 5),
+				"end_date": frappe.utils.add_days(current_date, 6)
+			}])
+
+	project.insert(ignore_permissions=True)
diff --git a/erpnext/setup/page/setup_wizard/setup_wizard.js b/erpnext/setup/page/setup_wizard/setup_wizard.js
index d521ada..b38bd1c 100644
--- a/erpnext/setup/page/setup_wizard/setup_wizard.js
+++ b/erpnext/setup/page/setup_wizard/setup_wizard.js
@@ -25,6 +25,7 @@
 			erpnext.wiz.user.slide,
 			erpnext.wiz.org.slide,
 			erpnext.wiz.branding.slide,
+			erpnext.wiz.users.slide,
 			erpnext.wiz.taxes.slide,
 			erpnext.wiz.customers.slide,
 			erpnext.wiz.suppliers.slide,
@@ -137,7 +138,7 @@
 			});
 			this.form.make();
 		} else {
-			$(this.body).html(this.html)
+			$(this.body).html(this.html);
 		}
 
 		if(this.id > 0) {
@@ -412,11 +413,30 @@
 			onload: function(slide) {
 				erpnext.wiz.org.load_chart_of_accounts(slide);
 				erpnext.wiz.org.bind_events(slide);
+				erpnext.wiz.org.set_fy_dates(slide);
 			},
 
 			css_class: "single-column"
 		},
 
+		set_fy_dates: function(slide) {
+			var country = slide.wiz.get_values().country;
+
+			if(country) {
+				var fy = erpnext.wiz.fiscal_years[country];
+				var current_year = moment(new Date()).year();
+				var next_year = current_year + 1;
+				if(!fy) {
+					fy = ["01-01", "12-31"];
+					next_year = current_year;
+				}
+
+				slide.get_field("fy_start_date").set_input(current_year + "-" + fy[0]);
+				slide.get_field("fy_end_date").set_input(next_year + "-" + fy[1]);
+			}
+
+		},
+
 		load_chart_of_accounts: function(slide) {
 			var country = slide.wiz.get_values().country;
 
@@ -486,11 +506,41 @@
 		},
 	},
 
+	users: {
+		slide: {
+			icon: "icon-money",
+			"title": __("Add Users"),
+			"help": __("Add users to your organization"),
+			"fields": [],
+			before_load: function(slide) {
+				slide.fields = [];
+				for(var i=1; i<5; i++) {
+					slide.fields = slide.fields.concat([
+						{fieldtype:"Section Break"},
+						{fieldtype:"Data", fieldname:"user_fullname_"+ i,
+							label:__("Full Name")},
+						{fieldtype:"Data", fieldname:"user_email_" + i,
+							label:__("Email ID"), placeholder:__("user@example.com"),
+							options: "Email"},
+						{fieldtype:"Column Break"},
+						{fieldtype: "Check", fieldname: "user_sales_" + i,
+							label:__("Sales"), default: 1},
+						{fieldtype: "Check", fieldname: "user_purchaser_" + i,
+							label:__("Purchaser"), default: 1},
+						{fieldtype: "Check", fieldname: "user_accountant_" + i,
+							label:__("Accountant"), default: 1},
+					]);
+				}
+			},
+			css_class: "two-column"
+		},
+	},
+
 	taxes: {
 		slide: {
 			icon: "icon-money",
 			"title": __("Add Taxes"),
-			"help": __("List your tax heads (e.g. VAT, Excise; they should have unique names) and their standard rates. This will create a standard template, which you can edit and add more later."),
+			"help": __("List your tax heads (e.g. VAT, Customs etc; they should have unique names) and their standard rates. This will create a standard template, which you can edit and add more later."),
 			"fields": [],
 			before_load: function(slide) {
 				slide.fields = [];
@@ -526,6 +576,7 @@
 							label:__("Contact Name") + " " + i, placeholder:__("Contact Name")}
 					])
 				}
+				slide.fields[1].reqd = 1;
 			},
 			css_class: "two-column"
 		},
@@ -549,6 +600,7 @@
 							label:__("Contact Name") + " " + i, placeholder:__("Contact Name")},
 					])
 				}
+				slide.fields[1].reqd = 1;
 			},
 			css_class: "two-column"
 		},
@@ -578,9 +630,11 @@
 						{fieldtype: "Check", fieldname: "is_sales_item_" + i, label:__("We sell this Item"), default: 1},
 						{fieldtype: "Check", fieldname: "is_purchase_item_" + i, label:__("We buy this Item")},
 						{fieldtype:"Column Break"},
+						{fieldtype:"Currency", fieldname:"item_price_" + i, label:__("Rate")},
 						{fieldtype:"Attach Image", fieldname:"item_img_" + i, label:__("Attach Image")},
 					])
 				}
+				slide.fields[1].reqd = 1;
 			},
 			css_class: "two-column"
 		},
@@ -627,3 +681,25 @@
 	},
 });
 
+// Source: https://en.wikipedia.org/wiki/Fiscal_year
+// default 1st Jan - 31st Dec
+
+erpnext.wiz.fiscal_years = {
+	"Afghanistan": ["12-20", "12-21"],
+	"Australia": ["07-01", "06-30"],
+	"Bangladesh": ["07-01", "06-30"],
+	"Canada": ["04-01", "03-31"],
+	"Costa Rica": ["10-01", "09-30"],
+	"Egypt": ["07-01", "06-30"],
+	"Hong Kong": ["04-01", "03-31"],
+	"India": ["04-01", "03-31"],
+	"Iran": ["06-23", "06-22"],
+	"Italy": ["07-01", "06-30"],
+	"Myanmar": ["04-01", "03-31"],
+	"New Zealand": ["04-01", "03-31"],
+	"Pakistan": ["07-01", "06-30"],
+	"Singapore": ["04-01", "03-31"],
+	"South Africa": ["03-01", "02-28"],
+	"Thailand": ["10-01", "09-30"],
+	"United Kingdom": ["04-01", "03-31"],
+}
diff --git a/erpnext/setup/page/setup_wizard/setup_wizard.py b/erpnext/setup/page/setup_wizard/setup_wizard.py
index 141b914..9ddd2dc 100644
--- a/erpnext/setup/page/setup_wizard/setup_wizard.py
+++ b/erpnext/setup/page/setup_wizard/setup_wizard.py
@@ -2,7 +2,7 @@
 # License: GNU General Public License v3. See license.txt
 
 from __future__ import unicode_literals
-import frappe, json
+import frappe, json, copy
 
 from frappe.utils import cstr, flt, getdate
 from frappe import _
@@ -13,6 +13,7 @@
 from frappe.utils.nestedset import get_root_of
 from .default_website import website_maker
 import install_fixtures
+from .sample_data import make_sample_data
 
 @frappe.whitelist()
 def setup_account(args=None):
@@ -38,6 +39,9 @@
 		create_fiscal_year_and_company(args)
 		frappe.local.message_log = []
 
+		create_users(args)
+		frappe.local.message_log = []
+
 		set_defaults(args)
 		frappe.local.message_log = []
 
@@ -81,6 +85,7 @@
 
 		frappe.clear_cache()
 
+		make_sample_data()
 	except:
 		if args:
 			traceback = frappe.get_traceback()
@@ -297,21 +302,45 @@
 				tax_group = frappe.db.get_value("Account", {"company": args.get("company_name"),
 					"is_group": 1, "account_type": "Tax", "root_type": "Liability"})
 				if tax_group:
-					frappe.get_doc({
-						"doctype":"Account",
-						"company": args.get("company_name").strip(),
-						"parent_account": tax_group,
-						"account_name": args.get("tax_" + str(i)),
-						"is_group": 0,
-						"report_type": "Balance Sheet",
-						"account_type": "Tax",
-						"tax_rate": flt(tax_rate) if tax_rate else None
-					}).insert()
+					account = make_tax_head(args, i, tax_group, tax_rate)
+					make_sales_and_purchase_tax_templates(account)
+
 			except frappe.NameError, e:
 				if e.args[2][0]==1062:
 					pass
 				else:
 					raise
+def make_tax_head(args, i, tax_group, tax_rate):
+	return frappe.get_doc({
+		"doctype":"Account",
+		"company": args.get("company_name").strip(),
+		"parent_account": tax_group,
+		"account_name": args.get("tax_" + str(i)),
+		"is_group": 0,
+		"report_type": "Balance Sheet",
+		"account_type": "Tax",
+		"tax_rate": flt(tax_rate) if tax_rate else None
+	}).insert(ignore_permissions=True)
+
+def make_sales_and_purchase_tax_templates(account):
+	doc = {
+		"doctype": "Sales Taxes and Charges Template",
+		"title": account.name,
+		"taxes": [{
+		    "category": "Valuation and Total",
+		    "charge_type": "On Net Total",
+			"account_head": account.name,
+			"description": "{0} @ {1}".format(account.account_name, account.tax_rate),
+			"rate": account.tax_rate
+		}]
+	}
+
+	# Sales
+	frappe.get_doc(copy.deepcopy(doc)).insert()
+
+	# Purchase
+	doc["doctype"] = "Purchase Taxes and Charges Template"
+	frappe.get_doc(copy.deepcopy(doc)).insert()
 
 def create_items(args):
 	for i in xrange(1,6):
@@ -349,9 +378,30 @@
 						filename, filetype, content = item_image
 						fileurl = save_file(filename, content, "Item", item, decode=True).file_url
 						frappe.db.set_value("Item", item, "image", fileurl)
+
+				if args.get("item_price_" + str(i)):
+					item_price = flt(args.get("item_price_" + str(i)))
+
+					if is_sales_item:
+						price_list_name = frappe.db.get_value("Price List", {"selling": 1})
+						make_item_price(item, price_list_name, item_price)
+
+					if is_purchase_item:
+						price_list_name = frappe.db.get_value("Price List", {"buying": 1})
+						make_item_price(item, price_list_name, item_price)
+
 			except frappe.NameError:
 				pass
 
+def make_item_price(item, price_list_name, item_price):
+	frappe.get_doc({
+		"doctype": "Item Price",
+		"price_list": price_list_name,
+		"item_code": item,
+		"price_list_rate": item_price
+	}).insert()
+
+
 def create_customers(args):
 	for i in xrange(1,6):
 		customer = args.get("customer_" + str(i))
@@ -451,6 +501,60 @@
 	if args.get("email") and hasattr(frappe.local, "login_manager"):
 		frappe.local.login_manager.login_as(args.get("email"))
 
+def create_users(args):
+	# create employee for self
+	emp = frappe.get_doc({
+		"doctype": "Employee",
+		"full_name": " ".join(filter(None, [args.get("first_name"), args.get("last_name")])),
+		"user_id": frappe.session.user,
+		"status": "Active",
+		"company": args.get("company_name")
+	})
+	emp.flags.ignore_mandatory = True
+	emp.insert(ignore_permissions = True)
+
+	for i in xrange(1,5):
+		email = args.get("user_email_" + str(i))
+		fullname = args.get("user_fullname_" + str(i))
+		if email:
+			if not fullname:
+				fullname = email.split("@")[0]
+
+			parts = fullname.split(" ", 1)
+
+			user = frappe.get_doc({
+				"doctype": "User",
+				"email": email,
+				"first_name": parts[0],
+				"last_name": parts[1] if len(parts) > 1 else "",
+				"enabled": 1,
+				"user_type": "System User"
+			})
+
+			# default roles
+			user.append_roles("Projects User", "Stock User", "Support Team")
+
+			if args.get("user_sales_" + str(i)):
+				user.append_roles("Sales User", "Sales Manager", "Accounts User")
+			if args.get("user_purchaser_" + str(i)):
+				user.append_roles("Purchase User", "Purchase Manager", "Accounts User")
+			if args.get("user_accountant_" + str(i)):
+				user.append_roles("Accounts Manager", "Accounts User")
+
+			user.flags.delay_emails = True
+			user.insert(ignore_permissions=True)
+
+			# create employee
+			emp = frappe.get_doc({
+				"doctype": "Employee",
+				"full_name": fullname,
+				"user_id": user.name,
+				"status": "Active",
+				"company": args.get("company_name")
+			})
+			emp.flags.ignore_mandatory = True
+			emp.insert(ignore_permissions = True)
+
 @frappe.whitelist()
 def load_messages(language):
 	frappe.clear_cache()
diff --git a/erpnext/setup/page/setup_wizard/test_setup_data.py b/erpnext/setup/page/setup_wizard/test_setup_data.py
index 43fc2cf..de54a1d 100644
--- a/erpnext/setup/page/setup_wizard/test_setup_data.py
+++ b/erpnext/setup/page/setup_wizard/test_setup_data.py
@@ -51,4 +51,15 @@
 "timezone": "America/New_York",
 "password": "password",
 "email": "test@erpnext.com",
+"user_email_1": "testsetup1@example.com",
+"user_fullname_1": "test setup user",
+"user_sales_1": 1,
+"user_purchaser_1": 1,
+"user_accountant_1": 1,
+"user_email_1": "testsetup2@example.com",
+"user_fullname_1": "test setup user",
+"user_sales_2": 1,
+"user_purchaser_2": 0,
+"user_accountant_2": 0
+
 }
diff --git a/erpnext/startup/notifications.py b/erpnext/startup/notifications.py
index 4190f2d..d065370 100644
--- a/erpnext/startup/notifications.py
+++ b/erpnext/startup/notifications.py
@@ -10,6 +10,7 @@
 			"Issue": {"status": "Open"},
 			"Warranty Claim": {"status": "Open"},
 			"Task": {"status": "Open"},
+			"Project": {"status": "Open"},
 			"Lead": {"status": "Open"},
 			"Contact": {"status": "Open"},
 			"Opportunity": {"status": "Open"},
diff --git a/erpnext/stock/doctype/item/item.js b/erpnext/stock/doctype/item/item.js
index 58b1adb..3bd5657 100644
--- a/erpnext/stock/doctype/item/item.js
+++ b/erpnext/stock/doctype/item/item.js
@@ -86,8 +86,12 @@
 	},
 	
 	manage_variants: function(frm) {
-		frappe.route_options = {"item_code": frm.doc.name };
-		frappe.set_route("List", "Manage Variants");
+		if (cur_frm.doc.__unsaved==1) {
+			frappe.throw(__("You have unsaved changes. Please save."))
+		} else {
+			frappe.route_options = {"item_code": frm.doc.name };
+			frappe.set_route("List", "Manage Variants");
+		}
 	}
 });
 
diff --git a/erpnext/stock/doctype/item/item.py b/erpnext/stock/doctype/item/item.py
index a2e0ade..d3d8e9c 100644
--- a/erpnext/stock/doctype/item/item.py
+++ b/erpnext/stock/doctype/item/item.py
@@ -325,7 +325,8 @@
 			for d in variants:
 				update_variant(self.name, d)
 				updated.append(d.item_code)
-			frappe.msgprint(_("Item Variants {0} updated").format(", ".join(updated)))
+			if updated:
+				frappe.msgprint(_("Item Variants {0} updated").format(", ".join(updated)))
 				
 	def validate_has_variants(self):
 		if not self.has_variants and frappe.db.get_value("Item", self.name, "has_variants"):
diff --git a/erpnext/stock/report/stock_ledger/stock_ledger.py b/erpnext/stock/report/stock_ledger/stock_ledger.py
index 0651ae8..c2c6d1a 100644
--- a/erpnext/stock/report/stock_ledger/stock_ledger.py
+++ b/erpnext/stock/report/stock_ledger/stock_ledger.py
@@ -9,8 +9,13 @@
 	columns = get_columns()
 	sl_entries = get_stock_ledger_entries(filters)
 	item_details = get_item_details(filters)
-
+	opening_row = get_opening_balance(filters, columns)
+	
 	data = []
+	
+	if opening_row:
+		data.append(opening_row)
+
 	for sle in sl_entries:
 		item_detail = item_details[sle.item_code]
 
@@ -20,7 +25,7 @@
 			(sle.incoming_rate if sle.actual_qty > 0 else 0.0),
 			sle.valuation_rate, sle.stock_value, sle.voucher_type, sle.voucher_no,
 			sle.batch_no, sle.serial_no, sle.company])
-
+			
 	return columns, data
 
 def get_columns():
@@ -40,7 +45,7 @@
 		where company = %(company)s and
 			posting_date between %(from_date)s and %(to_date)s
 			{sle_conditions}
-			order by posting_date desc, posting_time desc, name desc"""\
+			order by posting_date asc, posting_time asc, name asc"""\
 		.format(sle_conditions=get_sle_conditions(filters)), filters, as_dict=1)
 
 def get_item_details(filters):
@@ -73,3 +78,22 @@
 		conditions.append("voucher_no=%(voucher_no)s")
 
 	return "and {}".format(" and ".join(conditions)) if conditions else ""
+
+def get_opening_balance(filters, columns):
+	if not (filters.item_code and filters.warehouse and filters.from_date):
+		return
+
+	from erpnext.stock.stock_ledger import get_previous_sle
+	last_entry = get_previous_sle({
+		"item_code": filters.item_code,
+		"warehouse": filters.warehouse,
+		"posting_date": filters.from_date,
+		"posting_time": "00:00:00"
+	})
+	
+	row = [""]*len(columns)
+	row[1] = _("'Opening'")
+	for i, v in ((9, 'qty_after_transaction'), (11, 'valuation_rate'), (12, 'stock_value')):
+			row[i] = last_entry.get(v, 0)
+		
+	return row
\ No newline at end of file
diff --git a/erpnext/utilities/doctype/sms_log/sms_log.json b/erpnext/utilities/doctype/sms_log/sms_log.json
index e3c7741..ba88c62 100644
--- a/erpnext/utilities/doctype/sms_log/sms_log.json
+++ b/erpnext/utilities/doctype/sms_log/sms_log.json
@@ -1,32 +1,58 @@
 {
  "autoname": "SMSLOG/.########", 
- "creation": "2012-03-27 14:36:47.000000", 
+ "creation": "2012-03-27 14:36:47", 
  "docstatus": 0, 
  "doctype": "DocType", 
  "fields": [
   {
-   "fieldname": "column_break0", 
-   "fieldtype": "Column Break", 
-   "permlevel": 0, 
-   "width": "50%"
-  }, 
-  {
    "fieldname": "sender_name", 
    "fieldtype": "Data", 
    "label": "Sender Name", 
-   "permlevel": 0
+   "permlevel": 0, 
+   "read_only": 1
   }, 
   {
    "fieldname": "sent_on", 
    "fieldtype": "Date", 
    "label": "Sent On", 
-   "permlevel": 0
+   "permlevel": 0, 
+   "read_only": 1
   }, 
   {
-   "fieldname": "receiver_list", 
+   "fieldname": "column_break0", 
+   "fieldtype": "Column Break", 
+   "permlevel": 0, 
+   "read_only": 0, 
+   "width": "50%"
+  }, 
+  {
+   "fieldname": "message", 
    "fieldtype": "Small Text", 
-   "label": "Receiver List", 
-   "permlevel": 0
+   "label": "Message", 
+   "permlevel": 0, 
+   "read_only": 1
+  }, 
+  {
+   "fieldname": "sec_break1", 
+   "fieldtype": "Section Break", 
+   "options": "Simple", 
+   "permlevel": 0, 
+   "precision": "", 
+   "read_only": 0
+  }, 
+  {
+   "fieldname": "no_of_requested_sms", 
+   "fieldtype": "Int", 
+   "label": "No of Requested SMS", 
+   "permlevel": 0, 
+   "read_only": 1
+  }, 
+  {
+   "fieldname": "requested_numbers", 
+   "fieldtype": "Small Text", 
+   "label": "Requested Numbers", 
+   "permlevel": 0, 
+   "read_only": 1
   }, 
   {
    "fieldname": "column_break1", 
@@ -35,27 +61,24 @@
    "width": "50%"
   }, 
   {
-   "fieldname": "no_of_requested_sms", 
-   "fieldtype": "Int", 
-   "label": "No of Requested SMS", 
-   "permlevel": 0
-  }, 
-  {
    "fieldname": "no_of_sent_sms", 
    "fieldtype": "Int", 
    "label": "No of Sent SMS", 
-   "permlevel": 0
+   "permlevel": 0, 
+   "read_only": 1
   }, 
   {
-   "fieldname": "message", 
+   "fieldname": "sent_to", 
    "fieldtype": "Small Text", 
-   "label": "Message", 
-   "permlevel": 0
+   "label": "Sent To", 
+   "permlevel": 0, 
+   "precision": "", 
+   "read_only": 1
   }
  ], 
  "icon": "icon-mobile-phone", 
  "idx": 1, 
- "modified": "2013-12-20 19:24:35.000000", 
+ "modified": "2015-07-22 11:53:25.998578", 
  "modified_by": "Administrator", 
  "module": "Utilities", 
  "name": "SMS Log",