Merge branch 'master' into develop
diff --git a/erpnext/accounts/doctype/bank_reconciliation/bank_reconciliation.py b/erpnext/accounts/doctype/bank_reconciliation/bank_reconciliation.py
index 11dcfe7..0aaed8f 100644
--- a/erpnext/accounts/doctype/bank_reconciliation/bank_reconciliation.py
+++ b/erpnext/accounts/doctype/bank_reconciliation/bank_reconciliation.py
@@ -62,13 +62,13 @@
 
 		for d in entries:
 			row = self.append('payment_entries', {})
-
-			d.amount = fmt_money(d.debit if d.debit else d.credit, 2, d.account_currency) + " " + (_("Dr") if d.debit else _("Cr"))
+			amount = d.debit if d.debit else d.credit
+			d.amount = fmt_money(amount, 2, d.account_currency) + " " + (_("Dr") if d.debit else _("Cr"))
 			d.pop("credit")
 			d.pop("debit")
 			d.pop("account_currency")
 			row.update(d)
-			self.total_amount += flt(d.amount)
+			self.total_amount += flt(amount)
 
 	def update_clearance_date(self):
 		clearance_date_updated = False
diff --git a/erpnext/accounts/doctype/pricing_rule/pricing_rule.json b/erpnext/accounts/doctype/pricing_rule/pricing_rule.json
index 49af59b..777b34b 100644
--- a/erpnext/accounts/doctype/pricing_rule/pricing_rule.json
+++ b/erpnext/accounts/doctype/pricing_rule/pricing_rule.json
@@ -1,5 +1,6 @@
 {
  "allow_copy": 0, 
+ "allow_guest_to_view": 0, 
  "allow_import": 1, 
  "allow_rename": 1, 
  "autoname": "field:title", 
@@ -12,6 +13,7 @@
  "editable_grid": 0, 
  "fields": [
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -40,6 +42,7 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -69,6 +72,7 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -99,6 +103,7 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -129,6 +134,7 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -159,6 +165,7 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -189,6 +196,7 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -217,6 +225,7 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -247,6 +256,7 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -275,6 +285,7 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -303,6 +314,7 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -331,6 +343,7 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -359,6 +372,7 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -387,6 +401,7 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -417,6 +432,7 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -447,6 +463,7 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -477,6 +494,7 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -507,6 +525,7 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -537,6 +556,7 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -567,6 +587,7 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -597,6 +618,7 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -627,6 +649,7 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -655,6 +678,7 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -683,6 +707,7 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -711,6 +736,7 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -739,6 +765,7 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -767,6 +794,7 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -796,6 +824,7 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -824,6 +853,7 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -851,6 +881,7 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -880,6 +911,7 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -910,6 +942,7 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -941,6 +974,7 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -969,6 +1003,7 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -1000,6 +1035,7 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -1028,6 +1064,7 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -1058,6 +1095,7 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -1085,6 +1123,7 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -1114,6 +1153,7 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -1143,6 +1183,7 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -1173,6 +1214,39 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "depends_on": "eval:doc.price_or_discount==\"Price\"", 
+   "fieldname": "currency", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Currency", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Currency", 
+   "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_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -1202,6 +1276,7 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -1230,18 +1305,18 @@
    "unique": 0
   }
  ], 
+ "has_web_view": 0, 
  "hide_heading": 0, 
  "hide_toolbar": 0, 
  "icon": "fa fa-gift", 
  "idx": 1, 
  "image_view": 0, 
  "in_create": 0, 
- "in_dialog": 0, 
  "is_submittable": 0, 
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2017-02-17 16:21:28.446208", 
+ "modified": "2017-06-26 19:35:50.651619", 
  "modified_by": "Administrator", 
  "module": "Accounts", 
  "name": "Pricing Rule", 
diff --git a/erpnext/accounts/doctype/pricing_rule/pricing_rule.py b/erpnext/accounts/doctype/pricing_rule/pricing_rule.py
index 71897d4..af31d9b 100644
--- a/erpnext/accounts/doctype/pricing_rule/pricing_rule.py
+++ b/erpnext/accounts/doctype/pricing_rule/pricing_rule.py
@@ -23,6 +23,7 @@
 		self.validate_price_or_discount()
 		self.validate_max_discount()
 
