Merge pull request #7175 from neilLasrado/develop

Student Attendance Tool
diff --git a/erpnext/__init__.py b/erpnext/__init__.py
index 2d1a24d..97ab934 100644
--- a/erpnext/__init__.py
+++ b/erpnext/__init__.py
@@ -2,7 +2,7 @@
 from __future__ import unicode_literals
 import frappe
 
-__version__ = '7.1.21'
+__version__ = '7.1.23'
 
 def get_default_company(user=None):
 	'''Get default company for user'''
diff --git a/erpnext/accounts/doctype/account/account_tree.js b/erpnext/accounts/doctype/account/account_tree.js
index fc6a1b4..8c7925a 100644
--- a/erpnext/accounts/doctype/account/account_tree.js
+++ b/erpnext/accounts/doctype/account/account_tree.js
@@ -30,8 +30,8 @@
 			options: ['Asset', 'Liability', 'Equity', 'Income', 'Expense'].join('\n'),
 			depends_on: 'eval:doc.is_group && !doc.parent_account'},
 		{fieldtype:'Select', fieldname:'account_type', label:__('Account Type'),
-			options: ['', 'Accumulated Depreciation', 'Bank', 'Cash', 'Chargeable', 'Cost of Goods Sold', 'Depreciation', 
-				'Equity', 'Expense Account', 'Expenses Included In Valuation', 'Fixed Asset', 'Income Account', 'Payable', 'Receivable', 
+			options: ['', 'Accumulated Depreciation', 'Bank', 'Cash', 'Chargeable', 'Cost of Goods Sold', 'Depreciation',
+				'Equity', 'Expense Account', 'Expenses Included In Valuation', 'Fixed Asset', 'Income Account', 'Payable', 'Receivable',
 				'Round Off', 'Stock', 'Stock Adjustment', 'Stock Received But Not Billed', 'Tax', 'Temporary'].join('\n'),
 			description: __("Optional. This setting will be used to filter in various transactions.")
 		},
diff --git a/erpnext/accounts/doctype/budget/budget.js b/erpnext/accounts/doctype/budget/budget.js
index f6a2c88..40e929a 100644
--- a/erpnext/accounts/doctype/budget/budget.js
+++ b/erpnext/accounts/doctype/budget/budget.js
@@ -10,6 +10,14 @@
 				}
 			}
 		})
