Merge branch 'master' into develop
diff --git a/erpnext/accounts/doctype/salary_component_account/__init__.py b/erpnext/accounts/doctype/salary_component_account/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/accounts/doctype/salary_component_account/__init__.py
diff --git a/erpnext/accounts/doctype/salary_component_account/salary_component_account.json b/erpnext/accounts/doctype/salary_component_account/salary_component_account.json
new file mode 100644
index 0000000..6bbde22
--- /dev/null
+++ b/erpnext/accounts/doctype/salary_component_account/salary_component_account.json
@@ -0,0 +1,90 @@
+{
+ "allow_copy": 0, 
+ "allow_import": 0, 
+ "allow_rename": 0, 
+ "beta": 0, 
+ "creation": "2016-07-27 17:24:24.956896", 
+ "custom": 0, 
+ "docstatus": 0, 
+ "doctype": "DocType", 
+ "document_type": "", 
+ "editable_grid": 1, 
+ "fields": [
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "fieldname": "company", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 1, 
+   "label": "Company", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Company", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "description": "Default Bank / Cash account will be automatically updated in POS Invoice when this mode is selected.", 
+   "fieldname": "default_account", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 1, 
+   "label": "Default Account", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Account", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }
+ ], 
+ "hide_heading": 0, 
+ "hide_toolbar": 0, 
+ "idx": 0, 
+ "image_view": 0, 
+ "in_create": 0, 
+ "in_dialog": 0, 
+ "is_submittable": 0, 
+ "issingle": 0, 
+ "istable": 1, 
+ "max_attachments": 0, 
+ "modified": "2016-07-27 17:24:24.956896", 
+ "modified_by": "Administrator", 
+ "module": "Accounts", 
+ "name": "Salary Component Account", 
+ "name_case": "", 
+ "owner": "Administrator", 
+ "permissions": [], 
+ "quick_entry": 0, 
+ "read_only": 0, 
+ "read_only_onload": 0, 
+ "sort_field": "modified", 
+ "sort_order": "DESC", 
+ "track_seen": 0
+}
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/salary_component_account/salary_component_account.py b/erpnext/accounts/doctype/salary_component_account/salary_component_account.py
new file mode 100644
index 0000000..983d015
--- /dev/null
+++ b/erpnext/accounts/doctype/salary_component_account/salary_component_account.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# 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.model.document import Document
+
+class SalaryComponentAccount(Document):
+	pass
diff --git a/erpnext/accounts/report/balance_sheet/balance_sheet.py b/erpnext/accounts/report/balance_sheet/balance_sheet.py
index 4efd098..23fa762 100644
--- a/erpnext/accounts/report/balance_sheet/balance_sheet.py
+++ b/erpnext/accounts/report/balance_sheet/balance_sheet.py
@@ -8,7 +8,7 @@
 from erpnext.accounts.report.financial_statements import (get_period_list, get_columns, get_data)
 
 def execute(filters=None):
-	period_list = get_period_list(filters.fiscal_year, filters.periodicity)
+	period_list = get_period_list(filters.from_fiscal_year, filters.to_fiscal_year, filters.periodicity)
 
 	asset = get_data(filters.company, "Asset", "Debit", period_list, only_current_fiscal_year=False)
 	liability = get_data(filters.company, "Liability", "Credit", period_list, only_current_fiscal_year=False)
diff --git a/erpnext/accounts/report/cash_flow/cash_flow.js b/erpnext/accounts/report/cash_flow/cash_flow.js
index f5ddd15..455664f 100644
--- a/erpnext/accounts/report/cash_flow/cash_flow.js
+++ b/erpnext/accounts/report/cash_flow/cash_flow.js
@@ -2,7 +2,8 @@
 // For license information, please see license.txt
 
 frappe.require("assets/erpnext/js/financial_statements.js", function() {
-	frappe.query_reports["Cash Flow"] = erpnext.financial_statements;
+	frappe.query_reports["Cash Flow"] = $.extend({},
+		erpnext.financial_statements);
 
 	frappe.query_reports["Cash Flow"]["filters"].push({
 		"fieldname": "accumulated_values",
diff --git a/erpnext/accounts/report/cash_flow/cash_flow.py b/erpnext/accounts/report/cash_flow/cash_flow.py
index 3407526..24c5cd2 100644
--- a/erpnext/accounts/report/cash_flow/cash_flow.py
+++ b/erpnext/accounts/report/cash_flow/cash_flow.py
@@ -6,10 +6,11 @@
 from frappe import _
 from erpnext.accounts.report.financial_statements import (get_period_list, get_columns, get_data)
 from erpnext.accounts.report.profit_and_loss_statement.profit_and_loss_statement import get_net_profit_loss
+from erpnext.accounts.utils import get_fiscal_year
 
 
 def execute(filters=None):
-	period_list = get_period_list(filters.fiscal_year, filters.periodicity)
+	period_list = get_period_list(filters.from_fiscal_year, filters.to_fiscal_year, filters.periodicity)
 
 	operation_accounts = {
 		"section_name": "Operations",
@@ -49,9 +50,9 @@
 
 	# compute net profit / loss
 	income = get_data(filters.company, "Income", "Credit", period_list, 
-		accumulated_values=filters.accumulated_values, ignore_closing_entries=True)
+		accumulated_values=filters.accumulated_values, ignore_closing_entries=True, ignore_accumulated_values_for_fy= True)
 	expense = get_data(filters.company, "Expense", "Debit", period_list, 
-		accumulated_values=filters.accumulated_values, ignore_closing_entries=True)
+		accumulated_values=filters.accumulated_values, ignore_closing_entries=True, ignore_accumulated_values_for_fy= True)
 		
 	net_profit_loss = get_net_profit_loss(income, expense, period_list, filters.company)
 
@@ -98,33 +99,39 @@
 
 	return columns, data
 
-
 def get_account_type_based_data(company, account_type, period_list, accumulated_values):
 	data = {}
 	total = 0
 	for period in period_list:
+		start_date = get_start_date(period, accumulated_values)
 		gl_sum = frappe.db.sql_list("""
 			select sum(credit) - sum(debit)
 			from `tabGL Entry`
 			where company=%s and posting_date >= %s and posting_date <= %s 
 				and voucher_type != 'Period Closing Voucher'
 				and account in ( SELECT name FROM tabAccount WHERE account_type = %s)
-		""", (company, period["year_start_date"] if accumulated_values else period['from_date'], 
+		""", (company, start_date if accumulated_values else period['from_date'],
 			period['to_date'], account_type))
-		
+
 		if gl_sum and gl_sum[0]:
 			amount = gl_sum[0]
 			if account_type == "Depreciation":
 				amount *= -1
 		else:
 			amount = 0
-			
+
 		total += amount
 		data.setdefault(period["key"], amount)
-		
+
 	data["total"] = total
 	return data
 
+def get_start_date(period, accumulated_values):
+	start_date = period["year_start_date"]
+	if accumulated_values:
+		start_date = get_fiscal_year(period.to_date)[1]
+
+	return start_date
 
 def add_total_row_account(out, data, label, period_list, currency):
 	total_row = {
diff --git a/erpnext/accounts/report/financial_statements.py b/erpnext/accounts/report/financial_statements.py
index c930952..f6968a1 100644
--- a/erpnext/accounts/report/financial_statements.py
+++ b/erpnext/accounts/report/financial_statements.py
@@ -3,61 +3,71 @@
 
 from __future__ import unicode_literals
 import frappe
+import math
 from frappe import _
-from frappe.utils import (flt, getdate, get_first_day, get_last_day,
-	add_months, add_days, formatdate)
+from frappe.utils import (flt, getdate, get_first_day, get_last_day, date_diff,
+	add_months, add_days, formatdate, cint)
 
-def get_period_list(fiscal_year, periodicity):
+def get_period_list(from_fiscal_year, to_fiscal_year, periodicity):
 	"""Get a list of dict {"from_date": from_date, "to_date": to_date, "key": key, "label": label}
 		Periodicity can be (Yearly, Quarterly, Monthly)"""
 
-	fy_start_end_date = frappe.db.get_value("Fiscal Year", fiscal_year, ["year_start_date", "year_end_date"])
-	if not fy_start_end_date:
-		frappe.throw(_("Fiscal Year {0} not found.").format(fiscal_year))
+	from_fy_start_end_date = frappe.db.get_value("Fiscal Year", from_fiscal_year, ["year_start_date", "year_end_date"])
+	to_fy_start_end_date = frappe.db.get_value("Fiscal Year", to_fiscal_year, ["year_start_date", "year_end_date"])
+
+	if not from_fy_start_end_date:
+		frappe.throw(_("Start Year {0} not found.").format(from_fiscal_year))
+	
+	if not to_fy_start_end_date:
+		frappe.throw(_("End Year {0} not found.").format(to_fiscal_year))
 
 	# start with first day, so as to avoid year to_dates like 2-April if ever they occur]
-	year_start_date = get_first_day(getdate(fy_start_end_date[0]))
-	year_end_date = getdate(fy_start_end_date[1])
-	
-	if periodicity == "Yearly":
-		period_list = [frappe._dict({"from_date": year_start_date, "to_date": year_end_date, 
-			"key": fiscal_year, "label": fiscal_year})]
-	else:
-		months_to_add = {
-			"Half-Yearly": 6,
-			"Quarterly": 3,
-			"Monthly": 1
-		}[periodicity]
+	year_start_date = getdate(from_fy_start_end_date[0])
+	year_end_date = getdate(to_fy_start_end_date[1])
 
-		period_list = []
+	validate_fiscal_year(year_start_date, year_end_date)
 
-		start_date = year_start_date
-		for i in xrange(12 / months_to_add):
-			period = frappe._dict({
-				"from_date": start_date
-			})
-			to_date = add_months(start_date, months_to_add)
-			start_date = to_date
-			
-			if to_date == get_first_day(to_date):
-				# if to_date is the first day, get the last day of previous month
-				to_date = add_days(to_date, -1)
-			else:
-				# to_date should be the last day of the new to_date's month
-				to_date = get_last_day(to_date)
+	months_to_add = {
+		"Yearly": 12,
+		"Half-Yearly": 6,
+		"Quarterly": 3,
+		"Monthly": 1
+	}[periodicity]
 
-			if to_date <= year_end_date:
-				# the normal case
-				period.to_date = to_date
-			else:
-				# if a fiscal year ends before a 12 month period
-				period.to_date = year_end_date
-			
-			period_list.append(period)
-			
-			if period.to_date == year_end_date:
-				break
-				
+	period_list = []
+
+	start_date = year_start_date
+	months = get_months(year_start_date, year_end_date)
+
+	for i in xrange(months / months_to_add):
+		period = frappe._dict({
+			"from_date": start_date
+		})
+
+		to_date = add_months(start_date, months_to_add)
+		start_date = to_date
+		
+		if to_date == get_first_day(to_date):
+			# if to_date is the first day, get the last day of previous month
+			to_date = add_days(to_date, -1)
+		else:
+			# to_date should be the last day of the new to_date's month
+			to_date = get_last_day(to_date)
+
+		if to_date <= year_end_date:
+			# the normal case
+			period.to_date = to_date
+		else:
+			# if a fiscal year ends before a 12 month period
+			period.to_date = year_end_date
+
+		period.to_date_fiscal_year = get_date_fiscal_year(period.to_date)
+
+		period_list.append(period)
+
+		if period.to_date == year_end_date:
+			break
+
 	# common processing
 	for opts in period_list:
 		key = opts["to_date"].strftime("%b_%Y").lower()
@@ -75,6 +85,14 @@
 
 	return period_list
 
+def validate_fiscal_year(start_date, end_date):
+	if date_diff(end_date, start_date) <= 0:
+		frappe.throw(_("End Year cannot be before Start Year"))
+
+def get_months(start_date, end_date):
+	diff = (12 * end_date.year + end_date.month) - (12 * start_date.year + start_date.month)
+	return diff + 1
+
 def get_label(periodicity, from_date, to_date):
 	if periodicity=="Yearly":
 		if formatdate(from_date, "YYYY") == formatdate(to_date, "YYYY"):
@@ -87,7 +105,8 @@
 	return label
 	
 def get_data(company, root_type, balance_must_be, period_list, 
-		accumulated_values=1, only_current_fiscal_year=True, ignore_closing_entries=False):
+		accumulated_values=1, only_current_fiscal_year=True, ignore_closing_entries=False,
+		ignore_accumulated_values_for_fy=False):
 	accounts = get_accounts(company, root_type)
 	if not accounts:
 		return None
@@ -106,7 +125,7 @@
 			root.lft, root.rgt, 
 			gl_entries_by_account, ignore_closing_entries=ignore_closing_entries)
 
-	calculate_values(accounts_by_name, gl_entries_by_account, period_list, accumulated_values)
+	calculate_values(accounts_by_name, gl_entries_by_account, period_list, accumulated_values, ignore_accumulated_values_for_fy)
 	accumulate_values_into_parents(accounts, accounts_by_name, period_list, accumulated_values)
 	out = prepare_data(accounts, balance_must_be, period_list, company_currency)
 	out = filter_out_zero_value_rows(out, parent_children_map)
@@ -116,18 +135,26 @@
 
 	return out
 
-def calculate_values(accounts_by_name, gl_entries_by_account, period_list, accumulated_values):
+def calculate_values(accounts_by_name, gl_entries_by_account, period_list, accumulated_values, ignore_accumulated_values_for_fy):
 	for entries in gl_entries_by_account.values():
 		for entry in entries:
 			d = accounts_by_name.get(entry.account)
 			for period in period_list:
 				# check if posting date is within the period
+
+				fiscal_year = get_date_fiscal_year(entry.posting_date)
 				if entry.posting_date <= period.to_date:
-					if accumulated_values or entry.posting_date >= period.from_date:
+					if (accumulated_values or entry.posting_date >= period.from_date) and \
+						(fiscal_year == period.to_date_fiscal_year or not ignore_accumulated_values_for_fy):
 						d[period.key] = d.get(period.key, 0.0) + flt(entry.debit) - flt(entry.credit)
-						
+
 			if entry.posting_date < period_list[0].year_start_date:
 				d["opening_balance"] = d.get("opening_balance", 0.0) + flt(entry.debit) - flt(entry.credit)
+				
+def get_date_fiscal_year(date):
+	from erpnext.accounts.utils import get_fiscal_year
+	
+	return get_fiscal_year(date)[0]
 
 def accumulate_values_into_parents(accounts, accounts_by_name, period_list, accumulated_values):
 	"""accumulate children's values in parent accounts"""
diff --git a/erpnext/accounts/report/gross_profit/gross_profit.py b/erpnext/accounts/report/gross_profit/gross_profit.py
index aa0232b..a052821 100644
--- a/erpnext/accounts/report/gross_profit/gross_profit.py
+++ b/erpnext/accounts/report/gross_profit/gross_profit.py
@@ -6,6 +6,7 @@
 from frappe import _, scrub
 from frappe.utils import flt
 
+
 def execute(filters=None):
 	if not filters: filters = frappe._dict()
 	company_currency = frappe.db.get_value("Company", filters.company, "default_currency")
@@ -188,8 +189,8 @@
 		# stock_ledger_entries should already be filtered by item_code and warehouse and
 		# sorted by posting_date desc, posting_time desc
 		if item_code in self.non_stock_items:
-			# average purchasing rate for non-stock items
-			item_rate = self.get_average_buying_rate(item_code)
+			#Issue 6089-Get last purchasing rate for non-stock item
+			item_rate = self.get_last_purchase_rate(item_code)
 			return flt(row.qty) * item_rate
 
 		else:
@@ -225,6 +226,22 @@
 
 		return self.average_buying_rate[item_code]
 
+	def get_last_purchase_rate(self, item_code):
+		if self.filters.to_date:
+			last_purchase_rate = frappe.db.sql("""
+			select (a.base_rate / a.conversion_factor)
+			from `tabPurchase Invoice Item` a
+			where a.item_code = %s and a.docstatus=1
+			and modified <= %s 
+			order by a.modified desc limit 1""", (item_code,self.filters.to_date))
+		else:
+			last_purchase_rate = frappe.db.sql("""
+			select (a.base_rate / a.conversion_factor)
+			from `tabPurchase Invoice Item` a
+			where a.item_code = %s and a.docstatus=1
+			order by a.modified desc limit 1""", item_code)
+		return flt(last_purchase_rate[0][0]) if last_purchase_rate else 0
+
 	def load_invoice_items(self):
 		conditions = ""
 		if self.filters.company:
diff --git a/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.py b/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.py
index 62d6e69..3629d4d 100644
--- a/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.py
+++ b/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.py
@@ -8,12 +8,12 @@
 from erpnext.accounts.report.financial_statements import (get_period_list, get_columns, get_data)
 
 def execute(filters=None):
-	period_list = get_period_list(filters.fiscal_year, filters.periodicity)
+	period_list = get_period_list(filters.from_fiscal_year, filters.to_fiscal_year, filters.periodicity)
 	
 	income = get_data(filters.company, "Income", "Credit", period_list, 
-		accumulated_values=filters.accumulated_values, ignore_closing_entries=True)
+		accumulated_values=filters.accumulated_values, ignore_closing_entries=True, ignore_accumulated_values_for_fy= True)
 	expense = get_data(filters.company, "Expense", "Debit", period_list, 
-		accumulated_values=filters.accumulated_values, ignore_closing_entries=True)
+		accumulated_values=filters.accumulated_values, ignore_closing_entries=True, ignore_accumulated_values_for_fy= True)
 	
 	net_profit_loss = get_net_profit_loss(income, expense, period_list, filters.company)
 
@@ -54,7 +54,7 @@
 			return net_profit_loss
 
 def get_chart_data(filters, columns, income, expense, net_profit_loss):
-	x_intervals = ['x'] + [d.get("label") for d in columns[2:-1]]
+	x_intervals = ['x'] + [d.get("label") for d in columns[2:]]
 	
 	income_data, expense_data, net_profit = [], [], []
 	
diff --git a/erpnext/demo/setup_data.py b/erpnext/demo/setup_data.py
index 1be2cac..97dc894 100644
--- a/erpnext/demo/setup_data.py
+++ b/erpnext/demo/setup_data.py
@@ -290,9 +290,13 @@
 def setup_salary_structure():
 	f = frappe.get_doc('Fiscal Year', frappe.defaults.get_global_default('fiscal_year'))
 
+	ss = frappe.new_doc('Salary Structure')
+	ss.name = "Sample Salary Structure - " + str(f.year_start_date)
 	for e in frappe.get_all('Employee', fields=['name', 'date_of_joining']):
-		ss = frappe.new_doc('Salary Structure')
-		ss.employee = e.name
+		ss.append('employees', {
+			'employee': e.name,
+			'base': random.random() * 10000
+		})
 
 		if not e.date_of_joining:
 			continue
@@ -300,16 +304,24 @@
 		ss.from_date = e.date_of_joining if (e.date_of_joining
 			and e.date_of_joining > f.year_start_date) else f.year_start_date
 		ss.to_date = f.year_end_date
-		ss.append('earnings', {
-			'salary_component': 'Basic',
-			'amount': random.random() * 10000
-		})
-		ss.append('deductions', {
-			'salary_component': 'Income Tax',
-			'amount': random.random() * 1000
-		})
 
-		ss.insert()
+	ss.append('earnings', {
+		'salary_component': 'Basic',
+		"abbr":'B',
+		'condition': 'base > 5000',
+		'formula': 'base*.2',
+		'amount_based_on_formula': 1,
+		"idx": 1
+	})
+	ss.append('deductions', {
+		'salary_component': 'Income Tax',
+		"abbr":'IT',
+		'condition': 'base > 5000',
+		'amount': random.random() * 1000,
+		"idx": 1
+	})
+
+	ss.insert()
 
 def setup_salary_structure_for_timesheet():
 	for e in frappe.get_all('Salary Structure', fields=['name'], filters={'is_active': 'Yes'}, limit=2):
diff --git a/erpnext/demo/user/hr.py b/erpnext/demo/user/hr.py
index 3d5ac83..73f330d 100644
--- a/erpnext/demo/user/hr.py
+++ b/erpnext/demo/user/hr.py
@@ -92,13 +92,20 @@
 			expense.sanctioned_amount = sanctioned_amount
 
 def get_timesheet_based_salary_slip_employee():
-	return frappe.get_all('Salary Structure', fields = ["distinct employee as name"],
-		filters = {'salary_slip_based_on_timesheet': 1})
+	sal_struct = frappe.db.sql("""
+			select name from `tabSalary Structure`
+			where salary_slip_based_on_timesheet = 1
+			and docstatus != 2""")
+	if sal_struct:
+		employees = frappe.db.sql("""
+				select employee from `tabSalary Structure Employee`
+				where parent IN %(sal_struct)s""", {"sal_struct": sal_struct}, as_dict=True)
+		return employees
 	
 def make_timesheet_records():
 	employees = get_timesheet_based_salary_slip_employee()
-	for employee in employees:
-		ts = make_timesheet(employee.name, simulate = True, billable = 1, activity_type=get_random("Activity Type"))
+	for e in employees:
+		ts = make_timesheet(e.employee, simulate = True, billable = 1, activity_type=get_random("Activity Type"))
 
 		rand = random.random()
 		if rand >= 0.3:
diff --git a/erpnext/docs/assets/img/human-resources/condition-amount.png b/erpnext/docs/assets/img/human-resources/condition-amount.png
new file mode 100644
index 0000000..af95a11
--- /dev/null
+++ b/erpnext/docs/assets/img/human-resources/condition-amount.png
Binary files differ
diff --git a/erpnext/docs/assets/img/human-resources/condition-formula.png b/erpnext/docs/assets/img/human-resources/condition-formula.png
new file mode 100644
index 0000000..918d21c
--- /dev/null
+++ b/erpnext/docs/assets/img/human-resources/condition-formula.png
Binary files differ
diff --git a/erpnext/docs/assets/img/human-resources/salary-structure.png b/erpnext/docs/assets/img/human-resources/salary-structure.png
index af850ee..a135092 100644
--- a/erpnext/docs/assets/img/human-resources/salary-structure.png
+++ b/erpnext/docs/assets/img/human-resources/salary-structure.png
Binary files differ
diff --git a/erpnext/docs/assets/img/human-resources/salary-timesheet.png b/erpnext/docs/assets/img/human-resources/salary-timesheet.png
new file mode 100644
index 0000000..c18a1b7
--- /dev/null
+++ b/erpnext/docs/assets/img/human-resources/salary-timesheet.png
Binary files differ
diff --git a/erpnext/docs/user/manual/en/CRM/index.md b/erpnext/docs/user/manual/en/CRM/index.md
index e394333..2cc7e98 100644
--- a/erpnext/docs/user/manual/en/CRM/index.md
+++ b/erpnext/docs/user/manual/en/CRM/index.md
@@ -1,4 +1,3 @@
-#CRM
 # CRM
 
 ERPNext helps you track business **Opportunities** from **Leads** and
diff --git a/erpnext/docs/user/manual/en/human-resources/salary-and-payroll.md b/erpnext/docs/user/manual/en/human-resources/salary-and-payroll.md
index 05e01e1..62933df 100644
--- a/erpnext/docs/user/manual/en/human-resources/salary-and-payroll.md
+++ b/erpnext/docs/user/manual/en/human-resources/salary-and-payroll.md
@@ -42,15 +42,52 @@
 
 > Human Resources > Setup > Salary Structure > New Salary Structure
 
-#### Figure 1:Salary Structure
+#### Figure 1.1:Salary Structure
 
 <img class="screenshot" alt="Salary Structure" src="{{docs_base_url}}/assets/img/human-resources/salary-structure.png">
 
 ### In the Salary Structure,
 
-  * Select the Employee
+  * Select the Employees and enter Base (which is base salary or CTC) and Variable (if applicable)
   * Set the starting date from which this is valid (Note: There can only be one Salary Structure that can be “Active” for an Employee during any period)
-  * In the “Earnings” and “Deductions” table all your defined Earning Type and Deductions Type will be auto-populated. Set the values of the Earnings and Deductions and save the Salary Structure.
+
+#### Figure 1.2:Salary Structure for Salary Slip based on Timesheet
+
+<img class="screenshot" alt="Salary Structure" src="{{docs_base_url}}/assets/img/human-resources/salary-timesheet.png">
+  
+### Salary Slip Based on Timesheet 
+
+Salary Slip based on Timesheet is applicable if you have timesheet based payroll system
+  
+  * Check "Salary Slip Based on Timesheet"
+  * Select the salary component and enter Hour Rate (Note: This salary component gets added to earnings in Salary Slip)
+  
+### Earnings and Deductions in Salary Structure 
+
+In the “Earnings” and “Deductions” tables, you can calculate the values of Salary Components based on,
+
+  * Condition and Formula
+
+#### Figure 1.3:Condition and Formula
+
+<img class="screenshot" alt="Salary Structure" src="{{docs_base_url}}/assets/img/human-resources/condition-formula.png">
+
+  * Condition and Amount
+  
+#### Figure 1.4:Condition and Amount
+
+<img class="screenshot" alt="Salary Structure" src="{{docs_base_url}}/assets/img/human-resources/condition-amount.png">  
+
+  * Only Formula  
+  * Only Amount
+  
+Save the Salary Structure.
+
+In conditions and formulas, 
+
+  * Use field "base" for using base salary of the Employee
+  * Use Salary Component abbreviations. For example: BS for Basic Salary
+  * Use field name for employee details. For example: Employment Type for employment_type
 
 ### Leave Without Pay (LWP)
 
@@ -64,6 +101,7 @@
 If you don’t want ERPNext to manage LWP, just don’t click on LWP in any of the
 Earning Types and Deduction Types.
 
+
 * * *
 
 ### Creating Salary Slips
@@ -71,8 +109,9 @@
 Once the Salary Structure is created, you can make a salary slip from the same
 form or you can process your payroll for the month using Process Payroll.
 
-To create a salary slip from Salary Structure, click on the button Make Salary
-Slip.
+To create a new Salary Slip go to:
+
+> Human Resources > Setup > Salary Slip > New Salary Slip
 
 #### Figure 2: Salary Slip
 
diff --git a/erpnext/docs/user/manual/en/setting-up/email/email-alerts.md b/erpnext/docs/user/manual/en/setting-up/email/email-alerts.md
index 4caffbc..3fbb4e4 100644
--- a/erpnext/docs/user/manual/en/setting-up/email/email-alerts.md
+++ b/erpnext/docs/user/manual/en/setting-up/email/email-alerts.md
@@ -30,7 +30,7 @@
 
 
 ### Setting a Subject
-You can retrieve the data for a particular field by using `doc.[field_name]`. To use it in your subject / message, you have to surround it with `{{ }}`. These are called [Jinja](http://jinja.pocoo.org/) tags. So, for example to get the name of a document, you use `{{ doc.name }}`. The below example sends an email on saving a Task with the Subject, "TASK##### has been created"
+You can retrieve the data for a particular field by using `doc.[field_name]`. To use it in your subject / message, you have to surround it with `{% raw %}{{ }}{% endraw %}`. These are called [Jinja](http://jinja.pocoo.org/) tags. So, for example to get the name of a document, you use `{% raw %}{{ doc.name }}{% endraw %}`. The below example sends an email on saving a Task with the Subject, "TASK##### has been created"
 
 <img class="screenshot" alt="Setting Subject" src="{{docs_base_url}}/assets/img/setup/email/email-alert-subject.png">
 
@@ -44,7 +44,7 @@
 
 ### Setting a Message
 
-You can use both Jinja Tags (`{{ doc.[field_name] }}`) and HTML tags in the message textbox.
+You can use both Jinja Tags (`{% raw %}{{ doc.[field_name] }}{% endraw %}`) and HTML tags in the message textbox.
 
 	{% raw %}<h3>Order Overdue</h3>
 
diff --git a/erpnext/docs/user/manual/index.md b/erpnext/docs/user/manual/index.md
index a2db1ba..d6cf4f1 100644
--- a/erpnext/docs/user/manual/index.md
+++ b/erpnext/docs/user/manual/index.md
@@ -5,6 +5,6 @@
 
 Select your language
 
-1. [English](en)
-1. [Deutsch](de)
-1. [Español](es)
\ No newline at end of file
+1. [English]({{docs_base_url}}/user/manual/en)
+1. [Deutsch]({{docs_base_url}}/user/manual/de)
+1. [Español]({{docs_base_url}}/user/manual/es)
\ No newline at end of file
diff --git a/erpnext/hr/doctype/employee/employee.js b/erpnext/hr/doctype/employee/employee.js
index bb9edf9..f69f4e5 100755
--- a/erpnext/hr/doctype/employee/employee.js
+++ b/erpnext/hr/doctype/employee/employee.js
@@ -40,13 +40,6 @@
 				"Ms": "Female"
 			}[this.frm.doc.salutation]);
 		}
-	},
-
-	make_salary_structure: function(btn) {
-		frappe.model.open_mapped_doc({
-			method: "erpnext.hr.doctype.employee.employee.make_salary_structure",
-			frm: cur_frm
-		});
 	}
 });
 cur_frm.cscript = new erpnext.hr.EmployeeController({frm: cur_frm});