+		if self.price_or_discount != 'Price': self.currency = None
 		if not self.margin_type: self.margin_rate_or_amount = 0.0
 
 	def validate_mandatory(self):
@@ -179,9 +180,15 @@
 		item_details.margin_type = pricing_rule.margin_type
 		item_details.margin_rate_or_amount = pricing_rule.margin_rate_or_amount
 		if pricing_rule.price_or_discount == "Price":
+			if pricing_rule.get('currency') and \
+				pricing_rule.currency == args.currency:
+				price_list_rate = pricing_rule.price * (args.conversion_factor or 1.0)
+			else:
+				price_list_rate = (pricing_rule.price/flt(args.conversion_rate)) * args.conversion_factor or 1.0 \
+						if args.conversion_rate else 0.0
+
 			item_details.update({
-				"price_list_rate": (pricing_rule.price/flt(args.conversion_rate)) * args.conversion_factor or 1.0 \
-					if args.conversion_rate else 0.0,
+				"price_list_rate": price_list_rate,
 				"discount_percentage": 0.0
 			})
 		else:
@@ -240,7 +247,7 @@
 	conditions = item_variant_condition = ""
 	values =  {"item_code": args.get("item_code"), "brand": args.get("brand")}
 
-	for field in ["company", "customer", "supplier", "supplier_type", "campaign", "sales_partner"]:
+	for field in ["company", "customer", "supplier", "supplier_type", "campaign", "sales_partner", "currency"]:
 		if args.get(field):
 			conditions += " and ifnull("+field+", '') in (%("+field+")s, '')"
 			values[field] = args.get(field)
diff --git a/erpnext/accounts/report/financial_statements.py b/erpnext/accounts/report/financial_statements.py
index 270ad53..b6c4fd2 100644
--- a/erpnext/accounts/report/financial_statements.py
+++ b/erpnext/accounts/report/financial_statements.py
@@ -10,7 +10,7 @@
 from erpnext.accounts.utils import get_fiscal_year
 
 