+
+		frm.set_query("project", function() {
+			return {
+				filters: {
+					company: frm.doc.company
+				}
+			}
+		})
 		
 		frm.set_query("account", "accounts", function() {
 			return {
diff --git a/erpnext/accounts/doctype/budget/budget.json b/erpnext/accounts/doctype/budget/budget.json
index d88f374..d081364 100644
--- a/erpnext/accounts/doctype/budget/budget.json
+++ b/erpnext/accounts/doctype/budget/budget.json
@@ -15,47 +15,19 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
-   "fieldname": "cost_center", 
-   "fieldtype": "Link", 
+   "default": "Cost Center", 
+   "fieldname": "budget_against", 
+   "fieldtype": "Select", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
    "in_standard_filter": 1, 
-   "label": "Cost Center", 
+   "label": "Budget Against", 
    "length": 0, 
    "no_copy": 0, 
-   "options": "Cost Center", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 1, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0
-  }, 
-  {
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "fiscal_year", 
-   "fieldtype": "Link", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Fiscal Year", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Fiscal Year", 
+   "options": "\nCost Center\nProject", 
    "permlevel": 0, 
    "precision": "", 
    "print_hide": 0, 
@@ -90,7 +62,96 @@
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
-   "remember_last_selected_value": 1, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 1, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "depends_on": "eval:doc.budget_against == 'Cost Center'", 
+   "fieldname": "cost_center", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 1, 
+   "label": "Cost Center", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Cost Center", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "depends_on": "eval:doc.budget_against == 'Project'", 
+   "fieldname": "project", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 1, 
+   "label": "Project", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Project", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "fiscal_year", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Fiscal Year", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Fiscal Year", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
    "report_hide": 0, 
    "reqd": 1, 
    "search_index": 0, 
@@ -310,7 +371,7 @@
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2016-11-07 05:50:57.064961", 
+ "modified": "2016-11-30 08:51:10.453935", 
  "modified_by": "Administrator", 
  "module": "Accounts", 
  "name": "Budget", 
diff --git a/erpnext/accounts/doctype/budget/budget.py b/erpnext/accounts/doctype/budget/budget.py
index 2488dd6..5fc4fbf 100644
--- a/erpnext/accounts/doctype/budget/budget.py
+++ b/erpnext/accounts/doctype/budget/budget.py
@@ -1,4 +1,4 @@
-# -*- coding: utf-8 -*-
+ # -*- coding: utf-8 -*-
 # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors
 # For license information, please see license.txt
 
@@ -14,20 +14,25 @@
 
 class Budget(Document):
 	def autoname(self):
-		self.name = make_autoname(self.cost_center + "/" + self.fiscal_year + "/.###")
+		self.name = make_autoname(self.get(frappe.scrub(self.budget_against)) 
+			+ "/" + self.fiscal_year + "/.###")
 
 	def validate(self):
+		if not self.get(frappe.scrub(self.budget_against)):
+			frappe.throw(_("{0} is mandatory").format(self.budget_against))
 		self.validate_duplicate()
 		self.validate_accounts()
 
 	def validate_duplicate(self):
-		existing_budget = frappe.db.get_value("Budget", {"cost_center": self.cost_center,
+		budget_against_field = frappe.scrub(self.budget_against)
+		budget_against = self.get(budget_against_field)
+		existing_budget = frappe.db.get_value("Budget", {budget_against_field: budget_against,
 			"fiscal_year": self.fiscal_year, "company": self.company,
 			"name": ["!=", self.name], "docstatus": ["!=", 2]})
-		if existing_budget:
-			frappe.throw(_("Another Budget record {0} already exists against {1} for fiscal year {2}")
-				.format(existing_budget, self.cost_center, self.fiscal_year), DuplicateBudgetError)
-
+		if existing_budget: 
+			frappe.throw(_("Another Budget record '{0}' already exists against {1} '{2}' for fiscal year {3}")
+				.format(existing_budget, self.budget_against, budget_against, self.fiscal_year), DuplicateBudgetError)
+	
 	def validate_accounts(self):
 		account_list = []
 		for d in self.get('accounts'):
@@ -51,56 +56,104 @@
 
 def validate_expense_against_budget(args):
 	args = frappe._dict(args)
-	if not args.cost_center:
+	if not args.cost_center and not args.project:
 		return
-		
-	if frappe.db.get_value("Account", {"name": args.account, "root_type": "Expense"}):
-		cc_lft, cc_rgt = frappe.db.get_value("Cost Center", args.cost_center, ["lft", "rgt"])
+	for budget_against in [args.project, args.cost_center]:
+		if budget_against \
+				and frappe.db.get_value("Account", {"name": args.account, "root_type": "Expense"}):
 
-		budget_records = frappe.db.sql("""
-			select ba.budget_amount, b.monthly_distribution, b.cost_center,
-				b.action_if_annual_budget_exceeded, b.action_if_accumulated_monthly_budget_exceeded
-			from `tabBudget` b, `tabBudget Account` ba
-			where
-				b.name=ba.parent and b.fiscal_year=%s and ba.account=%s and b.docstatus=1
-				and exists(select name from `tabCost Center` where lft<=%s and rgt>=%s and name=b.cost_center)
-		""", (args.fiscal_year, args.account, cc_lft, cc_rgt), as_dict=True)
+			if args.project:
+				condition = "and exists(select name from `tabProject` where name=b.project)"
+				args.budget_against_field = "Project"
+			
+			elif args.cost_center:
+				cc_lft, cc_rgt = frappe.db.get_value("Cost Center", args.cost_center, ["lft", "rgt"])
+				condition = """and exists(select name from `tabCost Center` 
+					where lft<=%s and rgt>=%s and name=b.cost_center)""" % (cc_lft, cc_rgt)
+				args.budget_against_field = "Cost Center"
+			
+			args.budget_against = budget_against
 
-		for budget in budget_records:
-			if budget.budget_amount:
-				yearly_action = budget.action_if_annual_budget_exceeded
-				monthly_action = budget.action_if_accumulated_monthly_budget_exceeded
+			budget_records = frappe.db.sql("""
+				select
+					b.{budget_against_field}, ba.budget_amount, b.monthly_distribution,
+					b.action_if_annual_budget_exceeded, 
+					b.action_if_accumulated_monthly_budget_exceeded
+				from 
+					`tabBudget` b, `tabBudget Account` ba
+				where
+					b.name=ba.parent and b.fiscal_year=%s 
+					and ba.account=%s and b.docstatus=1
+					{condition}
+			""".format(condition=condition, 
+				budget_against_field=frappe.scrub(args.get("budget_against_field"))),
+				(args.fiscal_year, args.account), as_dict=True)
 
-				if monthly_action in ["Stop", "Warn"]:
-					budget_amount = get_accumulated_monthly_budget(budget.monthly_distribution,
-						args.posting_date, args.fiscal_year, budget.budget_amount)
+			validate_budget_records(args, budget_records)
 
-					args["month_end_date"] = get_last_day(args.posting_date)
-						
-					compare_expense_with_budget(args, budget.cost_center,
-						budget_amount, _("Accumulated Monthly"), monthly_action)
+def validate_budget_records(args, budget_records):
+	for budget in budget_records:
+		if budget.budget_amount:
+			yearly_action = budget.action_if_annual_budget_exceeded
+			monthly_action = budget.action_if_accumulated_monthly_budget_exceeded
 
-				if yearly_action in ("Stop", "Warn") and monthly_action != "Stop" \
-					and yearly_action != monthly_action:
-						compare_expense_with_budget(args, budget.cost_center,
-							flt(budget.budget_amount), _("Annual"), yearly_action)
+			if monthly_action in ["Stop", "Warn"]:
+				budget_amount = get_accumulated_monthly_budget(budget.monthly_distribution,
+					args.posting_date, args.fiscal_year, budget.budget_amount)
+				args["month_end_date"] = get_last_day(args.posting_date)
 
-def compare_expense_with_budget(args, cost_center, budget_amount, action_for, action):
-	actual_expense = get_actual_expense(args, cost_center)
+				compare_expense_with_budget(args, budget_amount, 
+					_("Accumulated Monthly"), monthly_action)
+
+			if yearly_action in ("Stop", "Warn") and monthly_action != "Stop" \
+				and yearly_action != monthly_action:
+				compare_expense_with_budget(args, flt(budget.budget_amount), 
+						_("Annual"), yearly_action)
+
+
+def compare_expense_with_budget(args, budget_amount, action_for, action):
+	actual_expense = get_actual_expense(args)
 	if actual_expense > budget_amount:
 		diff = actual_expense - budget_amount
-		currency = frappe.db.get_value('Company', frappe.db.get_value('Cost Center',
-			cost_center, 'company'), 'default_currency')
+		currency = frappe.db.get_value('Company', args.company, 'default_currency')
 
-		msg = _("{0} Budget for Account {1} against Cost Center {2} is {3}. It will exceed by {4}").format(_(action_for),
-			frappe.bold(args.account), frappe.bold(cost_center),
-			frappe.bold(fmt_money(budget_amount, currency=currency)), frappe.bold(fmt_money(diff, currency=currency)))
+		msg = _("{0} Budget for Account {1} against {2} {3} is {4}. It will exceed by {5}").format(
+				_(action_for), frappe.bold(args.account), args.budget_against_field, 
+				frappe.bold(args.budget_against), 
+				frappe.bold(fmt_money(budget_amount, currency=currency)), 
+				frappe.bold(fmt_money(diff, currency=currency)))
 
 		if action=="Stop":
 			frappe.throw(msg, BudgetError)
 		else:
 			frappe.msgprint(msg, indicator='orange')
 
+
+def get_actual_expense(args):
+	condition1 = " and gle.posting_date <= %(month_end_date)s" \
+		if args.get("month_end_date") else ""
+	if args.budget_against_field == "Cost Center":
+		lft_rgt = frappe.db.get_value(args.budget_against_field, 
+			args.budget_against, ["lft", "rgt"], as_dict=1)
+		args.update(lft_rgt)
+		condition2 = """and exists(select name from `tabCost Center` 
+			where lft>=%(lft)s and rgt<=%(rgt)s and name=gle.cost_center)"""
+	
+	elif args.budget_against_field == "Project":
+		condition2 = "and exists(select name from `tabProject` where name=gle.project)"
+
+	return flt(frappe.db.sql("""
+		select sum(gle.debit) - sum(gle.credit)
+		from `tabGL Entry` gle
+		where gle.account=%(account)s
+			{condition1}
+			and gle.fiscal_year=%(fiscal_year)s
+			and gle.company=%(company)s
+			and gle.docstatus=1
+			{condition2}
+	""".format(condition1=condition1, condition2=condition2), (args))[0][0])
+
+
 def get_accumulated_monthly_budget(monthly_distribution, posting_date, fiscal_year, annual_budget):
 	distribution = {}
 	if monthly_distribution:
@@ -121,21 +174,3 @@
 		dt = add_months(dt, 1)
 
 	return annual_budget * accumulated_percentage / 100
-
-def get_actual_expense(args, cost_center):
-	lft_rgt = frappe.db.get_value("Cost Center", cost_center, ["lft", "rgt"], as_dict=1)
-	args.update(lft_rgt)
-
-	condition = " and gle.posting_date <= %(month_end_date)s" if args.get("month_end_date") else ""
-
-	return flt(frappe.db.sql("""
-		select sum(gle.debit) - sum(gle.credit)
-		from `tabGL Entry` gle
-		where gle.account=%(account)s
-			and exists(select name from `tabCost Center`
-				where lft>=%(lft)s and rgt<=%(rgt)s and name=gle.cost_center)
-			and gle.fiscal_year=%(fiscal_year)s
-			and gle.company=%(company)s
-			and gle.docstatus=1
-			{condition}
-	""".format(condition=condition), (args))[0][0])
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/budget/test_budget.py b/erpnext/accounts/doctype/budget/test_budget.py
index ef6a1c8..15895dc 100644
--- a/erpnext/accounts/doctype/budget/test_budget.py
+++ b/erpnext/accounts/doctype/budget/test_budget.py
@@ -10,9 +10,9 @@
 
 class TestBudget(unittest.TestCase):		
 	def test_monthly_budget_crossed_ignore(self):
-		set_total_expense_zero("2013-02-28")
+		set_total_expense_zero("2013-02-28", "Cost Center")
 
-		budget = make_budget()
+		budget = make_budget("Cost Center")
 		
 		jv = make_journal_entry("_Test Account Cost for Goods Sold - _TC",
 			"_Test Bank - _TC", 40000, "_Test Cost Center - _TC", submit=True)
@@ -22,10 +22,10 @@
 			
 		budget.cancel()
 
-	def test_monthly_budget_crossed_stop(self):
-		set_total_expense_zero("2013-02-28")
+	def test_monthly_budget_crossed_stop1(self):
+		set_total_expense_zero("2013-02-28", "Cost Center")
 
-		budget = make_budget()
+		budget = make_budget("Cost Center")
 		
 		frappe.db.set_value("Budget", budget.name, "action_if_accumulated_monthly_budget_exceeded", "Stop")
 
@@ -37,10 +37,25 @@
 		budget.load_from_db()
 		budget.cancel()
 
-	def test_yearly_budget_crossed_stop(self):
-		set_total_expense_zero("2013-02-28")
+	def test_monthly_budget_crossed_stop2(self):
+		set_total_expense_zero("2013-02-28", "Project")
 
-		budget = make_budget()
+		budget = make_budget("Project")
+		
+		frappe.db.set_value("Budget", budget.name, "action_if_accumulated_monthly_budget_exceeded", "Stop")
+
+		jv = make_journal_entry("_Test Account Cost for Goods Sold - _TC",
+			"_Test Bank - _TC", 40000, "_Test Cost Center - _TC", project="_Test Project")
+
+		self.assertRaises(BudgetError, jv.submit)
+		
+		budget.load_from_db()
+		budget.cancel()
+
+	def test_yearly_budget_crossed_stop1(self):
+		set_total_expense_zero("2013-02-28", "Cost Center")
+
+		budget = make_budget("Cost Center")
 		
 		jv = make_journal_entry("_Test Account Cost for Goods Sold - _TC",
 			"_Test Bank - _TC", 150000, "_Test Cost Center - _TC")
@@ -49,10 +64,22 @@
 		
 		budget.cancel()
 
-	def test_monthly_budget_on_cancellation(self):
-		set_total_expense_zero("2013-02-28")
+	def test_yearly_budget_crossed_stop2(self):
+		set_total_expense_zero("2013-02-28", "Project")
 
-		budget = make_budget()
+		budget = make_budget("Project")
+		
+		jv = make_journal_entry("_Test Account Cost for Goods Sold - _TC",
+			"_Test Bank - _TC", 150000, "_Test Cost Center - _TC", project="_Test Project")
+
+		self.assertRaises(BudgetError, jv.submit)
+		
+		budget.cancel()
+
+	def test_monthly_budget_on_cancellation1(self):
+		set_total_expense_zero("2013-02-28", "Cost Center")
+
+		budget = make_budget("Cost Center")
 				
 		jv1 = make_journal_entry("_Test Account Cost for Goods Sold - _TC",
 			"_Test Bank - _TC", 20000, "_Test Cost Center - _TC", submit=True)
@@ -72,12 +99,37 @@
 		
 		budget.load_from_db()
 		budget.cancel()
+
+	def test_monthly_budget_on_cancellation2(self):
+		set_total_expense_zero("2013-02-28", "Project")
+
+		budget = make_budget("Project")
+				
+		jv1 = make_journal_entry("_Test Account Cost for Goods Sold - _TC",
+			"_Test Bank - _TC", 20000, "_Test Cost Center - _TC", submit=True, project="_Test Project")
+
+		self.assertTrue(frappe.db.get_value("GL Entry",
+			{"voucher_type": "Journal Entry", "voucher_no": jv1.name}))
+
+		jv2 = make_journal_entry("_Test Account Cost for Goods Sold - _TC",
+			"_Test Bank - _TC", 20000, "_Test Cost Center - _TC", submit=True, project="_Test Project")
+
+		self.assertTrue(frappe.db.get_value("GL Entry",
+			{"voucher_type": "Journal Entry", "voucher_no": jv2.name}))
+
+		frappe.db.set_value("Budget", budget.name, "action_if_accumulated_monthly_budget_exceeded", "Stop")
+		
+		self.assertRaises(BudgetError, jv1.cancel)
+		
+		budget.load_from_db()
+		budget.cancel()
+
 		
 	def test_monthly_budget_against_group_cost_center(self):
-		set_total_expense_zero("2013-02-28")
-		set_total_expense_zero("2013-02-28", "_Test Cost Center 2 - _TC")
+		set_total_expense_zero("2013-02-28", "Cost Center")
+		set_total_expense_zero("2013-02-28", "Cost Center", "_Test Cost Center 2 - _TC")
 		
-		budget = make_budget("_Test Company - _TC")
+		budget = make_budget("Cost Center", "_Test Company - _TC")
 		frappe.db.set_value("Budget", budget.name, "action_if_accumulated_monthly_budget_exceeded", "Stop")
 
 		jv = make_journal_entry("_Test Account Cost for Goods Sold - _TC",
@@ -88,28 +140,52 @@
 		budget.load_from_db()
 		budget.cancel()
 
-def set_total_expense_zero(posting_date, cost_center=None):
-	existing_expense = get_actual_expense({
+def set_total_expense_zero(posting_date, budget_against_field=None, budget_against_CC=None):
+	if budget_against_field == "Project":
+		budget_against = "_Test Project"
+	else:
+		budget_against = budget_against_CC or "_Test Cost Center - _TC"
+	existing_expense = get_actual_expense(frappe._dict({
 		"account": "_Test Account Cost for Goods Sold - _TC",
-		"cost_center": cost_center or "_Test Cost Center - _TC",
+		"cost_center": "_Test Cost Center - _TC",
 		"monthly_end_date": posting_date,
 		"company": "_Test Company",
-		"fiscal_year": "_Test Fiscal Year 2013"
-	}, cost_center or "_Test Cost Center - _TC")
+		"fiscal_year": "_Test Fiscal Year 2013",
+		"budget_against_field": budget_against_field,
+		"budget_against": budget_against
+	}))
 	
 	if existing_expense:
-		make_journal_entry("_Test Account Cost for Goods Sold - _TC",
+		if budget_against_field == "Cost Center":
+			make_journal_entry("_Test Account Cost for Goods Sold - _TC",
 			"_Test Bank - _TC", -existing_expense, "_Test Cost Center - _TC", submit=True)
+		elif budget_against_field == "Project":
+			make_journal_entry("_Test Account Cost for Goods Sold - _TC",
+			"_Test Bank - _TC", -existing_expense, "_Test Cost Center - _TC", submit=True, project="_Test Project")
 		
-def make_budget(cost_center=None):
+def make_budget(budget_against=None, cost_center=None):
+	if budget_against == "Project":
+		budget_list = frappe.get_all("Budget", fields=["name"], filters = {"name": ("like", "_Test Project/_Test Fiscal Year 2013%")})
+	else:
+		budget_list = frappe.get_all("Budget", fields=["name"], filters = {"name": ("like", "_Test Cost Center - _TC/_Test Fiscal Year 2013%")})
+	for d in budget_list:
+		frappe.db.sql("delete from `tabBudget` where name = %(name)s", d)
+		frappe.db.sql("delete from `tabBudget Account` where parent = %(name)s", d)
+
 	budget = frappe.new_doc("Budget")
-	budget.cost_center = cost_center or "_Test Cost Center - _TC"
+	
+	if budget_against == "Project":
+		budget.project = "_Test Project"
+	else:
+		budget.cost_center =cost_center or "_Test Cost Center - _TC"
+	
+	
 	budget.fiscal_year = "_Test Fiscal Year 2013"
 	budget.monthly_distribution = "_Test Distribution"
 	budget.company = "_Test Company"
 	budget.action_if_annual_budget_exceeded = "Stop"
 	budget.action_if_accumulated_monthly_budget_exceeded = "Ignore"
-	
+	budget.budget_against = budget_against
 	budget.append("accounts", {
 		"account": "_Test Account Cost for Goods Sold - _TC",
 		"budget_amount": 100000
diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.js b/erpnext/accounts/doctype/journal_entry/journal_entry.js
index 06ba5df..c98e77f 100644
--- a/erpnext/accounts/doctype/journal_entry/journal_entry.js
+++ b/erpnext/accounts/doctype/journal_entry/journal_entry.js
@@ -35,6 +35,14 @@
 
 	multi_currency: function(frm) {
 		erpnext.journal_entry.toggle_fields_based_on_currency(frm);
+	},
+	
+	posting_date: function(frm) {
+		if(!frm.doc.multi_currency) return;
+		
+		$.each(frm.doc.accounts || [], function(i, row) {
+			erpnext.journal_entry.set_exchange_rate(frm, row.doctype, row.name);
+		})
 	}
 })
 
@@ -345,7 +353,7 @@
 			});
 		}
 	},
-
+	
 	debit_in_account_currency: function(frm, cdt, cdn) {
 		erpnext.journal_entry.set_exchange_rate(frm, cdt, cdn);
 	},
@@ -420,6 +428,7 @@
 			frappe.call({
 				method: "erpnext.accounts.doctype.journal_entry.journal_entry.get_exchange_rate",
 				args: {
+					posting_date: frm.doc.posting_date,
 					account: row.account,
 					account_currency: row.account_currency,
 					company: frm.doc.company,
diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.py b/erpnext/accounts/doctype/journal_entry/journal_entry.py
index 2f3b101..cd79363 100644
--- a/erpnext/accounts/doctype/journal_entry/journal_entry.py
+++ b/erpnext/accounts/doctype/journal_entry/journal_entry.py
@@ -326,8 +326,9 @@
 			if d.account_currency == self.company_currency:
 				d.exchange_rate = 1
 			elif not d.exchange_rate or d.exchange_rate == 1 or \
-				(d.reference_type in ("Sales Invoice", "Purchase Invoice") and d.reference_name):
-					d.exchange_rate = get_exchange_rate(d.account, d.account_currency, self.company,
+				(d.reference_type in ("Sales Invoice", "Purchase Invoice") and d.reference_name and d.posting_date):
+					# Modified to include the posting date for which to retreive the exchange rate
+					d.exchange_rate = get_exchange_rate(self.posting_date, d.account, d.account_currency, self.company,
 						d.reference_type, d.reference_name, d.debit, d.credit, d.exchange_rate)
 
 			if not d.exchange_rate:
@@ -648,7 +649,9 @@
 	cost_center = frappe.db.get_value("Company", ref_doc.company, "cost_center")
 	exchange_rate = 1
 	if args.get("party_account"):
-		exchange_rate = get_exchange_rate(args.get("party_account"), args.get("party_account_currency"),
+		# Modified to include the posting date for which the exchange rate is required. 
+		# Assumed to be the posting date in the reference document
+		exchange_rate = get_exchange_rate(ref_doc.posting_date, args.get("party_account"), args.get("party_account_currency"),
 			ref_doc.company, ref_doc.doctype, ref_doc.name)
 
 	je = frappe.new_doc("Journal Entry")
@@ -681,7 +684,9 @@
 	bank_account = get_default_bank_cash_account(ref_doc.company, "Bank", account=args.get("bank_account"))
 	if bank_account:
 		bank_row.update(bank_account)
-		bank_row.exchange_rate = get_exchange_rate(bank_account["account"],
+		# Modified to include the posting date for which the exchange rate is required. 
+		# Assumed to be the posting date of the reference date
+		bank_row.exchange_rate = get_exchange_rate(ref_doc.posting_date, bank_account["account"],
 			bank_account["account_currency"], ref_doc.company)
 
 	bank_row.cost_center = cost_center
@@ -805,7 +810,10 @@
 		"party_type": party_type,
 		"account_type": account_details.account_type,
 		"account_currency": account_details.account_currency or company_currency,
-		"exchange_rate": get_exchange_rate(account, account_details.account_currency,
+		
+		# The date used to retreive the exchange rate here is the date passed in 
+		# as an argument to this function. It is assumed to be the date on which the balance is sought
+		"exchange_rate": get_exchange_rate(date, account, account_details.account_currency,
 			company, debit=debit, credit=credit, exchange_rate=exchange_rate)
 	}
 
@@ -815,8 +823,9 @@
 
 	return grid_values
 
+# Added posting_date as one of the parameters of get_exchange_rate
 @frappe.whitelist()
-def get_exchange_rate(account, account_currency=None, company=None,
+def get_exchange_rate(posting_date, account, account_currency=None, company=None,
 		reference_type=None, reference_name=None, debit=None, credit=None, exchange_rate=None):
 	from erpnext.setup.utils import get_exchange_rate
 	account_details = frappe.db.get_value("Account", account,
@@ -842,9 +851,10 @@
 				(account_details.root_type == "Liability" and debit)):
 			exchange_rate = get_average_exchange_rate(account)
 
-		if not exchange_rate and account_currency:
-			exchange_rate = get_exchange_rate(account_currency, company_currency)
-
+		# The date used to retreive the exchange rate here is the date passed 
+		# in as an argument to this function.
+		if not exchange_rate and account_currency and posting_date:
+			exchange_rate = get_exchange_rate(account_currency, company_currency, posting_date)
 	else:
 		exchange_rate = 1
 
diff --git a/erpnext/accounts/doctype/journal_entry/test_journal_entry.py b/erpnext/accounts/doctype/journal_entry/test_journal_entry.py
index 4740ad9..b4bb542 100644
--- a/erpnext/accounts/doctype/journal_entry/test_journal_entry.py
+++ b/erpnext/accounts/doctype/journal_entry/test_journal_entry.py
@@ -186,10 +186,10 @@
 		self.assertEqual(len(je.get("accounts")), 2)		
 		
 
-def make_journal_entry(account1, account2, amount, cost_center=None, posting_date=None, exchange_rate=1, save=True, submit=False):
+def make_journal_entry(account1, account2, amount, cost_center=None, posting_date=None, exchange_rate=1, save=True, submit=False, project=None):
 	if not cost_center:
 		cost_center = "_Test Cost Center - _TC"
-	
+
 	jv = frappe.new_doc("Journal Entry")
 	jv.posting_date = posting_date or "2013-02-14"
 	jv.company = "_Test Company"
@@ -199,12 +199,14 @@
 		{
 			"account": account1,
 			"cost_center": cost_center,
+			"project": project,
 			"debit_in_account_currency": amount if amount > 0 else 0,
 			"credit_in_account_currency": abs(amount) if amount < 0 else 0,
 			"exchange_rate": exchange_rate
 		}, {
 			"account": account2,
 			"cost_center": cost_center,
+			"project": project,
 			"credit_in_account_currency": amount if amount > 0 else 0,
 			"debit_in_account_currency": abs(amount) if amount < 0 else 0,
 			"exchange_rate": exchange_rate
diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.js b/erpnext/accounts/doctype/payment_entry/payment_entry.js
index 1f6199e..d3dbd31 100644
--- a/erpnext/accounts/doctype/payment_entry/payment_entry.js
+++ b/erpnext/accounts/doctype/payment_entry/payment_entry.js
@@ -327,6 +327,7 @@
 		frappe.call({
 			method: "erpnext.setup.utils.get_exchange_rate",
 			args: {
+				transaction_date: frm.doc.posting_date,
 				from_currency: from_currency,
 				to_currency: to_currency
 			},
@@ -335,6 +336,10 @@
 			}
 		})
 	},
+	
+	posting_date: function(frm) {
+		frm.events.paid_from_account_currency(frm);
+	},
 
 	source_exchange_rate: function(frm) {
 		if (frm.doc.paid_amount) {
@@ -425,6 +430,7 @@
 			method: 'erpnext.accounts.doctype.payment_entry.payment_entry.get_outstanding_reference_documents',
 			args: {
 				args: {
+					"posting_date": frm.doc.posting_date,
 					"company": frm.doc.company,
 					"party_type": frm.doc.party_type,
 					"payment_type": frm.doc.payment_type,
diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.py b/erpnext/accounts/doctype/payment_entry/payment_entry.py
index d4f8edb..02d2b6b 100644
--- a/erpnext/accounts/doctype/payment_entry/payment_entry.py
+++ b/erpnext/accounts/doctype/payment_entry/payment_entry.py
@@ -153,11 +153,11 @@
 				self.source_exchange_rate = get_average_exchange_rate(self.paid_from)
 			else:
 				self.source_exchange_rate = get_exchange_rate(self.paid_from_account_currency, 
-					self.company_currency)
+					self.company_currency, self.posting_date)
 		
 		if self.paid_to and not self.target_exchange_rate:
 			self.target_exchange_rate = get_exchange_rate(self.paid_to_account_currency, 
-				self.company_currency)
+				self.company_currency, self.posting_date)
 				
 	def validate_mandatory(self):
 		for field in ("paid_amount", "received_amount", "source_exchange_rate", "target_exchange_rate"):
@@ -482,12 +482,12 @@
 				d["exchange_rate"] = frappe.db.get_value(d.voucher_type, d.voucher_no, "conversion_rate")
 
 	# Get all SO / PO which are not fully billed or aginst which full advance not paid
-	orders_to_be_billed =  get_orders_to_be_billed(args.get("party_type"), args.get("party"), 
+	orders_to_be_billed =  get_orders_to_be_billed(args.get("posting_date"),args.get("party_type"), args.get("party"), 
 		party_account_currency, company_currency)
 	
 	return negative_outstanding_invoices + outstanding_invoices + orders_to_be_billed
 	
-def get_orders_to_be_billed(party_type, party, party_account_currency, company_currency):
+def get_orders_to_be_billed(posting_date, party_type, party, party_account_currency, company_currency):
 	voucher_type = 'Sales Order' if party_type == "Customer" else 'Purchase Order'
 
 	ref_field = "base_grand_total" if party_account_currency == company_currency else "grand_total"
@@ -517,7 +517,9 @@
 	order_list = []
 	for d in orders:
 		d["voucher_type"] = voucher_type
-		d["exchange_rate"] = get_exchange_rate(party_account_currency, company_currency)
+		# This assumes that the exchange rate required is the one in the SO
+		d["exchange_rate"] = get_exchange_rate(party_account_currency, 
+			company_currency, posting_date)
 		order_list.append(d)
 
 	return order_list
@@ -592,14 +594,19 @@
 			exchange_rate = 1
 		else:
 			total_amount = ref_doc.grand_total
+			
+			# Get the exchange rate from the original ref doc 
+			# or get it based on the posting date of the ref doc
 			exchange_rate = ref_doc.get("conversion_rate") or \
-				get_exchange_rate(party_account_currency, ref_doc.company_currency)
+				get_exchange_rate(party_account_currency, ref_doc.company_currency, ref_doc.posting_date)
 		
 		outstanding_amount = ref_doc.get("outstanding_amount") \
 			if reference_doctype in ("Sales Invoice", "Purchase Invoice") \
 			else flt(total_amount) - flt(ref_doc.advance_paid)			
 	else:
-		exchange_rate = get_exchange_rate(party_account_currency, ref_doc.company_currency)
+		# Get the exchange rate based on the posting date of the ref doc
+		exchange_rate = get_exchange_rate(party_account_currency, 
+			ref_doc.company_currency, ref_doc.posting_date)
 		
 	return frappe._dict({
 		"due_date": ref_doc.get("due_date"),
@@ -639,7 +646,7 @@
 	if party_amount:
 		grand_total = outstanding_amount = party_amount
 	elif dt in ("Sales Invoice", "Purchase Invoice"):
-		grand_total = doc.grand_total
+		grand_total = doc.base_grand_total if party_account_currency == doc.company_currency else doc.grand_total
 		outstanding_amount = doc.outstanding_amount
 	else:
 		total_field = "base_grand_total" if party_account_currency == doc.company_currency else "grand_total"
diff --git a/erpnext/accounts/doctype/payment_request/test_payment_request.py b/erpnext/accounts/doctype/payment_request/test_payment_request.py
index 73c412f..bf3e24f 100644
--- a/erpnext/accounts/doctype/payment_request/test_payment_request.py
+++ b/erpnext/accounts/doctype/payment_request/test_payment_request.py
@@ -9,7 +9,6 @@
 from erpnext.accounts.doctype.payment_request.payment_request import make_payment_request
 from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
 from erpnext.setup.utils import get_exchange_rate
-# test_records = frappe.get_test_records('Payment Request')
 
 test_dependencies = ["Currency Exchange", "Journal Entry", "Contact", "Address"]
 
diff --git a/erpnext/accounts/doctype/sales_invoice/pos.py b/erpnext/accounts/doctype/sales_invoice/pos.py
index d6cf120..9fb11f2 100644
--- a/erpnext/accounts/doctype/sales_invoice/pos.py
+++ b/erpnext/accounts/doctype/sales_invoice/pos.py
@@ -3,7 +3,6 @@
 
 from __future__ import unicode_literals
 import frappe, json
-from frappe import _
 from frappe.utils import nowdate
 from erpnext.setup.utils import get_exchange_rate
 from erpnext.stock.get_item_details import get_pos_profile
@@ -63,8 +62,10 @@
 
 	doc.currency = pos_profile.get('currency') or company_data.default_currency
 	doc.conversion_rate = 1.0
+	
 	if doc.currency != company_data.default_currency:
-		doc.conversion_rate = get_exchange_rate(doc.currency, company_data.default_currency)
+		doc.conversion_rate = get_exchange_rate(doc.currency, company_data.default_currency, doc.posting_date)
+		
 	doc.selling_price_list = pos_profile.get('selling_price_list') or \
 		frappe.db.get_value('Selling Settings', None, 'selling_price_list')
 	doc.naming_series = pos_profile.get('naming_series') or 'SINV-'
@@ -296,4 +297,3 @@
 		si_doc.docstatus = 0
 		si_doc.flags.ignore_mandatory = True
 		si_doc.insert()
-		frappe.log_error(frappe.get_traceback())
diff --git a/erpnext/accounts/report/financial_statements.py b/erpnext/accounts/report/financial_statements.py
index e66d20e..bc4a220 100644
--- a/erpnext/accounts/report/financial_statements.py
+++ b/erpnext/accounts/report/financial_statements.py
@@ -42,9 +42,6 @@
 		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
diff --git a/erpnext/accounts/report/purchase_register/purchase_register.py b/erpnext/accounts/report/purchase_register/purchase_register.py
index 4bba066..47f79f1 100644
--- a/erpnext/accounts/report/purchase_register/purchase_register.py
+++ b/erpnext/accounts/report/purchase_register/purchase_register.py
@@ -185,7 +185,7 @@
 			pr_list = [d.purchase_receipt]
 		elif d.po_detail:
 			pr_list = frappe.db.sql_list("""select distinct parent from `tabPurchase Receipt Item`
-				where docstatus=1 and prevdoc_detail_docname=%s""", d.po_detail)
+				where docstatus=1 and purchase_order_item=%s""", d.po_detail)
 
 		if pr_list:
 			invoice_po_pr_map.setdefault(d.parent, frappe._dict()).setdefault("purchase_receipt", pr_list)
diff --git a/erpnext/buying/report/quoted_item_comparison/quoted_item_comparison.py b/erpnext/buying/report/quoted_item_comparison/quoted_item_comparison.py
index 1793fc3..f627b4a 100644
--- a/erpnext/buying/report/quoted_item_comparison/quoted_item_comparison.py
+++ b/erpnext/buying/report/quoted_item_comparison/quoted_item_comparison.py
@@ -3,11 +3,9 @@
 
 from __future__ import unicode_literals
 from erpnext.setup.utils import get_exchange_rate
-
 import frappe
 
 def execute(filters=None):
-	
 	qty_list = get_quantity_list(filters.item)
 	
 	data = get_quote_list(filters.item, qty_list)
@@ -15,12 +13,9 @@
 	columns = get_columns(qty_list)
 	
 	return columns, data
-
 	
 def get_quote_list(item, qty_list):
-	
 	out = []
-	
 	if item:
 		price_data = []
 		suppliers = []
@@ -38,8 +33,11 @@
 			
 		#Add a row for each supplier
 		for root in set(suppliers):
-			supplier_currency = frappe.db.get_value("Supplier",root,"default_currency")
-			exg = get_exchange_rate(supplier_currency,company_currency)
+			supplier_currency = frappe.db.get_value("Supplier", root, "default_currency")
+			if supplier_currency:
+				exchange_rate = get_exchange_rate(supplier_currency, company_currency)
+			else:
+				exchange_rate = 1
 
 			row = frappe._dict({
 				"supplier_name": root
@@ -48,7 +46,7 @@
 				# Get the quantity for this row
 				for item_price in price_data:
 					if str(item_price.qty) == col.key and item_price.supplier == root:
-						row[col.key] = item_price.rate * exg
+						row[col.key] = item_price.rate * exchange_rate
 						row[col.key + "QUOTE"] = item_price.parent
 						break
 					else:
@@ -56,15 +54,11 @@
 						row[col.key + "QUOTE"] = ""
 			out.append(row)
 			
-
-	
 	return out
 	
 def get_quantity_list(item):
-	
 	out = []
 	
-			
 	if item:
 		qty_list = frappe.db.sql("""select distinct qty from `tabSupplier Quotation Item` where ifnull(item_code,'')=%s and docstatus < 2""", item, as_dict=1)
 		qty_list.sort(reverse=False)
@@ -102,5 +96,4 @@
 			"width": 90
 		})
 
-
-	return columns
\ No newline at end of file
+	return columns
diff --git a/erpnext/config/docs.py b/erpnext/config/docs.py
index 7b6915a..2d2cc0a 100644
--- a/erpnext/config/docs.py
+++ b/erpnext/config/docs.py
@@ -1,3 +1,7 @@
+from __future__ import unicode_literals
+
+docs_version = "7.x.x"
+
 source_link = "https://github.com/frappe/erpnext"
 docs_base_url = "https://frappe.github.io/erpnext"
 headline = "ERPNext Documentation"
@@ -15,8 +19,8 @@
 listed as one of the Best Open Source Softwares in the world by many online
 blogs."""
 
-docs_version = "7.x.x"
 splash_light_background = True
+google_analytics_id = 'UA-8911157-22'
 
 def get_context(context):
 	context.brand_html = ('<img class="brand-logo" src="'+context.docs_base_url
diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py
index 5796a4d..554529c 100644
--- a/erpnext/controllers/accounts_controller.py
+++ b/erpnext/controllers/accounts_controller.py
@@ -127,6 +127,11 @@
 			validate_due_date(self.posting_date, self.due_date, "Supplier", self.supplier, self.company)
 
 	def set_price_list_currency(self, buying_or_selling):
+		if self.meta.get_field("posting_date"):
+			transaction_date = self.posting_date
+		else:
+			transaction_date = self.transaction_date
+		 
 		if self.meta.get_field("currency"):
 			# price list part
 			fieldname = "selling_price_list" if buying_or_selling.lower() == "selling" \
@@ -139,8 +144,8 @@
 					self.plc_conversion_rate = 1.0
 
 				elif not self.plc_conversion_rate:
-					self.plc_conversion_rate = get_exchange_rate(
-						self.price_list_currency, self.company_currency)
+					self.plc_conversion_rate = get_exchange_rate(self.price_list_currency, 
+						self.company_currency, transaction_date)
 
 			# currency
 			if not self.currency:
@@ -150,7 +155,7 @@
 				self.conversion_rate = 1.0
 			elif not self.conversion_rate:
 				self.conversion_rate = get_exchange_rate(self.currency,
-					self.company_currency)
+					self.company_currency, transaction_date)
 
 	def set_missing_item_details(self, for_validate=False):
 		"""set missing item values"""
@@ -602,7 +607,6 @@
 		for item in duplicate_list:
 			self.remove(item)
 
-
 @frappe.whitelist()
 def get_tax_rate(account_head):
 	return frappe.db.get_value("Account", account_head, ["tax_rate", "account_name"], as_dict=True)
diff --git a/erpnext/crm/doctype/opportunity/opportunity.py b/erpnext/crm/doctype/opportunity/opportunity.py
index 6be0768..6ee9003 100644
--- a/erpnext/crm/doctype/opportunity/opportunity.py
+++ b/erpnext/crm/doctype/opportunity/opportunity.py
@@ -205,7 +205,8 @@
 		if company_currency == quotation.currency:
 			exchange_rate = 1
 		else:
-			exchange_rate = get_exchange_rate(quotation.currency, company_currency)
+			exchange_rate = get_exchange_rate(quotation.currency, company_currency, 
+				quotation.transaction_date)
 
 		quotation.conversion_rate = exchange_rate
 
diff --git a/erpnext/docs/assets/img/human-resources/payroll-frequency.png b/erpnext/docs/assets/img/human-resources/payroll-frequency.png
new file mode 100644
index 0000000..e639903
--- /dev/null
+++ b/erpnext/docs/assets/img/human-resources/payroll-frequency.png
Binary files differ
diff --git a/erpnext/docs/assets/img/human-resources/process-payroll.png b/erpnext/docs/assets/img/human-resources/process-payroll.png
index 2e2fbed..0901cbe 100644
--- a/erpnext/docs/assets/img/human-resources/process-payroll.png
+++ b/erpnext/docs/assets/img/human-resources/process-payroll.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 71f6013..83e4820 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/hr/doctype/process_payroll/process_payroll.js b/erpnext/hr/doctype/process_payroll/process_payroll.js
index 35c097a..3265f88 100644
--- a/erpnext/hr/doctype/process_payroll/process_payroll.js
+++ b/erpnext/hr/doctype/process_payroll/process_payroll.js
@@ -2,43 +2,43 @@
 // License: GNU General Public License v3. See license.txt
 
 frappe.ui.form.on("Process Payroll", {
-	refresh: function(frm) {
-		frm.disable_save();
-		frm.trigger("toggle_fields");
-		frm.trigger("set_month_dates");
-	},
-	
-	month: function(frm) {
-		frm.trigger("set_month_dates");
-	},
-	
-	fiscal_year: function(frm) {
-		frm.trigger("set_month_dates");
-	},
-	
-	salary_slip_based_on_timesheet: function(frm) {
-		frm.trigger("toggle_fields")
+	onload: function(frm) {
+		frm.doc.posting_date = frm.doc.start_date = frm.doc.end_date = frappe.datetime.nowdate()
 	},
 
-	toggle_fields: function(frm) {
-		frm.toggle_display(['from_date','to_date'],
-			cint(frm.doc.salary_slip_based_on_timesheet)==1);
-		frm.toggle_display(['fiscal_year', 'month'],
-			cint(frm.doc.salary_slip_based_on_timesheet)==0);
+	refresh: function(frm) {
+		frm.disable_save();
 	},
 	
-	set_month_dates: function(frm) {
+	payroll_frequency: function(frm) {
+		frm.trigger("set_start_end_dates");
+	},
+	
+	start_date: function(frm) {
+		frm.trigger("set_start_end_dates");
+	},
+	
+	end_date: function(frm) {
+		frm.trigger("set_start_end_dates");
+	},
+
+	payment_account: function(frm) {
+		frm.toggle_display(['make_bank_entry'], (frm.doc.payment_account!="" && frm.doc.payment_account!="undefined"));
+	},
+	
+	set_start_end_dates: function(frm) {
 		if (!frm.doc.salary_slip_based_on_timesheet){
 			frappe.call({
-				method:'erpnext.hr.doctype.process_payroll.process_payroll.get_month_details',
+				method:'erpnext.hr.doctype.process_payroll.process_payroll.get_start_end_dates',
 				args:{
-					year: frm.doc.fiscal_year, 
-					month: frm.doc.month
+					payroll_frequency: frm.doc.payroll_frequency,
+					start_date: frm.doc.start_date,
+					end_date: frm.doc.end_date
 				},
 				callback: function(r){
 					if (r.message){
-						frm.set_value('from_date', r.message.month_start_date);
-						frm.set_value('to_date', r.message.month_end_date);			
+						frm.set_value('start_date', r.message.start_date);
+						frm.set_value('end_date', r.message.end_date);			
 					}
 				}
 			})
@@ -56,17 +56,6 @@
 	}
 })
 
-cur_frm.cscript.onload = function(doc,cdt,cdn){
-		if(!doc.month) {
-			var today=new Date();
-			month = (today.getMonth()+01).toString();
-			if(month.length>1) doc.month = month;
-			else doc.month = '0'+month;
-		}
-		if(!doc.fiscal_year) doc.fiscal_year = sys_defaults['fiscal_year'];
-		refresh_many(['month', 'fiscal_year']);
-}
-
 cur_frm.cscript.display_activity_log = function(msg) {
 	if(!cur_frm.ss_html)
 		cur_frm.ss_html = $a(cur_frm.fields_dict['activity_log'].wrapper,'div');
@@ -92,7 +81,7 @@
 cur_frm.cscript.submit_salary_slip = function(doc, cdt, cdn) {
 	cur_frm.cscript.display_activity_log("");
 
-	frappe.confirm(__("Do you really want to Submit all Salary Slip from {0} to {1}", [doc.from_date, doc.to_date]), function() {
+	frappe.confirm(__("Do you really want to Submit all Salary Slip from {0} to {1}", [doc.start_date, doc.end_date]), function() {
 		// clear all in locals
 		if(locals["Salary Slip"]) {
 			$.each(locals["Salary Slip"], function(name, d) {
@@ -110,7 +99,7 @@
 }
 
 cur_frm.cscript.make_bank_entry = function(doc,cdt,cdn){
-    if(doc.company && doc.from_date && doc.to_date){
+    if(doc.company && doc.start_date && doc.end_date){
 		return cur_frm.cscript.reference_entry(doc,cdt,cdn);
     } else {
   	  msgprint(__("Company, From Date and To Date is mandatory"));
diff --git a/erpnext/hr/doctype/process_payroll/process_payroll.json b/erpnext/hr/doctype/process_payroll/process_payroll.json
index ae86c2d..8e0d395 100644
--- a/erpnext/hr/doctype/process_payroll/process_payroll.json
+++ b/erpnext/hr/doctype/process_payroll/process_payroll.json
@@ -22,6 +22,7 @@
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
+   "in_standard_filter": 0, 
    "label": "Select Employees", 
    "length": 0, 
    "no_copy": 0, 
@@ -48,6 +49,7 @@
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
+   "in_standard_filter": 0, 
    "length": 0, 
    "no_copy": 0, 
    "permlevel": 0, 
@@ -67,6 +69,7 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "default": "", 
    "fieldname": "company", 
    "fieldtype": "Link", 
    "hidden": 0, 
@@ -74,6 +77,7 @@
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 1, 
+   "in_standard_filter": 0, 
    "label": "Company", 
    "length": 0, 
    "no_copy": 0, 
@@ -102,6 +106,7 @@
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
+   "in_standard_filter": 0, 
    "label": "Posting Date", 
    "length": 0, 
    "no_copy": 0, 
@@ -122,6 +127,37 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "default": "Monthly", 
+   "depends_on": "eval:doc.salary_slip_based_on_timesheet == 0", 
+   "fieldname": "payroll_frequency", 
+   "fieldtype": "Select", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Payroll Frequency", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "\nMonthly\nFortnightly\nBimonthly\nWeekly\nDaily", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 1, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
    "fieldname": "column_break1", 
    "fieldtype": "Column Break", 
    "hidden": 0, 
@@ -129,6 +165,7 @@
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
+   "in_standard_filter": 0, 
    "length": 0, 
    "no_copy": 0, 
    "permlevel": 0, 
@@ -155,6 +192,7 @@
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 1, 
+   "in_standard_filter": 0, 
    "label": "Branch", 
    "length": 0, 
    "no_copy": 0, 
@@ -182,6 +220,7 @@
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
+   "in_standard_filter": 0, 
    "label": "Department", 
    "length": 0, 
    "no_copy": 0, 
@@ -209,6 +248,7 @@
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
+   "in_standard_filter": 0, 
    "label": "Designation", 
    "length": 0, 
    "no_copy": 0, 
@@ -236,6 +276,7 @@
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
+   "in_standard_filter": 0, 
    "length": 0, 
    "no_copy": 0, 
    "permlevel": 0, 
@@ -262,6 +303,7 @@
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
+   "in_standard_filter": 0, 
    "label": "Salary Slip Based on Timesheet", 
    "length": 0, 
    "no_copy": 0, 
@@ -289,6 +331,7 @@
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
+   "in_standard_filter": 0, 
    "label": "Select Payroll Period", 
    "length": 0, 
    "no_copy": 0, 
@@ -309,14 +352,16 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
-   "fieldname": "from_date", 
-   "fieldtype": "Data", 
+   "default": "Today", 
+   "fieldname": "start_date", 
+   "fieldtype": "Date", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
-   "label": "From", 
+   "in_standard_filter": 0, 
+   "label": "Start Date", 
    "length": 0, 
    "no_copy": 0, 
    "permlevel": 0, 
@@ -336,33 +381,6 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
-   "fieldname": "fiscal_year", 
-   "fieldtype": "Link", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_list_view": 0, 
-   "label": "Fiscal Year", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Fiscal Year", 
-   "permlevel": 0, 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 1, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0
-  }, 
-  {
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
    "fieldname": "column_break_11", 
    "fieldtype": "Column Break", 
    "hidden": 0, 
@@ -370,6 +388,7 @@
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
+   "in_standard_filter": 0, 
    "length": 0, 
    "no_copy": 0, 
    "permlevel": 0, 
@@ -389,14 +408,16 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
-   "fieldname": "to_date", 
-   "fieldtype": "Data", 
+   "default": "Today", 
+   "fieldname": "end_date", 
+   "fieldtype": "Date", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
-   "label": "To", 
+   "in_standard_filter": 0, 
+   "label": "End Date", 
    "length": 0, 
    "no_copy": 0, 
    "permlevel": 0, 
@@ -416,33 +437,6 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
-   "fieldname": "month", 
-   "fieldtype": "Select", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_list_view": 0, 
-   "label": "Month", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "\n01\n02\n03\n04\n05\n06\n07\n08\n09\n10\n11\n12", 
-   "permlevel": 0, 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 1, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0
-  }, 
-  {
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
    "fieldname": "process_payroll", 
    "fieldtype": "Section Break", 
    "hidden": 0, 
@@ -450,6 +444,7 @@
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
+   "in_standard_filter": 0, 
    "label": "Process Payroll", 
    "length": 0, 
    "no_copy": 0, 
@@ -477,6 +472,7 @@
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
+   "in_standard_filter": 0, 
    "length": 0, 
    "no_copy": 0, 
    "permlevel": 0, 
@@ -504,6 +500,7 @@
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
+   "in_standard_filter": 0, 
    "label": "Create Salary Slip", 
    "length": 0, 
    "no_copy": 0, 
@@ -530,6 +527,7 @@
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
+   "in_standard_filter": 0, 
    "length": 0, 
    "no_copy": 0, 
    "permlevel": 0, 
@@ -557,6 +555,7 @@
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
+   "in_standard_filter": 0, 
    "label": "Submit Salary Slip", 
    "length": 0, 
    "no_copy": 0, 
@@ -583,6 +582,7 @@
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
+   "in_standard_filter": 0, 
    "label": "Account", 
    "length": 0, 
    "no_copy": 0, 
@@ -611,6 +611,7 @@
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
+   "in_standard_filter": 0, 
    "label": "Payment Account", 
    "length": 0, 
    "no_copy": 0, 
@@ -632,15 +633,16 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
-   "depends_on": "eval:doc.payment_account", 
+   "depends_on": "", 
    "description": "Create Bank Entry for the total salary paid for the above selected criteria", 
    "fieldname": "make_bank_entry", 
    "fieldtype": "Button", 
-   "hidden": 0, 
+   "hidden": 1, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
+   "in_standard_filter": 0, 
    "label": "Make Bank Entry", 
    "length": 0, 
    "no_copy": 0, 
@@ -667,6 +669,7 @@
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
+   "in_standard_filter": 0, 
    "length": 0, 
    "no_copy": 0, 
    "permlevel": 0, 
@@ -692,6 +695,7 @@
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
+   "in_standard_filter": 0, 
    "label": "Activity Log", 
    "length": 0, 
    "no_copy": 0, 
@@ -718,7 +722,7 @@
  "issingle": 1, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2016-11-03 16:02:34.040851", 
+ "modified": "2016-11-26 01:14:51.691057", 
  "modified_by": "Administrator", 
  "module": "HR", 
  "name": "Process Payroll", 
diff --git a/erpnext/hr/doctype/process_payroll/process_payroll.py b/erpnext/hr/doctype/process_payroll/process_payroll.py
index 2077982..97e3876 100644
--- a/erpnext/hr/doctype/process_payroll/process_payroll.py
+++ b/erpnext/hr/doctype/process_payroll/process_payroll.py
@@ -3,10 +3,12 @@
 
 from __future__ import unicode_literals
 import frappe
-from frappe.utils import cint, flt, nowdate
+from frappe.utils import cint, flt, nowdate, add_days, getdate
 from frappe import _
 import collections
 from collections import defaultdict
+from calendar import monthrange
+from erpnext.accounts.utils import get_fiscal_year
 
 from frappe.model.document import Document
 
@@ -19,7 +21,12 @@
 		"""
 		cond = self.get_filter_condition()
 		cond += self.get_joining_releiving_condition()
-
+		
+		
+		struct_cond = ''
+		if self.payroll_frequency:
+			struct_cond = """and payroll_frequency = '%(payroll_frequency)s'""" % {"payroll_frequency": self.payroll_frequency}	
+			
 		sal_struct = frappe.db.sql("""
 				select name from `tabSalary Structure`
 				where docstatus != 2 and is_active = 'Yes' and company = %(company)s and
@@ -28,13 +35,11 @@
 		
 		if sal_struct:
 			cond += "and t2.parent IN %(sal_struct)s "
-
 			emp_list = frappe.db.sql("""
 				select t1.name
 				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
 
 
@@ -51,16 +56,16 @@
 
 	def get_joining_releiving_condition(self):
 		cond = """
-			and ifnull(t1.date_of_joining, '0000-00-00') <= '%(to_date)s'
-			and ifnull(t1.relieving_date, '2199-12-31') >= '%(from_date)s'
-		""" % {"from_date": self.from_date, "to_date": self.to_date}
+			and ifnull(t1.date_of_joining, '0000-00-00') <= '%(end_date)s'
+			and ifnull(t1.relieving_date, '2199-12-31') >= '%(start_date)s'
+		""" % {"start_date": self.start_date, "end_date": self.end_date}
 		return cond
 
 
 	def check_mandatory(self):
-		for f in ['company', 'from_date', 'to_date']:
-			if not self.get(f):
-				frappe.throw(_("Please set {0}").format(f))
+		for fieldname in ['company', 'payroll_frequency', 'start_date', 'end_date']:
+			if not self.get(fieldname):
+				frappe.throw(_("Please set {0}").format(self.meta.get_label(fieldname)))
 
 	def create_sal_slip(self):
 		"""
@@ -74,28 +79,28 @@
 			for emp in emp_list:
 				if not frappe.db.sql("""select name from `tabSalary Slip`
 						where docstatus!= 2 and employee = %s and start_date >= %s and end_date <= %s and company = %s
-						""", (emp[0], self.from_date, self.to_date, self.company)):
-					if self.salary_slip_based_on_timesheet:
+						""", (emp[0], self.start_date, self.end_date, self.company)):
+					if self.payroll_frequency == "Monthly" or self.payroll_frequency == '':
 						ss = frappe.get_doc({
 							"doctype": "Salary Slip",
 							"salary_slip_based_on_timesheet": self.salary_slip_based_on_timesheet,
-							"start_date": self.from_date,
-							"end_date": self.to_date,
 							"employee": emp[0],
 							"employee_name": frappe.get_value("Employee", {"name":emp[0]}, "employee_name"),
 							"company": self.company,
-							"posting_date": self.posting_date
+							"posting_date": self.posting_date,
+							"payroll_frequency": self.payroll_frequency
 						})
 					else:
 						ss = frappe.get_doc({
 							"doctype": "Salary Slip",
 							"salary_slip_based_on_timesheet": self.salary_slip_based_on_timesheet,
-							"fiscal_year": self.fiscal_year,
-							"month": self.month,
+							"start_date": self.start_date,
+							"end_date": self.end_date,
 							"employee": emp[0],
 							"employee_name": frappe.get_value("Employee", {"name":emp[0]}, "employee_name"),
 							"company": self.company,
-							"posting_date": self.posting_date
+							"posting_date": self.posting_date,
+							"payroll_frequency": self.payroll_frequency
 						})	
 					ss.insert()
 					ss_list.append(ss.name)
@@ -120,7 +125,7 @@
 			select t1.name, t1.salary_structure from `tabSalary Slip` t1
 			where t1.docstatus = %s and t1.start_date >= %s and t1.end_date <= %s 
 			and (t1.journal_entry is null or t1.journal_entry = "") and ifnull(salary_slip_based_on_timesheet,0) = %s %s
-		""" % ('%s', '%s', '%s','%s', cond), (ss_status, self.from_date, self.to_date, self.salary_slip_based_on_timesheet), as_dict=as_dict)
+		""" % ('%s', '%s', '%s','%s', cond), (ss_status, self.start_date, self.end_date, self.salary_slip_based_on_timesheet), as_dict=as_dict)
 		return ss_list
 
 
@@ -183,7 +188,7 @@
 		tot = frappe.db.sql("""
 			select sum(rounded_total) from `tabSalary Slip` t1
 			where t1.docstatus = 1 and start_date >= %s and end_date <= %s %s
-		""" % ('%s', '%s', cond), (self.from_date, self.to_date))
+		""" % ('%s', '%s', cond), (self.start_date, self.end_date))
 
 		return flt(tot[0][0])
 		
@@ -231,8 +236,8 @@
 		if earnings or deductions:
 			journal_entry = frappe.new_doc('Journal Entry')
 			journal_entry.voucher_type = 'Bank Entry'
-			journal_entry.user_remark = _('Payment of salary from {0} to {1}').format(self.from_date,
-				self.to_date)
+			journal_entry.user_remark = _('Payment of salary from {0} to {1}').format(self.start_date,
+				self.end_date)
 			journal_entry.company = self.company
 			journal_entry.posting_date = nowdate()
 		
@@ -257,6 +262,7 @@
 			journal_entry.set("accounts", account_amt_list)
 			journal_entry.cheque_no = reference_number
 			journal_entry.cheque_date = reference_date
+			journal_entry.multi_currency = 1
 			journal_entry.save()
 			try:
 				journal_entry.submit()
@@ -279,7 +285,7 @@
 		for ss in ss_list:
 			ss_obj = frappe.get_doc("Salary Slip",ss[0])
 			frappe.db.set_value("Salary Slip", ss_obj.name, "status", "Paid")
-			frappe.db.set_value("Salary Slip", ss_obj.name, "journal_entry", jv_name)
+			frappe.db.set_value("Salary Slip", ss_obj.name, "journal_entry", jv_name)		
 
 
 @frappe.whitelist()
@@ -293,12 +299,45 @@
 			diff_mnt = 12-int(ysd.month)+cint(month)
 		msd = ysd + relativedelta(months=diff_mnt) # month start date
 		month_days = cint(calendar.monthrange(cint(msd.year) ,cint(month))[1]) # days in month
+		mid_start = datetime.date(msd.year, cint(month), 16) # month mid start date
+		mid_end = datetime.date(msd.year, cint(month), 15) # month mid end date
 		med = datetime.date(msd.year, cint(month), month_days) # month end date
 		return frappe._dict({
 			'year': msd.year,
 			'month_start_date': msd,
 			'month_end_date': med,
+			'month_mid_start_date': mid_start,
+			'month_mid_end_date': mid_end,
 			'month_days': month_days
 		})
 	else:
-		frappe.throw(_("Fiscal Year {0} not found").format(year))
\ No newline at end of file
+		frappe.throw(_("Fiscal Year {0} not found").format(year))
+
+@frappe.whitelist()
+def get_start_end_dates(payroll_frequency, start_date, end_date):
+	if payroll_frequency == "Monthly" or payroll_frequency == "Bimonthly":
+		fiscal_year = get_fiscal_year(start_date)[0] or get_fiscal_year(end_date)[0]
+		month = "%02d" % getdate(start_date).month or "%02d" % getdate(end_date).month
+		m = get_month_details(fiscal_year, month)
+		if payroll_frequency == "Bimonthly":
+			if getdate(start_date).day <= 15:
+				start_date = m['month_start_date']
+				end_date = m['month_mid_end_date']
+			else:
+				start_date = m['month_mid_start_date']
+				end_date = m['month_end_date']
+		else:
+			start_date = m['month_start_date']
+			end_date = m['month_end_date']
+		
+	if payroll_frequency == "Weekly":
+		end_date = add_days(start_date, 6)
+			
+	if payroll_frequency == "Fortnightly":
+		end_date = add_days(start_date, 13)
+		
+	if payroll_frequency == "Daily":
+		end_date = start_date
+	return frappe._dict({
+		'start_date': start_date, 'end_date': end_date
+	})
\ No newline at end of file
diff --git a/erpnext/hr/doctype/process_payroll/test_process_payroll.py b/erpnext/hr/doctype/process_payroll/test_process_payroll.py
index 3be4b4c..5167365 100644
--- a/erpnext/hr/doctype/process_payroll/test_process_payroll.py
+++ b/erpnext/hr/doctype/process_payroll/test_process_payroll.py
@@ -18,15 +18,14 @@
 				get_salary_component_account(data.name)
 				
 		payment_account = frappe.get_value('Account', {'account_type': 'Cash', 'company': erpnext.get_default_company(),'is_group':0}, "name")
-		if not frappe.db.get_value("Salary Slip", {"fiscal_year": fiscal_year, "month": month}):
+		if not frappe.db.get_value("Salary Slip", {"start_date": "2016-11-01", "end_date": "2016-11-30"}):
 			process_payroll = frappe.get_doc("Process Payroll", "Process Payroll")
 			process_payroll.company = erpnext.get_default_company()
-			process_payroll.month = month
-			process_payroll.fiscal_year = fiscal_year
-			process_payroll.from_date = "2016-11-01"
-			process_payroll.to_date = "2016-11-30"
+			process_payroll.start_date = "2016-11-01"
+			process_payroll.end_date = "2016-11-30"
 			process_payroll.payment_account = payment_account
 			process_payroll.posting_date = nowdate()
+			process_payroll.payroll_frequency = "Monthly"
 			process_payroll.create_sal_slip()
 			process_payroll.submit_salary_slip()
 			if process_payroll.get_sal_slip_list(ss_status = 1):
diff --git a/erpnext/hr/doctype/salary_slip/salary_slip.js b/erpnext/hr/doctype/salary_slip/salary_slip.js
index e1120e8..8b0dd16 100644
--- a/erpnext/hr/doctype/salary_slip/salary_slip.js
+++ b/erpnext/hr/doctype/salary_slip/salary_slip.js
@@ -46,59 +46,44 @@
 	salary_slip_based_on_timesheet: function(frm) {
 		frm.trigger("toggle_fields")
 	},
+	
+	payroll_frequency: function(frm) {
+		frm.trigger("toggle_fields")
+	},
 
 	toggle_fields: function(frm) {
-		frm.toggle_display(['start_date', 'end_date', 'hourly_wages', 'timesheets'],
+		frm.toggle_display(['hourly_wages', 'timesheets'],
 			cint(frm.doc.salary_slip_based_on_timesheet)==1);
-		frm.toggle_display(['fiscal_year', 'month', 'total_days_in_month', 'leave_without_pay', 'payment_days'],
-			cint(frm.doc.salary_slip_based_on_timesheet)==0);
+
+		frm.toggle_display(['payment_days', 'total_working_days', 'leave_without_pay'],
+			frm.doc.payroll_frequency!="");
 	}
 })
 
 
-frappe.ui.form.on("Salary Slip Timesheet", {
-	time_sheet: function(frm, cdt, cdn) {
-		doc = frm.doc;
-		cur_frm.cscript.fiscal_year(doc, cdt, cdn)
-	}
-})
-
-
-// On load
-// -------------------------------------------------------------------
-cur_frm.cscript.onload = function(doc,dt,dn){
-	if((cint(doc.__islocal) == 1) && !doc.amended_from){
-		if(!doc.month) {
-			var today=new Date();
-			month = (today.getMonth()+01).toString();
-			if(month.length>1) doc.month = month;
-			else doc.month = '0'+month;
-		}
-		if(!doc.fiscal_year) doc.fiscal_year = sys_defaults['fiscal_year'];
-		refresh_many(['month', 'fiscal_year']);
-	}
-}
-
 // Get leave details
 //---------------------------------------------------------------------
-cur_frm.cscript.fiscal_year = function(doc,dt,dn){
-		return $c_obj(doc, 'get_emp_and_leave_details','',function(r, rt) {
-			var doc = locals[dt][dn];
+cur_frm.cscript.start_date = function(doc, dt, dn){
+	return frappe.call({
+		method: 'get_emp_and_leave_details',
+		doc: locals[dt][dn],
+		callback: function(r, rt) {
 			cur_frm.refresh();
 			calculate_all(doc, dt, dn);
-		});
+		}
+	});
 }
 
-cur_frm.cscript.month = cur_frm.cscript.salary_slip_based_on_timesheet = cur_frm.cscript.fiscal_year;
-cur_frm.cscript.start_date = cur_frm.cscript.end_date = cur_frm.cscript.fiscal_year;
+cur_frm.cscript.payroll_frequency = cur_frm.cscript.salary_slip_based_on_timesheet = cur_frm.cscript.start_date;
+cur_frm.cscript.end_date = cur_frm.cscript.start_date;
 
 cur_frm.cscript.employee = function(doc,dt,dn){
 	doc.salary_structure = ''
-	cur_frm.cscript.fiscal_year(doc, dt, dn)
+	cur_frm.cscript.start_date(doc, dt, dn)
 }
 
 cur_frm.cscript.leave_without_pay = function(doc,dt,dn){
-	if (doc.employee && doc.fiscal_year && doc.month) {
+	if (doc.employee && doc.start_date && doc.end_date) {
 		return $c_obj(doc, 'get_leave_details', {"lwp": doc.leave_without_pay}, function(r, rt) {
 			var doc = locals[dt][dn];
 			cur_frm.refresh();
@@ -135,7 +120,7 @@
 	for(var i = 0; i < tbl.length; i++){
 		if(cint(tbl[i].depends_on_lwp) == 1) {
 			tbl[i].amount =  Math.round(tbl[i].default_amount)*(flt(doc.payment_days) /
-				cint(doc.total_days_in_month)*100)/100;
+				cint(doc.total_working_days)*100)/100;
 			refresh_field('amount', tbl[i].name, 'earnings');
 		} else if(reset_amount) {
 			tbl[i].amount = tbl[i].default_amount;
@@ -155,7 +140,7 @@
 	var total_ded = 0;
 	for(var i = 0; i < tbl.length; i++){
 		if(cint(tbl[i].depends_on_lwp) == 1) {
-			tbl[i].amount = Math.round(tbl[i].default_amount)*(flt(doc.payment_days)/cint(doc.total_days_in_month)*100)/100;
+			tbl[i].amount = Math.round(tbl[i].default_amount)*(flt(doc.payment_days)/cint(doc.total_working_days)*100)/100;
 			refresh_field('amount', tbl[i].name, 'deductions');
 		} else if(reset_amount) {
 			tbl[i].amount = tbl[i].default_amount;
diff --git a/erpnext/hr/doctype/salary_slip/salary_slip.json b/erpnext/hr/doctype/salary_slip/salary_slip.json
index 4d69b01..062f41f 100644
--- a/erpnext/hr/doctype/salary_slip/salary_slip.json
+++ b/erpnext/hr/doctype/salary_slip/salary_slip.json
@@ -421,69 +421,7 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
-   "depends_on": "", 
-   "fieldname": "fiscal_year", 
-   "fieldtype": "Link", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 1, 
-   "in_list_view": 1, 
-   "in_standard_filter": 0, 
-   "label": "Fiscal Year", 
-   "length": 0, 
-   "no_copy": 0, 
-   "oldfieldname": "fiscal_year", 
-   "oldfieldtype": "Data", 
-   "options": "Fiscal Year", 
-   "permlevel": 0, 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 1, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0
-  }, 
-  {
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "depends_on": "", 
-   "fieldname": "month", 
-   "fieldtype": "Select", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 1, 
-   "in_list_view": 1, 
-   "in_standard_filter": 1, 
-   "label": "Month", 
-   "length": 0, 
-   "no_copy": 0, 
-   "oldfieldname": "month", 
-   "oldfieldtype": "Select", 
-   "options": "\n01\n02\n03\n04\n05\n06\n07\n08\n09\n10\n11\n12", 
-   "permlevel": 0, 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 1, 
-   "set_only_once": 0, 
-   "unique": 0, 
-   "width": "37%"
-  }, 
-  {
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
+   "default": "Today", 
    "fieldname": "start_date", 
    "fieldtype": "Date", 
    "hidden": 0, 
@@ -599,8 +537,39 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "default": "", 
+   "depends_on": "eval:(!doc.salary_slip_based_on_timesheet)", 
+   "fieldname": "payroll_frequency", 
+   "fieldtype": "Select", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Payroll Frequency", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "\nMonthly\nFortnightly\nBimonthly\nWeekly\nDaily", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
    "depends_on": "", 
-   "fieldname": "total_days_in_month", 
+   "fieldname": "total_working_days", 
    "fieldtype": "Float", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
@@ -1392,7 +1361,7 @@
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2016-11-07 05:58:37.151587", 
+ "modified": "2016-12-08 12:03:31.602913", 
  "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 34022bd..95bea7a 100644
--- a/erpnext/hr/doctype/salary_slip/salary_slip.py
+++ b/erpnext/hr/doctype/salary_slip/salary_slip.py
@@ -10,10 +10,12 @@
 from frappe import msgprint, _
 from erpnext.accounts.utils import get_fiscal_year
 from erpnext.setup.utils import get_company_currency
-from erpnext.hr.doctype.process_payroll.process_payroll import get_month_details
+from erpnext.hr.doctype.process_payroll.process_payroll import get_month_details, get_start_end_dates
 from erpnext.hr.doctype.employee.employee import get_holiday_list_for_employee
 from erpnext.utilities.transaction_base import TransactionBase
 
+from datetime import timedelta
+
 class SalarySlip(TransactionBase):
 	def autoname(self):
 		self.name = make_autoname('Sal Slip/' +self.employee + '/.#####')
@@ -22,8 +24,7 @@
 		self.status = self.get_status()
 		self.validate_dates()
 		self.check_existing()
-		self.set_month_dates()
-		
+		self.get_date_details()
 		if not (len(self.get("earnings")) or len(self.get("deductions"))):
 			# get details from salary structure
 			self.get_emp_and_leave_details()
@@ -120,7 +121,7 @@
 			self.set("earnings", [])
 			self.set("deductions", [])
 
-			self.set_month_dates()
+			self.get_date_details()
 			self.validate_dates()
 			joining_date, relieving_date = frappe.db.get_value("Employee", self.employee,
 				["date_of_joining", "relieving_date"])
@@ -146,20 +147,24 @@
 					'working_hours': data.total_hours
 				})
 
-	def set_month_dates(self):
-		if self.month and not self.salary_slip_based_on_timesheet:
-			m = get_month_details(self.fiscal_year, self.month)
-			self.start_date = m['month_start_date']
-			self.end_date = m['month_end_date']
+	def get_date_details(self):
+		date_details = get_start_end_dates(self.payroll_frequency, self.start_date, self.end_date)
+		self.start_date = date_details.start_date
+		self.end_date = date_details.end_date
+
 
 	def check_sal_struct(self, joining_date, relieving_date):
+		cond = ''
+		if self.payroll_frequency:
+			cond = """and payroll_frequency = '%(payroll_frequency)s'""" % {"payroll_frequency": self.payroll_frequency}
+			
 		st_name = frappe.db.sql("""select parent from `tabSalary Structure Employee`
 			where employee=%s
 			and parent in (select name from `tabSalary Structure`
 				where is_active = 'Yes'
 				and (from_date <= %s or from_date <= %s)
-				and (to_date is null or to_date >= %s or to_date >= %s))
-			""",(self.employee, self.start_date, joining_date, self.end_date, relieving_date))
+				and (to_date is null or to_date >= %s or to_date >= %s) %s)
+			"""% ('%s', '%s', '%s','%s','%s', cond),(self.employee, self.start_date, joining_date, self.end_date, relieving_date))
 			
 		if st_name:
 			if len(st_name) > 1:
@@ -185,9 +190,11 @@
 			
 	def process_salary_structure(self):
 		'''Calculate salary after salary structure details have been updated'''
+		self.get_date_details()
 		self.pull_emp_details()
 		self.get_leave_details()
 		self.calculate_net_pay()
+		
 
 	def add_earning_for_hourly_wages(self, salary_component):
 		default_type = False
@@ -210,14 +217,6 @@
 
 
 	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
-			self.fiscal_year = get_fiscal_year(nowdate())[0]
-
-		if not self.month:
-			self.month = "%02d" % getdate(nowdate()).month
-			self.set_month_dates()
-
 		if not joining_date:
 			joining_date, relieving_date = frappe.db.get_value("Employee", self.employee,
 				["date_of_joining", "relieving_date"])
@@ -236,7 +235,7 @@
 		elif lwp != actual_lwp:
 			frappe.msgprint(_("Leave Without Pay does not match with approved Leave Application records"))
 			
-		self.total_days_in_month = working_days
+		self.total_working_days = working_days
 		self.leave_without_pay = lwp
 		
 		payment_days = flt(self.get_payment_days(joining_date, relieving_date)) - flt(lwp)
@@ -244,16 +243,15 @@
 
 	def get_payment_days(self, joining_date, relieving_date):
 		start_date = getdate(self.start_date)
-
 		if joining_date:
-			if joining_date > getdate(self.start_date):
+			if getdate(self.start_date) <= joining_date <= getdate(self.end_date):
 				start_date = joining_date
 			elif joining_date > getdate(self.end_date):
 				return
 
 		end_date = getdate(self.end_date)
 		if relieving_date:
-			if relieving_date > start_date and relieving_date < getdate(self.end_date):
+			if getdate(self.start_date) <= relieving_date <= getdate(self.end_date):
 				end_date = relieving_date
 			elif relieving_date < getdate(self.start_date):
 				frappe.throw(_("Employee relieved on {0} must be set as 'Left'")
@@ -264,7 +262,6 @@
 		if not cint(frappe.db.get_value("HR Settings", None, "include_holidays_in_total_working_days")):
 			holidays = self.get_holidays_for_employee(start_date, end_date)
 			payment_days -= len(holidays)
-
 		return payment_days
 
 	def get_holidays_for_employee(self, start_date, end_date):
@@ -306,9 +303,9 @@
 	def check_existing(self):
 		if not self.salary_slip_based_on_timesheet:
 			ret_exist = frappe.db.sql("""select name from `tabSalary Slip`
-						where month = %s and fiscal_year = %s and docstatus != 2
+						where start_date = %s and end_date = %s and docstatus != 2
 						and employee = %s and name != %s""",
-						(self.month, self.fiscal_year, self.employee, self.name))
+						(self.start_date, self.end_date, self.employee, self.name))
 			if ret_exist:
 				self.employee = ''
 				frappe.throw(_("Salary Slip of employee {0} already created for this period").format(self.employee))
@@ -321,7 +318,7 @@
 		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.default_amount) * flt(self.payment_days)
-					/ cint(self.total_days_in_month)), self.precision("amount", component_type))
+					/ cint(self.total_working_days)), 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:
@@ -361,7 +358,7 @@
 		receiver = frappe.db.get_value("Employee", self.employee, "prefered_email")
 
 		if receiver:
-			subj = 'Salary Slip - from {0} to {1}, fiscal year {2}'.format(self.start_date, self.end_date, self.fiscal_year)
+			subj = 'Salary Slip - from {0} to {1}'.format(self.start_date, self.end_date)
 			frappe.sendmail([receiver], subject=subj, message = _("Please see attachment"),
 				attachments=[frappe.attach_print(self.doctype, self.name, file_name=self.name)], reference_doctype= self.doctype, reference_name= self.name)
 		else:
diff --git a/erpnext/hr/doctype/salary_slip/test_records.json b/erpnext/hr/doctype/salary_slip/test_records.json
deleted file mode 100644
index 20cef3d..0000000
--- a/erpnext/hr/doctype/salary_slip/test_records.json
+++ /dev/null
@@ -1,45 +0,0 @@
-[
- {
-  "company": "_Test Company", 
-  "doctype": "Salary Slip", 
-  "deductions": [
-   {
-	"doctype": "Salary Detail",
-    "amount": 100, 
-    "depends_on_lwp": 0, 
-    "salary_component": "_Test Professional Tax", 
-    "parentfield": "deductions"
-   }, 
-   {
-	"doctype": "Salary Detail",
-    "amount": 48.39, 
-    "depends_on_lwp": 0, 
-    "salary_component": "_Test TDS", 
-    "parentfield": "deductions"
-   }
-  ],   
-  "earnings": [
-   {
-    "doctype": "Salary Detail", 
-    "amount": 14516.13, 
-    "depends_on_lwp": 0, 
-    "salary_component": "_Test Basic Salary", 
-    "parentfield": "earnings"
-   }, 
-   {
-    "doctype": "Salary Detail",
-    "amount": 500, 
-    "depends_on_lwp": 0, 
-    "salary_component": "_Test Allowance", 
-    "parentfield": "earnings"
-   }
-  ], 
-  "employee": "_T-Employee-0001", 
-  "employee_name": "_Test Employee", 
-  "posting_date": "2013-02-01",
-  "fiscal_year": "_Test Fiscal Year 2013", 
-  "month": "01", 
-  "payment_days": 31, 
-  "total_days_in_month": 31
- }
-]
\ No newline at end of file
diff --git a/erpnext/hr/doctype/salary_slip/test_salary_slip.py b/erpnext/hr/doctype/salary_slip/test_salary_slip.py
index 57a3711..4025db7 100644
--- a/erpnext/hr/doctype/salary_slip/test_salary_slip.py
+++ b/erpnext/hr/doctype/salary_slip/test_salary_slip.py
@@ -5,41 +5,41 @@
 import unittest
 import frappe
 import erpnext
-from frappe.utils.make_random import get_random
-from frappe.utils import today, now_datetime, getdate, cstr, add_years, nowdate
+import calendar
+from erpnext.accounts.utils import get_fiscal_year
+from frappe.utils import getdate, nowdate, add_days
 from erpnext.hr.doctype.salary_structure.salary_structure import make_salary_slip
 from erpnext.hr.doctype.process_payroll.test_process_payroll import get_salary_component_account
+from erpnext.hr.doctype.process_payroll.process_payroll import get_month_details
 
 class TestSalarySlip(unittest.TestCase):
 	def setUp(self):
-		make_salary_component(["Basic Salary", "Allowance", "HRA", "Professional Tax", "TDS"])
+		make_earning_salary_component(["Basic Salary", "Allowance", "HRA"])
+		make_deduction_salary_component(["Professional Tax", "TDS"])
 		
 		for dt in ["Leave Application", "Leave Allocation", "Salary Slip"]:
 			frappe.db.sql("delete from `tab%s`" % dt)
 
 		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])
-		la.insert()
-		la.status = "Approved"
-		la.submit()
 
 	def tearDown(self):
 		frappe.db.set_value("HR Settings", None, "include_holidays_in_total_working_days", 0)
 		frappe.set_user("Administrator")
 
 	def test_salary_slip_with_holidays_included(self):
+		no_of_days = self.get_no_of_days()
 		frappe.db.set_value("HR Settings", None, "include_holidays_in_total_working_days", 1)
 		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.make_employee_salary_slip("test_employee@salary.com", "Monthly"))
 
-		self.assertEquals(ss.total_days_in_month, 31)
-		self.assertEquals(ss.payment_days, 31)
+		self.assertEquals(ss.total_working_days, no_of_days[0])
+		self.assertEquals(ss.payment_days, no_of_days[0])
 		self.assertEquals(ss.earnings[0].amount, 5000)
 		self.assertEquals(ss.earnings[1].amount, 3000)
 		self.assertEquals(ss.deductions[0].amount, 5000)
@@ -48,15 +48,16 @@
 		self.assertEquals(ss.net_pay, 3000)
 
 	def test_salary_slip_with_holidays_excluded(self):
+		no_of_days = self.get_no_of_days()
 		frappe.db.set_value("HR Settings", None, "include_holidays_in_total_working_days", 0)
 		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.make_employee_salary_slip("test_employee@salary.com", "Monthly"))
 
-		self.assertEquals(ss.total_days_in_month, 28)
-		self.assertEquals(ss.payment_days, 28)
+		self.assertEquals(ss.total_working_days, no_of_days[0] - no_of_days[1])
+		self.assertEquals(ss.payment_days, no_of_days[0] - no_of_days[1])
 		self.assertEquals(ss.earnings[0].amount, 5000)
 		self.assertEquals(ss.earnings[0].default_amount, 5000)
 		self.assertEquals(ss.earnings[1].amount, 3000)
@@ -66,43 +67,52 @@
 		self.assertEquals(ss.net_pay, 3000)
 		
 	def test_payment_days(self):
+		no_of_days = self.get_no_of_days()
 		# Holidays not included in working days
-		frappe.db.set_value("HR Settings", None, "include_holidays_in_total_working_days", 0)
+		frappe.db.set_value("HR Settings", None, "include_holidays_in_total_working_days", 1)
 
 		# set joinng date in the same month
 		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"))
+		if getdate(nowdate()).day > 15:
+			date_of_joining = getdate(add_days(nowdate(),-10))
+			relieving_date = getdate(add_days(nowdate(),-10))
+		elif getdate(nowdate()).day < 15 and getdate(nowdate()).day > 5:
+			date_of_joining = getdate(add_days(nowdate(),-3))
+			relieving_date = getdate(add_days(nowdate(),-3))
+		elif getdate(nowdate()).day < 5 and not getdate(nowdate()).day == 1:
+			date_of_joining = getdate(add_days(nowdate(),-1))
+			relieving_date = getdate(add_days(nowdate(),-1))
+		elif getdate(nowdate()).day == 1:
+			date_of_joining = getdate(nowdate())
+			relieving_date = getdate(nowdate())
 
-		self.assertEquals(ss.total_days_in_month, 28)
-		self.assertEquals(ss.payment_days, 28)
-
-		# set relieving date in the same month
-		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, 28)
-		self.assertEquals(ss.payment_days, 28)
-		ss.save()
-		
+		frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}, "name"), "date_of_joining", date_of_joining)
 		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)	
-		self.assertEquals(ss.total_days_in_month, 28)
-		self.assertEquals(ss.payment_days, 28)
+		
+		ss = frappe.get_doc("Salary Slip",
+			self.make_employee_salary_slip("test_employee@salary.com", "Monthly"))
+
+		self.assertEquals(ss.total_working_days, no_of_days[0])
+		self.assertEquals(ss.payment_days, (no_of_days[0] - getdate(date_of_joining).day + 1))
+
+		# set relieving date in the same month
+		frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}, "name"), "date_of_joining", (add_days(nowdate(),-60)))
+		frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}, "name"), "relieving_date", relieving_date)
+		frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}, "name"), "status", "Left")
 		ss.save()
-				#
-		# 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)
+		
+		self.assertEquals(ss.total_working_days, no_of_days[0])
+		self.assertEquals(ss.payment_days, getdate(relieving_date).day)
+
+		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")
 
 	def test_employee_salary_slip_read_permission(self):
 		self.make_employee("test_employee@salary.com")
 
 		salary_slip_test_employee = frappe.get_doc("Salary Slip",
-			self.make_employee_salary_slip("test_employee@salary.com"))
+			self.make_employee_salary_slip("test_employee@salary.com", "Monthly"))
 		frappe.set_user("test_employee@salary.com")
 		self.assertTrue(salary_slip_test_employee.has_permission("read"))
 
@@ -115,11 +125,33 @@
 
 		self.make_employee("test_employee@salary.com")
 		ss = frappe.get_doc("Salary Slip",
-			self.make_employee_salary_slip("test_employee@salary.com"))
+			self.make_employee_salary_slip("test_employee@salary.com", "Monthly"))
 		ss.submit()
 		email_queue = frappe.db.sql("""select name from `tabEmail Queue`""")
 		self.assertTrue(email_queue)
 
+	def test_payroll_frequency(self):
+		fiscal_year = get_fiscal_year(nowdate())[0]
+		month = "%02d" % getdate(nowdate()).month
+		m = get_month_details(fiscal_year, month)
+
+		for payroll_frequncy in ["Monthly", "Bimonthly", "Fortnightly", "Weekly", "Daily"]:
+			self.make_employee(payroll_frequncy + "_test_employee@salary.com")
+			ss = frappe.get_doc("Salary Slip",
+				self.make_employee_salary_slip(payroll_frequncy + "_test_employee@salary.com", payroll_frequncy))
+			if payroll_frequncy == "Monthly":
+				self.assertEqual(ss.end_date, m['month_end_date'])
+			elif payroll_frequncy == "Bimonthly":
+				if getdate(ss.start_date).day <= 15:
+					self.assertEqual(ss.end_date, m['month_mid_end_date'])
+				else:
+					self.assertEqual(ss.end_date, m['month_end_date'])
+			elif payroll_frequncy == "Fortnightly":
+				self.assertEqual(ss.end_date, getdate(add_days(nowdate(),13)))
+			elif payroll_frequncy == "Weekly":
+				self.assertEqual(ss.end_date, getdate(add_days(nowdate(),6)))
+			elif payroll_frequncy == "Daily":
+				self.assertEqual(ss.end_date, getdate(nowdate()))
 
 	def make_employee(self, user):
 		if not frappe.db.get_value("User", user):
@@ -148,29 +180,30 @@
 				"status": "Active",
 				"employment_type": "Intern"
 			}).insert()
-			
+
 	def make_holiday_list(self):
+		fiscal_year = get_fiscal_year(nowdate())
 		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),
