Merge pull request #6126 from rohitwaghchaure/multiyear_financial_statements

[Enhancement] Multi year financial statements
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/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
index e751841..af95a11 100644
--- a/erpnext/docs/assets/img/human-resources/condition-amount.png
+++ 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
index 1413a1b..918d21c 100644
--- a/erpnext/docs/assets/img/human-resources/condition-formula.png
+++ b/erpnext/docs/assets/img/human-resources/condition-formula.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/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/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.py b/erpnext/hr/doctype/salary_component/salary_component.py
index 20a5e85..ca69568 100644
--- a/erpnext/hr/doctype/salary_component/salary_component.py
+++ b/erpnext/hr/doctype/salary_component/salary_component.py
@@ -5,6 +5,7 @@
 from __future__ import unicode_literals
 import frappe
 from frappe.model.document import Document
+from frappe import _
 
 class SalaryComponent(Document):
 	def validate(self):
diff --git a/erpnext/hr/doctype/salary_detail/salary_detail.json b/erpnext/hr/doctype/salary_detail/salary_detail.json
index 44e8d9e..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", 
@@ -336,7 +336,7 @@
  "issingle": 0, 
  "istable": 1, 
  "max_attachments": 0, 
- "modified": "2016-08-18 13:01:37.617174", 
+ "modified": "2016-08-22 00:25:44.331685",
  "modified_by": "Administrator", 
  "module": "HR", 
  "name": "Salary Detail", 
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/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/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' },
+]
+