diff --git a/erpnext/hr/doctype/employee/employee.py b/erpnext/hr/doctype/employee/employee.py
index 18b166b..c6b3633 100755
--- a/erpnext/hr/doctype/employee/employee.py
+++ b/erpnext/hr/doctype/employee/employee.py
@@ -178,19 +178,6 @@
 	return ret
 
 
-@frappe.whitelist()
-def make_salary_structure(source_name, target=None):
-	target = get_mapped_doc("Employee", source_name, {
-		"Employee": {
-			"doctype": "Salary Structure",
-			"field_map": {
-				"name": "employee",
-			}
-		}
-	})
-	target.make_earn_ded_table()
-	return target
-
 def validate_employee_role(doc, method):
 	# called via User hook
 	if "Employee" in [d.role for d in doc.get("user_roles")]:
diff --git a/erpnext/hr/doctype/hr_settings/hr_settings.json b/erpnext/hr/doctype/hr_settings/hr_settings.json
index ba2c38b..d7892c7 100644
--- a/erpnext/hr/doctype/hr_settings/hr_settings.json
+++ b/erpnext/hr/doctype/hr_settings/hr_settings.json
@@ -8,6 +8,7 @@
  "docstatus": 0, 
  "doctype": "DocType", 
  "document_type": "Other", 
+ "editable_grid": 1, 
  "fields": [
   {
    "allow_on_submit": 0, 
@@ -187,6 +188,31 @@
    "search_index": 0, 
    "set_only_once": 0, 
    "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "fieldname": "max_working_hours_against_timesheet", 
+   "fieldtype": "Float", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Max working hours against Timesheet", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
   }
  ], 
  "hide_heading": 0, 
@@ -200,7 +226,7 @@
  "issingle": 1, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2016-06-27 16:20:59.737869", 
+ "modified": "2016-08-10 12:32:39.780599", 
  "modified_by": "Administrator", 
  "module": "HR", 
  "name": "HR Settings", 
diff --git a/erpnext/hr/doctype/process_payroll/process_payroll.py b/erpnext/hr/doctype/process_payroll/process_payroll.py
index c80c660..c7162b8 100644
--- a/erpnext/hr/doctype/process_payroll/process_payroll.py
+++ b/erpnext/hr/doctype/process_payroll/process_payroll.py
@@ -10,6 +10,7 @@
 
 class ProcessPayroll(Document):
 
+
 	def get_emp_list(self):
 		"""
 			Returns list of active employees based on selected criteria
@@ -18,15 +19,23 @@
 		cond = self.get_filter_condition()
 		cond += self.get_joining_releiving_condition()
 
+		sal_struct = frappe.db.sql("""
+				select name from `tabSalary Structure`
+				where docstatus != 2 and
+				ifnull(salary_slip_based_on_timesheet,0) = 0""")
+
+		if sal_struct:
+			cond += "and t2.parent IN %(sal_struct)s "
+
 		emp_list = frappe.db.sql("""
 			select t1.name
-			from `tabEmployee` t1, `tabSalary Structure` t2
-			where t1.docstatus!=2 and t2.docstatus != 2 and 
-			ifnull(t2.salary_slip_based_on_timesheet,0) = 0 and t1.name = t2.employee
-		%s """% cond)
+			from `tabEmployee` t1, `tabSalary Structure Employee` t2
+			where t1.docstatus!=2 and t1.name = t2.employee
+		%s """% cond, {"sal_struct": sal_struct})
 
 		return emp_list
 
+
 	def get_filter_condition(self):
 		self.check_mandatory()
 
diff --git a/erpnext/hr/doctype/salary_component/salary_component.json b/erpnext/hr/doctype/salary_component/salary_component.json
index 3cf83c1..5595fcc 100644
--- a/erpnext/hr/doctype/salary_component/salary_component.json
+++ b/erpnext/hr/doctype/salary_component/salary_component.json
@@ -9,6 +9,7 @@
  "docstatus": 0, 
  "doctype": "DocType", 
  "document_type": "Setup", 
+ "editable_grid": 1, 
  "fields": [
   {
    "allow_on_submit": 0, 
@@ -39,6 +40,33 @@
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
+   "fieldname": "salary_component_abbr", 
+   "fieldtype": "Data", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 1, 
+   "in_list_view": 1, 
+   "label": "Abbr", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "print_width": "120px", 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0, 
+   "width": "120px"
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
    "fieldname": "description", 
    "fieldtype": "Small Text", 
    "hidden": 0, 
@@ -59,6 +87,32 @@
    "search_index": 0, 
    "set_only_once": 0, 
    "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "fieldname": "accounts", 
+   "fieldtype": "Table", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Accounts", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Salary Component Account", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
   }
  ], 
  "hide_heading": 0, 
@@ -72,7 +126,7 @@
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2016-07-01 12:42:46.103131", 
+ "modified": "2016-07-27 17:40:18.335540", 
  "modified_by": "Administrator", 
  "module": "HR", 
  "name": "Salary Component", 
diff --git a/erpnext/hr/doctype/salary_component/salary_component.py b/erpnext/hr/doctype/salary_component/salary_component.py
index 5a37172..ca69568 100644
--- a/erpnext/hr/doctype/salary_component/salary_component.py
+++ b/erpnext/hr/doctype/salary_component/salary_component.py
@@ -5,6 +5,24 @@
 from __future__ import unicode_literals
 import frappe
 from frappe.model.document import Document
+from frappe import _
 
 class SalaryComponent(Document):
-	pass
+	def validate(self):
+		self.validate_abbr()
+		
+
+	def validate_abbr(self):
+		if not self.salary_component_abbr:
+			self.salary_component_abbr = ''.join([c[0] for c in self.salary_component.split()]).upper()
+
+		self.salary_component_abbr = self.salary_component_abbr.strip()
+
+		if self.get('__islocal') and len(self.salary_component_abbr) > 5:
+			frappe.throw(_("Abbreviation cannot have more than 5 characters"))
+
+		if not self.salary_component_abbr.strip():
+			frappe.throw(_("Abbreviation is mandatory"))
+
+		if frappe.db.sql("select salary_component_abbr from `tabSalary Component` where name!=%s and salary_component_abbr=%s", (self.name, self.salary_component_abbr)):
+			frappe.throw(_("Abbreviation already used for another salary component"))
\ No newline at end of file
diff --git a/erpnext/hr/doctype/salary_detail/salary_detail.json b/erpnext/hr/doctype/salary_detail/salary_detail.json
index eadfccf..d809787 100644
--- a/erpnext/hr/doctype/salary_detail/salary_detail.json
+++ b/erpnext/hr/doctype/salary_detail/salary_detail.json
@@ -21,7 +21,7 @@
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 1, 
-   "label": "Salary Component", 
+   "label": "Component",
    "length": 0, 
    "no_copy": 0, 
    "options": "Salary Component", 
@@ -40,13 +40,171 @@
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
+   "depends_on": "eval:doc.parenttype=='Salary Structure'", 
+   "fieldname": "abbr", 
+   "fieldtype": "Data", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Abbr", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "salary_component.salary_component_abbr", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 1, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "fieldname": "section_break_2", 
+   "fieldtype": "Section Break", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "depends_on": "eval:doc.parenttype=='Salary Structure'", 
+   "fieldname": "condition", 
+   "fieldtype": "Code", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Condition", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "default": "1", 
+   "depends_on": "eval:doc.parenttype=='Salary Structure'", 
+   "fieldname": "amount_based_on_formula", 
+   "fieldtype": "Check", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Amount based on formula", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "default": "", 
+   "depends_on": "eval:doc.amount_based_on_formula!=0 && doc.parenttype=='Salary Structure'", 
+   "description": "", 
+   "fieldname": "formula", 
+   "fieldtype": "Code", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Formula", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "fieldname": "section_break_8", 
+   "fieldtype": "Section Break", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "depends_on": "eval:doc.amount_based_on_formula!==1 || doc.parenttype==='Salary Slip'", 
    "fieldname": "amount", 
    "fieldtype": "Currency", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