+				"from_date": fiscal_year[1],
+				"to_date": fiscal_year[2],
 				"weekly_off": "Sunday"
 			}).insert()	
 			holiday_list.get_weekly_off_dates()
 			holiday_list.save()
-				
-	def make_employee_salary_slip(self, user):
+
+	def make_employee_salary_slip(self, user, payroll_frequency):
 		employee = frappe.db.get_value("Employee", {"user_id": user})
-		salary_structure = make_salary_structure("Salary Structure Test for Salary Slip")
+		salary_structure = make_salary_structure(payroll_frequency + " Salary Structure Test for Salary Slip", payroll_frequency, employee)
 		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, 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.payroll_frequency = payroll_frequency
+			salary_slip.start_date = nowdate()
 			salary_slip.posting_date = nowdate()
 			salary_slip.insert()
 			# salary_slip.submit()
@@ -185,38 +218,68 @@
 		activity_type.wage_rate = 25
 		activity_type.save()
 
-def make_salary_component(salary_components):
+	def get_no_of_days(self):
+		no_of_days_in_month = calendar.monthrange(getdate(nowdate()).year,
+		                                  getdate(nowdate()).month)
+		no_of_holidays_in_month = len([1 for i in calendar.monthcalendar(getdate(nowdate()).year,
+		                                  getdate(nowdate()).month) if i[6] != 0])
+		return [no_of_days_in_month[1], no_of_holidays_in_month]
+
+
+def make_earning_salary_component(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
+				"salary_component": salary_component,
+				"type": "Earning"
 			})
 			sal_comp.insert()
 		get_salary_component_account(salary_component)
 
