[Enhancement] Budget against Project
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..d177fa8 100644
--- a/erpnext/accounts/doctype/budget/budget.json
+++ b/erpnext/accounts/doctype/budget/budget.json
@@ -15,47 +15,18 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
-   "fieldname": "cost_center", 
-   "fieldtype": "Link", 
+   "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 +61,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 +370,7 @@
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2016-11-07 05:50:57.064961", 
+ "modified": "2016-11-22 11:58:42.211690", 
  "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..7df7151 100644
--- a/erpnext/accounts/doctype/budget/budget.py
+++ b/erpnext/accounts/doctype/budget/budget.py
@@ -14,20 +14,32 @@
 
 class Budget(Document):
 	def autoname(self):
-		self.name = make_autoname(self.cost_center + "/" + self.fiscal_year + "/.###")
-
+		if self.cost_center:
+			self.name = make_autoname(self.cost_center + "/" + self.fiscal_year + "/.###")
+		elif self.project:
+			self.name = make_autoname(self.project + "/" + self.fiscal_year + "/.###")
+	
 	def validate(self):
-		self.validate_duplicate()
+		if self.cost_center:
+			self.validate_duplicate("cost_center")
+		if self.project:
+			self.validate_duplicate("project")
 		self.validate_accounts()
 
-	def validate_duplicate(self):
-		existing_budget = frappe.db.get_value("Budget", {"cost_center": self.cost_center,
+	def validate_duplicate(self, budget_against):
+		budget_against_type = None
+		if budget_against == "cost_center":
+			budget_against_type == self.cost_center
+		elif budget_against == "project":
+			budget_against_type == self.project
+
+		existing_budget = frappe.db.get_value("Budget", {budget_against: budget_against_type,
 			"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)
-
+				.format(existing_budget, budget_against_type, self.fiscal_year), DuplicateBudgetError)
+	
 	def validate_accounts(self):
 		account_list = []
 		for d in self.get('accounts'):
@@ -51,49 +63,80 @@
 
 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"])
+		if args.project:
+			budget_records_against_project = frappe.db.sql("""
+				select
+					ba.budget_amount, b.monthly_distribution, b.project,
+					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 `tabProject` where name=b.project)
+			""",(args.fiscal_year, args.account), as_dict=True)
+			validate_budget_records(args, budget_records_against_project)
 
-		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.cost_center:
+			budget_records_against_cost_center = 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)
+			validate_budget_records(args, budget_records_against_cost_center)
 
-		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 monthly_action in ["Stop", "Warn"]:
-					budget_amount = get_accumulated_monthly_budget(budget.monthly_distribution,
-						args.posting_date, args.fiscal_year, budget.budget_amount)
+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
 
-					args["month_end_date"] = get_last_day(args.posting_date)
-						
-					compare_expense_with_budget(args, budget.cost_center,
-						budget_amount, _("Accumulated Monthly"), monthly_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)
 
-				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)
+				args["month_end_date"] = get_last_day(args.posting_date)
+				
+				if budget.cost_center:
+					compare_expense_with_budget(args, "Cost Center", budget.cost_center,
+					budget_amount, _("Accumulated Monthly"), monthly_action)
+				elif budget.project:
+					compare_expense_with_budget(args, "Project", budget.project,
+					budget_amount, _("Accumulated Monthly"), monthly_action)
 
-def compare_expense_with_budget(args, cost_center, budget_amount, action_for, action):
-	actual_expense = get_actual_expense(args, cost_center)
+			if yearly_action in ("Stop", "Warn") and monthly_action != "Stop" \
+				and yearly_action != monthly_action:
+					if budget.cost_center:
+						compare_expense_with_budget(args, "Cost Center", budget.cost_center,
+						flt(budget.budget_amount), _("Annual"), yearly_action)
+					elif budget.project:
+						compare_expense_with_budget(args, "Project", budget.project,
+						flt(budget_amount), _("Annual"), yearly_action)
+
+
+
+def compare_expense_with_budget(args, budget_against, budget_against_type, budget_amount, action_for, action):
+	if budget_against == "Cost Center":
+		actual_expense = get_actual_expense_for_CC(args, budget_against_type)
+	elif budget_against == "Project":
+		actual_expense = get_actual_expense_for_project(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),
+		msg = _("{0} Budget for Account {1} against {2} {3} is {4}. It will exceed by {5}").format(_(action_for),
+			frappe.bold(args.account), budget_against, frappe.bold(budget_against_type),
 			frappe.bold(fmt_money(budget_amount, currency=currency)), frappe.bold(fmt_money(diff, currency=currency)))
 
 		if action=="Stop":
@@ -101,6 +144,43 @@
 		else:
 			frappe.msgprint(msg, indicator='orange')
 
+
+def get_actual_expense_for_CC(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])
+
+
+def get_actual_expense_for_project(args):
+	
+	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 `tabProject`
+				where name=gle.project)
+			and gle.fiscal_year=%(fiscal_year)s
+			and gle.company=%(company)s
+			and gle.docstatus=1
+			{condition}
+	""".format(condition=condition), (args))[0][0])
+
+
 def get_accumulated_monthly_budget(monthly_distribution, posting_date, fiscal_year, annual_budget):
 	distribution = {}
 	if monthly_distribution:
@@ -121,21 +201,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