-   "in_list_view": 1, 
+   "in_list_view": 0, 
    "label": "Amount", 
    "length": 0, 
    "no_copy": 0, 
@@ -66,30 +224,7 @@
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
-   "fieldname": "column_break_3", 
-   "fieldtype": "Column Break", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_list_view": 0, 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0
-  }, 
-  {
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
+   "depends_on": "", 
    "fieldname": "depends_on_lwp", 
    "fieldtype": "Check", 
    "hidden": 0, 
@@ -102,6 +237,33 @@
    "no_copy": 0, 
    "permlevel": 0, 
    "precision": "", 
+   "print_hide": 1, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "depends_on": "eval:doc.parenttype=='Salary Structure'", 
+   "fieldname": "default_amount", 
+   "fieldtype": "Currency", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Default Amount", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Company:company:default_currency", 
+   "permlevel": 0, 
+   "precision": "", 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
@@ -115,17 +277,43 @@
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
-   "fieldname": "default_amount", 
-   "fieldtype": "Currency", 
+   "depends_on": "eval:doc.parenttype=='Salary Structure'", 
+   "fieldname": "section_break_11", 
+   "fieldtype": "Section Break", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
-   "label": "Default Amount", 
    "length": 0, 
    "no_copy": 0, 
-   "options": "Company:company:default_currency", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "depends_on": "eval:doc.parenttype=='Salary Structure'", 
+   "fieldname": "condition_and_formula_help", 
+   "fieldtype": "HTML", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Condition and Formula Help", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "<h3>Condition and Formula Help</h3>\n\n<p>Notes:</p>\n\n<ol>\n<li>Use field <code>base</code> for using base salary of the Employee</li>\n<li>Use Salary Component abbreviations in conditions and formulas. <code>BS = Basic Salary</code></li>\n<li>Use field name for employee details in conditions and formulas. <code>Employment Type = employment_type</code><code>Branch = branch</code></li>\n<li>Direct Amount can also be entered based on Condtion. See example 3</li></ol>\n\n<h4>Examples</h4>\n<ol>\n<li>Calculating Basic Salary based on <code>base</code>\n<pre><code>Condition: base &lt; 10000</code></pre>\n<pre><code>Formula: base * .2</code></pre></li>\n<li>Calculating HRA based on Basic Salary<code>BS</code> \n<pre><code>Condition: BS &gt; 2000</code></pre>\n<pre><code>Formula: BS * .1</code></pre></li>\n<li>Calculating TDS based on Employment Type<code>employment_type</code> \n<pre><code>Condition: employment_type==\"Intern\"</code></pre>\n<pre><code>Amount: 1000</code></pre></li>\n</ol>", 
    "permlevel": 0, 
    "precision": "", 
    "print_hide": 0, 
@@ -148,7 +336,7 @@
  "issingle": 0, 
  "istable": 1, 
  "max_attachments": 0, 
- "modified": "2016-07-11 03:28:06.925361", 
+ "modified": "2016-08-22 00:25:44.331685",
  "modified_by": "Administrator", 
  "module": "HR", 
  "name": "Salary Detail", 
diff --git a/erpnext/hr/doctype/salary_slip/salary_slip.js b/erpnext/hr/doctype/salary_slip/salary_slip.js
index 6cfba4b..3b6eef8 100644
--- a/erpnext/hr/doctype/salary_slip/salary_slip.js
+++ b/erpnext/hr/doctype/salary_slip/salary_slip.js
@@ -24,7 +24,7 @@
 
 	refresh: function(frm) {
 		frm.trigger("toggle_fields")
-	},
+	},	
 
 	salary_slip_based_on_timesheet: function(frm) {
 		frm.trigger("toggle_fields")
diff --git a/erpnext/hr/doctype/salary_slip/salary_slip.json b/erpnext/hr/doctype/salary_slip/salary_slip.json
index 75146d9..a6f5266 100644
--- a/erpnext/hr/doctype/salary_slip/salary_slip.json
+++ b/erpnext/hr/doctype/salary_slip/salary_slip.json
@@ -9,6 +9,7 @@
  "docstatus": 0, 
  "doctype": "DocType", 
  "document_type": "Setup", 
+ "editable_grid": 0, 
  "fields": [
   {
    "allow_on_submit": 0, 
@@ -1172,7 +1173,7 @@
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2016-07-07 12:49:01.596547", 
+ "modified": "2016-08-10 15:57:59.944600", 
  "modified_by": "Administrator", 
  "module": "HR", 
  "name": "Salary Slip", 
diff --git a/erpnext/hr/doctype/salary_slip/salary_slip.py b/erpnext/hr/doctype/salary_slip/salary_slip.py
index 3bc7f0e..c82dcf5 100644
--- a/erpnext/hr/doctype/salary_slip/salary_slip.py
+++ b/erpnext/hr/doctype/salary_slip/salary_slip.py
@@ -25,23 +25,84 @@
 		self.set_month_dates()
 		
 		if not (len(self.get("earnings")) or len(self.get("deductions"))):
+			# get details from salary structure
 			self.get_emp_and_leave_details()
 		else:
 			self.get_leave_details(lwp = self.leave_without_pay)
 
-		if self.salary_slip_based_on_timesheet or not self.net_pay:
-			self.calculate_net_pay()
+		# if self.salary_slip_based_on_timesheet or not self.net_pay:
+		# 	self.calculate_net_pay()
 
 		company_currency = get_company_currency(self.company)
 		self.total_in_words = money_in_words(self.rounded_total, company_currency)
-
-		set_employee_name(self)
+		
+		if frappe.db.get_single_value("HR Settings", "max_working_hours_against_timesheet"):
+			max_working_hours = frappe.db.get_single_value("HR Settings", "max_working_hours_against_timesheet")
+			if self.salary_slip_based_on_timesheet and (self.total_working_hours > int(max_working_hours)):
+				frappe.msgprint(_("Total working hours should not be greater than max working hours {0}").
+								format(max_working_hours), alert=True)
 
 	def validate_dates(self):
 		if date_diff(self.end_date, self.start_date) < 0:
 			frappe.throw(_("To date cannot be before From date"))
+			
+	def calculate_component_amounts(self):
+		if not getattr(self, '_salary_structure_doc', None):
+			self._salary_structure_doc = frappe.get_doc('Salary Structure', self.salary_structure)
+
+		data = self.get_data_for_eval()
+		for key in ('earnings', 'deductions'):
+			for d in self._salary_structure_doc.get(key):
+				amount = self.eval_condition_and_formula(d, data)				
+				if amount:
+					self.append(key, {
+						'amount': amount,
+						'default_amount': amount,
+						'depends_on_lwp' : d.depends_on_lwp,
+						'salary_component' : d.salary_component
+					})
+	
+	def eval_condition_and_formula(self, d, data):
+		try:
+			if d.condition:
+				if not eval(d.condition, None, data):
+					return None
+	
+			amount = d.amount
+			if d.amount_based_on_formula:
+				if d.formula:
+					amount = eval(d.formula, None, data)
+	
+				data[d.abbr] = amount
+			return amount
+		except NameError as err:
+		    frappe.throw(_("Name error: {0}".format(err)))
+		except SyntaxError as err:
+		    frappe.throw(_("Syntax error in formula or condition: {0}".format(err)))
+		except:
+		    frappe.throw(_("Error in formula or condition"))
+		    raise	
+	
+	def get_data_for_eval(self):
+		'''Returns data for evaluating formula'''
+		data = frappe._dict()
+		
+		for d in self._salary_structure_doc.employees:
+			if d.employee == self.employee:
+				data.base, data.variable = d.base, d.variable
+	
+		data.update(frappe.get_doc("Employee", self.employee).as_dict())
+
+		# set values for components
+		salary_components = frappe.get_all("Salary Component", fields=["salary_component_abbr"])
+		for salary_component in salary_components:
+			data[salary_component.salary_component_abbr] = 0
+			
+		return data
+		
 
 	def get_emp_and_leave_details(self):
+		'''First time, load all the components from salary structure'''
 		if self.employee:
 			self.set("earnings", [])
 			self.set("deductions", [])
@@ -55,10 +116,10 @@
 			struct = self.check_sal_struct(joining_date, relieving_date)
 
 			if struct:
-				ss_doc = frappe.get_doc('Salary Structure', struct)
-				self.salary_slip_based_on_timesheet = ss_doc.salary_slip_based_on_timesheet or 0
+				self._salary_structure_doc = frappe.get_doc('Salary Structure', struct)
+				self.salary_slip_based_on_timesheet = self._salary_structure_doc.salary_slip_based_on_timesheet or 0
 				self.set_time_sheet()
-				self.pull_sal_struct(ss_doc)
+				self.pull_sal_struct()
 
 	def set_time_sheet(self):
 		if self.salary_slip_based_on_timesheet:
@@ -79,28 +140,44 @@
 			self.end_date = m['month_end_date']
 
 	def check_sal_struct(self, joining_date, relieving_date):
-		struct = frappe.db.sql("""select name from `tabSalary Structure`
-			where employee=%s and is_active = 'Yes'
-			and (from_date <= %s or from_date <= %s)
-			and (to_date is null or to_date >= %s or to_date >= %s) order by from_date desc limit 1""",
-			(self.employee, self.start_date, joining_date, self.end_date, relieving_date))
+		st_name = frappe.db.sql("""select parent from `tabSalary Structure Employee`
+			where employee=%s order by modified desc limit 1""",self.employee)
+			
+		if st_name:
+			struct = frappe.db.sql("""select name from `tabSalary Structure`
+				where name=%s and is_active = 'Yes'
+				and (from_date <= %s or from_date <= %s)
+				and (to_date is null or to_date >= %s or to_date >= %s) order by from_date desc limit 1""",
+				(st_name, self.start_date, joining_date, self.end_date, relieving_date))
 
-		if not struct:
+			if not struct:
+				self.salary_structure = None
+				frappe.throw(_("No active or default Salary Structure found for employee {0} for the given dates")
+					.format(self.employee), title=_('Salary Structure Missing'))
+
+			return struct and struct[0][0] or ''
+		else:
 			self.salary_structure = None
 			frappe.throw(_("No active or default Salary Structure found for employee {0} for the given dates")
-				.format(self.employee), title=_('Salary Structure Missing'))
+				.format(self.employee), title=_('Salary Structure Missing'))	
 
-		return struct and struct[0][0] or ''
-
-	def pull_sal_struct(self, ss_doc):
+	def pull_sal_struct(self):
 		from erpnext.hr.doctype.salary_structure.salary_structure import make_salary_slip
-		make_salary_slip(ss_doc.name, self)
+		make_salary_slip(self._salary_structure_doc.name, self)
 
 		if self.salary_slip_based_on_timesheet:
-			self.salary_structure = ss_doc.name
-			self.hour_rate = ss_doc.hour_rate
+			self.salary_structure = self._salary_structure_doc.name
+			self.hour_rate = self._salary_structure_doc.hour_rate
 			self.total_working_hours = sum([d.working_hours or 0.0 for d in self.timesheets]) or 0.0
-			self.add_earning_for_hourly_wages(ss_doc.salary_component)
+			self.add_earning_for_hourly_wages(self._salary_structure_doc.salary_component)
+			
+			
+			
+	def process_salary_structure(self):
+		'''Calculate salary after salary structure details have been updated'''
+		self.pull_emp_details()
+		self.get_leave_details()
+		self.calculate_net_pay()
 
 	def add_earning_for_hourly_wages(self, salary_component):
 		default_type = False
@@ -121,6 +198,7 @@
 			self.bank_name = emp.bank_name
 			self.bank_account_no = emp.bank_ac_no
 
+
 	def get_leave_details(self, joining_date=None, relieving_date=None, lwp=None):
 		if not self.fiscal_year:
 			# if default fiscal year is not set, get from nowdate
@@ -222,35 +300,28 @@
 				if frappe.db.get_value('Timesheet', data.time_sheet, 'status') == 'Payrolled':
 					frappe.throw(_("Salary Slip of employee {0} already created for time sheet {1}").format(self.employee, data.time_sheet))
 
-	def calculate_earning_total(self):
-		self.gross_pay = flt(self.arrear_amount) + flt(self.leave_encashment_amount)
-		for d in self.get("earnings"):
-			if cint(d.depends_on_lwp) == 1 and not self.salary_slip_based_on_timesheet:
-				d.amount = rounded((flt(d.default_amount) * flt(self.payment_days)
-					/ cint(self.total_days_in_month)), self.precision("amount", "earnings"))
-			elif not self.payment_days and not self.salary_slip_based_on_timesheet:
-				d.amount = 0
-			elif not d.amount:
-				d.amount = d.default_amount
-			self.gross_pay += flt(d.amount)
-
-	def calculate_ded_total(self):
-		self.total_deduction = 0
-		for d in self.get('deductions'):
+	def sum_components(self, component_type, total_field):
+		for d in self.get(component_type):
 			if cint(d.depends_on_lwp) == 1 and not self.salary_slip_based_on_timesheet:
 				d.amount = rounded((flt(d.amount) * flt(self.payment_days)
-					/ cint(self.total_days_in_month)), self.precision("amount", "deductions"))
+					/ cint(self.total_days_in_month)), self.precision("amount", component_type))
 			elif not self.payment_days and not self.salary_slip_based_on_timesheet:
 				d.amount = 0
 			elif not d.amount:
 				d.amount = d.default_amount
-			self.total_deduction += flt(d.amount)
+			self.set(total_field, self.get(total_field) + flt(d.amount))
 
 	def calculate_net_pay(self):
+		self.calculate_component_amounts()
+
 		disable_rounded_total = cint(frappe.db.get_value("Global Defaults", None, "disable_rounded_total"))
 
-		self.calculate_earning_total()
-		self.calculate_ded_total()
+		self.gross_pay = flt(self.arrear_amount) + flt(self.leave_encashment_amount)
+		self.total_deduction = 0
+
+		self.sum_components('earnings', 'gross_pay')
+		self.sum_components('deductions', 'total_deduction')
+
 		self.net_pay = flt(self.gross_pay) - flt(self.total_deduction)
 		self.rounded_total = rounded(self.net_pay,
 			self.precision("net_pay") if disable_rounded_total else 0)
diff --git a/erpnext/hr/doctype/salary_slip/test_salary_slip.py b/erpnext/hr/doctype/salary_slip/test_salary_slip.py
index d90d4b2..503996d 100644
--- a/erpnext/hr/doctype/salary_slip/test_salary_slip.py
+++ b/erpnext/hr/doctype/salary_slip/test_salary_slip.py
@@ -4,19 +4,22 @@
 
 import unittest
 import frappe
-from frappe.utils import today, now_datetime, getdate, cstr
-from erpnext.hr.doctype.employee.employee import make_salary_structure
+import erpnext
+from frappe.utils import today, now_datetime, getdate, cstr, add_years, nowdate
 from erpnext.hr.doctype.salary_structure.salary_structure import make_salary_slip
 from erpnext.hr.doctype.leave_application.test_leave_application import make_allocation_record
 
 class TestSalarySlip(unittest.TestCase):
 	def setUp(self):
+		self.make_salary_component(["Basic Salary", "Allowance", "HRA", "Professional Tax", "TDS"])
+		
 		for dt in ["Leave Application", "Leave Allocation", "Salary Slip"]:
 			frappe.db.sql("delete from `tab%s`" % dt)
 
 		make_allocation_record(leave_type="_Test Leave Type LWP")
-
-		frappe.db.set_value("Company", "_Test Company", "default_holiday_list", "_Test Holiday List")
+		
+		self.make_holiday_list()
+		frappe.db.set_value("Company", erpnext.get_default_company(), "default_holiday_list", "Salary Slip Test Holiday List")
 
 		from erpnext.hr.doctype.leave_application.test_leave_application import _test_records as leave_applications
 		la = frappe.copy_doc(leave_applications[2])
@@ -30,71 +33,78 @@
 
 	def test_salary_slip_with_holidays_included(self):
 		frappe.db.set_value("HR Settings", None, "include_holidays_in_total_working_days", 1)
-		ss = frappe.copy_doc(test_records[0])
-		ss.insert()
+		self.make_employee("test_employee@salary.com")
+		frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}, "name"), "relieving_date", None)
+		frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}, "name"), "status", "Active")
+		ss = frappe.get_doc("Salary Slip",
+			self.make_employee_salary_slip("test_employee@salary.com"))
 
 		self.assertEquals(ss.total_days_in_month, 31)
-		self.assertEquals(ss.payment_days, 30)
-		self.assertEquals(ss.earnings[0].amount, 14516.13)
-		self.assertEquals(ss.earnings[1].amount, 500)
-		self.assertEquals(ss.deductions[0].amount, 100)
-		self.assertEquals(ss.deductions[1].amount, 48.39)
-		self.assertEquals(ss.gross_pay, 15016.13)
-		self.assertEquals(ss.net_pay, 14867.74)
+		self.assertEquals(ss.payment_days, 31)
+		self.assertEquals(ss.earnings[0].amount, 0)
+		self.assertEquals(ss.earnings[1].amount, 0)
+		self.assertEquals(ss.deductions[0].amount, 0)
+		self.assertEquals(ss.deductions[1].amount, 0)
+		self.assertEquals(ss.gross_pay, 0)
+		self.assertEquals(ss.net_pay, 0)
 
 	def test_salary_slip_with_holidays_excluded(self):
 		frappe.db.set_value("HR Settings", None, "include_holidays_in_total_working_days", 0)
-		ss = frappe.copy_doc(test_records[0])
-		ss.insert()
+		self.make_employee("test_employee@salary.com")
+		frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}, "name"), "relieving_date", None)
+		frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}, "name"), "status", "Active")
+		ss = frappe.get_doc("Salary Slip",
+			self.make_employee_salary_slip("test_employee@salary.com"))
 
