resolved merge conflicts
diff --git a/erpnext/__init__.py b/erpnext/__init__.py
index f4876bd..029d066 100644
--- a/erpnext/__init__.py
+++ b/erpnext/__init__.py
@@ -5,7 +5,7 @@
 from erpnext.hooks import regional_overrides
 from frappe.utils import getdate
 
-__version__ = '10.0.14'
+__version__ = '10.0.15'
 
 def get_default_company(user=None):
 	'''Get default company for user'''
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
index 3f9bca7..21b71ff 100644
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
@@ -96,7 +96,7 @@
 		if not self.credit_to:
 			self.credit_to = get_party_account("Supplier", self.supplier, self.company)
 		if not self.due_date:
-			self.due_date = get_due_date(self.posting_date, "Supplier", self.supplier)
+			self.due_date = get_due_date(self.posting_date, "Supplier", self.supplier, self.company)
 
 		super(PurchaseInvoice, self).set_missing_values(for_validate)
 
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
index bf6ad49..266e3e1 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
@@ -237,7 +237,7 @@
 		if not self.debit_to:
 			self.debit_to = get_party_account("Customer", self.customer, self.company)
 		if not self.due_date and self.customer:
-			self.due_date = get_due_date(self.posting_date, "Customer", self.customer)
+			self.due_date = get_due_date(self.posting_date, "Customer", self.customer, self.company)
 
 		super(SalesInvoice, self).set_missing_values(for_validate)
 
diff --git a/erpnext/accounts/party.py b/erpnext/accounts/party.py
index 7bccfe8..5237a71 100644
--- a/erpnext/accounts/party.py
+++ b/erpnext/accounts/party.py
@@ -51,7 +51,7 @@
 	set_other_values(out, party, party_type)
 	set_price_list(out, party, party_type, price_list)
 	out["taxes_and_charges"] = set_taxes(party.name, party_type, posting_date, company, out.customer_group, out.supplier_type)
-	out["payment_terms_template"] = get_pyt_term_template(party.name, party_type)
+	out["payment_terms_template"] = get_pyt_term_template(party.name, party_type, company)
 
 	if not out.get("currency"):
 		out["currency"] = currency
@@ -164,7 +164,7 @@
 	out = {
 		party_type.lower(): party,
 		account_fieldname : account,
-		"due_date": get_due_date(posting_date, party_type, party)
+		"due_date": get_due_date(posting_date, party_type, party, company)
 	}
 	return out
 
@@ -267,12 +267,12 @@
 
 
 @frappe.whitelist()
-def get_due_date(posting_date, party_type, party):
+def get_due_date(posting_date, party_type, party, company=None):
 	"""Get due date from `Payment Terms Template`"""
 	due_date = None
 	if posting_date and party:
 		due_date = posting_date
-		template_name = get_pyt_term_template(party, party_type)
+		template_name = get_pyt_term_template(party, party_type, company)
 		if template_name:
 			due_date = get_due_date_from_template(template_name, posting_date).strftime("%Y-%m-%d")
 		else:
@@ -305,12 +305,11 @@
 
 	return due_date
 
-
-def validate_due_date(posting_date, due_date, party_type, party):
+def validate_due_date(posting_date, due_date, party_type, party, company=None):
 	if getdate(due_date) < getdate(posting_date):
 		frappe.throw(_("Due Date cannot be before Posting Date"))
 	else:
-		default_due_date = get_due_date(posting_date, party_type, party)
+		default_due_date = get_due_date(posting_date, party_type, party, company)
 		if not default_due_date:
 			return
 
@@ -360,14 +359,32 @@
 
 
 @frappe.whitelist()
-def get_pyt_term_template(party_name, party_type):
+def get_pyt_term_template(party_name, party_type, company=None):
+	if party_type not in ("Customer", "Supplier"):
+		return
+
 	template = None
-	if party_type in ('Customer', 'Supplier'):
-		template = frappe.db.get_value(party_type, party_name, fieldname='payment_terms')
+	if party_type == 'Customer':
+		customer = frappe.db.get_value("Customer", party_name,
+			fieldname=['payment_terms', "customer_group"], as_dict=1)
+		template = customer.payment_terms
+
+		if not template and customer.customer_group:
+			template = frappe.db.get_value("Customer Group",
+				customer.customer_group, fieldname='payment_terms')
+	else:
+		supplier = frappe.db.get_value("Supplier", party_name,
+			fieldname=['payment_terms', "supplier_type"], as_dict=1)
+		template = supplier.payment_terms
+
+		if not template and supplier.supplier_type:
+			template = frappe.db.get_value("Supplier Type", supplier.supplier_type, fieldname='payment_terms')
+
+	if not template and company:
+		template = frappe.db.get_value("Company", company, fieldname='payment_terms')
 
 	return template
 
-
 def validate_party_frozen_disabled(party_type, party_name):
 	if party_type and party_name:
 		if party_type in ("Customer", "Supplier"):
diff --git a/erpnext/buying/doctype/supplier/test_records.json b/erpnext/buying/doctype/supplier/test_records.json
index 7479f55..370ce8d 100644
--- a/erpnext/buying/doctype/supplier/test_records.json
+++ b/erpnext/buying/doctype/supplier/test_records.json
@@ -9,7 +9,6 @@
   "doctype": "Supplier",
   "supplier_name": "_Test Supplier P",
   "supplier_type": "_Test Supplier Type",