-def make_salary_structure(sal_struct):
+def make_deduction_salary_component(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,
+				"type": "Deduction"
+			})
+			sal_comp.insert()
+		get_salary_component_account(salary_component)
+
+def make_salary_structure(sal_struct, payroll_frequency, employee):
 	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(),
+			"employees": get_employee_details(employee),
 			"earnings": get_earnings_component(),
 			"deductions": get_deductions_component(),
+			"payroll_frequency": payroll_frequency,
 			"payment_account": frappe.get_value('Account', {'account_type': 'Cash', 'company': erpnext.get_default_company(),'is_group':0}, "name")
 		}).insert()
+
+	elif not frappe.db.get_value("Salary Structure Employee",{'parent':sal_struct, 'employee':employee},'name'):
+		sal_struct = frappe.get_doc("Salary Structure", sal_struct)
+		sal_struct.append("employees", {"employee": employee,
+			"employee_name": employee,
+			"base": 32000,
+			"variable": 3200
+			})
+		sal_struct.save()
+		sal_struct = sal_struct.name
 	return sal_struct
-			
-			
-def get_employee_details():
-	return [{"employee": frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}, "name"),
+
+def get_employee_details(employee):
+	return [{"employee": employee,
 			"base": 25000,
 			"variable": 5000
 			}
 		]
