[fix] patch missing salary component type based on existing salary slips (#6955)

diff --git a/erpnext/hr/report/monthly_salary_register/monthly_salary_register.py b/erpnext/hr/report/monthly_salary_register/monthly_salary_register.py
index 2c6cf72..6e1265e 100644
--- a/erpnext/hr/report/monthly_salary_register/monthly_salary_register.py
+++ b/erpnext/hr/report/monthly_salary_register/monthly_salary_register.py
@@ -8,32 +8,32 @@
 
 def execute(filters=None):
 	if not filters: filters = {}
-	
+
 	salary_slips = get_salary_slips(filters)
 	columns, earning_types, ded_types = get_columns(salary_slips)
 	ss_earning_map = get_ss_earning_map(salary_slips)
 	ss_ded_map = get_ss_ded_map(salary_slips)
-	
-	
+
+
 	data = []
 	for ss in salary_slips:
 		row = [ss.name, ss.employee, ss.employee_name, ss.branch, ss.department, ss.designation,
 			ss.company, ss.month, ss.leave_withut_pay, ss.payment_days]
-			
+
 		for e in earning_types:
 			row.append(ss_earning_map.get(ss.name, {}).get(e))
-			
+
 		row += [ss.arrear_amount, ss.leave_encashment_amount, ss.gross_pay]
-		
+
 		for d in ded_types:
 			row.append(ss_ded_map.get(ss.name, {}).get(d))
-		
+
 		row += [ss.total_deduction, ss.net_pay]
-		
+
 		data.append(row)
-	
+
 	return columns, data
-	
+
 def get_columns(salary_slips):
 	columns = [
 		_("Salary Slip ID") + ":Link/Salary Slip:150",_("Employee") + ":Link/Employee:120", _("Employee Name") + "::140", _("Branch") + ":Link/Branch:120",
@@ -41,7 +41,7 @@
 		_("Company") + ":Link/Company:120", _("Month") + "::80", _("Leave Without Pay") + ":Float:130",
 		_("Payment Days") + ":Float:120"
 	]
-	
+
 	salary_components = {_("Earning"): [], _("Deduction"): []}
 
 	for component in frappe.db.sql("""select distinct sd.salary_component, sc.type
@@ -61,47 +61,47 @@
 	conditions, filters = get_conditions(filters)
 	salary_slips = frappe.db.sql("""select * from `tabSalary Slip` where docstatus = 1 %s
 		order by employee, month""" % conditions, filters, as_dict=1)
-	
+
 	if not salary_slips:
-		msgprint(_("No salary slip found for month: ") + cstr(filters.get("month")) + 
-			_(" and year: ") + cstr(filters.get("fiscal_year")), raise_exception=1)
-	
+		frappe.throw(_("No salary slip found for month {0} and year {1}").format(
+			filters.get("month"), filters.get("fiscal_year")))
+
 	return salary_slips
-	
+
 def get_conditions(filters):
 	conditions = ""
 	if filters.get("month"):
-		month = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", 
+		month = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov",
 			"Dec"].index(filters["month"]) + 1
 		filters["month"] = month
 		conditions += " and month = %(month)s"
-	
+
 	if filters.get("fiscal_year"): conditions += " and fiscal_year = %(fiscal_year)s"
 	if filters.get("company"): conditions += " and company = %(company)s"
 	if filters.get("employee"): conditions += " and employee = %(employee)s"
-	
+
 	return conditions, filters
-	
+
 def get_ss_earning_map(salary_slips):
-	ss_earnings = frappe.db.sql("""select parent, salary_component, amount 
+	ss_earnings = frappe.db.sql("""select parent, salary_component, amount
 		from `tabSalary Detail` where parent in (%s)""" %
 		(', '.join(['%s']*len(salary_slips))), tuple([d.name for d in salary_slips]), as_dict=1)
-	
+
 	ss_earning_map = {}
 	for d in ss_earnings:
 		ss_earning_map.setdefault(d.parent, frappe._dict()).setdefault(d.salary_component, [])
 		ss_earning_map[d.parent][d.salary_component] = flt(d.amount)
-	
+
 	return ss_earning_map
 
 def get_ss_ded_map(salary_slips):
-	ss_deductions = frappe.db.sql("""select parent, salary_component, amount 
+	ss_deductions = frappe.db.sql("""select parent, salary_component, amount
 		from `tabSalary Detail` where parent in (%s)""" %
 		(', '.join(['%s']*len(salary_slips))), tuple([d.name for d in salary_slips]), as_dict=1)
-	
+
 	ss_ded_map = {}
 	for d in ss_deductions:
 		ss_ded_map.setdefault(d.parent, frappe._dict()).setdefault(d.salary_component, [])
 		ss_ded_map[d.parent][d.salary_component] = flt(d.amount)
-	
+
 	return ss_ded_map
\ No newline at end of file
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index d9e336d..5f8531d 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -347,4 +347,5 @@
 erpnext.patches.v7_1.add_account_user_role_for_timesheet
 erpnext.patches.v7_0.set_base_amount_in_invoice_payment_table
 erpnext.patches.v7_1.update_invoice_status
-erpnext.patches.v7_0.po_status_issue_for_pr_return
\ No newline at end of file
+erpnext.patches.v7_0.po_status_issue_for_pr_return
+erpnext.patches.v7_1.update_missing_salary_component_type
diff --git a/erpnext/patches/v7_1/update_missing_salary_component_type.py b/erpnext/patches/v7_1/update_missing_salary_component_type.py
new file mode 100644
index 0000000..7f6002d
--- /dev/null
+++ b/erpnext/patches/v7_1/update_missing_salary_component_type.py
@@ -0,0 +1,25 @@
+from __future__ import unicode_literals
+
+import frappe
+
+'''
+Some components do not have type set, try and guess whether they turn up in
+earnings or deductions in existing salary slips
+'''
+
+def execute():
+	for s in frappe.db.sql('select name from `tabSalary Component` where ifnull(type, "")=""'):
+		compontent = frappe.get_doc('Salary Component', s[0])
+
+		# guess
+		guess = frappe.db.sql('''select
+			parentfield from `tabSalary Detail`
+			where salary_component=%s limit 1''', s[0])
+
+		if guess:
+			compontent.type = 'Earning' if guess[0][0]=='earnings' else 'Deduction'
+
+		else:
+			compontent.type = 'Deduction'
+
+		compontent.save()
\ No newline at end of file