-  "credit_days_based_on": "Fixed Days"
  },
  {
   "doctype": "Supplier",
diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py
index c7b5206..b3672cb 100644
--- a/erpnext/controllers/accounts_controller.py
+++ b/erpnext/controllers/accounts_controller.py
@@ -135,9 +135,9 @@
 			if not self.due_date:
 				frappe.throw(_("Due Date is mandatory"))
 
-			validate_due_date(self.posting_date, self.due_date, "Customer", self.customer)
+			validate_due_date(self.posting_date, self.due_date, "Customer", self.customer, self.company)
 		elif self.doctype == "Purchase Invoice":
-			validate_due_date(self.posting_date, self.due_date, "Supplier", self.supplier)
+			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"):
diff --git a/erpnext/education/api.py b/erpnext/education/api.py
index ea4da69..99fb36e 100644
--- a/erpnext/education/api.py
+++ b/erpnext/education/api.py
@@ -269,7 +269,10 @@
 	:param Percentage: Score Percentage Percentage
 	"""
 	grading_scale_intervals = {}
-	for d in frappe.get_all("Grading Scale Interval", fields=["grade_code", "threshold"], filters={"parent": grading_scale}):
+	if not hasattr(frappe.local, 'grading_scale'):
+		grading_scale = frappe.get_all("Grading Scale Interval", fields=["grade_code", "threshold"], filters={"parent": grading_scale})
+		frappe.local.grading_scale = grading_scale
+	for d in frappe.local.grading_scale:
 		grading_scale_intervals.update({d.threshold:d.grade_code})
 	intervals = sorted(grading_scale_intervals.keys(), key=float, reverse=True)
 	for interval in intervals:
diff --git a/erpnext/education/doctype/assessment_criteria/assessment_criteria.py b/erpnext/education/doctype/assessment_criteria/assessment_criteria.py
index e666a74..eadc0de 100644
--- a/erpnext/education/doctype/assessment_criteria/assessment_criteria.py
+++ b/erpnext/education/doctype/assessment_criteria/assessment_criteria.py
@@ -6,5 +6,9 @@
 import frappe
 from frappe.model.document import Document
 
+STD_CRITERIA = ["total", "total score", "total grade", "maximum score", "score", "grade"]
+
 class AssessmentCriteria(Document):
-	pass
+	def validate(self):
+		if self.assessment_criteria.lower() in STD_CRITERIA:
+			frappe.throw("Can't create standard criteria. Please rename the criteria")
\ No newline at end of file
diff --git a/erpnext/education/report/course_wise_assessment_report/course_wise_assessment_report.html b/erpnext/education/report/course_wise_assessment_report/course_wise_assessment_report.html
index 60300b0..e46a5e7 100644
--- a/erpnext/education/report/course_wise_assessment_report/course_wise_assessment_report.html
+++ b/erpnext/education/report/course_wise_assessment_report/course_wise_assessment_report.html
@@ -6,9 +6,15 @@
 {% } %}
 <h4 class="text-center">{%= __("Assessment Report") %}</h4>
 <hr>
+<h5 class="text-center">{%= __("Academic Year: ") %} {%= filters.academic_year %} </h5>
+{% if (filters.academic_term){ %}
+<h5 class="text-center">{%= __("Academic Term: ") %} {%= filters.academic_term %} </h5>
+{% } %}
 <h5 class="text-center">{%= __("Course Code: ") %} {%= filters.course %}</h5>
 <h5 class="text-center">{%= __("Assessment Group: ") %} {%= filters.assessment_group %}</h5>
-<h5 class="text-center">{%= __("Assessment Plan: ") %} {%= data_to_be_printed[0]["assessment_plan"] %} </h5>
+{% if (filters.student_group){ %}
+<h5 class="text-center">{%= __("Student Group: ") %} {%= filters.student_group %} </h5>
+{% } %}
 <hr>
 
 <table class="table table-bordered">
diff --git a/erpnext/education/report/course_wise_assessment_report/course_wise_assessment_report.js b/erpnext/education/report/course_wise_assessment_report/course_wise_assessment_report.js
index 42b19eb..8c42d48 100644
--- a/erpnext/education/report/course_wise_assessment_report/course_wise_assessment_report.js
+++ b/erpnext/education/report/course_wise_assessment_report/course_wise_assessment_report.js
@@ -4,18 +4,17 @@
 frappe.query_reports["Course wise Assessment Report"] = {
 	"filters": [
 		{
-			"fieldname":"assessment_group",
-			"label": __("Assessment Group"),
+			"fieldname":"academic_year",
+			"label": __("Academic Year"),
 			"fieldtype": "Link",
-			"options": "Assessment Group",
-			"reqd": 1,
-			"get_query": function() {
-				return{
-					filters: {
-						'is_group': 0
-					}
-				};
-			}
+			"options": "Academic Year",
+			"reqd": 1
+		},
+		{
+			"fieldname":"academic_term",
+			"label": __("Academic Term"),
+			"fieldtype": "Link",
+			"options": "Academic Term"
 		},
 		{
 			"fieldname":"course",
@@ -29,6 +28,13 @@
 			"label": __("Student Group"),
 			"fieldtype": "Link",
 			"options": "Student Group"
+		},
+		{
+			"fieldname":"assessment_group",
+			"label": __("Assessment Group"),
+			"fieldtype": "Link",
+			"options": "Assessment Group",
+			"reqd": 1
 		}
 	]
 };
diff --git a/erpnext/education/report/course_wise_assessment_report/course_wise_assessment_report.py b/erpnext/education/report/course_wise_assessment_report/course_wise_assessment_report.py
index ff17238..a50ad7b 100644
--- a/erpnext/education/report/course_wise_assessment_report/course_wise_assessment_report.py
+++ b/erpnext/education/report/course_wise_assessment_report/course_wise_assessment_report.py
@@ -5,129 +5,189 @@
 import frappe
 from frappe import _
 from frappe.utils import flt
-from collections import defaultdict
+from collections import defaultdict, OrderedDict
 from erpnext.education.api import get_grade
 
 
 def execute(filters=None):
-	data = []
-
+	data, chart, grades = [], [], []
 	args = frappe._dict()
+	grade_wise_analysis = defaultdict(dict)
+
+	args["academic_year"] = filters.get("academic_year")
+	args["course"] = filters.get("course")
 	args["assessment_group"] = filters.get("assessment_group")
+
+	args["academic_term"] = filters.get("academic_term")
+	args["student_group"] = filters.get("student_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")
+	returned_values = get_formatted_result(args, get_assessment_criteria=True)
+	student_dict = returned_values["student_details"]
+	result_dict = returned_values["assessment_result"]
+	assessment_criteria_dict = returned_values["assessment_criteria"]
+
+	for student in result_dict:
+		student_row = {}
+		student_row["student"] = student
+		student_row["student_name"] = student_dict[student]
+		for criteria in assessment_criteria_dict:
+			scrub_criteria = frappe.scrub(criteria)
+			if criteria in result_dict[student][args.course][args.assessment_group]:
+				student_row[scrub_criteria] = result_dict[student][args.course][args.assessment_group][criteria]["grade"]
+				student_row[scrub_criteria + "_score"] = result_dict[student][args.course][args.assessment_group][criteria]["score"]
+
+				# create the list of possible grades
+				if student_row[scrub_criteria] not in grades:
+					grades.append(student_row[scrub_criteria])
+				
+				# create the dict of for gradewise analysis
+				if student_row[scrub_criteria] not in grade_wise_analysis[criteria]:
+					grade_wise_analysis[criteria][student_row[scrub_criteria]] = 1
+				else:
+					grade_wise_analysis[criteria][student_row[scrub_criteria]] += 1
+			else:
+				student_row[frappe.scrub(criteria)] = ""
+				student_row[frappe.scrub(criteria)+ "_score"] = ""
+		data.append(student_row)
+
+	assessment_criteria_list = [d for d in assessment_criteria_dict]
+	columns = get_column(assessment_criteria_dict)
+	chart = get_chart_data(grades, assessment_criteria_list, grade_wise_analysis)
+
+	return columns, data, None, chart
 
 
-	# find all assessment plan and related details linked with the given filters
-	def get_assessment_details():
-		if args["student_group"]:
-			cond = "and ap.student_group=%(student_group)s"
+def get_formatted_result(args, get_assessment_criteria=False, get_course=False):
+	cond, cond1, cond2, cond3, cond4 = " ", " ", " ", " ", " "
+	args_list = [args.academic_year]
+
+	if args.course:
+		cond = " and ar.course=%s"
+		args_list.append(args.course)
+
+	if args.academic_term:
+		cond1 = " and ar.academic_term=%s"
+		args_list.append(args.academic_term)
+
+	if args.student_group:
+		cond2 = " and ar.student_group=%s"
+		args_list.append(args.student_group)
+
+	create_total_dict = False
+	group_type = frappe.get_value("Assessment Group", args.assessment_group, "is_group")
+	if group_type:
+		from frappe.desk.treeview import get_children
+		assessment_groups = [d.get("value") for d in get_children("Assessment Group",
+			args.assessment_group) if d.get("value") and not d.get("expandable")]
+		cond3 = " and ar.assessment_group in (%s)"%(', '.join(['%s']*len(assessment_groups)))
+	else:
+		assessment_groups = [args.assessment_group]
+		cond3 = " and ar.assessment_group=%s"
+	args_list += assessment_groups
+
+	if args.students:
+		cond4 = " and ar.student in (%s)"%(', '.join(['%s']*len(args.students)))
+		args_list += args.students
+
+	assessment_result = frappe.db.sql('''
+		SELECT
+			ar.student, ar.student_name, ar.academic_year, ar.academic_term, ar.program, ar.course,
+			ar.assessment_plan, ar.grading_scale, ar.assessment_group, ar.student_group,
+			ard.assessment_criteria, ard.maximum_score, ard.grade, ard.score
+		FROM
+			`tabAssessment Result` ar, `tabAssessment Result Detail` ard
+		WHERE
+			ar.name=ard.parent and ar.docstatus=1 and ar.academic_year=%s {0} {1} {2} {3} {4}
+		ORDER BY
+			ard.assessment_criteria'''.format(cond, cond1, cond2, cond3, cond4),
+		tuple(args_list), as_dict=1)
+
+	# create the nested dictionary structure as given below:
+	# <variable_name>.<student_name>.<course>.<assessment_group>.<assessment_criteria>.<grade/score/max_score>
+	# "Total Score" -> assessment criteria used for totaling and args.assessment_group -> for totaling all the assesments
+
+	student_details = {}
+	formatted_assessment_result = defaultdict(dict)
+	assessment_criteria_dict = OrderedDict()
+	course_dict = OrderedDict()
+	total_maximum_score = None
+	if not (len(assessment_groups) == 1 and assessment_groups[0] == args.assessment_group):
+		create_total_dict = True
+
+	# add the score for a given score and recalculate the grades
+	def add_score_and_recalculate_grade(result, assessment_group, assessment_criteria):
+		formatted_assessment_result[result.student][result.course][assessment_group]\
+			[assessment_criteria]["maximum_score"] += result.maximum_score
+		formatted_assessment_result[result.student][result.course][assessment_group]\
+			[assessment_criteria]["score"] += result.score
+		tmp_grade = get_grade(result.grading_scale, ((formatted_assessment_result[result.student][result.course]
+			[assessment_group][assessment_criteria]["score"])/(formatted_assessment_result[result.student]
+			[result.course][assessment_group][assessment_criteria]["maximum_score"]))*100)
+		formatted_assessment_result[result.student][result.course][assessment_group]\
+			[assessment_criteria]["grade"] = tmp_grade
+
+	# create the assessment criteria "Total Score" with the sum of all the scores of the assessment criteria in a given assessment group
+	def add_total_score(result, assessment_group):
+		if "Total Score" not in formatted_assessment_result[result.student][result.course][assessment_group]:
+			formatted_assessment_result[result.student][result.course][assessment_group]["Total Score"] = frappe._dict({
+				"assessment_criteria": "Total Score", "maximum_score": result.maximum_score, "score": result.score, "grade": result.grade})
 		else:
-			cond = ''
+			add_score_and_recalculate_grade(result, assessment_group, "Total Score")
 
-		assessment_plan = frappe.db.sql('''
-			select
-				ap.name, ap.student_group, ap.grading_scale, 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)
+	for result in assessment_result:
+		if result.student not in student_details:
+			student_details[result.student] = result.student_name
 
-		assessment_plan_list = list(set([d["name"] for d in assessment_plan]))
-		if not assessment_plan_list:
-			frappe.throw(_("No assessment plan linked with this assessment group"))
+		assessment_criteria_details = frappe._dict({"assessment_criteria": result.assessment_criteria,
+			"maximum_score": result.maximum_score, "score": result.score, "grade": result.grade})
 
-		assessment_criteria_list = list(set([(d["assessment_criteria"],d["max_score"]) for d in assessment_plan]))
-		student_group_list = list(set([d["student_group"] for d in assessment_plan]))
-		total_maximum_score = flt(sum([flt(d[1]) for d in assessment_criteria_list]))
-		grading_scale = assessment_plan[0]["grading_scale"]
+		if not formatted_assessment_result[result.student]:
+			formatted_assessment_result[result.student] = defaultdict(dict)
+		if not formatted_assessment_result[result.student][result.course]:
+			formatted_assessment_result[result.student][result.course] = defaultdict(dict)
 
-		return assessment_plan_list, assessment_criteria_list, total_maximum_score, grading_scale, student_group_list
+		if not create_total_dict:
+			formatted_assessment_result[result.student][result.course][result.assessment_group]\
+				[result.assessment_criteria] = assessment_criteria_details
+			add_total_score(result, result.assessment_group)
+
+		# create the total of all the assessment groups criteria-wise
+		elif create_total_dict:
+			if not formatted_assessment_result[result.student][result.course][args.assessment_group]:
+				formatted_assessment_result[result.student][result.course][args.assessment_group] = defaultdict(dict)
+				formatted_assessment_result[result.student][result.course][args.assessment_group]\
+					[result.assessment_criteria] = assessment_criteria_details
+			elif result.assessment_criteria not in formatted_assessment_result[result.student][result.course][args.assessment_group]:
+				formatted_assessment_result[result.student][result.course][args.assessment_group]\
+					[result.assessment_criteria] = assessment_criteria_details
+			elif result.assessment_criteria in formatted_assessment_result[result.student][result.course][args.assessment_group]:
+				add_score_and_recalculate_grade(result, args.assessment_group, result.assessment_criteria)
+
+			add_total_score(result, args.assessment_group)
+
+		total_maximum_score = formatted_assessment_result[result.student][result.course][args.assessment_group]\
+			["Total Score"]["maximum_score"]
+		if get_assessment_criteria:
+			assessment_criteria_dict[result.assessment_criteria] = formatted_assessment_result[result.student][result.course]\
+				[args.assessment_group][result.assessment_criteria]["maximum_score"]
+		if get_course:
+			course_dict[result.course] = total_maximum_score
+
+	if get_assessment_criteria and total_maximum_score:
+		assessment_criteria_dict["Total Score"] = total_maximum_score
+
+	return {
+		"student_details": student_details,
+		"assessment_result": formatted_assessment_result,
+		"assessment_criteria": assessment_criteria_dict,
+		"course_dict": course_dict
+	}
 
 
-	# get all the result and make a dict map student as the key and value as dict of result
-	def get_result_map():
-		result_dict = defaultdict(dict)
-		kounter = defaultdict(dict)
-		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)
-
-		for result in assessment_result:
-			if "total_score" in result_dict[result.student]:
-				total_score = result_dict[result.student]["total_score"] + result.score
-			else:
-				total_score = result.score
-			total = get_grade(grading_scale, (total_score/total_maximum_score)*100)
-
-			if result.grade in kounter[result.assessment_criteria]:
-				kounter[result.assessment_criteria][result.grade] += 1
-			else:
-				kounter[result.assessment_criteria].update({result.grade: 1})
-
-			if "Total" not in kounter:
-				kounter["Total"] = {}
-
-			if "total" in result_dict[result.student]:
-				prev_grade = result_dict[result.student]["total"]
-				prev_grade_count = kounter["Total"].get(prev_grade) - 1
-				kounter["Total"].update({prev_grade: prev_grade_count})
-			latest_grade_count = kounter["Total"].get(total)+1 if kounter["Total"].get(total) else 1
-			kounter["Total"].update({total: latest_grade_count})
-
-			result_dict[result.student].update({
-					frappe.scrub(result.assessment_criteria): result.grade,
-					frappe.scrub(result.assessment_criteria)+"_score": result.score,
-					"total_score": total_score,
-					"total": total
-				})
-
-		return result_dict, kounter
-
-	# make data from the result dict
-	def get_data():
-		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])
-		return student_list
-
-
-	# get chart data
-	def get_chart():
-		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))
-		criteria_list = [d[0] for d in assessment_criteria_list] + ["Total"]
-		return get_chart_data(grades, criteria_list, kounter)
-
-
-	assessment_plan_list, assessment_criteria_list, total_maximum_score, grading_scale,\
-		student_group_list = get_assessment_details()
-	result_dict, kounter = get_result_map()
-	data = get_data()
-
-	columns = get_column(assessment_criteria_list, total_maximum_score)
-	chart = get_chart()
-	data_to_be_printed = [{
-		"assessment_plan": ", ".join(assessment_plan_list)
-	}]
-
-	return columns, data, None, chart, data_to_be_printed
-
-def get_column(assessment_criteria, total_maximum_score):
+def get_column(assessment_criteria):
 	columns = [{
 		"fieldname": "student",
 		"label": _("Student ID"),
@@ -143,40 +203,28 @@
 	}]
 	for d in assessment_criteria:
 		columns.append({
-			"fieldname": frappe.scrub(d[0]),
-			"label": d[0],
+			"fieldname": frappe.scrub(d),
+			"label": d,
 			"fieldtype": "Data",
 			"width": 110
 		})
 		columns.append({
-			"fieldname": frappe.scrub(d[0]) +"_score",
-			"label": "Score(" + str(int(d[1])) + ")",
+			"fieldname": frappe.scrub(d) +"_score",
+			"label": "Score(" + str(int(assessment_criteria[d])) + ")",
 			"fieldtype": "Float",
 			"width": 100
 		})
 
-	columns += [{
-		"fieldname": "total",
-		"label": "Total",
-		"fieldtype": "Data",
-		"width": 100
-	},
-	{
-		"fieldname": "total_score",
-		"label": "Total Score("+ str(int(total_maximum_score)) + ")",
-		"fieldtype": "Float",
-		"width": 110
-	}]
-
 	return columns
 
-def get_chart_data(grades, assessment_criteria_list, kounter):
+
+def get_chart_data(grades, criteria_list, kounter):
 	grades = sorted(grades)
 	datasets = []
 
 	for grade in grades:
 		tmp = frappe._dict({"values":[], "title": grade})
-		for criteria in assessment_criteria_list:
+		for criteria in criteria_list:
 			if grade in kounter[criteria]:
 				tmp["values"].append(kounter[criteria][grade])
 			else:
@@ -185,7 +233,7 @@
 
 	return {
 		"data": {
-			"labels": assessment_criteria_list,
+			"labels": criteria_list,
 			"datasets": datasets
 		},
 		"type": 'bar',
diff --git a/erpnext/education/report/final_assessment_grades/__init__.py b/erpnext/education/report/final_assessment_grades/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/education/report/final_assessment_grades/__init__.py
diff --git a/erpnext/education/report/final_assessment_grades/final_assessment_grades.js b/erpnext/education/report/final_assessment_grades/final_assessment_grades.js
new file mode 100644
index 0000000..ba0a42f
--- /dev/null
+++ b/erpnext/education/report/final_assessment_grades/final_assessment_grades.js
@@ -0,0 +1,38 @@
+// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+/* eslint-disable */
+
+frappe.query_reports["Final Assessment Grades"] = {
+	"filters": [
+		{
+			"fieldname":"academic_year",
+			"label": __("Academic Year"),
+			"fieldtype": "Link",
+			"options": "Academic Year",
+			"reqd": 1
+		},
+		{
+			"fieldname":"student_group",
+			"label": __("Student Group"),
+			"fieldtype": "Link",
+			"options": "Student Group",
+			"reqd": 1,
+			"get_query": function() {
+				return{
+					filters: {
+						"group_based_on": "Batch",
+						"academic_year": frappe.query_report_filters_by_name.academic_year.value
+					}
+				};
+			}
+		},
+		{
+			"fieldname":"assessment_group",
+			"label": __("Assessment Group"),
+			"fieldtype": "Link",
+			"options": "Assessment Group",
+			"reqd": 1
+		}
+
+	]
+}
diff --git a/erpnext/education/report/final_assessment_grades/final_assessment_grades.json b/erpnext/education/report/final_assessment_grades/final_assessment_grades.json
new file mode 100644
index 0000000..1efbb6e
--- /dev/null
+++ b/erpnext/education/report/final_assessment_grades/final_assessment_grades.json
@@ -0,0 +1,20 @@
+{
+ "add_total_row": 0, 
+ "apply_user_permissions": 1, 
+ "creation": "2018-01-22 17:04:43.412054", 
+ "disabled": 0, 
+ "docstatus": 0, 
+ "doctype": "Report", 
+ "idx": 0, 
+ "is_standard": "Yes", 
+ "letter_head": "Shishuvan Secondary School", 
+ "modified": "2018-01-22 17:04:43.412054", 
+ "modified_by": "Administrator", 
+ "module": "Education", 
+ "name": "Final Assessment Grades", 
+ "owner": "Administrator", 
+ "ref_doctype": "Assessment Result", 
+ "report_name": "Final Assessment Grades", 
+ "report_type": "Script Report", 
+ "roles": []
+}
\ No newline at end of file
diff --git a/erpnext/education/report/final_assessment_grades/final_assessment_grades.py b/erpnext/education/report/final_assessment_grades/final_assessment_grades.py
new file mode 100644
index 0000000..efc9aff
--- /dev/null
+++ b/erpnext/education/report/final_assessment_grades/final_assessment_grades.py
@@ -0,0 +1,85 @@
+# 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
+
+from erpnext.education.report.course_wise_assessment_report.course_wise_assessment_report import get_formatted_result
+from erpnext.education.report.course_wise_assessment_report.course_wise_assessment_report import get_chart_data
+
+
+def execute(filters=None):
+	columns, data, grades = [], [], []
+	args = frappe._dict()
+	course_wise_analysis = defaultdict(dict)
+
+	args["academic_year"] = filters.get("academic_year")
+	assessment_group = args["assessment_group"] = filters.get("assessment_group")
+
+	student_group = filters.get("student_group")
+	args.students = frappe.db.sql_list("select student from `tabStudent Group Student` where parent=%s", (student_group))
+
+	values = get_formatted_result(args, get_course=True)
+	student_details = values.get("student_details")
+	assessment_result = values.get("assessment_result")
+	course_dict = values.get("course_dict")
+
+	for student in args.students:
+		student_row = {}
+		student_row["student"] = student
+		student_row["student_name"] = student_details[student]
+		for course in course_dict:
+			scrub_course = frappe.scrub(course)
+			if assessment_group in assessment_result[student][course]:
+				student_row["grade_" + scrub_course] = assessment_result[student][course][assessment_group]["Total Score"]["grade"]
+				student_row["score_" + scrub_course] = assessment_result[student][course][assessment_group]["Total Score"]["score"]
+
+				# create the list of possible grades
+				if student_row["grade_" + scrub_course] not in grades:
+					grades.append(student_row["grade_" + scrub_course])
+
+				# create the dict of for gradewise analysis
+				if student_row["grade_" + scrub_course] not in course_wise_analysis[course]:
+					course_wise_analysis[course][student_row["grade_" + scrub_course]] = 1
+				else:
+					course_wise_analysis[course][student_row["grade_" + scrub_course]] += 1
+
+		data.append(student_row)
+
+	course_list = [d for d in course_dict]
+	columns = get_column(course_dict)
+	chart = get_chart_data(grades, course_list, course_wise_analysis)
+	return columns, data, None, chart
+
+
+def get_column(course_dict):
+	columns = [{
+		"fieldname": "student",
+		"label": _("Student ID"),
+		"fieldtype": "Link",
+		"options": "Student",
+		"width": 90
+	},
+	{
+		"fieldname": "student_name",
+		"label": _("Student Name"),
+		"fieldtype": "Data",
+		"width": 160
+	}]
+	for course in course_dict:
+		columns.append({
+			"fieldname": "grade_" + frappe.scrub(course),
+			"label": course,
+			"fieldtype": "Data",
+			"width": 110
+		})
+		columns.append({
+			"fieldname": "score_" + frappe.scrub(course),
+			"label": "Score(" + str(course_dict[course]) + ")",
+			"fieldtype": "Float",
+			"width": 100
+		})
+
+	return columns
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index b4433fb..3905215 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -183,7 +183,6 @@
 execute:frappe.db.sql("""delete from `tabProject Task`""")
 erpnext.patches.v5_0.update_item_desc_in_invoice
 erpnext.patches.v5_1.fix_against_account
-erpnext.patches.v5_1.fix_credit_days_based_on
 execute:frappe.rename_doc("DocType", "Salary Manager", "Process Payroll", force=True)
 erpnext.patches.v5_1.rename_roles
 erpnext.patches.v5_1.default_bom
@@ -489,5 +488,9 @@
 erpnext.patches.v10_0.fichier_des_ecritures_comptables_for_france
 erpnext.patches.v10_0.update_assessment_plan
 erpnext.patches.v10_0.update_assessment_result
+<<<<<<< HEAD
 erpnext.patches.v10_0.added_extra_gst_custom_field
 erpnext.patches.v10_0.workflow_leave_application #2018-01-24
+=======
+erpnext.patches.v10_0.set_default_payment_terms_based_on_company
+>>>>>>> master
diff --git a/erpnext/patches/v10_0/set_default_payment_terms_based_on_company.py b/erpnext/patches/v10_0/set_default_payment_terms_based_on_company.py
new file mode 100644
index 0000000..1b59633
--- /dev/null
+++ b/erpnext/patches/v10_0/set_default_payment_terms_based_on_company.py
@@ -0,0 +1,37 @@
+from __future__ import unicode_literals
+import frappe
+from erpnext.patches.v8_10.change_default_customer_credit_days import make_payment_term, make_template
+
+def execute():
+	for dt in ("Company", "Customer Group"):
+		frappe.reload_doc("setup", "doctype", frappe.scrub(dt))
+
+		credit_records = frappe.db.sql("""
+			SELECT DISTINCT `credit_days`, `credit_days_based_on`, `name`
+			from `tab{0}`
+			where
+				((credit_days_based_on='Fixed Days' or credit_days_based_on is null) and credit_days is not null)
+				or credit_days_based_on='Last Day of the Next Month'
+		""".format(dt), as_dict=1)
+
+		for d in credit_records:
+			template = create_payment_terms_template(d)
+
+			frappe.db.sql("""
+				update `tab{0}`
+				set `payment_terms` = %s
+				where name = %s
+			""".format(dt), (template, d.name))
+
+def create_payment_terms_template(data):
+	if data.credit_days_based_on == "Fixed Days":
+		pyt_template_name = 'Default Payment Term - N{0}'.format(data.credit_days)
+	else:
+		pyt_template_name = 'Default Payment Term - EO2M'
+
+	if not frappe.db.exists("Payment Terms Template", pyt_template_name):
+		payment_term = make_payment_term(data.credit_days, data.credit_days_based_on)
+		template = make_template(payment_term)
+	else:
+		template = frappe.get_doc("Payment Terms Template", pyt_template_name)
+	return template
\ No newline at end of file
diff --git a/erpnext/patches/v5_1/fix_credit_days_based_on.py b/erpnext/patches/v5_1/fix_credit_days_based_on.py
deleted file mode 100644
index 6df19f2..0000000
--- a/erpnext/patches/v5_1/fix_credit_days_based_on.py
+++ /dev/null
@@ -1,9 +0,0 @@
-from __future__ import unicode_literals
-
-import frappe
-
-def execute():
-	for dt in ("Customer", "Customer Group", "Company"):
-		frappe.reload_doctype(dt, force=True)
-		frappe.db.sql("""update `tab{0}` set credit_days_based_on='Fixed Days'
-			where ifnull(credit_days, 0) > 0""".format(dt))
diff --git a/erpnext/patches/v8_10/change_default_customer_credit_days.py b/erpnext/patches/v8_10/change_default_customer_credit_days.py
index 640c8aa..eddafb5 100644
--- a/erpnext/patches/v8_10/change_default_customer_credit_days.py
+++ b/erpnext/patches/v8_10/change_default_customer_credit_days.py
@@ -17,7 +17,8 @@
 			SELECT DISTINCT `credit_days`, `credit_days_based_on`, `name`
 			from `tab{0}`
 			where
-				(credit_days_based_on='Fixed Days' and credit_days is not null)
+				((credit_days_based_on='Fixed Days' or credit_days_based_on is null)
+					and credit_days is not null)
 				or credit_days_based_on='Last Day of the Next Month'
 		""".format(doctype))
 
diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js
index f155e09..abde665 100644
--- a/erpnext/public/js/controllers/transaction.js
+++ b/erpnext/public/js/controllers/transaction.js
@@ -523,7 +523,8 @@
 					},
 					callback: function(r, rt) {
 						if(r.message) {
-							me.frm.set_value("due_date", r.message);
+							me.frm.doc.due_date = r.message;
+							refresh_field("due_date");
 							frappe.ui.form.trigger(me.frm.doc.doctype, "currency");
 							me.recalculate_terms();
 						}
@@ -538,7 +539,7 @@
 	due_date: function() {
 		// due_date is to be changed, payment terms template and/or payment schedule must
 		// be removed as due_date is automatically changed based on payment terms
-		if (this.frm.doc.due_date) {
+		if (this.frm.doc.due_date && !this.frm.updating_party_details) {
 			if (this.frm.doc.payment_terms_template ||
 				(this.frm.doc.payment_schedule && this.frm.doc.payment_schedule.length)) {
 				var message1 = "";
@@ -555,11 +556,9 @@
 					if (message1.length !== 0) message2 = " and " + message2;
 					final_message = final_message + message2;
 				}
-
 				frappe.msgprint(final_message);
 			}
-
-	    }
+		}
 	},
 
 	recalculate_terms: function() {
diff --git a/erpnext/selling/doctype/customer/customer.js b/erpnext/selling/doctype/customer/customer.js
index 9603290..92734cc 100644
--- a/erpnext/selling/doctype/customer/customer.js
+++ b/erpnext/selling/doctype/customer/customer.js
@@ -43,7 +43,7 @@
 
 		frappe.dynamic_link = {doc: frm.doc, fieldname: 'name', doctype: 'Customer'}
 
-		frm.toggle_display(['address_html','contact_html'], !frm.doc.__islocal);
+		frm.toggle_display(['address_html','contact_html','primary_contact_detail'], !frm.doc.__islocal);
 
 		if(!frm.doc.__islocal) {
 			frappe.contacts.render_address_and_contact(frm);
diff --git a/erpnext/selling/sales_common.js b/erpnext/selling/sales_common.js
index 3d174b7..5ca2618 100644
--- a/erpnext/selling/sales_common.js
+++ b/erpnext/selling/sales_common.js
@@ -340,7 +340,8 @@
 
 	conversion_factor: function(doc, cdt, cdn, dont_fetch_price_list_rate) {
 	    this._super(doc, cdt, cdn, dont_fetch_price_list_rate);
-		if(frappe.meta.get_docfield(cdt, "stock_qty", cdn)) {
+		if(frappe.meta.get_docfield(cdt, "stock_qty", cdn) &&
+			in_list(['Delivery Note', 'Sales Invoice'], doc.doctype)) {
 			this.set_batch_number(cdt, cdn);
 		}
 	},
diff --git a/erpnext/setup/doctype/company/company.json b/erpnext/setup/doctype/company/company.json
index 9824c70..d444417 100644
--- a/erpnext/setup/doctype/company/company.json
+++ b/erpnext/setup/doctype/company/company.json
@@ -1186,6 +1186,35 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fieldname": "column_break_26", 
+   "fieldtype": "Column Break", 
+   "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, 
+   "length": 0, 
+   "no_copy": 0, 
+   "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, 
+   "columns": 0, 
    "depends_on": "eval:!doc.__islocal", 
    "fieldname": "credit_limit", 
    "fieldtype": "Currency", 
@@ -1219,8 +1248,9 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
-   "fieldname": "column_break_26", 
-   "fieldtype": "Column Break", 
+   "depends_on": "", 
+   "fieldname": "payment_terms", 
+   "fieldtype": "Link", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
@@ -1228,8 +1258,10 @@
    "in_global_search": 0, 
    "in_list_view": 0, 
    "in_standard_filter": 0, 
+   "label": "Default Payment Terms Template", 
    "length": 0, 
    "no_copy": 0, 
+   "options": "Payment Terms Template", 
    "permlevel": 0, 
    "precision": "", 
    "print_hide": 0, 
@@ -1248,69 +1280,6 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
-   "fieldname": "credit_days_based_on", 
-   "fieldtype": "Select", 
-   "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": "Credit Days Based On", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "\nFixed Days\nLast Day of the Next Month", 
-   "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, 
-   "columns": 0, 
-   "depends_on": "eval:(!doc.__islocal && doc.credit_days_based_on=='Fixed Days')", 
-   "fieldname": "credit_days", 
-   "fieldtype": "Int", 
-   "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": "Credit Days", 
-   "length": 0, 
-   "no_copy": 0, 
-   "oldfieldname": "credit_days", 
-   "oldfieldtype": "Int", 
-   "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, 
-   "set_only_once": 0, 
-   "unique": 0
-  }, 
-  {
-   "allow_bulk_edit": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
    "depends_on": "eval:!doc.__islocal", 
    "fieldname": "auto_accounting_for_stock_settings", 
    "fieldtype": "Section Break", 
@@ -2052,7 +2021,7 @@
  "istable": 0, 
  "max_attachments": 0, 
  "menu_index": 0, 
- "modified": "2017-12-07 18:40:24.646920", 
+ "modified": "2018-01-29 12:40:24.646920", 
  "modified_by": "Administrator", 
  "module": "Setup", 
  "name": "Company", 
diff --git a/erpnext/setup/doctype/customer_group/customer_group.json b/erpnext/setup/doctype/customer_group/customer_group.json
index 316f11b..062a49a 100644
--- a/erpnext/setup/doctype/customer_group/customer_group.json
+++ b/erpnext/setup/doctype/customer_group/customer_group.json
@@ -162,12 +162,14 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
-   "fieldname": "credit_days_based_on", 
-   "fieldtype": "Select", 
+   "depends_on": "", 
+   "fieldname": "payment_terms", 
+   "fieldtype": "Link", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
@@ -175,10 +177,10 @@
    "in_global_search": 0, 
    "in_list_view": 0, 
    "in_standard_filter": 0, 
-   "label": "Credit Days Based On", 
+   "label": "Default Payment Terms Template", 
    "length": 0, 
    "no_copy": 0, 
-   "options": "\nFixed Days\nLast Day of the Next Month", 
+   "options": "Payment Terms Template", 
    "permlevel": 0, 
    "precision": "", 
    "print_hide": 0, 
@@ -196,35 +198,6 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
-   "depends_on": "eval:doc.credit_days_based_on=='Fixed Days'", 
-   "fieldname": "credit_days", 
-   "fieldtype": "Int", 
-   "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": "Credit Days", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 1, 
-   "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": "credit_limit", 
    "fieldtype": "Currency", 
    "hidden": 0, 
@@ -411,7 +384,7 @@
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2017-02-20 13:25:31.549874", 
+ "modified": "2018-01-29 13:25:31.549874", 
  "modified_by": "Administrator", 
  "module": "Setup", 
  "name": "Customer Group", 
diff --git a/erpnext/stock/dashboard/item_dashboard.js b/erpnext/stock/dashboard/item_dashboard.js
index 23820d3..2748436 100644
--- a/erpnext/stock/dashboard/item_dashboard.js
+++ b/erpnext/stock/dashboard/item_dashboard.js
@@ -75,7 +75,7 @@
 			this.content.find('.more').addClass('hidden');
 		}
 
-        // If not any stock in any warehouses provide a message to end user
+		// If not any stock in any warehouses provide a message to end user
 		if (context.data.length > 0) {
 			$(frappe.render_template('item_dashboard_list', context)).appendTo(this.result);
 		} else {
@@ -86,6 +86,7 @@
 	get_item_dashboard_data: function(data, max_count, show_item) {
 		if(!max_count) max_count = 0;
 		if(!data) data = [];
+
 		data.forEach(function(d) {
 			d.actual_or_pending = d.projected_qty + d.reserved_qty + d.reserved_qty_for_production;
 			d.pending_qty = 0;
@@ -97,9 +98,16 @@
 			max_count = Math.max(d.actual_or_pending, d.actual_qty,
 				d.total_reserved, max_count);
 		});
+
+		var can_write = 0;
+		if(frappe.boot.user.can_write.indexOf("Stock Entry")>=0){
+			can_write = 1;
+		}
+
 		return {
 			data: data,
 			max_count: max_count,
+			can_write:can_write,
 			show_item: show_item || false
 		}
 	}
@@ -187,4 +195,4 @@
 				frappe.set_route('Form', doc.doctype, doc.name);
 			})
 		});