-		self.assertEquals(ss.total_days_in_month, 29)
-		self.assertEquals(ss.payment_days, 28)
-		self.assertEquals(ss.earnings[0].amount, 14516.13)
-		self.assertEquals(ss.earnings[1].amount, 500)
-		self.assertEquals(ss.deductions[0].amount, 100)
-		self.assertEquals(ss.deductions[1].amount, 48.39)
-		self.assertEquals(ss.gross_pay, 15016.13)
-		self.assertEquals(ss.net_pay, 14867.74)
-
+		self.assertEquals(ss.total_days_in_month, 27)
+		self.assertEquals(ss.payment_days, 27)
+		self.assertEquals(ss.earnings[0].amount, 0)
+		self.assertEquals(ss.earnings[0].default_amount, 5000)
+		self.assertEquals(ss.earnings[1].amount, 0)
+		self.assertEquals(ss.deductions[0].amount, 0)
+		self.assertEquals(ss.deductions[1].amount, 0)
+		self.assertEquals(ss.gross_pay, 0)
+		self.assertEquals(ss.net_pay, 0)
+		
 	def test_payment_days(self):
 		# Holidays not included in working days
 		frappe.db.set_value("HR Settings", None, "include_holidays_in_total_working_days", 0)
 
 		# set joinng date in the same month
-		frappe.db.set_value("Employee", "_T-Employee-0001", "date_of_joining", "2013-01-11")
+		self.make_employee("test_employee@salary.com")
+		frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}, "name"), "date_of_joining", "2013-01-11")
+		
+		ss = frappe.get_doc("Salary Slip",
+			self.make_employee_salary_slip("test_employee@salary.com"))
 
-		ss = frappe.copy_doc(test_records[0])
-		ss.insert()
-
-		self.assertEquals(ss.total_days_in_month, 29)
-		self.assertEquals(ss.payment_days, 19)
+		self.assertEquals(ss.total_days_in_month, 27)
+		self.assertEquals(ss.payment_days, 27)
 
 		# set relieving date in the same month
-		frappe.db.set_value("Employee", "_T-Employee-0001", "relieving_date", "2013-01-28")
+		frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}, "name"), "relieving_date", "12-12-2016")
+		frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}, "name"), "status", "Left")
+		
+		self.assertEquals(ss.total_days_in_month, 27)
+		self.assertEquals(ss.payment_days, 27)
 		ss.save()
-		self.assertEquals(ss.total_days_in_month, 29)
-		self.assertEquals(ss.payment_days, 16)
-
+		
+		frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}, "name"), "relieving_date", None)
+		frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}, "name"), "status", "Active")
 		# Holidays included in working days
-		frappe.db.set_value("HR Settings", None, "include_holidays_in_total_working_days", 1)
+		frappe.db.set_value("HR Settings", None, "include_holidays_in_total_working_days", 1)	
+		self.assertEquals(ss.total_days_in_month, 27)
+		self.assertEquals(ss.payment_days, 27)
 		ss.save()
-		self.assertEquals(ss.total_days_in_month, 31)
-		self.assertEquals(ss.payment_days, 17)
-
-		frappe.db.set_value("Employee", "_T-Employee-0001", "date_of_joining", "2001-01-11")
-		frappe.db.set_value("Employee", "_T-Employee-0001", "relieving_date", None)
+				#
+		# frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}, "name"), "date_of_joining", "2001-01-11")
+		# frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}, "name"), "relieving_date", None)
 
 	def test_employee_salary_slip_read_permission(self):
-		self.make_employee("test_employee@example.com")
-		self.make_employee("test_employee_2@example.com")
+		self.make_employee("test_employee@salary.com")
 
 		salary_slip_test_employee = frappe.get_doc("Salary Slip",
-			self.make_employee_salary_slip("test_employee@example.com"))
-
-		salary_slip_test_employee_2 = frappe.get_doc("Salary Slip",
-			self.make_employee_salary_slip("test_employee_2@example.com"))
-
-		frappe.set_user("test_employee@example.com")
+			self.make_employee_salary_slip("test_employee@salary.com"))
+		frappe.set_user("test_employee@salary.com")
 		self.assertTrue(salary_slip_test_employee.has_permission("read"))
 
 	def test_email_salary_slip(self):
@@ -104,8 +114,10 @@
 		hr_settings.email_salary_slip_to_employee = 1
 		hr_settings.save()
 
-		self.make_employee("test_employee@example.com")
-		self.make_employee_salary_slip("test_employee@example.com")
+		self.make_employee("test_employee@salary.com")
+		ss = frappe.get_doc("Salary Slip",
+			self.make_employee_salary_slip("test_employee@salary.com"))
+		ss.submit()
 		email_queue = frappe.db.sql("""select name from `tabEmail Queue`""")
 		self.assertTrue(email_queue)
 
@@ -123,32 +135,52 @@
 		if not frappe.db.get_value("Employee", {"user_id": user}):
 			frappe.get_doc({
 				"doctype": "Employee",
-				"naming_series": "_T-Employee-",
+				"naming_series": "EMP-",
 				"employee_name": user,
+				"company": erpnext.get_default_company(),
 				"user_id": user,
-				"company": "_Test Company",
 				"date_of_birth": "1990-05-08",
 				"date_of_joining": "2013-01-01",
-				"department": "_Test Department 1",
+				"department": frappe.get_all("Department", fields="name")[0].name,
 				"gender": "Female",
 				"company_email": user,
-				"status": "Active"
+				"status": "Active",
+				"employment_type": "Intern"
 			}).insert()
-
+			
+	def make_holiday_list(self):
+		if not frappe.db.get_value("Holiday List", "Salary Slip Test Holiday List"):
+			holiday_list = frappe.get_doc({
+				"doctype": "Holiday List",
+				"holiday_list_name": "Salary Slip Test Holiday List",
+				"from_date": nowdate(),
+				"to_date": add_years(nowdate(), 1),
+				"weekly_off": "Sunday"
+			}).insert()	
+			holiday_list.get_weekly_off_dates()
+			holiday_list.save()
+			
+	def make_salary_component(self, salary_components):
+		for salary_component in salary_components:
+			if not frappe.db.exists('Salary Component', salary_component):
+				sal_comp = frappe.get_doc({
+					"doctype": "Salary Component",
+					"salary_component": salary_component
+				})
+				sal_comp.insert()		
+		
 	def make_employee_salary_slip(self, user):
 		employee = frappe.db.get_value("Employee", {"user_id": user})
-		salary_structure = frappe.db.get_value("Salary Structure", {"employee": employee})
-		if not salary_structure:
-			salary_structure = make_salary_structure(employee)
-			salary_structure.from_date = today()
-			salary_structure.insert()
-			salary_structure = salary_structure.name
-
-		salary_slip = frappe.db.get_value("Salary Slip", {"employee": employee})
+		salary_structure = make_salary_structure("Salary Structure Test for Salary Slip")
+		salary_slip = frappe.db.get_value("Salary Slip", {"employee": frappe.db.get_value("Employee", {"user_id": user})})
+		
 		if not salary_slip:
-			salary_slip = make_salary_slip(salary_structure)
+			salary_slip = make_salary_slip(salary_structure, employee = employee)
+			salary_slip.employee_name = frappe.get_value("Employee", {"name":frappe.db.get_value("Employee", {"user_id": user})}, "employee_name")
+			salary_slip.month = "12"
+			salary_slip.fiscal_year = "_Test Fiscal Year 2016"
 			salary_slip.insert()
-			salary_slip.submit()
+			# salary_slip.submit()
 			salary_slip = salary_slip.name
 
 		return salary_slip
@@ -160,6 +192,82 @@
 		activity_type.wage_rate = 25
 		activity_type.save()
 
-test_dependencies = ["Leave Application", "Holiday List"]
 
-test_records = frappe.get_test_records('Salary Slip')
+def make_salary_structure(sal_struct):
+	if not frappe.db.exists('Salary Structure', sal_struct):
+		frappe.get_doc({
+			"doctype": "Salary Structure",
+			"name": sal_struct,
+			"company": erpnext.get_default_company(),
+			"from_date": nowdate(),
+			"employees": get_employee_details(),
+			"earnings": get_earnings_component(),
+			"deductions": get_deductions_component()			
+		}).insert()
+	return sal_struct
+			
+			
+def get_employee_details():
+	return [{"employee": frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}, "name"),
+			"base": 25000,
+			"variable": 5000
+			}
+		]
+			
+def get_earnings_component():	
+	return [
+				{
+					"salary_component": 'Basic Salary',
+					"abbr":'BS',
+					"condition": 'base > 10000',
+					"formula": 'base*.2',
+					"idx": 1
+				},
+				{
+					"salary_component": 'Basic Salary',
+					"abbr":'BS',
+					"condition": 'base < 10000',
+					"formula": 'base*.1',
+					"idx": 2
+				},
+				{
+					"salary_component": 'HRA',
+					"abbr":'H',
+					"amount": 3000,
+					"idx": 3
+				},
+				{
+					"salary_component": 'Allowance',
+					"abbr":'A',
+					"condition": 'H < 10000',
+					"formula": 'BS*.5',
+					"idx": 4
+				},
+			]
+			
+def get_deductions_component():	
+	return [
+				{
+					"salary_component": 'Professional Tax',
+					"abbr":'PT',
+					"condition": 'base > 10000',
+					"formula": 'base*.2',
+					"idx": 1
+				},
+				{
+					"salary_component": 'TDS',
+					"abbr":'T',
+					"formula": 'base*.5',
+					"idx": 2
+				},
+				{
+					"salary_component": 'TDS',
+					"abbr":'T',
+					"condition": 'employment_type=="Intern"',
+					"formula": 'base*.1',
+					"idx": 3
+				}
+			]			
+
+test_dependencies = ["Leave Application", "Holiday List"]
+			
\ No newline at end of file
diff --git a/erpnext/hr/doctype/salary_structure/salary_structure.js b/erpnext/hr/doctype/salary_structure/salary_structure.js
index fab7ac4..a108e38 100755
--- a/erpnext/hr/doctype/salary_structure/salary_structure.js
+++ b/erpnext/hr/doctype/salary_structure/salary_structure.js
@@ -9,15 +9,7 @@
 	e_tbl = doc.earnings || [];
 	d_tbl = doc.deductions || [];
 	if (e_tbl.length == 0 && d_tbl.length == 0)
-		return $c_obj(doc,'make_earn_ded_table','', function(r, rt) { refresh_many(['earnings', 'deductions']);});
-}
-
-cur_frm.cscript.refresh = function(doc, dt, dn){
-	if((!doc.__islocal) && (doc.is_active == 'Yes') && cint(doc.salary_slip_based_on_timesheet == 0)){
-		cur_frm.add_custom_button(__('Salary Slip'),
-			cur_frm.cscript['Make Salary Slip'], __("Make"));
-		cur_frm.page.set_inner_btn_group_as_primary(__("Make"));
-	}
+		return function(r, rt) { refresh_many(['earnings', 'deductions']);};
 }
 
 frappe.ui.form.on('Salary Structure', {
@@ -25,29 +17,54 @@
 		frm.trigger("toggle_fields")
 		frm.fields_dict['earnings'].grid.set_column_disp("default_amount", false);
 		frm.fields_dict['deductions'].grid.set_column_disp("default_amount", false);
-	},
+		
+		frm.add_custom_button(__("Preview Salary Slip"),
+			function() { frm.trigger('preview_salary_slip'); }, "icon-sitemap", "btn-default");
+		
+	},	
 
 	salary_slip_based_on_timesheet: function(frm) {
 		frm.trigger("toggle_fields")
 	},
-
+	
+	preview_salary_slip: function(frm) {
+		var d = new frappe.ui.Dialog({
+			title: __("Preview Salary Slip"),
+			fields: [
+				{"fieldname":"employee", "fieldtype":"Select", "label":__("Employee"),
+				options: $.map(frm.doc.employees, function(d) { return d.employee }), reqd: 1, label:"Employee"},
+				{fieldname:"fetch", "label":__("Show Salary Slip"), "fieldtype":"Button"}
+			]
+		});
+		d.get_input("fetch").on("click", function() {
+			var values = d.get_values();
+			if(!values) return;
+			frm.doc.salary_slip_based_on_timesheet?print_format="Salary Slip based on Timesheet":print_format="Salary Slip Standard";
+				
+			frappe.call({
+				method: "erpnext.hr.doctype.salary_structure.salary_structure.make_salary_slip",
+				args: {
+					source_name: frm.doc.name,
+					employee: values.employee,
+					as_print: 1,
+					print_format: print_format
+				},
+				callback: function(r) {
+					var new_window = window.open();
+					new_window.document.write(r.message);
+					// frappe.msgprint(r.message);
+				}
+			});
+		});
+		d.show();
+	},
+	
 	toggle_fields: function(frm) {
 		frm.toggle_display(['salary_component', 'hour_rate'], frm.doc.salary_slip_based_on_timesheet);
 		frm.toggle_reqd(['salary_component', 'hour_rate'], frm.doc.salary_slip_based_on_timesheet);
 	}
 })
 
-cur_frm.cscript['Make Salary Slip'] = function() {
-	frappe.model.open_mapped_doc({
-		method: "erpnext.hr.doctype.salary_structure.salary_structure.make_salary_slip",
-		frm: cur_frm
-	});
-}
-
-cur_frm.cscript.employee = function(doc, dt, dn){
-	if (doc.employee)
-		return get_server_fields('get_employee_details','','',doc,dt,dn);
-}
 
 cur_frm.cscript.amount = function(doc, cdt, cdn){
 	calculate_totals(doc, cdt, cdn);
@@ -79,10 +96,6 @@
 	if(doc.employee && doc.is_active == "Yes") frappe.model.clear_doc("Employee", doc.employee);
 }
 
-cur_frm.fields_dict.employee.get_query = function(doc,cdt,cdn) {
-	return{ query: "erpnext.controllers.queries.employee_query" }
-}
-
 
 frappe.ui.form.on('Salary Detail', {
 	amount: function(frm) {
@@ -96,4 +109,12 @@
 	deductions_remove: function(frm) {
 		calculate_totals(frm.doc);
 	}
-})
\ No newline at end of file
+})
+
+frappe.ui.form.on('Salary Structure Employee', {
+	onload: function(frm) {
+		frm.set_query("employee","employees", function(doc,cdt,cdn) {
+			return{ query: "erpnext.controllers.queries.employee_query" }
+		})
+	}
+});
diff --git a/erpnext/hr/doctype/salary_structure/salary_structure.json b/erpnext/hr/doctype/salary_structure/salary_structure.json
index 4cdc67b..7ee4204 100644
--- a/erpnext/hr/doctype/salary_structure/salary_structure.json
+++ b/erpnext/hr/doctype/salary_structure/salary_structure.json
@@ -2,6 +2,7 @@
  "allow_copy": 0, 
  "allow_import": 1, 
  "allow_rename": 0, 
+ "autoname": "Prompt", 
  "beta": 0, 
  "creation": "2013-03-07 18:50:29", 
  "custom": 0, 
@@ -38,140 +39,6 @@
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
-   "fieldname": "employee", 
-   "fieldtype": "Link", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 1, 
-   "in_list_view": 0, 
-   "label": "Employee", 
-   "length": 0, 
-   "no_copy": 0, 
-   "oldfieldname": "employee", 
-   "oldfieldtype": "Link", 
-   "options": "Employee", 
-   "permlevel": 0, 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "report_hide": 0, 
-   "reqd": 1, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0
-  }, 
-  {
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "fieldname": "employee_name", 
-   "fieldtype": "Data", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_list_view": 1, 
-   "label": "Employee Name", 
-   "length": 0, 
-   "no_copy": 0, 
-   "oldfieldname": "employee_name", 
-   "oldfieldtype": "Data", 
-   "permlevel": 0, 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 1, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0
-  }, 
-  {
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "fieldname": "branch", 
-   "fieldtype": "Link", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 1, 
-   "in_list_view": 0, 
-   "label": "Branch", 
-   "length": 0, 
-   "no_copy": 0, 
-   "oldfieldname": "branch", 
-   "oldfieldtype": "Select", 
-   "options": "Branch", 
-   "permlevel": 0, 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 1, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0
-  }, 
-  {
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "fieldname": "designation", 
-   "fieldtype": "Link", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 1, 
-   "in_list_view": 0, 
-   "label": "Designation", 
-   "length": 0, 
-   "no_copy": 0, 
-   "oldfieldname": "designation", 
-   "oldfieldtype": "Select", 
-   "options": "Designation", 
-   "permlevel": 0, 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 1, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0
-  }, 
-  {
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "fieldname": "department", 
-   "fieldtype": "Link", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 1, 
-   "in_list_view": 0, 
-   "label": "Department", 
-   "length": 0, 
-   "no_copy": 0, 
-   "oldfieldname": "department", 
-   "oldfieldtype": "Select", 
-   "options": "Department", 
-   "permlevel": 0, 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 1, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0
-  }, 
-  {
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
    "fieldname": "company", 
    "fieldtype": "Link", 
    "hidden": 0, 
@@ -354,6 +221,57 @@
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
+   "fieldname": "employee_break", 
+   "fieldtype": "Section Break", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "description": "Select employees for current Salary Structure", 
+   "fieldname": "employees", 
+   "fieldtype": "Table", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Employees", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Salary Structure Employee", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 1, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
    "fieldname": "time_sheet_earning_detail", 
    "fieldtype": "Section Break", 
    "hidden": 0, 
@@ -498,6 +416,7 @@
    "oldfieldname": "earning_deduction", 
    "oldfieldtype": "Section Break", 
    "permlevel": 0, 
+   "precision": "2", 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
@@ -671,7 +590,7 @@
    "collapsible": 0, 
    "fieldname": "total_earning", 
    "fieldtype": "Currency", 
-   "hidden": 0, 
+   "hidden": 1, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
@@ -698,7 +617,7 @@
    "collapsible": 0, 
    "fieldname": "total_deduction", 
    "fieldtype": "Currency", 
-   "hidden": 0, 
+   "hidden": 1, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
@@ -723,33 +642,9 @@
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
-   "fieldname": "column_break3", 
-   "fieldtype": "Column Break", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_list_view": 0, 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0, 
-   "width": "50%"
-  }, 
-  {
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
    "fieldname": "net_pay", 
    "fieldtype": "Currency", 
-   "hidden": 0, 
+   "hidden": 1, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
@@ -780,7 +675,7 @@
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2016-07-13 23:56:01.550518", 
+ "modified": "2016-08-10 12:18:31.521436", 
  "modified_by": "Administrator", 
  "module": "HR", 
  "name": "Salary Structure", 
@@ -832,7 +727,7 @@
  "read_only_onload": 0, 
  "sort_field": "modified", 
  "sort_order": "DESC", 
- "timeline_field": "employee", 
- "title_field": "employee_name", 
+ "timeline_field": "", 
+ "title_field": "", 
  "track_seen": 0
 }