-			
+
 def get_earnings_component():	
 	return [
 				{
@@ -270,7 +333,4 @@
 					"formula": 'base*.1',
 					"idx": 3
 				}
-			]			
-
-test_dependencies = ["Leave Application", "Holiday List"]
-			
\ No newline at end of file
+			]
\ 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 d3ab809..0bc67a7 100755
--- a/erpnext/hr/doctype/salary_structure/salary_structure.js
+++ b/erpnext/hr/doctype/salary_structure/salary_structure.js
@@ -15,6 +15,8 @@
 
 frappe.ui.form.on('Salary Structure', {
 	onload: function(frm) {
+		frm.toggle_reqd(['payroll_frequency'], !frm.doc.salary_slip_based_on_timesheet),
+		
 		frm.set_query("salary_component", "earnings", function() {
 			return {
 				filters: {
@@ -142,6 +144,7 @@
 	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);
+		frm.toggle_reqd(['payroll_frequency'], !frm.doc.salary_slip_based_on_timesheet);
 	}
 });
 
diff --git a/erpnext/hr/doctype/salary_structure/salary_structure.json b/erpnext/hr/doctype/salary_structure/salary_structure.json
index 8a9068d..5c0a635 100644
--- a/erpnext/hr/doctype/salary_structure/salary_structure.json
+++ b/erpnext/hr/doctype/salary_structure/salary_structure.json
@@ -100,6 +100,37 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "default": "", 
+   "depends_on": "eval:(!doc.salary_slip_based_on_timesheet)", 
+   "fieldname": "payroll_frequency", 
+   "fieldtype": "Select", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Payroll Frequency", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "\nMonthly\nFortnightly\nBimonthly\nWeekly\nDaily", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
    "fieldname": "column_break1", 
    "fieldtype": "Column Break", 
    "hidden": 0, 
@@ -863,7 +894,7 @@
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2016-11-07 05:13:46.584365", 
+ "modified": "2016-12-07 14:57:22.083825", 
  "modified_by": "Administrator", 
  "module": "HR", 
  "name": "Salary Structure", 
diff --git a/erpnext/hr/doctype/salary_structure/test_salary_structure.py b/erpnext/hr/doctype/salary_structure/test_salary_structure.py
index 81f6743..9217c64 100644
--- a/erpnext/hr/doctype/salary_structure/test_salary_structure.py
+++ b/erpnext/hr/doctype/salary_structure/test_salary_structure.py
@@ -8,25 +8,16 @@
 from frappe.utils.make_random import get_random
 from frappe.utils import nowdate, add_days, add_years
 from erpnext.hr.doctype.salary_structure.salary_structure import make_salary_slip
-from erpnext.hr.doctype.salary_slip.test_salary_slip import make_salary_component
-# test_records = frappe.get_test_records('Salary Structure')
+from erpnext.hr.doctype.salary_slip.test_salary_slip import make_earning_salary_component, make_deduction_salary_component
 
 class TestSalaryStructure(unittest.TestCase):
 	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")
-		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")
+		make_earning_salary_component(["Basic Salary", "Allowance", "HRA"])
+		make_deduction_salary_component(["Professional Tax", "TDS"])
+		self.make_employee("test_employee@salary.com")
+		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"):
@@ -87,9 +78,9 @@
 	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.start_date = nowdate()
 	sal_slip.posting_date = nowdate()
+	sal_slip.payroll_frequency =  "Monthly"
 	sal_slip.insert()
 	sal_slip.submit()
 	return sal_slip	
@@ -104,6 +95,7 @@
 			"employees": get_employee_details(),
 			"earnings": get_earnings_component(),
 			"deductions": get_deductions_component(),
+			"payroll_frequency": "Monthly",
 			"payment_account": frappe.get_value('Account', {'account_type': 'Cash', 'company': erpnext.get_default_company(),'is_group':0}, "name")
 		}).insert()
 	return sal_struct
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 1789c75..0c38d45 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,7 +6,7 @@
  "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\": \"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\"}]", 
+ "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_working_days\"}, {\"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-08-22 00:21:42.600548", 
  "modified_by": "Administrator", 
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index 6069a4d..94212ec 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -354,3 +354,5 @@
 erpnext.patches.v7_0.update_autoname_field
 erpnext.patches.v7_1.update_bom_base_currency
 erpnext.patches.v7_0.update_status_of_po_so
+erpnext.patches.v7_1.set_budget_against_as_cost_center
+erpnext.patches.v7_1.set_currency_exchange_date
\ No newline at end of file
diff --git a/erpnext/patches/v6_16/update_billing_status_in_dn_and_pr.py b/erpnext/patches/v6_16/update_billing_status_in_dn_and_pr.py
index b660d39..481f130 100644
--- a/erpnext/patches/v6_16/update_billing_status_in_dn_and_pr.py
+++ b/erpnext/patches/v6_16/update_billing_status_in_dn_and_pr.py
@@ -22,7 +22,7 @@
 
 	# Update billed_amt in DN and PR which are not against any order
 	for d in frappe.db.sql("""select name from `tabPurchase Receipt Item` item
-		where (prevdoc_detail_docname is null or prevdoc_detail_docname = '') and docstatus=1""", as_dict=1):
+		where (purchase_order_item is null or purchase_order_item = '') and docstatus=1""", as_dict=1):
 
 		billed_amt = frappe.db.sql("""select sum(amount) from `tabPurchase Invoice Item`
 			where pr_detail=%s and docstatus=1""", d.name)
diff --git a/erpnext/patches/v7_0/update_status_of_po_so.py b/erpnext/patches/v7_0/update_status_of_po_so.py
index 0e2dd74..c0b6f59 100644
--- a/erpnext/patches/v7_0/update_status_of_po_so.py
+++ b/erpnext/patches/v7_0/update_status_of_po_so.py
@@ -18,9 +18,9 @@
 			`tabPurchase Order`.per_received = round((select sum(if(qty > ifnull(received_qty, 0),
 					ifnull(received_qty, 0), qty)) / sum(qty) *100 from `tabPurchase Order Item`
 					where parent = `tabPurchase Order`.name), 2),
-			`tabPurchase Order`.per_billed = round((select sum( if(amount > ifnull(billed_amt, 0),
+			`tabPurchase Order`.per_billed = ifnull(round((select sum( if(amount > ifnull(billed_amt, 0),
 					ifnull(billed_amt, 0), amount)) / sum(amount) *100 from `tabPurchase Order Item`
-					where parent = `tabPurchase Order`.name), 2)""")
+					where parent = `tabPurchase Order`.name), 2), 0)""")
 
 def update_so_per_delivered_per_billed():
 	frappe.db.sql(""" 