-}
+}
\ No newline at end of file
diff --git a/erpnext/stock/dashboard/item_dashboard_list.html b/erpnext/stock/dashboard/item_dashboard_list.html
index 63f2480..e0b3431 100644
--- a/erpnext/stock/dashboard/item_dashboard_list.html
+++ b/erpnext/stock/dashboard/item_dashboard_list.html
@@ -39,6 +39,7 @@
 					</span>
 				</span>
 			</div>
+			{% if can_write %}
 			<div class="col-sm-2 text-right" style="margin-top: 8px;">
 				{% if d.actual_qty %}
 				<button class="btn btn-default btn-xs btn-move"
@@ -52,6 +53,7 @@
 					data-item="{{ d.item_code }}"
 					data-rate="{{ d.valuation_rate }}">{{ __("Add") }}</a>
 			</div>
+			{% endif %}
 		</div>
 	</div>
 {% endfor %}
diff --git a/erpnext/stock/doctype/batch/batch_list.js b/erpnext/stock/doctype/batch/batch_list.js
index 2138fa1..7ee81aa 100644
--- a/erpnext/stock/doctype/batch/batch_list.js
+++ b/erpnext/stock/doctype/batch/batch_list.js
@@ -1,7 +1,7 @@
 frappe.listview_settings['Batch'] = {
 	add_fields: ["item", "expiry_date"],
 	get_indicator: function(doc) {
-		if(doc.expiry_date && frappe.datetime.get_diff(doc.expiry_date) <= 0) {
+		if(doc.expiry_date && frappe.datetime.get_diff(doc.expiry_date, frappe.datetime.nowdate()) <= 0) {
 			return [__("Expired"), "red", "expiry_date,>=,Today"]
 		} else if(doc.expiry_date) {
 			return [__("Not Expired"), "green", "expiry_date,<,Today"]
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py
index dd8d998..80afd49 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.py
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.py
@@ -293,7 +293,7 @@
 
 			# get basic rate
 			if not d.bom_no:
-				if not flt(d.basic_rate) or d.s_warehouse or force:
+				if (not flt(d.basic_rate) and not d.allow_zero_valuation_rate) or d.s_warehouse or force:
 					basic_rate = flt(get_incoming_rate(args), self.precision("basic_rate", d))
 					if basic_rate > 0:
 						d.basic_rate = basic_rate
@@ -304,7 +304,8 @@
 
 			# get scrap items basic rate
 			if d.bom_no:
-				if not flt(d.basic_rate) and getattr(self, "pro_doc", frappe._dict()).scrap_warehouse == d.t_warehouse:
+				if not flt(d.basic_rate) and not d.allow_zero_valuation_rate and \
+					getattr(self, "pro_doc", frappe._dict()).scrap_warehouse == d.t_warehouse:
 					basic_rate = flt(get_incoming_rate(args), self.precision("basic_rate", d))
 					if basic_rate > 0:
 						d.basic_rate = basic_rate
diff --git a/erpnext/utilities/user_progress_utils.py b/erpnext/utilities/user_progress_utils.py
index 18d38c0..58a03e3 100644
--- a/erpnext/utilities/user_progress_utils.py
+++ b/erpnext/utilities/user_progress_utils.py
@@ -40,12 +40,12 @@
 @frappe.whitelist()
 def create_letterhead(args_data):
 	args = json.loads(args_data)
-	letterhead = args.get("letterhead").encode('utf-8')
+	letterhead = args.get("letterhead")
 	if letterhead:
 		try:
 			frappe.get_doc({
 					"doctype":"Letter Head",
-					"content":"""<div><img src="{0}" style='max-width: 100%%;'><br></div>""".format(letterhead),
+					"content":"""<div><img src="{0}" style='max-width: 100%%;'><br></div>""".format(letterhead.encode('utf-8')),
 					"letter_head_name": _("Standard"),
 					"is_default": 1
 			}).insert()