\ No newline at end of file
diff --git a/erpnext/hr/doctype/salary_structure/salary_structure.py b/erpnext/hr/doctype/salary_structure/salary_structure.py
index c2f95af..d4bc6e3 100644
--- a/erpnext/hr/doctype/salary_structure/salary_structure.py
+++ b/erpnext/hr/doctype/salary_structure/salary_structure.py
@@ -4,7 +4,7 @@
 from __future__ import unicode_literals
 import frappe
 
-from frappe.utils import cstr, flt, getdate
+from frappe.utils import cstr, flt, getdate, cint
 from frappe.model.naming import make_autoname
 from frappe import _
 from frappe.model.mapper import get_mapped_doc
@@ -12,29 +12,12 @@
 from erpnext.hr.utils import set_employee_name
 
 class SalaryStructure(Document):
-	def autoname(self):
-		self.name = make_autoname(self.employee + '/.SST' + '/.#####')
-		
+	
 	def validate(self):
-		self.check_overlap()
 		self.validate_amount()
-		self.validate_employee()
 		self.validate_joining_date()
-		set_employee_name(self)
-
-	def get_employee_details(self):
-		ret = {}
-		det = frappe.db.sql("""select employee_name, branch, designation, department
-			from `tabEmployee` where name = %s""", self.employee)
-		if det:
-			ret = {
-				'employee_name': cstr(det[0][0]),
-				'branch': cstr(det[0][1]),
-				'designation': cstr(det[0][2]),
-				'department': cstr(det[0][3]),
-				'backup_employee': cstr(self.employee)
-			}
-		return ret
+		for e in self.get('employees'):
+			set_employee_name(e)
 
 	def get_ss_values(self,employee):
 		basic_info = frappe.db.sql("""select bank_name, bank_ac_no
@@ -43,71 +26,23 @@
 			'bank_ac_no': basic_info and basic_info[0][1] or ''}
 		return ret
 
-	def make_table(self, doct_name, tab_fname, tab_name):
-		list1 = frappe.db.sql("select name from `tab%s` where docstatus != 2" % doct_name)
-		for li in list1:
-			child = self.append(tab_fname, {})
-			if(tab_fname == 'earnings'):
-				child.salary_component = cstr(li[0])
-				child.amount = 0
-			elif(tab_fname == 'deductions'):
-				child.salary_component = cstr(li[0])
-				child.amount = 0
-
-	def make_earn_ded_table(self):
-		self.make_table('Salary Component','earnings','Salary Detail')
-		self.make_table('Salary Component','deductions', 'Salary Detail')
-
-	def check_overlap(self):
-		existing = frappe.db.sql("""select name from `tabSalary Structure`
-			where employee = %(employee)s and
-			(
-				(%(from_date)s > from_date and %(from_date)s < to_date) or
-				(%(to_date)s > from_date and %(to_date)s < to_date) or
-				(%(from_date)s <= from_date and %(to_date)s >= to_date))
-			and name!=%(name)s
-			and docstatus < 2""",
-			{
-				"employee": self.employee,
-				"from_date": self.from_date,
-				"to_date": self.to_date,
-				"name": self.name or "No Name"
-			}, as_dict=True)
-			
-		if existing:
-			frappe.throw(_("Salary structure {0} already exist, more than one salary structure for same period is not allowed").format(existing[0].name))
-
 	def validate_amount(self):
 		if flt(self.net_pay) < 0 and self.salary_slip_based_on_timesheet:
 			frappe.throw(_("Net pay cannot be negative"))
 
-	def validate_employee(self):
-		old_employee = frappe.db.get_value("Salary Structure", self.name, "employee")
-		if old_employee and self.employee != old_employee:
-			frappe.throw(_("Employee can not be changed"))
-
 	def validate_joining_date(self):
-		joining_date = getdate(frappe.db.get_value("Employee", self.employee, "date_of_joining"))
-		if getdate(self.from_date) < joining_date:
-			frappe.throw(_("From Date in Salary Structure cannot be lesser than Employee Joining Date."))
+		for e in self.get('employees'):
+			joining_date = getdate(frappe.db.get_value("Employee", e.employee, "date_of_joining"))
+			if getdate(self.from_date) < joining_date:
+				frappe.throw(_("From Date in Salary Structure cannot be lesser than Employee Joining Date."))
+				
 
 @frappe.whitelist()
-def make_salary_slip(source_name, target_doc=None):
+def make_salary_slip(source_name, target_doc = None, employee = None, as_print = False, print_format = None):
 	def postprocess(source, target):
-		# copy earnings and deductions table
-		for key in ('earnings', 'deductions'):
-			for d in source.get(key):
-				target.append(key, {
-					'amount': d.amount,
-					'default_amount': d.amount,
-					'depends_on_lwp' : d.depends_on_lwp,
-					'salary_component' : d.salary_component
-				})
-
-		target.run_method("pull_emp_details")
-		target.run_method("get_leave_details")
-		target.run_method("calculate_net_pay")
-			
+		if employee:
+			target.employee = employee
+		target.run_method('process_salary_structure')
 
 	doc = get_mapped_doc("Salary Structure", source_name, {
 		"Salary Structure": {
@@ -119,4 +54,8 @@
 		}
 	}, target_doc, postprocess, ignore_child_tables=True)
 
-	return doc
+	if cint(as_print):
+		doc.name = 'Preview for {0}'.format(employee)
+		return frappe.get_print(doc.doctype, doc.name, doc = doc, print_format = print_format)
+	else:
+		return doc
\ No newline at end of file
diff --git a/erpnext/hr/doctype/salary_structure/test_records.json b/erpnext/hr/doctype/salary_structure/test_records.json
deleted file mode 100644
index 08841d1..0000000
--- a/erpnext/hr/doctype/salary_structure/test_records.json
+++ /dev/null
@@ -1,24 +0,0 @@
-[
-	{
-		"doctype": "Salary Structure",
-		"name": "_Test Salary Structure 1",
-		"employee": "_T-Employee-0001",
-		"from_date": "2014-02-01",
-		"earnings": [
-			{
-				"salary_component": "_Test Basic Salary"
-			},
-			{
-				"salary_component": "_Test Allowance"
-			}
-		],
-		"deductions": [
-			{
-				"salary_component": "_Test Professional Tax"
-			},
-			{
-				"salary_component": "_Test TDS"
-			}
-		]
-	}
-]
diff --git a/erpnext/hr/doctype/salary_structure/test_salary_structure.py b/erpnext/hr/doctype/salary_structure/test_salary_structure.py
index 63d0eed..ef9231a 100644
--- a/erpnext/hr/doctype/salary_structure/test_salary_structure.py
+++ b/erpnext/hr/doctype/salary_structure/test_salary_structure.py
@@ -4,8 +4,183 @@
 
 import frappe
 import unittest
-
-test_records = frappe.get_test_records('Salary Structure')
+import erpnext
+from frappe.utils import nowdate, add_days, add_years
+from erpnext.hr.doctype.salary_structure.salary_structure import make_salary_slip
+# test_records = frappe.get_test_records('Salary Structure')
 
 class TestSalaryStructure(unittest.TestCase):
-	pass
+	def test_setup(self):
+		if not frappe.db.exists("Fiscal Year", "_Test Fiscal Year 2016"):
+			fy = frappe.get_doc({
+				"doctype": "Fiscal Year",
+				"year": "_Test Fiscal Year 2016",
+				"year_end_date": "2016-12-31",
+				"year_start_date": "2016-01-01"
+			})
+			fy.insert()
+			
+		self.make_holiday_list()
+		frappe.db.set_value("Company", erpnext.get_default_company(), "default_holiday_list", "Salary Structure Test Holiday List")
+		self.make_salary_component(["Basic Salary", "Allowance", "HRA", "Professional Tax", "TDS"])
+		employee1 = self.make_employee("test_employee@salary.com")
+		employee2 = self.make_employee("test_employee_2@salary.com")
+		
+	def make_holiday_list(self):
+		if not frappe.db.get_value("Holiday List", "Salary Structure Test Holiday List"):
+			holiday_list = frappe.get_doc({
+				"doctype": "Holiday List",
+				"holiday_list_name": "Salary Structure Test Holiday List",
+				"from_date": nowdate(),
+				"to_date": add_years(nowdate(), 1),
+				"weekly_off": "Sunday"
+			}).insert()	
+			holiday_list.get_weekly_off_dates()
+			holiday_list.save()
+	
+	def make_employee(self, user):
+		if not frappe.db.get_value("User", user):
+			frappe.get_doc({
+				"doctype": "User",
+				"email": user,
+				"first_name": user,
+				"new_password": "password",
+				"user_roles": [{"doctype": "UserRole", "role": "Employee"}]
+			}).insert()
+			
+
+		if not frappe.db.get_value("Employee", {"user_id": user}):
+			emp = frappe.get_doc({
+				"doctype": "Employee",
+				"naming_series": "EMP-",
+				"employee_name": user,
+				"company": erpnext.get_default_company(),
+				"user_id": user,
+				"date_of_birth": "1990-05-08",
+				"date_of_joining": "2013-01-01",
+				"relieving_date": "",
+				"department": frappe.get_all("Department", fields="name")[0].name,
+				"gender": "Female",
+				"company_email": user,
+				"status": "Active",
+				"employment_type": "Intern"
+			}).insert()
+			return emp.name
+		else:
+			return frappe.get_value("Employee", {"employee_name":user}, "name")
+	
+	def make_salary_component(self, salary_components):
+		for salary_component in salary_components:
+			if not frappe.db.exists('Salary Component', salary_component):
+				sal_comp = frappe.get_doc({
+					"doctype": "Salary Component",
+					"salary_component": salary_component
+				})
+				sal_comp.insert()
+				
+
+		
+	def test_amount_totals(self):
+		sal_slip = frappe.get_value("Salary Slip", {"employee_name":"test_employee@salary.com"})
+		if not sal_slip:
+			sal_slip = make_salary_slip_from_salary_structure(employee=frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}))
+			self.assertEquals(sal_slip.get("salary_structure"), 'Salary Structure Sample')
+			self.assertEquals(sal_slip.get("earnings")[0].amount, 0)
+			self.assertEquals(sal_slip.get("deductions")[0].amount, 0)
+			self.assertEquals(sal_slip.get("deductions")[1].amount, 0)
+			self.assertEquals(sal_slip.get("total_deduction"), 0)
+			self.assertEquals(sal_slip.get("net_pay"), 0)
+			
+		
+def make_salary_slip_from_salary_structure(employee):
+	sal_struct = make_salary_structure('Salary Structure Sample')
+	sal_slip = make_salary_slip(sal_struct, employee = employee)
+	sal_slip.employee_name = frappe.get_value("Employee", {"name":employee}, "employee_name")
+	sal_slip.month = "11"
+	sal_slip.fiscal_year = "_Test Fiscal Year 2016"
+	sal_slip.insert()
+	sal_slip.submit()
+	return sal_slip	
+	
+def make_salary_structure(sal_struct):
+	if not frappe.db.exists('Salary Structure', sal_struct):
+		frappe.get_doc({
+			"doctype": "Salary Structure",
+			"name": sal_struct,
+			"company": erpnext.get_default_company(),
+			"from_date": nowdate(),
+			"employees": get_employee_details(),
+			"earnings": get_earnings_component(),
+			"deductions": get_deductions_component()			
+		}).insert()
+	return sal_struct
+			
+			
+def get_employee_details():
+	return [{"employee": frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}, "name"),
+			"base": 25000,
+			"variable": 5000,
+			"idx": 1
+			},
+			{"employee": frappe.get_value("Employee", {"employee_name":"test_employee_2@salary.com"}, "name"),
+			 "base": 2100,
+			 "variable": 100,
+			 "idx": 2
+			}
+		]
+			
+def get_earnings_component():	
+	return [
+				{
+					"salary_component": 'Basic Salary',
+					"abbr":'BS',
+					"condition": 'base > 10000',
+					"formula": 'base*.2',
+					"idx": 1
+				},
+				{
+					"salary_component": 'Basic Salary',
+					"abbr":'BS',
+					"condition": 'base < 10000',
+					"formula": 'base*.1',
+					"idx": 2
+				},
+				{
+					"salary_component": 'HRA',
+					"abbr":'H',
+					"amount": 3000,
+					"idx": 3
+				},
+				{
+					"salary_component": 'Allowance',
+					"abbr":'A',
+					"condition": 'H < 10000',
+					"formula": 'BS*.5',
+					"idx": 4
+				},
+			]
+			
+def get_deductions_component():	
+	return [
+				{
+					"salary_component": 'Professional Tax',
+					"abbr":'PT',
+					"condition": 'base > 10000',
+					"formula": 'base*.2',
+					"idx": 1
+				},
+				{
+					"salary_component": 'TDS',
+					"abbr":'T',
+					"formula": 'base*.5',
+					"idx": 2
+				},
+				{
+					"salary_component": 'TDS',
+					"abbr":'T',
+					"condition": 'employment_type=="Intern"',
+					"formula": 'base*.1',
+					"idx": 3
+				}
+			]			
+			
\ No newline at end of file
diff --git a/erpnext/hr/doctype/salary_structure_employee/__init__.py b/erpnext/hr/doctype/salary_structure_employee/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/hr/doctype/salary_structure_employee/__init__.py
diff --git a/erpnext/hr/doctype/salary_structure_employee/salary_structure_employee.json b/erpnext/hr/doctype/salary_structure_employee/salary_structure_employee.json
new file mode 100644
index 0000000..aae33e3
--- /dev/null
+++ b/erpnext/hr/doctype/salary_structure_employee/salary_structure_employee.json
@@ -0,0 +1,139 @@
+{
+ "allow_copy": 0, 
+ "allow_import": 0, 
+ "allow_rename": 0, 
+ "autoname": "employee", 
+ "beta": 0, 
+ "creation": "2016-07-26 11:53:43.621605", 
+ "custom": 0, 
+ "docstatus": 0, 
+ "doctype": "DocType", 
+ "document_type": "", 
+ "editable_grid": 1, 
+ "fields": [
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "fieldname": "employee", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 1, 
+   "label": "Employee", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Employee", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 1, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "fieldname": "employee_name", 
+   "fieldtype": "Data", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Employee Name", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 1, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "fieldname": "base", 
+   "fieldtype": "Currency", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 1, 
+   "label": "Base", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 1, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "fieldname": "variable", 
+   "fieldtype": "Currency", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 1, 
+   "label": "Variable", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }
+ ], 
+ "hide_heading": 0, 
+ "hide_toolbar": 0, 
+ "idx": 0, 
+ "image_view": 0, 
+ "in_create": 0, 
+ "in_dialog": 0, 
+ "is_submittable": 0, 
+ "issingle": 0, 
+ "istable": 1, 
+ "max_attachments": 0, 
+ "modified": "2016-08-11 12:18:14.526977", 
+ "modified_by": "Administrator", 
+ "module": "HR", 
+ "name": "Salary Structure Employee", 
+ "name_case": "", 
+ "owner": "Administrator", 
+ "permissions": [], 
+ "quick_entry": 1, 
+ "read_only": 0, 
+ "read_only_onload": 0, 
+ "sort_field": "modified", 
+ "sort_order": "DESC", 
+ "track_seen": 0
+}
\ No newline at end of file
diff --git a/erpnext/hr/doctype/salary_structure_employee/salary_structure_employee.py b/erpnext/hr/doctype/salary_structure_employee/salary_structure_employee.py
new file mode 100644
index 0000000..dfcac3f
--- /dev/null
+++ b/erpnext/hr/doctype/salary_structure_employee/salary_structure_employee.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# 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.model.document import Document
+
+class SalaryStructureEmployee(Document):
+	pass
diff --git a/erpnext/hr/print_format/salary_slip_based_on_timesheet/salary_slip_based_on_timesheet.json b/erpnext/hr/print_format/salary_slip_based_on_timesheet/salary_slip_based_on_timesheet.json
index c5154d7..20c7d23 100644
--- a/erpnext/hr/print_format/salary_slip_based_on_timesheet/salary_slip_based_on_timesheet.json
+++ b/erpnext/hr/print_format/salary_slip_based_on_timesheet/salary_slip_based_on_timesheet.json
@@ -6,9 +6,9 @@
  "docstatus": 0, 
  "doctype": "Print Format", 
  "font": "Default", 
- "format_data": "[{\"fieldname\": \"print_heading_template\", \"fieldtype\": \"HTML\", \"options\": \" <h3 style=\\\"text-align: right;\\\">{{doc.name}}</h3><div><hr></div> \"}, {\"fieldtype\": \"Section Break\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"employee\"}, {\"print_hide\": 0, \"fieldname\": \"employee_name\"}, {\"print_hide\": 0, \"fieldname\": \"department\"}, {\"print_hide\": 0, \"fieldname\": \"designation\"}, {\"print_hide\": 0, \"fieldname\": \"branch\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"start_date\"}, {\"print_hide\": 0, \"fieldname\": \"end_date\"}, {\"print_hide\": 0, \"fieldname\": \"total_working_hours\"}, {\"print_hide\": 0, \"fieldname\": \"hour_rate\"}, {\"fieldtype\": \"Section Break\"}, {\"fieldtype\": \"Column Break\"}, {\"visible_columns\": [{\"print_hide\": 0, \"fieldname\": \"time_sheet\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"working_hours\", \"print_width\": \"\"}], \"print_hide\": 0, \"fieldname\": \"timesheets\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldtype\": \"Section Break\"}, {\"fieldtype\": \"Column Break\"}, {\"visible_columns\": [{\"print_hide\": 0, \"fieldname\": \"salary_component\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"amount\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"depends_on_lwp\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"default_amount\", \"print_width\": \"\"}], \"print_hide\": 0, \"fieldname\": \"earnings\"}, {\"fieldtype\": \"Column Break\"}, {\"visible_columns\": [{\"print_hide\": 0, \"fieldname\": \"salary_component\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"amount\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"depends_on_lwp\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"default_amount\", \"print_width\": \"\"}], \"print_hide\": 0, \"fieldname\": \"deductions\"}, {\"fieldtype\": \"Section Break\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"gross_pay\"}, {\"print_hide\": 0, \"fieldname\": \"total_deduction\"}, {\"print_hide\": 0, \"fieldname\": \"net_pay\"}, {\"print_hide\": 0, \"fieldname\": \"rounded_total\"}, {\"print_hide\": 0, \"fieldname\": \"total_in_words\"}]", 
+ "format_data": "[{\"fieldname\": \"print_heading_template\", \"fieldtype\": \"HTML\", \"options\": \"  <h3 style=\\\"text-align: right;\\\">{{doc.name}}</h3><div><hr></div>  \"}, {\"fieldtype\": \"Section Break\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"employee\"}, {\"print_hide\": 0, \"fieldname\": \"employee_name\"}, {\"print_hide\": 0, \"fieldname\": \"department\"}, {\"print_hide\": 0, \"fieldname\": \"designation\"}, {\"print_hide\": 0, \"fieldname\": \"branch\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"start_date\"}, {\"print_hide\": 0, \"fieldname\": \"end_date\"}, {\"print_hide\": 0, \"fieldname\": \"total_working_hours\"}, {\"print_hide\": 0, \"fieldname\": \"hour_rate\"}, {\"fieldtype\": \"Section Break\"}, {\"fieldtype\": \"Column Break\"}, {\"visible_columns\": [{\"print_hide\": 0, \"fieldname\": \"time_sheet\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"working_hours\", \"print_width\": \"\"}], \"print_hide\": 0, \"fieldname\": \"timesheets\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldtype\": \"Section Break\"}, {\"fieldtype\": \"Column Break\"}, {\"visible_columns\": [{\"print_hide\": 0, \"fieldname\": \"salary_component\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"amount\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"depends_on_lwp\", \"print_width\": \"\"}], \"print_hide\": 0, \"fieldname\": \"earnings\"}, {\"fieldtype\": \"Column Break\"}, {\"visible_columns\": [{\"print_hide\": 0, \"fieldname\": \"salary_component\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"amount\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"depends_on_lwp\", \"print_width\": \"\"}], \"print_hide\": 0, \"fieldname\": \"deductions\"}, {\"fieldtype\": \"Section Break\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"gross_pay\"}, {\"print_hide\": 0, \"fieldname\": \"total_deduction\"}, {\"print_hide\": 0, \"fieldname\": \"net_pay\"}, {\"print_hide\": 0, \"fieldname\": \"rounded_total\"}, {\"print_hide\": 0, \"fieldname\": \"total_in_words\"}]", 
  "idx": 0, 
- "modified": "2016-07-07 13:09:43.734752", 
+ "modified": "2016-08-21 21:02:59.896033", 
  "modified_by": "Administrator", 
  "name": "Salary Slip based on Timesheet", 
  "owner": "Administrator", 
diff --git a/erpnext/hr/print_format/salary_slip_standard/salary_slip_standard.json b/erpnext/hr/print_format/salary_slip_standard/salary_slip_standard.json
index f8bd328..1789c75 100644
--- a/erpnext/hr/print_format/salary_slip_standard/salary_slip_standard.json
+++ b/erpnext/hr/print_format/salary_slip_standard/salary_slip_standard.json
@@ -6,9 +6,9 @@
  "docstatus": 0, 
  "doctype": "Print Format", 
  "font": "Default", 
- "format_data": "[{\"fieldname\": \"print_heading_template\", \"fieldtype\": \"HTML\", \"options\": \"  <h3 style=\\\"text-align: right;\\\"><span style=\\\"line-height: 1.42857;\\\">{{doc.name}}</span></h3>\\n<div>\\n    <hr style=\\\"text-align: center;\\\">\\n</div>  \"}, {\"fieldtype\": \"Section Break\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"employee\"}, {\"print_hide\": 0, \"fieldname\": \"company\"}, {\"print_hide\": 0, \"fieldname\": \"employee_name\"}, {\"print_hide\": 0, \"fieldname\": \"department\"}, {\"print_hide\": 0, \"fieldname\": \"designation\"}, {\"print_hide\": 0, \"fieldname\": \"branch\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"start_date\"}, {\"print_hide\": 0, \"fieldname\": \"end_date\"}, {\"print_hide\": 0, \"fieldname\": \"total_days_in_month\"}, {\"print_hide\": 0, \"fieldname\": \"leave_without_pay\"}, {\"print_hide\": 0, \"fieldname\": \"payment_days\"}, {\"fieldtype\": \"Section Break\"}, {\"fieldtype\": \"Column Break\"}, {\"visible_columns\": [{\"print_hide\": 0, \"fieldname\": \"salary_component\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"amount\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"depends_on_lwp\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"default_amount\", \"print_width\": \"\"}], \"print_hide\": 0, \"fieldname\": \"earnings\"}, {\"fieldtype\": \"Column Break\"}, {\"visible_columns\": [{\"print_hide\": 0, \"fieldname\": \"salary_component\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"amount\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"depends_on_lwp\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"default_amount\", \"print_width\": \"\"}], \"print_hide\": 0, \"fieldname\": \"deductions\"}, {\"fieldtype\": \"Section Break\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"arrear_amount\"}, {\"print_hide\": 0, \"fieldname\": \"leave_encashment_amount\"}, {\"print_hide\": 0, \"fieldname\": \"gross_pay\"}, {\"print_hide\": 0, \"fieldname\": \"total_deduction\"}, {\"print_hide\": 0, \"fieldname\": \"net_pay\"}, {\"print_hide\": 0, \"fieldname\": \"rounded_total\"}, {\"print_hide\": 0, \"fieldname\": \"total_in_words\"}]", 
+ "format_data": "[{\"fieldname\": \"print_heading_template\", \"fieldtype\": \"HTML\", \"options\": \"   <h3 style=\\\"text-align: right;\\\"><span style=\\\"line-height: 1.42857;\\\">{{doc.name}}</span></h3>\\n<div>\\n    <hr style=\\\"text-align: center;\\\">\\n</div>   \"}, {\"fieldtype\": \"Section Break\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"employee\"}, {\"print_hide\": 0, \"fieldname\": \"company\"}, {\"print_hide\": 0, \"fieldname\": \"employee_name\"}, {\"print_hide\": 0, \"fieldname\": \"department\"}, {\"print_hide\": 0, \"fieldname\": \"designation\"}, {\"print_hide\": 0, \"fieldname\": \"branch\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"start_date\"}, {\"print_hide\": 0, \"fieldname\": \"end_date\"}, {\"print_hide\": 0, \"fieldname\": \"total_days_in_month\"}, {\"print_hide\": 0, \"fieldname\": \"leave_without_pay\"}, {\"print_hide\": 0, \"fieldname\": \"payment_days\"}, {\"fieldtype\": \"Section Break\"}, {\"fieldtype\": \"Column Break\"}, {\"visible_columns\": [{\"print_hide\": 0, \"fieldname\": \"salary_component\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"amount\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"depends_on_lwp\", \"print_width\": \"\"}], \"print_hide\": 0, \"fieldname\": \"earnings\"}, {\"fieldtype\": \"Column Break\"}, {\"visible_columns\": [{\"print_hide\": 0, \"fieldname\": \"salary_component\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"amount\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"depends_on_lwp\", \"print_width\": \"\"}], \"print_hide\": 0, \"fieldname\": \"deductions\"}, {\"fieldtype\": \"Section Break\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"arrear_amount\"}, {\"print_hide\": 0, \"fieldname\": \"leave_encashment_amount\"}, {\"print_hide\": 0, \"fieldname\": \"gross_pay\"}, {\"print_hide\": 0, \"fieldname\": \"total_deduction\"}, {\"print_hide\": 0, \"fieldname\": \"net_pay\"}, {\"print_hide\": 0, \"fieldname\": \"rounded_total\"}, {\"print_hide\": 0, \"fieldname\": \"total_in_words\"}]", 
  "idx": 0, 
- "modified": "2016-07-07 13:04:55.804431", 
+ "modified": "2016-08-22 00:21:42.600548", 
  "modified_by": "Administrator", 
  "name": "Salary Slip Standard", 
  "owner": "Administrator", 
diff --git a/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.json b/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.json
index 26ba5b7..8438e07 100644
--- a/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.json
+++ b/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.json
@@ -9,6 +9,7 @@
  "docstatus": 0, 
  "doctype": "DocType", 
  "document_type": "Setup", 
+ "editable_grid": 0, 
  "fields": [
   {
    "allow_on_submit": 0, 
@@ -475,33 +476,6 @@
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
-   "default": "1", 
-   "depends_on": "get_items_from", 
-   "description": "If checked, BOM for sub-assembly items will be considered for getting raw materials. Otherwise, all sub-assembly items will be treated as a raw material.", 
-   "fieldname": "use_multi_level_bom", 
-   "fieldtype": "Check", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_list_view": 0, 
-   "label": "Use Multi-Level BOM", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0
-  }, 
-  {
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
    "fieldname": "items", 
    "fieldtype": "Table", 
    "hidden": 0, 
@@ -699,19 +673,124 @@
    "search_index": 0, 
    "set_only_once": 0, 
    "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "fieldname": "column_break_2", 
+   "fieldtype": "Column Break", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "default": "1", 
+   "depends_on": "", 
+   "description": "If checked, all the children of each production item will be included in the Material Requests.", 
+   "fieldname": "use_multi_level_bom", 
+   "fieldtype": "Check", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Use Multi-Level BOM", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "description": "If checked, only Purchase material requests for final raw materials will be included in the Material Requests. Otherwise, Material Requests for parent items will be created", 
+   "fieldname": "only_raw_materials", 
+   "fieldtype": "Check", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Only Obtain Raw Materials", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "depends_on": "use_multi_level_bom", 
+   "description": "If checked, raw materials for items that are sub-contracted will be included in the Material Requests", 
+   "fieldname": "include_subcontracted", 
+   "fieldtype": "Check", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Include sub-contracted raw materials", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
   }
  ], 
  "hide_heading": 0, 
  "hide_toolbar": 1, 
  "icon": "icon-calendar", 
  "idx": 1, 
+ "image_view": 0, 
  "in_create": 1, 
  "in_dialog": 0, 
  "is_submittable": 0, 
  "issingle": 1, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2016-06-02 17:59:48.976304", 
+ "modified": "2016-08-17 05:35:34.331954", 
  "modified_by": "Administrator", 
  "module": "Manufacturing", 
  "name": "Production Planning Tool", 
@@ -731,6 +810,7 @@
    "print": 1, 
    "read": 1, 
    "report": 0, 
+   "restrict": 0, 
    "role": "Manufacturing User", 
    "set_user_permissions": 0, 
    "share": 1, 
diff --git a/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.py b/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.py
index 5fbcf1e..acb3ab8 100644
--- a/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.py
+++ b/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.py
@@ -175,7 +175,7 @@
 				and bom.is_active = 1) %s""" % \
 			(", ".join(["%s"] * len(mr_list)), item_condition), tuple(mr_list), as_dict=1)
 