@@ -30,9 +30,9 @@
 			`tabSales Order`.per_delivered = round((select sum( if(qty > ifnull(delivered_qty, 0),
 					ifnull(delivered_qty, 0), qty)) / sum(qty) *100 from `tabSales Order Item` 
 					where parent = `tabSales Order`.name), 2), 
-			`tabSales Order`.per_billed = round((select sum( if(amount > ifnull(billed_amt, 0),
+			`tabSales Order`.per_billed = ifnull(round((select sum( if(amount > ifnull(billed_amt, 0),
 					ifnull(billed_amt, 0), amount)) / sum(amount) *100 from `tabSales Order Item`
-					where parent = `tabSales Order`.name), 2)""")
+					where parent = `tabSales Order`.name), 2), 0)""")
 
 def update_status():
 	frappe.db.sql("""
diff --git a/erpnext/patches/v7_1/set_budget_against_as_cost_center.py b/erpnext/patches/v7_1/set_budget_against_as_cost_center.py
new file mode 100644
index 0000000..1d334a5
--- /dev/null
+++ b/erpnext/patches/v7_1/set_budget_against_as_cost_center.py
@@ -0,0 +1,10 @@
+import frappe
+
+def execute():
+	frappe.reload_doc("accounts", "doctype", "budget")
+	frappe.db.sql("""
+		update
+			`tabBudget`
+		set
+			budget_against = 'Cost Center'
+		""")
diff --git a/erpnext/patches/v7_1/set_currency_exchange_date.py b/erpnext/patches/v7_1/set_currency_exchange_date.py
new file mode 100644
index 0000000..7d8e4f0
--- /dev/null
+++ b/erpnext/patches/v7_1/set_currency_exchange_date.py
@@ -0,0 +1,9 @@
+import frappe
+
+def execute():
+	frappe.reload_doctype("Currency Exchange")
+	frappe.db.sql("""
+		update `tabCurrency Exchange` 
+		set `date` = '2010-01-01' 
+		where date is null or date = '' or date = '0000-00-00'
+	""")
\ No newline at end of file
diff --git a/erpnext/projects/doctype/timesheet/test_timesheet.py b/erpnext/projects/doctype/timesheet/test_timesheet.py
index 98866ab..11d0b1c 100644
--- a/erpnext/projects/doctype/timesheet/test_timesheet.py
+++ b/erpnext/projects/doctype/timesheet/test_timesheet.py
@@ -7,7 +7,7 @@
 import unittest
 import datetime
 from frappe.utils.make_random import get_random
-from frappe.utils import now_datetime, nowdate
+from frappe.utils import now_datetime, nowdate, add_days
 from erpnext.projects.doctype.timesheet.timesheet import OverlapError
 from erpnext.projects.doctype.timesheet.timesheet import make_salary_slip, make_sales_invoice
 from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
@@ -76,7 +76,7 @@
 		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.from_date = add_days(nowdate(), -30)
 		salary_structure.salary_component = "Basic"
 		salary_structure.hour_rate = 50.0
 		salary_structure.company = "_Test Company"
diff --git a/erpnext/projects/doctype/timesheet/timesheet.py b/erpnext/projects/doctype/timesheet/timesheet.py
index bb19581..48d3e00 100644
--- a/erpnext/projects/doctype/timesheet/timesheet.py
+++ b/erpnext/projects/doctype/timesheet/timesheet.py
@@ -79,9 +79,9 @@
 			self.status = "Completed"
 
 	def set_dates(self):
-		if self.docstatus < 2:
-			start_date = min([d.from_time for d in self.time_logs])
-			end_date = max([d.to_time for d in self.time_logs])
+		if self.docstatus < 2 and self.time_logs:
+			start_date = min([getdate(d.from_time) for d in self.time_logs])
+			end_date = max([getdate(d.to_time) for d in self.time_logs])
 
 			if start_date and end_date:
 				self.start_date = getdate(start_date)
diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js
index 954b03b..c31b0c8 100644
--- a/erpnext/public/js/controllers/transaction.js
+++ b/erpnext/public/js/controllers/transaction.js
@@ -413,6 +413,7 @@
 	transaction_date: function() {
 		if (this.frm.doc.transaction_date) {
 			this.frm.transaction_date = this.frm.doc.transaction_date;
+			frappe.ui.form.trigger(this.frm.doc.doctype, "currency");
 		}
 	},
 
@@ -434,9 +435,12 @@
 					callback: function(r, rt) {
 						if(r.message) {
 							me.frm.set_value("due_date", r.message);
+							frappe.ui.form.trigger(me.frm.doc.doctype, "currency");
 						}
 					}
 				})
+			} else {
+				frappe.ui.form.trigger(me.frm.doc.doctype, "currency");
 			}
 		}
 	},
@@ -450,6 +454,10 @@
 	},
 
 	currency: function() {
+		/* manqala 19/09/2016: let the translation date be whichever of the transaction_date or posting_date is available */
+		var transaction_date = this.frm.doc.transaction_date || this.frm.doc.posting_date;
+		/* end manqala */
+		
 		var me = this;
 		this.set_dynamic_labels();
 
@@ -457,7 +465,7 @@
 		// Added `ignore_pricing_rule` to determine if document is loading after mapping from another doc
 		if(this.frm.doc.currency && this.frm.doc.currency !== company_currency
 				&& !this.frm.doc.ignore_pricing_rule) {
-			this.get_exchange_rate(this.frm.doc.currency, company_currency,
+			this.get_exchange_rate(transaction_date, this.frm.doc.currency, company_currency,
 				function(exchange_rate) {
 					me.frm.set_value("conversion_rate", exchange_rate);
 				});
@@ -485,10 +493,11 @@
 		}
 	},
 
-	get_exchange_rate: function(from_currency, to_currency, callback) {
+	get_exchange_rate: function(transaction_date, from_currency, to_currency, callback) {
 		return frappe.call({
 			method: "erpnext.setup.utils.get_exchange_rate",
 			args: {
+				transaction_date: transaction_date,
 				from_currency: from_currency,
 				to_currency: to_currency
 			},
@@ -505,7 +514,7 @@
 		var company_currency = this.get_company_currency();
 		// Added `ignore_pricing_rule` to determine if document is loading after mapping from another doc
 		if(this.frm.doc.price_list_currency !== company_currency  && !this.frm.doc.ignore_pricing_rule) {
-			this.get_exchange_rate(this.frm.doc.price_list_currency, company_currency,
+			this.get_exchange_rate(this.frm.doc.posting_date, this.frm.doc.price_list_currency, company_currency,
 				function(exchange_rate) {
 					me.frm.set_value("plc_conversion_rate", exchange_rate);
 				});
diff --git a/erpnext/setup/doctype/company/fixtures/india/__init__.py b/erpnext/setup/doctype/company/fixtures/india/__init__.py
index 2aeec99..0f4bd4f 100644
--- a/erpnext/setup/doctype/company/fixtures/india/__init__.py
+++ b/erpnext/setup/doctype/company/fixtures/india/__init__.py
@@ -7,9 +7,10 @@
 
 def install(company):
 	docs = [
-		{'doctype': 'Salary Component', 'salary_component': 'Professional Tax', 'description': 'Professional Tax'},
-		{'doctype': 'Salary Component', 'salary_component': 'Provident Fund', 'description': 'Provident fund'},
-		{'doctype': 'Salary Component', 'salary_component': 'House Rent Allowance', 'description': 'House Rent Allowance'}
+		{'doctype': 'Salary Component', 'salary_component': 'Professional Tax', 'description': 'Professional Tax', 'type': 'Deduction'},
+		{'doctype': 'Salary Component', 'salary_component': 'Provident Fund', 'description': 'Provident fund', 'type': 'Deduction'},
+		{'doctype': 'Salary Component', 'salary_component': 'House Rent Allowance', 'description': 'House Rent Allowance', 'type': 'Earning'},
+		{'doctype': 'Salary Component', 'salary_component': 'Basic', 'description': 'Basic', 'type': 'Earning'}
 	]
 
 	for d in docs:
diff --git a/erpnext/setup/doctype/currency_exchange/currency_exchange.json b/erpnext/setup/doctype/currency_exchange/currency_exchange.json
index 44cea20..76e1a6b 100644
--- a/erpnext/setup/doctype/currency_exchange/currency_exchange.json
+++ b/erpnext/setup/doctype/currency_exchange/currency_exchange.json
@@ -17,6 +17,33 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fieldname": "date", 
+   "fieldtype": "Date", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 1, 
+   "label": "Date", 
+   "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, 
+   "width": "5"
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
    "fieldname": "from_currency", 
    "fieldtype": "Link", 
    "hidden": 0, 
@@ -38,7 +65,8 @@
    "reqd": 1, 
    "search_index": 0, 
    "set_only_once": 0, 
-   "unique": 0
+   "unique": 0, 
+   "width": "3"
   }, 
   {
    "allow_on_submit": 0, 
@@ -66,7 +94,8 @@
    "reqd": 1, 
    "search_index": 0, 
    "set_only_once": 0, 
-   "unique": 0
+   "unique": 0, 
+   "width": "3"
   }, 
   {
    "allow_on_submit": 0, 
@@ -94,7 +123,8 @@
    "reqd": 1, 
    "search_index": 0, 
    "set_only_once": 0, 
-   "unique": 0
+   "unique": 0, 
+   "width": "3"
   }
  ], 
  "hide_heading": 0, 
@@ -108,7 +138,7 @@
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2016-11-07 05:28:09.772560", 
+ "modified": "2016-11-08 05:28:09.772560", 
  "modified_by": "Administrator", 
  "module": "Setup", 
  "name": "Currency Exchange", 
@@ -202,5 +232,8 @@
  "quick_entry": 1, 
  "read_only": 0, 
  "read_only_onload": 0, 
+ "sort_field": "name", 
+ "sort_order": "DESC", 
+ "title_field": "", 
  "track_seen": 0
 }
\ No newline at end of file
diff --git a/erpnext/setup/doctype/currency_exchange/currency_exchange.py b/erpnext/setup/doctype/currency_exchange/currency_exchange.py
index 6022812..7f1a43c 100644
--- a/erpnext/setup/doctype/currency_exchange/currency_exchange.py
+++ b/erpnext/setup/doctype/currency_exchange/currency_exchange.py
@@ -7,13 +7,15 @@
 import frappe
 from frappe import _
 from frappe.model.document import Document
+from frappe.utils import get_datetime, get_datetime_str, formatdate
 
 class CurrencyExchange(Document):
-	def autoname(self):
-		self.name = self.from_currency + "-" + self.to_currency
+    def autoname(self):
+        self.name = formatdate(get_datetime_str(self.date),"yyyy-MM-dd") + "-" + self.from_currency + "-" + self.to_currency
+        #self.name = self.date + "-" + self.from_currency + "-" + self.to_currency
 
-	def validate(self):
-		self.validate_value("exchange_rate", ">", 0)
+    def validate(self):
+        self.validate_value("exchange_rate", ">", 0)
 
-		if self.from_currency == self.to_currency:
-			frappe.throw(_("From Currency and To Currency cannot be same"))
+        if self.from_currency == self.to_currency:
+            frappe.throw(_("From Currency and To Currency cannot be same"))
diff --git a/erpnext/setup/doctype/currency_exchange/test_currency_exchange.py b/erpnext/setup/doctype/currency_exchange/test_currency_exchange.py
index 0077630..181f072 100644
--- a/erpnext/setup/doctype/currency_exchange/test_currency_exchange.py
+++ b/erpnext/setup/doctype/currency_exchange/test_currency_exchange.py
@@ -3,5 +3,18 @@
 from __future__ import unicode_literals
 
 
-import frappe
-test_records = frappe.get_test_records('Currency Exchange')
\ No newline at end of file
+import frappe, unittest
+test_records = frappe.get_test_records('Currency Exchange')
+
+class TestCurrencyExchange(unittest.TestCase):
+	def test_exchnage_rate(self):
+		from erpnext.setup.utils import get_exchange_rate
+		
+		# Exchange rate as on 15th Jan, 2016, should be fetched from Currency Exchange record
+		exchange_rate = get_exchange_rate("USD", "INR", "2016-01-15")
+		self.assertEqual(exchange_rate, 60.0)
+		
+		# Exchange rate as on 15th Dec, 2015, should be fetched from fixer.io
+		exchange_rate = get_exchange_rate("USD", "INR", "2015-12-15")
+		self.assertFalse(exchange_rate==60)
+		
\ No newline at end of file
diff --git a/erpnext/setup/doctype/currency_exchange/test_records.json b/erpnext/setup/doctype/currency_exchange/test_records.json
index 784bf26..23edd8a 100644
--- a/erpnext/setup/doctype/currency_exchange/test_records.json
+++ b/erpnext/setup/doctype/currency_exchange/test_records.json
@@ -1,18 +1,21 @@
 [
  {
   "doctype": "Currency Exchange", 
+  "date": "2016-01-01",
   "exchange_rate": 60.0, 
   "from_currency": "USD", 
   "to_currency": "INR"
  }, 
  {
   "doctype": "Currency Exchange", 
+  "date": "2016-01-01",
   "exchange_rate": 0.773, 
   "from_currency": "USD", 
   "to_currency": "EUR"
  }, 
  {
   "doctype": "Currency Exchange", 
+  "date": "2016-01-01",
   "exchange_rate": 0.0167, 
   "from_currency": "INR", 
   "to_currency": "USD"
diff --git a/erpnext/setup/utils.py b/erpnext/setup/utils.py
index eda2042..0c214e4 100644
--- a/erpnext/setup/utils.py
+++ b/erpnext/setup/utils.py
@@ -5,7 +5,8 @@
 import frappe
 from frappe import _, throw
 from frappe.utils import flt
-
+from frappe.utils import get_datetime_str, nowdate
+	
 def get_company_currency(company):
 	currency = frappe.db.get_value("Company", company, "default_currency", cache=True)
 	if not currency:
@@ -64,36 +65,44 @@
 	frappe.db.commit()
 
 @frappe.whitelist()
-def get_exchange_rate(from_currency, to_currency):
+def get_exchange_rate(from_currency, to_currency, transaction_date=None):
+	if not transaction_date:
+		transaction_date = nowdate()
 	if not (from_currency and to_currency):
+		# manqala 19/09/2016: Should this be an empty return or should it throw and exception?
 		return
 	
 	if from_currency == to_currency:
 		return 1
 	
-	exchange = "%s-%s" % (from_currency, to_currency)
-	value = flt(frappe.db.get_value("Currency Exchange", exchange, "exchange_rate"))
+	# cksgb 19/09/2016: get last entry in Currency Exchange with from_currency and to_currency.
+	entries = frappe.get_all("Currency Exchange", fields = ["exchange_rate"], 
+		filters=[
+			["date", "<=", get_datetime_str(transaction_date)], 
+			["from_currency", "=", from_currency], 
+			["to_currency", "=", to_currency]
+		], order_by="date desc", limit=1)
+	
+	if entries:
+		return flt(entries[0].exchange_rate)
 
-	if not value:
-		try:
-			cache = frappe.cache()
-			key = "currency_exchange_rate:{0}:{1}".format(from_currency, to_currency)
-			value = cache.get(key)
+	try:
+		cache = frappe.cache()
+		key = "currency_exchange_rate:{0}:{1}".format(from_currency, to_currency)
+		value = cache.get(key)
 
-			if not value:
-				import requests
-				response = requests.get("http://api.fixer.io/latest", params={
-					"base": from_currency,
-					"symbols": to_currency
-				})
-				# expire in 6 hours
-				response.raise_for_status()
-				value = response.json()["rates"][to_currency]
-				cache.setex(key, value, 6 * 60 * 60)
+		if not value:
+			import requests
+			response = requests.get("http://api.fixer.io/latest", params={
+				"base": from_currency,
+				"symbols": to_currency
+			})
+			# expire in 6 hours
+			response.raise_for_status()
+			value = response.json()["rates"][to_currency]
+			cache.setex(key, value, 6 * 60 * 60)
 
-			return flt(value)
-		except:
-			frappe.msgprint(_("Unable to find exchange rate for {0} to {1}").format(from_currency, to_currency))
-			return 0.0
-	else:
-		return value
+		return flt(value)
+	except:
+		frappe.msgprint(_("Unable to find exchange rate for {0} to {1} for key date {2}").format(from_currency, to_currency, transaction_date))
+		return 0.0
\ No newline at end of file
diff --git a/erpnext/shopping_cart/doctype/shopping_cart_settings/shopping_cart_settings.py b/erpnext/shopping_cart/doctype/shopping_cart_settings/shopping_cart_settings.py
index d8d00ef..6915ef5 100644
--- a/erpnext/shopping_cart/doctype/shopping_cart_settings/shopping_cart_settings.py
+++ b/erpnext/shopping_cart/doctype/shopping_cart_settings/shopping_cart_settings.py
@@ -8,6 +8,7 @@
 from frappe import _, msgprint
 from frappe.utils import comma_and
 from frappe.model.document import Document
+from frappe.utils import get_datetime, get_datetime_str, now_datetime
 
 class ShoppingCartSetupError(frappe.ValidationError): pass
 
@@ -38,11 +39,18 @@
 		expected_to_exist = [currency + "-" + company_currency
 			for currency in price_list_currency_map.values()
 			if currency != company_currency]
+		
+		# manqala 20/09/2016: set up selection parameters for query from tabCurrency Exchange	
+		from_currency = [currency for currency in price_list_currency_map.values() if currency != company_currency]
+		to_currency = company_currency
+		# manqala end
 
 		if expected_to_exist:
-			exists = frappe.db.sql_list("""select name from `tabCurrency Exchange`
-				where name in (%s)""" % (", ".join(["%s"]*len(expected_to_exist)),),
-				tuple(expected_to_exist))
+			# manqala 20/09/2016: modify query so that it uses date in the selection from Currency Exchange.
+			# exchange rates defined with date less than the date on which this document is being saved will be selected
+			exists = frappe.db.sql_list("""select CONCAT(from_currency,'-',to_currency) from `tabCurrency Exchange`
+				where from_currency in (%s) and to_currency = "%s" and date <= curdate()""" % (", ".join(["%s"]*len(from_currency)), to_currency), tuple(from_currency))
+			# manqala end
 
 			missing = list(set(expected_to_exist).difference(exists))
 
diff --git a/erpnext/stock/doctype/material_request_item/material_request_item.json b/erpnext/stock/doctype/material_request_item/material_request_item.json
index f7ca7d9..b1d6ec0 100644
--- a/erpnext/stock/doctype/material_request_item/material_request_item.json
+++ b/erpnext/stock/doctype/material_request_item/material_request_item.json
@@ -23,6 +23,7 @@
    "ignore_xss_filter": 0, 
    "in_filter": 1, 
    "in_list_view": 1, 
+   "in_standard_filter": 0, 
    "label": "Item Code", 
    "length": 0, 
    "no_copy": 0, 
@@ -34,6 +35,7 @@
    "print_hide_if_no_value": 0, 
    "print_width": "100px", 
    "read_only": 0, 
+   "remember_last_selected_value": 0, 
    "report_hide": 0, 
    "reqd": 1, 
    "search_index": 1, 
@@ -53,12 +55,14 @@
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
+   "in_standard_filter": 0, 
    "length": 0, 
    "no_copy": 0, 
    "permlevel": 0, 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
+   "remember_last_selected_value": 0, 
    "report_hide": 0, 
    "reqd": 0, 
    "search_index": 0, 
@@ -77,6 +81,7 @@
    "ignore_xss_filter": 0, 
    "in_filter": 1, 
    "in_list_view": 0, 
+   "in_standard_filter": 0, 
    "label": "Item Name", 
    "length": 0, 
    "no_copy": 0, 
@@ -87,6 +92,7 @@
    "print_hide_if_no_value": 0, 
    "print_width": "100px", 
    "read_only": 0, 
+   "remember_last_selected_value": 0, 
    "report_hide": 0, 
    "reqd": 0, 
    "search_index": 1, 
@@ -106,6 +112,7 @@
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
+   "in_standard_filter": 0, 
    "label": "Description", 
    "length": 0, 
    "no_copy": 0, 
@@ -114,6 +121,7 @@
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
+   "remember_last_selected_value": 0, 
    "report_hide": 0, 
    "reqd": 0, 
    "search_index": 0, 
@@ -132,6 +140,7 @@
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
+   "in_standard_filter": 0, 
    "label": "Description", 
    "length": 0, 
    "no_copy": 0, 
@@ -142,6 +151,7 @@
    "print_hide_if_no_value": 0, 
    "print_width": "250px", 
    "read_only": 0, 
+   "remember_last_selected_value": 0, 
    "report_hide": 0, 
    "reqd": 1, 
    "search_index": 0, 
@@ -161,6 +171,7 @@
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
+   "in_standard_filter": 0, 
    "length": 0, 
    "no_copy": 0, 
    "permlevel": 0, 
@@ -168,6 +179,7 @@
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
+   "remember_last_selected_value": 0, 
    "report_hide": 0, 
    "reqd": 0, 
    "search_index": 0, 
@@ -186,6 +198,7 @@
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
+   "in_standard_filter": 0, 
    "label": "Image", 
    "length": 0, 
    "no_copy": 0, 
@@ -194,6 +207,7 @@
    "print_hide": 1, 
    "print_hide_if_no_value": 0, 
    "read_only": 1, 
+   "remember_last_selected_value": 0, 
    "report_hide": 0, 
    "reqd": 0, 
    "search_index": 0, 
@@ -212,6 +226,7 @@
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
+   "in_standard_filter": 0, 
    "label": "Quantity and Warehouse", 
    "length": 0, 
    "no_copy": 0, 
@@ -219,6 +234,7 @@
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
+   "remember_last_selected_value": 0, 
    "report_hide": 0, 
    "reqd": 0, 
    "search_index": 0, 
@@ -237,6 +253,7 @@
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 1, 
+   "in_standard_filter": 0, 
    "label": "Quantity", 
    "length": 0, 
    "no_copy": 0, 
@@ -247,6 +264,7 @@
    "print_hide_if_no_value": 0, 
    "print_width": "80px", 
    "read_only": 0, 
+   "remember_last_selected_value": 0, 
    "report_hide": 0, 
    "reqd": 1, 
    "search_index": 0, 
@@ -266,6 +284,7 @@
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
+   "in_standard_filter": 0, 
    "label": "Stock UOM", 
    "length": 0, 
    "no_copy": 0, 
@@ -277,6 +296,7 @@
    "print_hide_if_no_value": 0, 
    "print_width": "70px", 
    "read_only": 1, 
+   "remember_last_selected_value": 0, 
    "report_hide": 0, 
    "reqd": 1, 
    "search_index": 0, 
@@ -296,6 +316,7 @@
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 1, 
+   "in_standard_filter": 0, 
    "label": "For Warehouse", 
    "length": 0, 
    "no_copy": 0, 
@@ -307,6 +328,7 @@
    "print_hide_if_no_value": 0, 
    "print_width": "100px", 
    "read_only": 0, 
+   "remember_last_selected_value": 0, 
    "report_hide": 0, 
    "reqd": 0, 
    "search_index": 0, 
@@ -326,12 +348,14 @@
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
+   "in_standard_filter": 0, 
    "length": 0, 
    "no_copy": 0, 
    "permlevel": 0, 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
+   "remember_last_selected_value": 0, 
    "report_hide": 0, 
    "reqd": 0, 
    "search_index": 0, 
@@ -351,6 +375,7 @@
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 1, 
+   "in_standard_filter": 0, 
    "label": "Required Date", 
    "length": 0, 
    "no_copy": 0, 
@@ -361,6 +386,7 @@
    "print_hide_if_no_value": 0, 
    "print_width": "100px", 
    "read_only": 0, 
+   "remember_last_selected_value": 0, 
    "report_hide": 0, 
    "reqd": 1, 
    "search_index": 0, 
@@ -380,6 +406,7 @@
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
+   "in_standard_filter": 0, 
    "label": "More Information", 
    "length": 0, 
    "no_copy": 0, 
@@ -387,6 +414,7 @@
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
+   "remember_last_selected_value": 0, 
    "report_hide": 0, 
    "reqd": 0, 
    "search_index": 0, 
@@ -406,6 +434,7 @@
    "ignore_xss_filter": 0, 
    "in_filter": 1, 
    "in_list_view": 0, 
+   "in_standard_filter": 0, 
    "label": "Item Group", 
    "length": 0, 
    "no_copy": 0, 
@@ -416,6 +445,7 @@
    "print_hide": 1, 
    "print_hide_if_no_value": 0, 
    "read_only": 1, 
+   "remember_last_selected_value": 0, 
    "report_hide": 0, 
    "reqd": 0, 
    "search_index": 1, 
@@ -434,6 +464,7 @@
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
+   "in_standard_filter": 0, 
    "label": "Brand", 
    "length": 0, 
    "no_copy": 0, 
@@ -445,6 +476,7 @@
    "print_hide_if_no_value": 0, 
    "print_width": "100px", 
    "read_only": 1, 
+   "remember_last_selected_value": 0, 
    "report_hide": 0, 
    "reqd": 0, 
    "search_index": 0, 
@@ -464,6 +496,7 @@
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
+   "in_standard_filter": 0, 
    "label": "Lead Time Date", 
    "length": 0, 
    "no_copy": 1, 
@@ -473,6 +506,7 @@
    "print_hide": 1, 
    "print_hide_if_no_value": 0, 
    "read_only": 1, 
+   "remember_last_selected_value": 0, 
    "report_hide": 0, 
    "reqd": 0, 
    "search_index": 0, 
@@ -491,6 +525,7 @@
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
+   "in_standard_filter": 0, 
    "label": "Sales Order", 
    "length": 0, 
    "no_copy": 0, 
@@ -499,6 +534,7 @@
    "print_hide": 1, 
    "print_hide_if_no_value": 0, 
    "read_only": 1, 
+   "remember_last_selected_value": 0, 
    "report_hide": 0, 
    "reqd": 0, 
    "search_index": 0, 
@@ -517,6 +553,7 @@
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
+   "in_standard_filter": 0, 
    "label": "Project", 
    "length": 0, 
    "no_copy": 0, 
@@ -526,6 +563,7 @@
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 1, 
+   "remember_last_selected_value": 0, 
    "report_hide": 0, 
    "reqd": 0, 
    "search_index": 0, 
@@ -544,12 +582,14 @@
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
+   "in_standard_filter": 0, 
    "length": 0, 
    "no_copy": 0, 
    "permlevel": 0, 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
+   "remember_last_selected_value": 0, 
    "report_hide": 0, 
    "reqd": 0, 
    "search_index": 0, 
@@ -568,6 +608,7 @@
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
+   "in_standard_filter": 0, 
    "label": "Min Order Qty", 
    "length": 0, 
    "no_copy": 1, 
@@ -578,6 +619,7 @@
    "print_hide_if_no_value": 0, 
    "print_width": "70px", 
    "read_only": 1, 
+   "remember_last_selected_value": 0, 
    "report_hide": 0, 
    "reqd": 0, 
    "search_index": 0, 
@@ -597,6 +639,7 @@
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
+   "in_standard_filter": 0, 
    "label": "Projected Qty", 
    "length": 0, 
    "no_copy": 1, 
@@ -607,6 +650,7 @@
    "print_hide_if_no_value": 0, 
    "print_width": "70px", 
    "read_only": 1, 
+   "remember_last_selected_value": 0, 
    "report_hide": 0, 
    "reqd": 0, 
    "search_index": 0, 
@@ -626,6 +670,7 @@
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
+   "in_standard_filter": 0, 
    "label": "Actual Qty", 
    "length": 0, 
    "no_copy": 1, 
@@ -634,6 +679,7 @@
    "print_hide": 1, 
    "print_hide_if_no_value": 0, 
    "read_only": 1, 
+   "remember_last_selected_value": 0, 
    "report_hide": 1, 
    "reqd": 0, 
    "search_index": 0, 
@@ -652,6 +698,7 @@
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
+   "in_standard_filter": 0, 
    "label": "Completed Qty", 
    "length": 0, 
    "no_copy": 1, 
@@ -661,6 +708,7 @@
    "print_hide": 1, 
    "print_hide_if_no_value": 0, 
    "read_only": 1, 
+   "remember_last_selected_value": 0, 
    "report_hide": 0, 
    "reqd": 0, 
    "search_index": 0, 
@@ -679,6 +727,7 @@
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
+   "in_standard_filter": 0, 
    "label": "Page Break", 
    "length": 0, 
    "no_copy": 1, 
@@ -688,6 +737,7 @@
    "print_hide": 1, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
+   "remember_last_selected_value": 0, 
    "report_hide": 0, 
    "reqd": 0, 
    "search_index": 0, 
@@ -705,7 +755,7 @@
  "issingle": 0, 
  "istable": 1, 
  "max_attachments": 0, 
- "modified": "2016-10-17 04:58:33.317145", 
+ "modified": "2016-12-08 14:49:48.397015", 
  "modified_by": "Administrator", 
  "module": "Stock", 
  "name": "Material Request Item", 
diff --git a/erpnext/stock/doctype/quality_inspection/quality_inspection.py b/erpnext/stock/doctype/quality_inspection/quality_inspection.py
index 3ba3056..c3808f7 100644
--- a/erpnext/stock/doctype/quality_inspection/quality_inspection.py
+++ b/erpnext/stock/doctype/quality_inspection/quality_inspection.py
@@ -33,12 +33,11 @@
 				
 	def on_cancel(self):
 		if self.reference_type and self.reference_name:
-			frappe.db.sql("""update `tab{doctype} Item` t1, `tab{doctype}` t2
-				set t1.quality_inspection = null, t2.modified = %s
-				where t1.parent = %s and t1.item_code = %s and t1.parent = t2.name"""
-				.format(doctype=self.reference_type),
-				(self.modified, self.reference_name, self.item_code))
-
+			frappe.db.sql("""update `tab{doctype} Item` 
+				set quality_inspection = null, modified=%s 
+				where quality_inspection = %s"""
+				.format(doctype=self.reference_type), (self.modified, self.name))
+				
 def item_query(doctype, txt, searchfield, start, page_len, filters):
 	if filters.get("from"):
 		from frappe.desk.reportview import get_match_cond
diff --git a/erpnext/stock/get_item_details.py b/erpnext/stock/get_item_details.py
index 57e2c06..16ea58e 100644
--- a/erpnext/stock/get_item_details.py
+++ b/erpnext/stock/get_item_details.py
@@ -43,7 +43,7 @@
 	get_party_item_code(args, item_doc, out)
 
 	if out.get("warehouse"):
-		out.update(get_bin_details_and_serial_nos(args.item_code, out.warehouse, args.qty, args.serial_no))	
+		out.update(get_bin_details(args.item_code, out.warehouse))	
 
 	if frappe.db.exists("Product Bundle", args.item_code):
 		valuation_rate = 0.0
@@ -481,7 +481,9 @@
 
 	if (not plc_conversion_rate) or (price_list_currency and args.price_list_currency \
 		and price_list_currency != args.price_list_currency):
-			plc_conversion_rate = get_exchange_rate(price_list_currency, args.currency) or plc_conversion_rate
+        # cksgb 19/09/2016: added args.transaction_date as posting_date argument for get_exchange_rate
+			plc_conversion_rate = get_exchange_rate(price_list_currency, args.currency, 
+				args.transaction_date) or plc_conversion_rate
 
 	return frappe._dict({
 		"price_list_currency": price_list_currency,
diff --git a/erpnext/support/doctype/issue/issue.js b/erpnext/support/doctype/issue/issue.js
index 21ef5b8..2bee422 100644
--- a/erpnext/support/doctype/issue/issue.js
+++ b/erpnext/support/doctype/issue/issue.js
@@ -15,5 +15,21 @@
 				frm.save();
 			});
 		}
+	},
+
+	timeline_refresh: function(frm) {
+		// create button for "Add to Knowledge Base"
+		if(frappe.model.can_create('Help Article')) {
+			$('<button class="btn btn-xs btn-default btn-add-to-kb pull-right" style="margin-top: -2px">'+
+				__('Add to Knowledge Base') + '</button>')
+				.appendTo(frm.timeline.wrapper.find('.comment-header'))
+				.on('click', function() {
+					var content = $(this).parents('.timeline-item:first').find('.timeline-item-content').html();
+					var doc = frappe.model.get_new_doc('Help Article');
+					doc.title = frm.doc.subject;
+					doc.content = content;
+					frappe.set_route('Form', 'Help Article', doc.name);
+				});
+		}
 	}
 });
diff --git a/erpnext/support/web_form/issues/issues.json b/erpnext/support/web_form/issues/issues.json
index 4b7c70c..6474799 100644
--- a/erpnext/support/web_form/issues/issues.json
+++ b/erpnext/support/web_form/issues/issues.json
@@ -1,8 +1,12 @@
 {
+ "accept_payment": 0, 
  "allow_comments": 1, 
  "allow_delete": 1, 
  "allow_edit": 1, 
+ "allow_incomplete": 0, 
  "allow_multiple": 1, 
+ "allow_print": 0, 
+ "amount": 0.0, 
  "breadcrumbs": "[{\"title\":\"Issues\", \"name\":\"issues\"}]", 
  "creation": "2016-06-24 15:50:33.186483", 
  "doc_type": "Issue", 
@@ -11,13 +15,16 @@
  "idx": 0, 
  "is_standard": 1, 
  "login_required": 1, 
- "modified": "2016-06-24 15:52:24.768558", 
+ "max_attachment_size": 0, 
+ "modified": "2016-12-07 04:26:13.917693", 
  "modified_by": "Administrator", 
  "module": "Support", 
  "name": "issues", 
  "owner": "Administrator", 
  "published": 1, 
  "route": "issues", 
+ "show_sidebar": 1, 
+ "sidebar_items": [], 
  "success_message": "", 
  "success_url": "/issues", 
  "title": "Issue", 
@@ -27,6 +34,8 @@
    "fieldtype": "Data", 
    "hidden": 0, 
    "label": "Subject", 
+   "max_length": 0, 
+   "max_value": 0, 
    "read_only": 0, 
    "reqd": 1
   }, 
@@ -36,15 +45,30 @@
    "fieldtype": "Select", 
    "hidden": 0, 
    "label": "Status", 
+   "max_length": 0, 
+   "max_value": 0, 
    "options": "Open\nReplied\nHold\nClosed", 
    "read_only": 1, 
    "reqd": 0
   }, 
   {
+   "fieldname": "customer", 
+   "fieldtype": "Data", 
+   "hidden": 0, 
+   "label": "Customer", 
+   "max_length": 0, 
+   "max_value": 0, 
+   "options": "Customer", 
+   "read_only": 1, 
+   "reqd": 0
+  }, 
+  {
    "fieldname": "description", 
    "fieldtype": "Text", 
    "hidden": 0, 
    "label": "Description", 
+   "max_length": 0, 
+   "max_value": 0, 
    "read_only": 0, 
    "reqd": 0
   }, 
@@ -53,6 +77,8 @@
    "fieldtype": "Attach", 
    "hidden": 0, 
    "label": "Attachment", 
+   "max_length": 0, 
+   "max_value": 0, 
    "read_only": 0, 
    "reqd": 0
   }
diff --git a/erpnext/utilities/web_form/addresses/addresses.json b/erpnext/utilities/web_form/addresses/addresses.json
index 50fe6e9..6d3fefc 100644
--- a/erpnext/utilities/web_form/addresses/addresses.json
+++ b/erpnext/utilities/web_form/addresses/addresses.json
@@ -1,8 +1,12 @@
 {
+ "accept_payment": 0, 
  "allow_comments": 0, 
  "allow_delete": 0, 
  "allow_edit": 1, 
+ "allow_incomplete": 0, 
  "allow_multiple": 1, 
+ "allow_print": 0, 
+ "amount": 0.0, 
  "creation": "2016-06-24 15:50:33.196990", 
  "doc_type": "Address", 
  "docstatus": 0, 
@@ -10,13 +14,16 @@
  "idx": 0, 
  "is_standard": 1, 
  "login_required": 1, 
- "modified": "2016-06-24 16:11:28.802353", 
+ "max_attachment_size": 0, 
+ "modified": "2016-12-07 04:17:02.020768", 
  "modified_by": "Administrator", 
  "module": "Utilities", 
  "name": "addresses", 
  "owner": "Administrator", 
  "published": 1, 
  "route": "address", 
+ "show_sidebar": 0, 
+ "sidebar_items": [], 
  "success_url": "/addresses", 
  "title": "Address", 
  "web_form_fields": [
@@ -26,6 +33,8 @@
    "fieldtype": "Data", 
    "hidden": 0, 
    "label": "Address Title", 
+   "max_length": 0, 
+   "max_value": 0, 
    "read_only": 0, 
    "reqd": 0
   }, 
@@ -34,6 +43,8 @@
    "fieldtype": "Select", 
    "hidden": 0, 
    "label": "Address Type", 
+   "max_length": 0, 
+   "max_value": 0, 
    "options": "Billing\nShipping\nOffice\nPersonal\nPlant\nPostal\nShop\nSubsidiary\nWarehouse\nOther", 
    "read_only": 0, 
    "reqd": 1
@@ -43,6 +54,8 @@
    "fieldtype": "Data", 
    "hidden": 0, 
    "label": "Address Line 1", 
+   "max_length": 0, 
+   "max_value": 0, 
    "read_only": 0, 
    "reqd": 1
   }, 
@@ -51,6 +64,8 @@
    "fieldtype": "Data", 
    "hidden": 0, 
    "label": "Address Line 2", 
+   "max_length": 0, 
+   "max_value": 0, 
    "read_only": 0, 
    "reqd": 0
   }, 
@@ -59,6 +74,8 @@
    "fieldtype": "Data", 
    "hidden": 0, 
    "label": "City/Town", 
+   "max_length": 0, 
+   "max_value": 0, 
    "read_only": 0, 
    "reqd": 1
   }, 
@@ -67,6 +84,8 @@
    "fieldtype": "Data", 
    "hidden": 0, 
    "label": "State", 
+   "max_length": 0, 
+   "max_value": 0, 
    "read_only": 0, 
    "reqd": 0
   }, 
@@ -75,6 +94,8 @@
    "fieldtype": "Data", 
    "hidden": 0, 
    "label": "Postal Code", 
+   "max_length": 0, 
+   "max_value": 0, 
    "read_only": 0, 
    "reqd": 0
   }, 
@@ -83,6 +104,8 @@
    "fieldtype": "Link", 
    "hidden": 0, 
    "label": "Country", 
+   "max_length": 0, 
+   "max_value": 0, 
    "options": "Country", 
    "read_only": 0, 
    "reqd": 1
@@ -90,6 +113,8 @@
   {
    "fieldtype": "Column Break", 
    "hidden": 0, 
+   "max_length": 0, 
+   "max_value": 0, 
    "read_only": 0, 
    "reqd": 0
   }, 
@@ -98,6 +123,8 @@
    "fieldtype": "Data", 
    "hidden": 0, 
    "label": "Email Id", 
+   "max_length": 0, 
+   "max_value": 0, 
    "read_only": 0, 
    "reqd": 0
   }, 
@@ -106,6 +133,8 @@
    "fieldtype": "Data", 
    "hidden": 0, 
    "label": "Phone", 
+   "max_length": 0, 
+   "max_value": 0, 
    "read_only": 0, 
    "reqd": 1
   }, 
@@ -116,6 +145,8 @@
    "fieldtype": "Check", 
    "hidden": 0, 
    "label": "Preferred Billing Address", 
+   "max_length": 0, 
+   "max_value": 0, 
    "read_only": 0, 
    "reqd": 0
   }, 
@@ -126,6 +157,8 @@
    "fieldtype": "Check", 
    "hidden": 0, 
    "label": "Preferred Shipping Address", 
+   "max_length": 0, 
+   "max_value": 0, 
    "read_only": 0, 
    "reqd": 0
   }