-def get_period_list(from_fiscal_year, to_fiscal_year, periodicity, accumulated_values=False, 
+def get_period_list(from_fiscal_year, to_fiscal_year, periodicity, accumulated_values=False,
 	company=None, reset_period_on_fy_change=True):
 	"""Get a list of dict {"from_date": from_date, "to_date": to_date, "key": key, "label": label}
 		Periodicity can be (Yearly, Quarterly, Monthly)"""
@@ -85,8 +85,8 @@
 	return period_list
 
 def get_fiscal_year_data(from_fiscal_year, to_fiscal_year):
-	fiscal_year = frappe.db.sql("""select min(year_start_date) as year_start_date, 
-		max(year_end_date) as year_end_date from `tabFiscal Year` where 
+	fiscal_year = frappe.db.sql("""select min(year_start_date) as year_start_date,
+		max(year_end_date) as year_end_date from `tabFiscal Year` where
 		name between %(from_fiscal_year)s and %(to_fiscal_year)s""",
 		{'from_fiscal_year': from_fiscal_year, 'to_fiscal_year': to_fiscal_year}, as_dict=1)
 
@@ -110,7 +110,7 @@
 		label = formatdate(from_date, "MMM YY") + "-" + formatdate(to_date, "MMM YY")
 
 	return label
-	
+
 def get_data(company, root_type, balance_must_be, period_list, filters=None,
 		accumulated_values=1, only_current_fiscal_year=True, ignore_closing_entries=False,
 		ignore_accumulated_values_for_fy=False):
@@ -119,16 +119,16 @@
 		return None
 
 	accounts, accounts_by_name, parent_children_map = filter_accounts(accounts)
-	
+
 	company_currency = frappe.db.get_value("Company", company, "default_currency")
 
 	gl_entries_by_account = {}
 	for root in frappe.db.sql("""select lft, rgt from tabAccount
 			where root_type=%s and ifnull(parent_account, '') = ''""", root_type, as_dict=1):
-			
-		set_gl_entries_by_account(company, 
+
+		set_gl_entries_by_account(company,
 			period_list[0]["year_start_date"] if only_current_fiscal_year else None,
-			period_list[-1]["to_date"], 
+			period_list[-1]["to_date"],
 			root.lft, root.rgt, filters,
 			gl_entries_by_account, ignore_closing_entries=ignore_closing_entries)
 
@@ -136,7 +136,7 @@
 	accumulate_values_into_parents(accounts, accounts_by_name, period_list, accumulated_values)
 	out = prepare_data(accounts, balance_must_be, period_list, company_currency)
 	out = filter_out_zero_value_rows(out, parent_children_map)
-	
+
 	if out:
 		add_total_row(out, root_type, balance_must_be, period_list, company_currency)
 
@@ -151,13 +151,13 @@
 
 				if entry.posting_date <= period.to_date:
 					if (accumulated_values or entry.posting_date >= period.from_date) and \
-						(not ignore_accumulated_values_for_fy or 
+						(not ignore_accumulated_values_for_fy or
 							entry.fiscal_year == period.to_date_fiscal_year):
 						d[period.key] = d.get(period.key, 0.0) + flt(entry.debit) - flt(entry.credit)
 
 			if entry.posting_date < period_list[0].year_start_date:
 				d["opening_balance"] = d.get("opening_balance", 0.0) + flt(entry.debit) - flt(entry.credit)
-				
+
 def accumulate_values_into_parents(accounts, accounts_by_name, period_list, accumulated_values):
 	"""accumulate children's values in parent accounts"""
 	for d in reversed(accounts):
@@ -165,7 +165,7 @@
 			for period in period_list:
 				accounts_by_name[d.parent_account][period.key] = \
 					accounts_by_name[d.parent_account].get(period.key, 0.0) + d.get(period.key, 0.0)
-			
+
 			accounts_by_name[d.parent_account]["opening_balance"] = \
 				accounts_by_name[d.parent_account].get("opening_balance", 0.0) + d.get("opening_balance", 0.0)
 
@@ -173,15 +173,15 @@
 	data = []
 	year_start_date = period_list[0]["year_start_date"].strftime("%Y-%m-%d")
 	year_end_date = period_list[-1]["year_end_date"].strftime("%Y-%m-%d")
-	
+
 	for d in accounts:
 		# add to output
 		has_value = False
 		total = 0
 		row = frappe._dict({
-			"account_name": d.account_name,
-			"account": d.name,
-			"parent_account": d.parent_account,
+			"account_name": _(d.account_name),
+			"account": _(d.name),
+			"parent_account": _(d.parent_account),
 			"indent": flt(d.indent),
 			"year_start_date": year_start_date,
 			"year_end_date": year_end_date,
@@ -192,7 +192,7 @@
 			if d.get(period.key) and balance_must_be=="Credit":
 				# change sign based on Debit or Credit, since calculation is done using (debit - credit)
 				d[period.key] *= -1
-		
+
 			row[period.key] = flt(d.get(period.key, 0.0), 3)
 
 			if abs(row[period.key]) >= 0.005:
@@ -203,9 +203,9 @@
 		row["has_value"] = has_value
 		row["total"] = total
 		data.append(row)
-		
+
 	return data
-	
+
 def filter_out_zero_value_rows(data, parent_children_map, show_zero_values=False):
 	data_with_value = []
 	for d in data:
@@ -224,8 +224,8 @@
 
 def add_total_row(out, root_type, balance_must_be, period_list, company_currency):
 	total_row = {
-		"account_name": "'" + _("Total {0} ({1})").format(root_type, balance_must_be) + "'",
-		"account": "'" + _("Total {0} ({1})").format(root_type, balance_must_be) + "'",
+		"account_name": "'" + _("Total {0} ({1})").format(_(root_type), _(balance_must_be)) + "'",
+		"account": "'" + _("Total {0} ({1})").format(_(root_type), _(balance_must_be)) + "'",
 		"currency": company_currency
 	}
 
@@ -235,11 +235,11 @@
 				total_row.setdefault(period.key, 0.0)
 				total_row[period.key] += row.get(period.key, 0.0)
 				row[period.key] = ""
-			
+
 			total_row.setdefault("total", 0.0)
 			total_row["total"] += flt(row["total"])
 			row["total"] = ""
-	
+
 	if total_row.has_key("total"):
 		out.append(total_row)
 
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.py b/erpnext/buying/doctype/purchase_order/purchase_order.py
index b3bbb92..7e5020a 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.py
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.py
@@ -270,6 +270,9 @@
 	doc = get_mapped_doc("Purchase Order", source_name,	{
 		"Purchase Order": {
 			"doctype": "Purchase Receipt",
+			"field_map": {
+				"per_billed": "per_billed"
+			},
 			"validation": {
 				"docstatus": ["=", 1],
 			}
diff --git a/erpnext/config/schools.py b/erpnext/config/schools.py
index c54f808..b984578 100644
--- a/erpnext/config/schools.py
+++ b/erpnext/config/schools.py
@@ -137,7 +137,14 @@
 				{
 					"type": "doctype",
 					"name": "Assessment Result Tool"
-				}
+				},
+				{
+					"type": "report",
+					"is_query_report": True,
+					"name": "Course wise Assessment Report",
+					"doctype": "Assessment Result"
+				},
+
 			]
 		},
 		{
diff --git a/erpnext/schools/report/course_wise_assessment_report/__init__.py b/erpnext/schools/report/course_wise_assessment_report/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/schools/report/course_wise_assessment_report/__init__.py
diff --git a/erpnext/schools/report/course_wise_assessment_report/course_wise_assessment_report.js b/erpnext/schools/report/course_wise_assessment_report/course_wise_assessment_report.js
new file mode 100644
index 0000000..42b19eb
--- /dev/null
+++ b/erpnext/schools/report/course_wise_assessment_report/course_wise_assessment_report.js
@@ -0,0 +1,34 @@
+// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.query_reports["Course wise Assessment Report"] = {
+	"filters": [
+		{
+			"fieldname":"assessment_group",
+			"label": __("Assessment Group"),
+			"fieldtype": "Link",
+			"options": "Assessment Group",
+			"reqd": 1,
+			"get_query": function() {
+				return{
+					filters: {
+						'is_group': 0
+					}
+				};
+			}
+		},
+		{
+			"fieldname":"course",
+			"label": __("Course"),
+			"fieldtype": "Link",
+			"options": "Course",
+			"reqd": 1
+		},
+		{
+			"fieldname":"student_group",
+			"label": __("Student Group"),
+			"fieldtype": "Link",
+			"options": "Student Group"
+		}
+	]
+};
diff --git a/erpnext/schools/report/course_wise_assessment_report/course_wise_assessment_report.json b/erpnext/schools/report/course_wise_assessment_report/course_wise_assessment_report.json
new file mode 100644
index 0000000..6b089d2
--- /dev/null
+++ b/erpnext/schools/report/course_wise_assessment_report/course_wise_assessment_report.json
@@ -0,0 +1,23 @@
+{
+ "add_total_row": 0, 
+ "apply_user_permissions": 1, 
+ "creation": "2017-05-05 14:46:13.776133", 
+ "disabled": 0, 
+ "docstatus": 0, 
+ "doctype": "Report", 
+ "idx": 0, 
+ "is_standard": "Yes", 
+ "modified": "2017-05-05 14:47:18.080385", 
+ "modified_by": "Administrator", 
+ "module": "Schools", 
+ "name": "Course wise Assessment Report", 
+ "owner": "Administrator", 
+ "ref_doctype": "Assessment Result", 
+ "report_name": "Course wise Assessment Report", 
+ "report_type": "Script Report", 
+ "roles": [
+  {
+   "role": "Academics User"
+  }
+ ]
+}
\ No newline at end of file
diff --git a/erpnext/schools/report/course_wise_assessment_report/course_wise_assessment_report.py b/erpnext/schools/report/course_wise_assessment_report/course_wise_assessment_report.py
new file mode 100644
index 0000000..b5a2fc1
--- /dev/null
+++ b/erpnext/schools/report/course_wise_assessment_report/course_wise_assessment_report.py
@@ -0,0 +1,122 @@
+# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe import _
+from collections import defaultdict
+
+def execute(filters=None):
+	args = frappe._dict()
+	args["assessment_group"] = filters.get("assessment_group")
+	if args["assessment_group"] == "All Assessment Groups":
+		frappe.throw(_("Please select the assessment group other than 'All Assessment Groups'"))
+
+	args["course"] = filters.get("course")
+	args["student_group"] = filters.get("student_group")
+	if args["student_group"]:
+		cond = "and ap.student_group=%(student_group)s"
+	else:
+		cond = ''
+
+	# find all assessment plan linked with the filters provided
+	assessment_plan = frappe.db.sql('''
+		select
+			ap.name, ap.student_group, apc.assessment_criteria, apc.maximum_score as max_score
+		from
+			`tabAssessment Plan` ap, `tabAssessment Plan Criteria` apc
+		where
+			ap.assessment_group=%(assessment_group)s and ap.course=%(course)s and
+			ap.name=apc.parent and ap.docstatus=1 {0}
+		order by
+			apc.assessment_criteria'''.format(cond), (args), as_dict=1)
+
+	assessment_plan_list = set([d["name"] for d in assessment_plan])
+	if not assessment_plan_list:
+		frappe.throw(_("No assessment plan linked with this assessment group"))
+
+	student_group_list = set([d["student_group"] for d in assessment_plan])
+	assessment_result = frappe.db.sql('''select ar.student, ard.assessment_criteria, ard.grade, ard.score
+		from `tabAssessment Result` ar, `tabAssessment Result Detail` ard
+		where ar.assessment_plan in (%s) and ar.name=ard.parent and ar.docstatus=1
+		order by ard.assessment_criteria''' %', '.join(['%s']*len(assessment_plan_list)),
+		tuple(assessment_plan_list), as_dict=1)
+
+	result_dict = defaultdict(dict)
+	kounter = defaultdict(dict)
+	for result in assessment_result:
+		result_dict[result.student].update({frappe.scrub(result.assessment_criteria): result.grade,
+			frappe.scrub(result.assessment_criteria)+"_score": result.score})
+		if result.grade in kounter[result.assessment_criteria]:
+			kounter[result.assessment_criteria][result.grade] += 1
+		else:
+			kounter[result.assessment_criteria].update({result.grade: 1})
+
+	student_list = frappe.db.sql('''select sgs.student, sgs.student_name
+		from `tabStudent Group` sg, `tabStudent Group Student` sgs
+		where sg.name = sgs.parent and sg.name in (%s)
+		order by sgs.group_roll_number asc''' %', '.join(['%s']*len(student_group_list)),
+		tuple(student_group_list), as_dict=1)
+
+	for student in student_list:
+		student.update(result_dict[student.student])
+	data = student_list
+
+	columns = get_column(list(set([(d["assessment_criteria"],d["max_score"]) for d in assessment_plan])))
+
+	grading_scale = frappe.db.get_value("Assessment Plan", list(assessment_plan_list)[0], "grading_scale")
+	grades = frappe.db.sql_list('''select grade_code from `tabGrading Scale Interval` where parent=%s''',
+		(grading_scale))
+	assessment_criteria_list = list(set([d["assessment_criteria"] for d in assessment_plan]))
+	chart = get_chart_data(grades, assessment_criteria_list, kounter)
+
+	return columns, data, None, chart
+
+def get_column(assessment_criteria):
+	columns = [{
+		"fieldname": "student",
+		"label": _("Student ID"),
+		"fieldtype": "Link",
+		"options": "Student",
+		"width": 90
+	},
+	{
+		"fieldname": "student_name",
+		"label": _("Student Name"),
+		"fieldtype": "Data",
+		"width": 160
+	}]
+	for d in assessment_criteria:
+		columns.append({
+			"fieldname": frappe.scrub(d[0]),
+			"label": d[0],
+			"fieldtype": "Data",
+			"width": 110
+		})
+		columns.append({
+			"fieldname": frappe.scrub(d[0]) +"_score",
+			"label": "Score(" + str(int(d[1])) + ")",
+			"fieldtype": "Float",
+			"width": 100
+		})
+	return columns
+
+def get_chart_data(grades, assessment_criteria_list, kounter):
+	grades = sorted(grades)
+	chart_data = []
+	chart_data.append(["x"] + assessment_criteria_list)
+	for grade in grades:
+		tmp = [grade]
+		for ac in assessment_criteria_list:
+			if grade in kounter[ac]:
+				tmp.append(kounter[ac][grade])
+			else:
+				tmp.append(0)
+		chart_data.append(tmp)
+	return {
+		"data": {
+			"x": "x",
+			"columns": chart_data
+		},
+		"chart_type": 'bar',
+	}
diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
index 647eb67..f60eb6a 100644
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
@@ -119,7 +119,8 @@
 		frappe.db.set(self, 'status', 'Submitted')
 
 		self.update_prevdoc_status()
-		self.update_billing_status()
+		if self.per_billed < 100:
+			self.update_billing_status()
 
 		if not self.is_return:
 			update_last_purchase_rate(self, 1)