-		self.add_items(items)
+		self.add_items(items) 
 
 
 	def add_items(self, items):
@@ -313,10 +313,10 @@
 			}
 		"""
 		item_list = []
-
+		
 		for bom, so_wise_qty in bom_dict.items():
 			bom_wise_item_details = {}
-			if self.use_multi_level_bom:
+			if self.use_multi_level_bom and self.only_raw_materials and self.include_subcontracted:
 				# get all raw materials with sub assembly childs
 				# Did not use qty_consumed_per_unit in the query, as it leads to rounding loss
 				for d in frappe.db.sql("""select fb.item_code,
@@ -326,28 +326,46 @@
 					where bom.name = fb.parent and item.name = fb.item_code
 					and (item.is_sub_contracted_item = 0 or ifnull(item.default_bom, "")="")
 					and item.is_stock_item = 1
-					and fb.docstatus<2 and bom.name=%s
-					group by fb.item_code, fb.stock_uom""", bom, as_dict=1):
+					and fb.docstatus<2 and bom.name=%(bom)s
+					group by fb.item_code, fb.stock_uom""", {"bom":bom}, as_dict=1):
 						bom_wise_item_details.setdefault(d.item_code, d)
 			else:
 				# Get all raw materials considering SA items as raw materials,
 				# so no childs of SA items
-				for d in frappe.db.sql("""select bom_item.item_code,
-					ifnull(sum(bom_item.qty/ifnull(bom.quantity, 1)), 0) as qty,
-					bom_item.description, bom_item.stock_uom, item.min_order_qty
-					from `tabBOM Item` bom_item, `tabBOM` bom, tabItem item
-					where bom.name = bom_item.parent and bom.name = %s and bom_item.docstatus < 2
-					and bom_item.item_code = item.name
-					and item.is_stock_item = 1
-					group by bom_item.item_code""", bom, as_dict=1):
-						bom_wise_item_details.setdefault(d.item_code, d)
+				bom_wise_item_details = self.get_subitems(bom_wise_item_details, bom,1, \
+					self.use_multi_level_bom,self.only_raw_materials, self.include_subcontracted)
+				
 			for item, item_details in bom_wise_item_details.items():
 				for so_qty in so_wise_qty:
 					item_list.append([item, flt(item_details.qty) * so_qty[1], item_details.description,
 						item_details.stock_uom, item_details.min_order_qty, so_qty[0]])
-
+						
 		self.make_items_dict(item_list)
 
+	def get_subitems(self,bom_wise_item_details, bom, parent_qty, include_sublevel, only_raw, supply_subs):
+		for d in frappe.db.sql("""select bom_item.item_code, default_material_request_type,
+			ifnull(%(parent_qty)s * sum(bom_item.qty/ifnull(bom.quantity, 1)), 0) as qty, 
+			item.is_sub_contracted_item as is_sub_contracted, item.default_bom as default_bom
+			from `tabBOM Item` bom_item, `tabBOM` bom, tabItem item
+			where bom.name = bom_item.parent and bom.name = %(bom)s and bom_item.docstatus < 2
+			and bom_item.item_code = item.name
+			and item.is_stock_item = 1
+			group by bom_item.item_code""", {"bom": bom, "parent_qty": parent_qty}, as_dict=1):
+			if (d.default_material_request_type == "Purchase" and not (d.is_sub_contracted \
+				and only_raw and include_sublevel)) or (d.default_material_request_type == \
+				"Manufacture" and not only_raw):
+				if d.item_code in bom_wise_item_details:
+					bom_wise_item_details[d.item_code].qty = bom_wise_item_details[d.item_code].qty\
+						+ d.qty
+				else:
+					bom_wise_item_details[d.item_code] = d
+			if include_sublevel:
+				if (d.default_material_request_type == "Purchase" and d.is_sub_contracted \
+					and supply_subs) or (d.default_material_request_type == "Manufacture"):
+					child_details = self.get_subitems(bom_wise_item_details,d.default_bom, \
+						d.qty, include_sublevel, only_raw, supply_subs)
+		return bom_wise_item_details
+
 	def make_items_dict(self, item_list):
 		for i in item_list:
 			self.item_dict.setdefault(i[0], []).append([flt(i[1]), i[2], i[3], i[4], i[5]])
diff --git a/erpnext/manufacturing/doctype/production_planning_tool/test_production_planning_tool.py b/erpnext/manufacturing/doctype/production_planning_tool/test_production_planning_tool.py
new file mode 100644
index 0000000..ea4da0c
--- /dev/null
+++ b/erpnext/manufacturing/doctype/production_planning_tool/test_production_planning_tool.py
@@ -0,0 +1,391 @@
+# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
+# MIT License. See license.txt
+
+import frappe
+import frappe.defaults
+import unittest
+from frappe.test_runner import make_test_records
+
+from erpnext.manufacturing.doctype.production_planning_tool.production_planning_tool import ProductionPlanningTool
+
+# load test records and dependencies
+
+test_records = frappe.get_test_records('Production Planning Tool')
+
+test_dependencies = ["Item","BOM"]
+
+class TestEvent(unittest.TestCase):
+	
+	def test_materials_requests_all_raw_multi_level(self):
+		items = ["_Test PPT Item Raw A","_Test PPT Item Raw B","_Test PPT Item Raw C","_Test PPT Item Raw D",
+			"_Test PPT Item Sub A","_Test PPT Item Sub B","_Test PPT Item Sub C","_Test PPT Item SC A",
+			"_Test PPT Item SC B","_Test PPT Item Master"]
+		quantities = [14,9,36,1,0,0,0,0,0,0]
+		types = ["Purchase","Purchase","Purchase","Purchase","Manufacture","Manufacture","Manufacture","Purchase",
+			"Purchase","Manufacture"]
+		
+		self.runtest_materials_requests(items, quantities, types, use_multi_level_bom=1, only_raw_materials=1, \
+			include_subcontracted=1)
+	
+	def test_materials_requests_multi_no_subcontracted(self):
+		items = ["_Test PPT Item Raw A","_Test PPT Item Raw B","_Test PPT Item Raw C","_Test PPT Item Raw D",
+			"_Test PPT Item Sub A","_Test PPT Item Sub B","_Test PPT Item Sub C","_Test PPT Item SC A",
+			"_Test PPT Item SC B","_Test PPT Item Master"]
+		quantities = [14,5,20,0,0,0,0,0,0,0]
+		types = ["Purchase","Purchase","Purchase","Purchase","Manufacture","Manufacture","Manufacture","Purchase",
+			"Purchase","Manufacture"]
+		
+		# This one should fail for now
+		self.runtest_materials_requests(items, quantities, types, use_multi_level_bom=1, only_raw_materials=1, \
+			include_subcontracted=0)
+
+		
+
+	def test_materials_requests_manufacture_and_sub_multi_level(self):
+		items = ["_Test PPT Item Raw A","_Test PPT Item Raw B","_Test PPT Item Raw C","_Test PPT Item Raw D",
+			"_Test PPT Item Sub A","_Test PPT Item Sub B","_Test PPT Item Sub C","_Test PPT Item SC A",
+			"_Test PPT Item SC B","_Test PPT Item Master"]
+		quantities = [14,9,36,1,2,5,2,1,4,0]
+		types = ["Purchase","Purchase","Purchase","Purchase","Manufacture","Manufacture","Manufacture","Purchase",
+			"Purchase","Manufacture"]
+		
+		self.runtest_materials_requests(items, quantities, types, use_multi_level_bom=1, only_raw_materials=0, \
+			include_subcontracted=1)
+	
+	def test_materials_requests_manufacture_multi_level(self):
+		items = ["_Test PPT Item Raw A","_Test PPT Item Raw B","_Test PPT Item Raw C","_Test PPT Item Raw D",
+			"_Test PPT Item Sub A","_Test PPT Item Sub B","_Test PPT Item Sub C","_Test PPT Item SC A",
+			"_Test PPT Item SC B","_Test PPT Item Master"]
+		quantities = [14,5,20,0,2,5,2,1,4,0]
+		types = ["Purchase","Purchase","Purchase","Purchase","Manufacture","Manufacture","Manufacture","Purchase",
+			"Purchase","Manufacture"]
+		
+		self.runtest_materials_requests(items, quantities, types, use_multi_level_bom=1, only_raw_materials=0, \
+			include_subcontracted=0)
+	
+	
+	
+	def test_materials_requests_single_level_purch_only(self):
+		items = ["_Test PPT Item Raw A","_Test PPT Item Raw B","_Test PPT Item Raw C","_Test PPT Item Raw D",
+			"_Test PPT Item Sub A","_Test PPT Item Sub B","_Test PPT Item Sub C","_Test PPT Item SC A",
+			"_Test PPT Item SC B","_Test PPT Item Master"]
+		quantities = [2,0,0,0,0,0,0,1,0,0]
+		types = ["Purchase","Purchase","Purchase","Purchase","Manufacture","Manufacture","Manufacture","Purchase",
+			"Purchase","Manufacture"]
+		
+		self.runtest_materials_requests(items, quantities, types, use_multi_level_bom=0, only_raw_materials=1, \
+			include_subcontracted=0)
+	
+	def test_materials_requests_single_level(self):
+		items = ["_Test PPT Item Raw A","_Test PPT Item Raw B","_Test PPT Item Raw C","_Test PPT Item Raw D",
+			"_Test PPT Item Sub A","_Test PPT Item Sub B","_Test PPT Item Sub C","_Test PPT Item SC A",
+			"_Test PPT Item SC B","_Test PPT Item Master"]
+		quantities = [2,0,0,0,2,1,0,1,0,0]
+		types = ["Purchase","Purchase","Purchase","Purchase","Manufacture","Manufacture","Manufacture","Purchase",
+			"Purchase","Manufacture"]
+		
+		self.runtest_materials_requests(items, quantities, types, use_multi_level_bom=0, only_raw_materials=0, \
+			include_subcontracted=0)
+	
+	def runtest_materials_requests(self, items, quantities, types,use_multi_level_bom, only_raw_materials, \
+		include_subcontracted):
+		
+		clear_material_requests()
+		create_test_records()
+		
+		ppt = run_production_planning_tool(use_multi_level_bom=use_multi_level_bom, 
+			only_raw_materials=only_raw_materials, include_subcontracted=include_subcontracted, 
+			item_code = "_Test PPT Item Master", bom_no = "BOM-_Test PPT Item Master-001", 
+			planned_qty = 1, planned_start_date = "5/5/2029", 
+			warehouse = "_Test Warehouse - _TC", company = "_Test Company")
+			
+		create_material_requests(ppt)
+		
+		for item, qty, type in zip(items, quantities, types):
+			self.assertEqual(qty, get_requested_qty(item))
+			for mat_req_type in get_requested_types(item):
+				self.assertEqual(type, mat_req_type) 
+				
+def create_test_records():
+	from erpnext.stock.doctype.item.test_item import make_item
+	
+	subA = make_item("_Test PPT Item Sub A",{
+		"item_code": "_Test PPT Item Sub A",
+		"item_name": "_Test PPT Item Sub A",
+		"description": "A manufactured _Test PPT Item Sub Assembly",
+		"default_material_request_type": "Manufacture",
+		"is_sub_contracted_item": 0,
+		"is_stock_item": 1,
+		"stock_uom": "_Test UOM",
+		"item_group": "_Test Item Group",
+		"default_warehouse": "_Test Warehouse - _TC"})
+		
+	subB = make_item("_Test PPT Item Sub B",{
+		"item_code": "_Test PPT Item Sub B",
+		"item_name": "_Test PPT Item Sub B",
+		"description": "A manufactured _Test PPT Item Sub Assembly",
+		"default_material_request_type": "Manufacture",
+		"is_sub_contracted_item": 0,
+		"is_stock_item": 1,
+		"stock_uom": "_Test UOM",
+		"item_group": "_Test Item Group",
+		"default_warehouse": "_Test Warehouse - _TC"})
+		
+	subC = make_item("_Test PPT Item Sub C",{
+		"item_code": "_Test PPT Item Sub C",
+		"item_name": "_Test PPT Item Sub C",
+		"description": "A manufactured _Test PPT Item Sub Assembly",
+		"default_material_request_type": "Manufacture",
+		"is_sub_contracted_item": 0,
+		"is_stock_item": 1,
+		"stock_uom": "_Test UOM",
+		"item_group": "_Test Item Group",
+		"default_warehouse": "_Test Warehouse - _TC"})
+		
+	sCA = make_item("_Test PPT Item SC A",{
+		"item_code": "_Test PPT Item SC A",
+		"item_name": "_Test PPT Item SC A",
+		"description": "A subcontracted part with raw materials",
+		"default_material_request_type": "Purchase",
+		"is_sub_contracted_item": 1,
+		"is_stock_item": 1,
+		"stock_uom": "_Test UOM",
+		"item_group": "_Test Item Group",
+		"default_warehouse": "_Test Warehouse - _TC"})
+	subA = make_item("_Test PPT Item Sub A",{
+		"item_code": "_Test PPT Item Sub A",
+		"item_name": "_Test PPT Item Sub A",
+		"description": "A manufactured _Test PPT Item Sub Assembly",
+		"default_material_request_type": "Manufacture",
+		"is_sub_contracted_item": 0,
+		"is_stock_item": 1,
+		"stock_uom": "_Test UOM",
+		"item_group": "_Test Item Group",
+		"default_warehouse": "_Test Warehouse - _TC"})
+	sCB = make_item("_Test PPT Item SC B",{
+		"item_code": "_Test PPT Item SC B",
+		"item_name": "_Test PPT Item SC B",
+		"description": "A subcontracted part with raw materials",
+		"default_material_request_type": "Purchase",
+		"is_sub_contracted_item": 1,
+		"is_stock_item": 1,
+		"stock_uom": "_Test UOM",
+		"item_group": "_Test Item Group",
+		"default_warehouse": "_Test Warehouse - _TC"})
+		
+	rawA = make_item("_Test PPT Item Raw A",{
+		"item_code": "_Test PPT Item Raw A",
+		"item_name": "_Test PPT Item Raw A",
+		"description": "A raw material",
+		"default_material_request_type": "Purchase",
+		"is_sub_contracted_item": 0,
+		"is_stock_item": 1,
+		"stock_uom": "_Test UOM",
+		"item_group": "_Test Item Group",
+		"default_warehouse": "_Test Warehouse - _TC"})
+		
+	rawB = make_item("_Test PPT Item Raw B",{
+		"item_code": "_Test PPT Item Raw B",
+		"item_name": "_Test PPT Item Raw B",
+		"description": "A raw material",
+		"default_material_request_type": "Purchase",
+		"is_sub_contracted_item": 0,
+		"is_stock_item": 1,
+		"stock_uom": "_Test UOM",
+		"item_group": "_Test Item Group",
+		"default_warehouse": "_Test Warehouse - _TC"})
+		
+	rawC = make_item("_Test PPT Item Raw C",{
+		"item_code": "_Test PPT Item Raw C",
+		"item_name": "_Test PPT Item Raw C",
+		"description": "A raw material",
+		"default_material_request_type": "Purchase",
+		"is_sub_contracted_item": 0,
+		"is_stock_item": 1,
+		"stock_uom": "_Test UOM",
+		"item_group": "_Test Item Group",
+		"default_warehouse": "_Test Warehouse - _TC"})
+		
+	rawD = make_item("_Test PPT Item Raw D",{
+		"item_code": "_Test PPT Item Raw D",
+		"item_name": "_Test PPT Item Raw D",
+		"description": "A raw material",
+		"default_material_request_type": "Purchase",
+		"is_sub_contracted_item": 0,
+		"is_stock_item": 1,
+		"stock_uom": "_Test UOM",
+		"item_group": "_Test Item Group",
+		"default_warehouse": "_Test Warehouse - _TC"})
+		
+	master = make_item("_Test PPT Item Master",{
+		"item_code": "_Test PPT Item Master",
+		"item_name": "_Test PPT Item Master",
+		"description": "The final assembly",
+		"default_material_request_type": "Manufacture",
+		"is_sub_contracted_item": 0,
+		"is_stock_item": 1,
+		"stock_uom": "_Test UOM",
+		"item_group": "_Test Item Group",
+		"default_warehouse": "_Test Warehouse - _TC"})
+		
+	
+	
+	bom_subB = make_bom("BOM-_Test PPT Item Sub B-001",{"quantity":1.0,
+		"item": "_Test PPT Item Sub B",
+		"is_active": 1,
+		"is_default": 1,
+		"docstatus": 1,
+		"with_operations": 0}, [{"item_code": "_Test PPT Item Raw B", "doctype":"BOM Item", "qty":1,  
+				"rate":100, "amount": 100, "stock_uom": "_Test UOM"},
+			{"item_code": "_Test PPT Item Raw C", "doctype":"BOM Item", "qty":4, "rate":100,  
+				"amount": 400,"stock_uom": "_Test UOM"}])
+	
+	bom_subC = make_bom("BOM-_Test PPT Item Sub C-001",{"quantity":1,
+		"item": "_Test PPT Item Sub C",
+		"is_active": 1,
+		"is_default": 1,
+		"docstatus": 1,
+		"with_operations": 0}, [
+			{"item_code": "_Test PPT Item Raw A","item_name": "_Test PPT Item Raw A",   
+				"doctype":"BOM Item", "qty":6, "rate":100, "amount": 600},
+			{"item_code": "_Test PPT Item Sub B","item_name": "_Test PPT Item Sub B",   
+				"bom_no":"BOM-_Test PPT Item Sub B-001", "doctype":"BOM Item", "qty":2,  
+				"rate":100, "amount": 200}])
+		
+	bom_sCA = make_bom("BOM-_Test PPT Item SC A-001",{"quantity":1,
+		"item": "_Test PPT Item SC A",
+		"is_active": 1,
+		"is_default": 1,
+		"docstatus": 1,
+		"with_operations": 0}, [
+			{"item_code": "_Test PPT Item Raw D","item_name": "_Test PPT Item Raw D",  
+				"doctype":"BOM Item", "qty":1, "rate":100, "amount": 100}])
+	
+	bom_sCB = make_bom("BOM-_Test PPT Item SC B-001",{"quantity":1,
+		"item": "_Test PPT Item SC B",
+		"is_active": 1,
+		"is_default": 1,
+		"docstatus": 1,
+		"with_operations": 0}, [
+			{"item_code": "_Test PPT Item Raw B","item_name": "_Test PPT Item Raw B", 
+				"doctype":"BOM Item", "qty":1, "rate":100, "amount": 100},
+			{"item_code": "_Test PPT Item Raw C","item_name": "_Test PPT Item Raw C",   
+				"doctype":"BOM Item", "qty":4, "rate":100, "amount": 400}])
+	
+	bom_subA = make_bom("BOM-_Test PPT Item Sub A-001",{"quantity":1,
+		"item": "_Test PPT Item Sub A",
+		"is_active": 1,
+		"is_default": 1,
+		"docstatus": 1,
+		"with_operations": 0}, [
+			{"item_code": "_Test PPT Item Sub C","item_name": "_Test PPT Item Sub C",   
+				"bom_no":"BOM-_Test PPT Item Sub C-001", "doctype":"BOM Item",  
+				"qty":1, "rate":100, "amount": 100},
+			{"item_code": "_Test PPT Item SC B","item_name": "_Test PPT Item SC B",  
+				"bom_no":"BOM-_Test PPT Item SC B-001", "doctype":"BOM Item", "qty":2,  
+				"rate":100, "amount": 200}])		
+				
+	bom_master = make_bom("BOM-_Test PPT Item Master-001",{"quantity":1,
+		"item": "_Test PPT Item Master",
+		"is_active": 1,
+		"is_default": 1,
+		"docstatus": 1,
+		"with_operations": 0}, [
+			{"item_code": "_Test PPT Item Sub A","item_name": "_Test PPT Item Sub A",   
+				"bom_no":"BOM-_Test PPT Item Sub A-001", 
+				"doctype":"BOM Item", "qty":2, "rate":100, "amount": 200},
+			{"item_code": "_Test PPT Item Sub B","item_name": "_Test PPT Item Sub B",   
+				"bom_no":"BOM-_Test PPT Item Sub B-001", 
+				"doctype":"BOM Item", "qty":1, "rate":100, "amount": 100},
+			{"item_code": "_Test PPT Item Raw A","item_name": "_Test PPT Item Raw A",  
+				"doctype":"BOM Item", "qty":2, "rate":100,  
+				"amount": 200},
+			{"item_code": "_Test PPT Item SC A","item_name": "_Test PPT Item SC A",   
+				"bom_no":"BOM-_Test PPT Item SC A-001",  
+				"doctype":"BOM Item", "qty":1, "rate":100, "amount": 100}
+			])
+
+
+def make_bom(name, properties=None, items=None):
+	if frappe.db.exists("BOM", name):
+		return frappe.get_doc("BOM", name)
+		
+	bom = frappe.new_doc("BOM")
+	item = frappe.get_doc({
+		"doctype": "BOM",
+		"name": name,
+		"quantity": "1",
+		"with_operations": 0
+	})
+	
+	if properties:
+		bom.update(properties)
+	
+	if items:
+		for item in items:
+			bom.append("items", item)
+	
+
+	bom.insert()
+	bom.submit()
+	
+	return bom
+	
+def clear_material_requests():
+	frappe.db.sql("delete from `tabMaterial Request Item`")
+	frappe.db.sql("delete from `tabMaterial Request`")
+
+
+def run_production_planning_tool(**args):
+	ppt = frappe.new_doc("Production Planning Tool")
+	args = frappe._dict(args)
+	
+	if args.use_multi_level_bom:
+		ppt.use_multi_level_bom = args.use_multi_level_bom
+	else:
+		ppt.use_multi_level_bom = 0
+		
+	if args.only_raw_materials:
+		ppt.only_raw_materials = args.only_raw_materials
+	else:
+		ppt.only_raw_materials = 0
+		
+	if args.include_subcontracted:
+		ppt.include_subcontracted = args.include_subcontracted
+	else:
+		ppt.include_subcontracted = 0
+		
+	if args.warehouse:
+		ppt.purchase_request_for_warehouse = args.warehouse 
+		
+	if args.company:
+		ppt.company = args.company
+	ppt.create_material_requests_for_all_required_qty = 1
+	
+	ppt.append("items",{"item_code": args.item_code, "bom_no": args.bom_no, "planned_qty": args.planned_qty, 
+		"planned_start_date": args.planned_start_date, "warehouse": args.warehouse})
+	
+	return ppt
+
+def create_production_orders(ppt):
+	raise_production_orders(ppt)
+
+def create_material_requests(ppt):
+	ppt.raise_material_requests()
+	
+def get_requested_qty(item_code):
+	total_qty = 0
+	for d in frappe.db.sql("""select item.qty as qty 
+		from `tabMaterial Request` mat_req, `tabMaterial Request Item` item 
+		where item.item_code = %(item_code)s and item.parent = mat_req.name""", {"item_code":item_code}, as_dict=1):
+		total_qty += d.qty
+	return total_qty
+
+def get_requested_types(item_code):
+	types = []
+	for d in frappe.db.sql("""select mat_req.material_request_type as type 
+		from `tabMaterial Request` mat_req, `tabMaterial Request Item` item 
+		where item.item_code = %(item_code)s and item.parent = mat_req.name""", {"item_code":item_code}, as_dict=1):
+		types.append(d.type)
+	return types
+	
\ No newline at end of file
diff --git a/erpnext/manufacturing/doctype/production_planning_tool/test_records.json b/erpnext/manufacturing/doctype/production_planning_tool/test_records.json
new file mode 100644
index 0000000..2e807ef
--- /dev/null
+++ b/erpnext/manufacturing/doctype/production_planning_tool/test_records.json
@@ -0,0 +1,3 @@
+[
+	
+]
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index ef9f4da..e938b7d 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -23,13 +23,15 @@
 execute:frappe.reload_doc('buying', 'doctype', 'supplier') # 2014-01-29
 execute:frappe.reload_doc('accounts', 'doctype', 'asset_category')
 execute:frappe.reload_doc('accounts', 'doctype', 'pricing_rule')
+
+erpnext.patches.v5_2.change_item_selects_to_checks
 execute:frappe.reload_doctype('Item')
+
 erpnext.patches.v4_0.map_charge_to_taxes_and_charges
 execute:frappe.reload_doc('support', 'doctype', 'newsletter') # 2014-01-31
 execute:frappe.reload_doc('hr', 'doctype', 'employee') # 2014-02-03
 execute:frappe.db.sql("update tabPage set module='Core' where name='Setup'")
 
-erpnext.patches.v5_2.change_item_selects_to_checks
 erpnext.patches.v4_0.fields_to_be_renamed
 erpnext.patches.v4_0.rename_sitemap_to_route
 erpnext.patches.v7_0.re_route #2016-06-27
@@ -310,4 +312,5 @@
 erpnext.patches.v7_0.rename_examination_to_assessment
 erpnext.patches.v7_0.set_portal_settings
 erpnext.patches.v7_0.repost_future_gle_for_purchase_invoice
-erpnext.patches.v7_0.fix_duplicate_icons
\ No newline at end of file
+erpnext.patches.v7_0.fix_duplicate_icons
+erpnext.patches.v7_0.move_employee_parent_to_child_in_salary_structure
\ No newline at end of file
diff --git a/erpnext/patches/v7_0/convert_timelog_to_timesheet.py b/erpnext/patches/v7_0/convert_timelog_to_timesheet.py
index d00980f..b802656 100644
--- a/erpnext/patches/v7_0/convert_timelog_to_timesheet.py
+++ b/erpnext/patches/v7_0/convert_timelog_to_timesheet.py
@@ -16,6 +16,7 @@
 		time_sheet = make_timesheet(data.production_order)
 		args = get_timelog_data(data)
 		add_timesheet_detail(time_sheet, args)
+		time_sheet.docstatus = data.docstatus
 		time_sheet.note = data.note
 		time_sheet.company = company
 		
@@ -24,15 +25,6 @@
 		time_sheet.calculate_total_amounts()
 		time_sheet.flags.ignore_validate = True
 		time_sheet.save(ignore_permissions=True)
-		
-		# To ignore validate_mandatory_fields function
-		if data.docstatus == 1:
-			time_sheet.db_set("docstatus", 1)
-			for d in time_sheet.get("time_logs"):
-				d.db_set("docstatus", 1)
-			time_sheet.update_production_order(time_sheet.name)
-			time_sheet.update_task_and_project()
-			
 
 def get_timelog_data(data):
 	return {
diff --git a/erpnext/patches/v7_0/migrate_schools_to_erpnext.py b/erpnext/patches/v7_0/migrate_schools_to_erpnext.py
index 2aa6f04..f64f400 100644
--- a/erpnext/patches/v7_0/migrate_schools_to_erpnext.py
+++ b/erpnext/patches/v7_0/migrate_schools_to_erpnext.py
@@ -9,13 +9,12 @@
 	frappe.reload_doc('website', 'doctype', 'portal_menu_item')
 	frappe.reload_doc('buying', 'doctype', 'request_for_quotation')
 
-	if frappe.db.exists("Module Def", "Academics") \
-			and frappe.db.get_value("Module Def", "Academics", "app_name") == "schools":
+	if 'schools' in frappe.get_installed_apps():
 		frappe.db.sql("""delete from `tabDesktop Icon`""")
 		
 		if not frappe.db.exists('Module Def', 'Schools') and frappe.db.exists('Module Def', 'Academics'):
 			frappe.rename_doc("Module Def", "Academics", "Schools")
-
+			
 		remove_from_installed_apps("schools")
 
 def reload_doctypes_for_schools_icons():
diff --git a/erpnext/patches/v7_0/move_employee_parent_to_child_in_salary_structure.py b/erpnext/patches/v7_0/move_employee_parent_to_child_in_salary_structure.py
new file mode 100644
index 0000000..509c0a8
--- /dev/null
+++ b/erpnext/patches/v7_0/move_employee_parent_to_child_in_salary_structure.py
@@ -0,0 +1,11 @@
+import frappe
+
+def execute():
+	frappe.reload_doc('hr', 'doctype', 'salary_structure')
+	frappe.reload_doc('hr', 'doctype', 'salary_structure_employee')
+	for ss in frappe.db.sql(""" select employee, name from `tabSalary Structure`""", as_dict=True):
+		ss_doc = frappe.get_doc('Salary Structure', ss.name)
+		se = ss_doc.append('employees',{})
+		se.employee = ss.employee
+		se.base = 0
+		ss_doc.save()
diff --git a/erpnext/projects/doctype/timesheet/test_timesheet.py b/erpnext/projects/doctype/timesheet/test_timesheet.py
index 300933a..e443435 100644
--- a/erpnext/projects/doctype/timesheet/test_timesheet.py
+++ b/erpnext/projects/doctype/timesheet/test_timesheet.py
@@ -27,7 +27,7 @@
 
 		self.assertEquals(salary_slip.total_working_hours, 2)
 		self.assertEquals(salary_slip.hour_rate, 50)
-		self.assertEquals(salary_slip.net_pay, 150)
+		self.assertEquals(salary_slip.net_pay, 50)
 		self.assertEquals(salary_slip.timesheets[0].time_sheet, timesheet.name)
 		self.assertEquals(salary_slip.timesheets[0].working_hours, 2)
 		
@@ -54,35 +54,42 @@
 		timesheet = frappe.get_doc('Timesheet', timesheet.name)
 		self.assertEquals(sales_invoice.total_billing_amount, 100)
 		self.assertEquals(timesheet.status, 'Billed')
+				
 
 def make_salary_structure(employee):
-	name = frappe.db.get_value('Salary Structure', {'employee': employee, 'salary_slip_based_on_timesheet': 1}, 'name')
+	name = frappe.db.get_value('Salary Structure Employee', {'employee': employee}, 'parent')
 	if name:
 		salary_structure = frappe.get_doc('Salary Structure', name)
 	else:
 		salary_structure = frappe.new_doc("Salary Structure")
+		salary_structure.name = "Timesheet Salary Structure Test"
+		salary_structure.salary_slip_based_on_timesheet = 1
+		salary_structure.from_date = nowdate()
+		salary_structure.salary_component = "Basic"
+		salary_structure.hour_rate = 50.0
+		salary_structure.company= "_Test Company"
 
-	salary_structure.salary_slip_based_on_timesheet = 1
-	salary_structure.employee = employee
-	salary_structure.from_date = nowdate()
-	salary_structure.salary_component = "Basic"
-	salary_structure.hour_rate = 50.0
-	salary_structure.company= "_Test Company"
+		salary_structure.set('employees', [])
+		salary_structure.set('earnings', [])
+		salary_structure.set('deductions', [])
 
-	salary_structure.set('earnings', [])
-	salary_structure.set('deductions', [])
+		es = salary_structure.append('employees', {
+			"employee": employee,
+			"base": 1200 
+		})
+		
+		
+		es = salary_structure.append('earnings', {
+			"salary_component": "_Test Allowance",
+			"amount": 100 
+		})
 
-	es = salary_structure.append('earnings', {
-		"salary_component": "_Test Allowance",
-		"amount": 100 
-	})
+		ds = salary_structure.append('deductions', {
+			"salary_component": "_Test Professional Tax",
+			"amount": 50
+		})
 
-	ds = salary_structure.append('deductions', {
-		"salary_component": "_Test Professional Tax",
-		"amount": 50
-	})
-
-	salary_structure.save(ignore_permissions=True)
+		salary_structure.save(ignore_permissions=True)
 
 	return salary_structure
 
diff --git a/erpnext/public/build.json b/erpnext/public/build.json
index 340ebdb..ac1c7c3 100644
--- a/erpnext/public/build.json
+++ b/erpnext/public/build.json
@@ -26,7 +26,8 @@
 		"public/js/payment/pos_payment.html",
 		"public/js/payment/payment_details.html",
 		"public/js/templates/item_selector.html",
-		"public/js/utils/item_selector.js"
+		"public/js/utils/item_selector.js",
+		"public/js/help_links.js"
 	],
 	"js/item-dashboard.min.js": [
 		"stock/dashboard/item_dashboard.html",
diff --git a/erpnext/public/js/conf.js b/erpnext/public/js/conf.js
index 233bd2e..d17bba8 100644
--- a/erpnext/public/js/conf.js
+++ b/erpnext/public/js/conf.js
@@ -16,8 +16,25 @@
 
 	$('[data-link="docs"]').attr("href", "https://manual.erpnext.com")
 	$('[data-link="issues"]').attr("href", "https://github.com/frappe/erpnext/issues")
+
+
+	// default documentation goes to erpnext
+	$('[data-link-type="documentation"]').attr('data-path', 'user/manual/index');
+
+	// additional help links for erpnext
+	var $help_menu = $('.dropdown-help ul .documentation-links');
+
+	$('<li><a data-link-type="forum" href="https://discuss.erpnext.com" \
+		target="_blank">'+__('User Forum')+'</a></li>').insertBefore($help_menu);
+	$('<li><a href="https://gitter.im/frappe/erpnext" \
+		target="_blank">'+__('Chat')+'</a></li>').insertBefore($help_menu);
+	$('<li><a href="https://github.com/frappe/erpnext/issues" \
+		target="_blank">'+__('Report an Issue')+'</a></li>').insertBefore($help_menu);
+
 });
 
+
+
 // doctypes created via tree
 $.extend(frappe.create_routes, {
 	"Customer Group": "Tree/Customer Group",
diff --git a/erpnext/public/js/financial_statements.js b/erpnext/public/js/financial_statements.js
index c1e53a2..4127e6e 100644
--- a/erpnext/public/js/financial_statements.js
+++ b/erpnext/public/js/financial_statements.js
@@ -1,37 +1,7 @@
 frappe.provide("erpnext.financial_statements");
 
 erpnext.financial_statements = {
-	"filters": [
-		{
-			"fieldname":"company",
-			"label": __("Company"),
-			"fieldtype": "Link",
-			"options": "Company",
-			"default": frappe.defaults.get_user_default("Company"),
-			"reqd": 1
-		},
-		{
-			"fieldname":"fiscal_year",
-			"label": __("Fiscal Year"),
-			"fieldtype": "Link",
-			"options": "Fiscal Year",
-			"default": frappe.defaults.get_user_default("fiscal_year"),
-			"reqd": 1
-		},
-		{
-			"fieldname": "periodicity",
-			"label": __("Periodicity"),
-			"fieldtype": "Select",
-			"options": [
-				{ "value": "Monthly", "label": __("Monthly") },
-				{ "value": "Quarterly", "label": __("Quarterly") },
-				{ "value": "Half-Yearly", "label": __("Half-Yearly") },
-				{ "value": "Yearly", "label": __("Yearly") }
-			],
-			"default": "Monthly",
-			"reqd": 1
-		}
-	],
+	"filters": get_filters(),
 	"formatter": function(row, cell, value, columnDef, dataContext, default_formatter) {
 		if (columnDef.df.fieldname=="account") {
 			value = dataContext.account_name;
@@ -71,6 +41,8 @@
 	"initial_depth": 3,
 	onload: function(report) {
 		// dropdown for links to other financial statements
+		erpnext.financial_statements.filters = get_filters()
+
 		report.page.add_inner_button(__("Balance Sheet"), function() {
 			var filters = report.get_values();
 			frappe.set_route('query-report', 'Balance Sheet', {company: filters.company});
@@ -85,3 +57,45 @@
 		}, 'Financial Statements');
 	}
 };
+
+function get_filters(){
+	return [
+		{
+			"fieldname":"company",
+			"label": __("Company"),
+			"fieldtype": "Link",
+			"options": "Company",
+			"default": frappe.defaults.get_user_default("Company"),
+			"reqd": 1
+		},
+		{
+			"fieldname":"from_fiscal_year",
+			"label": __("Start Year"),
+			"fieldtype": "Link",
+			"options": "Fiscal Year",
+			"default": frappe.defaults.get_user_default("fiscal_year"),
+			"reqd": 1
+		},
+		{
+			"fieldname":"to_fiscal_year",
+			"label": __("End Year"),
+			"fieldtype": "Link",
+			"options": "Fiscal Year",
+			"default": frappe.defaults.get_user_default("fiscal_year"),
+			"reqd": 1
+		},
+		{
+			"fieldname": "periodicity",
+			"label": __("Periodicity"),
+			"fieldtype": "Select",
+			"options": [
+				{ "value": "Monthly", "label": __("Monthly") },
+				{ "value": "Quarterly", "label": __("Quarterly") },
+				{ "value": "Half-Yearly", "label": __("Half-Yearly") },
+				{ "value": "Yearly", "label": __("Yearly") }
+			],
+			"default": "Monthly",
+			"reqd": 1
+		}
+	]
+}
diff --git a/erpnext/public/js/help_links.js b/erpnext/public/js/help_links.js
new file mode 100644
index 0000000..3595d77
--- /dev/null
+++ b/erpnext/public/js/help_links.js
@@ -0,0 +1,162 @@
+frappe.provide('frappe.help.help_links');
+
+frappe.help.help_links['Form/Rename Tool'] = [
+	{ label: 'Bulk Rename', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/data/bulk-rename.html' },
+]
+
+frappe.help.help_links['List/Customer'] = [
+	{ label: 'Customer', url: 'https://frappe.github.io/erpnext/user/manual/en/CRM/customer.html' },
+]
+
+frappe.help.help_links['Form/Naming Series'] = [
+	{ label: 'Naming Series', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/settings/naming-series' },
+	{ label: 'Setting the Current Value for Naming Series', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/articles/naming-series-current-value' },
+]
+
+frappe.help.help_links['Form/Global Defaults'] = [
+	{ label: 'Global Settings', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/settings/global-defaults' },
+]
+
+frappe.help.help_links['Form/Email Digest'] = [
+	{ label: 'Email Digest', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/email/email-digest' },
+]
+
+frappe.help.help_links['List/Print Heading'] = [
+	{ label: 'Print Heading', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/print/print-headings' },
+]
+
+frappe.help.help_links['List/Letter Head'] = [
+	{ label: 'Letter Head', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/print/letter-head' },
+]
+
+frappe.help.help_links['List/Address Template'] = [
+	{ label: 'Address Template', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/print/address-template' },
+]
+
+frappe.help.help_links['List/Terms and Conditions'] = [
+	{ label: 'Terms and Conditions', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/print/terms-and-conditions' },
+]
+
+frappe.help.help_links['List/Cheque Print Template'] = [
+	{ label: 'Cheque Print Template', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/print/cheque-print-template' },
+]
+
+frappe.help.help_links['List/Sales Taxes and Charges Template'] = [
+	{ label: 'Setting Up Taxes', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/setting-up-taxes' },
+]
+
+frappe.help.help_links['List/Purchase Taxes and Charges Template'] = [
+	{ label: 'Setting Up Taxes', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/setting-up-taxes' },
+]
+
+frappe.help.help_links['List/POS Profile'] = [
+	{ label: 'POS Profile', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/pos-setting' },
+]
+
+frappe.help.help_links['List/Price List'] = [
+	{ label: 'Price List', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/price-lists' },
+]
+
+frappe.help.help_links['List/Authorization Rule'] = [
+	{ label: 'Authorization Rule', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/authorization-rule' },
+]
+
+frappe.help.help_links['Form/SMS Settings'] = [
+	{ label: 'SMS Settings', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/sms-setting' },
+]
+
+frappe.help.help_links['List/Stock Reconciliation'] = [
+	{ label: 'Stock Reconciliation', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/stock-reconciliation-for-non-serialized-item' },
+]
+
+frappe.help.help_links['Tree/Territory'] = [
+	{ label: 'Territory', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/territory' },
+]
+
+frappe.help.help_links['Form/Dropbox Backup'] = [
+	{ label: 'Dropbox Backup', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/third-party-backups' },
+	{ label: 'Setting Up Dropbox Backup', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/articles/setting-up-dropbox-backups' },
+]
+
+frappe.help.help_links['List/Workflow'] = [
+	{ label: 'Workflow', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/workflows' },
+]
+
+frappe.help.help_links['List/Company'] = [
+	{ label: 'Company', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/company-setup' },
+	{ label: 'Managing Multiple Companies', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/articles/managing-multiple-companies' },
+	{ label: 'Delete All Related Transactions for a Company', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/articles/delete-a-company-and-all-related-transactions' },
+]
+
+frappe.help.help_links['permission-manager'] = [
+	{ label: 'Role Permissions Manager', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/users-and-permissions/role-based-permissions' },
+	{ label: 'Managing Perm Level in Permissions Manager', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/articles/managing-perm-level' },
+]
+
+frappe.help.help_links['data-import-tool'] = [
+	{ label: 'Importing and Exporting Data', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/data/data-import-tool.html' },
+	{ label: 'Overwriting Data from Data Import Tool', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/articles/overwriting-data-from-data-import-tool' },
+]
+
+//Accounts
+
+frappe.help.help_links['modules/Accounts'] = [
+	{ label: 'Introduction to Accounts', url: 'http://frappe.github.io/erpnext/user/manual/en/accounts/' },
+	{ label: 'Chart of Accounts', url: 'https://frappe.github.io/erpnext/user/manual/en/accounts/chart-of-accounts.html' },
+	{ label: 'Multi Currency Accounting', url: 'https://frappe.github.io/erpnext/user/manual/en/accounts/multi-currency-accounting' },
+]
+
+frappe.help.help_links['Tree/Account'] = [
+	{ label: 'Chart of Accounts', url: 'https://frappe.github.io/erpnext/user/manual/en/accounts/chart-of-accounts' },
+]
+
+frappe.help.help_links['List/Sales Invoice'] = [
+	{ label: 'Sales Invoice', url: 'https://frappe.github.io/erpnext/user/manual/en/accounts/sales-invoice' },
+]
+
+frappe.help.help_links['pos'] = [
+	{ label: 'Point of Sale Invoice', url: 'https://frappe.github.io/erpnext/user/manual/en/accounts/point-of-sale-pos-invoice' },
+]
+
+frappe.help.help_links['List/Purchase Invoice'] = [
+	{ label: 'Purchase Invoice', url: 'https://frappe.github.io/erpnext/user/manual/en/accounts/purchase-invoice' },
+]
+
+frappe.help.help_links['List/Journal Entry'] = [
+	{ label: 'Journal Entry', url: 'https://frappe.github.io/erpnext/user/manual/en/accounts/journal-entry' },
+	{ label: 'Advance Payment Entry', url: 'https://frappe.github.io/erpnext/user/manual/en/accounts/advance-payment-entry' },
+]
+
+frappe.help.help_links['List/Payment Entry'] = [
+	{ label: 'Payment Entry', url: 'https://frappe.github.io/erpnext/user/manual/en/accounts/payment-entry' },
+]
+
+frappe.help.help_links['List/Payment Request'] = [
+	{ label: 'Payment Request', url: 'https://frappe.github.io/erpnext/user/manual/en/accounts/payment-request' },
+]
+
+frappe.help.help_links['List/Asset'] = [
+	{ label: 'Managing Fixed Assets', url: 'https://frappe.github.io/erpnext/user/manual/en/accounts/managing-fixed-assets' },
+]
+
+frappe.help.help_links['Tree/Cost Center'] = [
+	{ label: 'Budgeting', url: 'https://frappe.github.io/erpnext/user/manual/en/accounts/budgeting' },
+]
+
+frappe.help.help_links['List/Item'] = [
+	{ label: 'Barcode', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/bar-code' },
+	{ label: 'Item Wise Taxation', url: 'https://frappe.github.io/erpnext/user/manual/en/accounts/item-wise-taxation' },
+]
+
+frappe.help.help_links['List/Purchase Receipt'] = [
+	{ label: 'Barcode', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/bar-code' },
+]
+
+frappe.help.help_links['List/Delivery Note'] = [
+	{ label: 'Barcode', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/bar-code' },
+]
+
+frappe.help.help_links['Tree'] = [
+	{ label: 'Managing Tree Structure Masters', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/articles/managing-tree-structure-masters' },
+]
+