fix(hr): Auto Attendance

> fixing minor bug in shift calculation
> adding 'Mark Auto Attendance' button in shift and related fixes
> changed employee checkin naming series
> added aditional validation for employee checkin
> added/updated dashboard for Attendance, Employee, Shift Type
diff --git a/erpnext/hr/doctype/attendance/attendance_dashboard.py b/erpnext/hr/doctype/attendance/attendance_dashboard.py
new file mode 100644
index 0000000..5dd9403
--- /dev/null
+++ b/erpnext/hr/doctype/attendance/attendance_dashboard.py
@@ -0,0 +1,13 @@
+from __future__ import unicode_literals
+from frappe import _
+
+def get_data():
+	return {
+		'fieldname': 'attendance',
+		'transactions': [
+			{
+				'label': '',
+				'items': ['Employee Checkin']
+			}
+		]
+	}
diff --git a/erpnext/hr/doctype/employee/employee_dashboard.py b/erpnext/hr/doctype/employee/employee_dashboard.py
index e3cc33d..162b697 100644
--- a/erpnext/hr/doctype/employee/employee_dashboard.py
+++ b/erpnext/hr/doctype/employee/employee_dashboard.py
@@ -9,7 +9,7 @@
 		'transactions': [
 			{
 				'label': _('Leave and Attendance'),
-				'items': ['Attendance', 'Attendance Request', 'Leave Application', 'Leave Allocation']
+				'items': ['Attendance', 'Attendance Request', 'Leave Application', 'Leave Allocation', 'Employee Checkin']
 			},
 			{
 				'label': _('Lifecycle'),
@@ -40,4 +40,4 @@
 				'items': ['Training Event', 'Training Result', 'Training Feedback', 'Employee Skill Map']
 			},
 		]
-	}
\ No newline at end of file
+	}
diff --git a/erpnext/hr/doctype/employee_checkin/employee_checkin.json b/erpnext/hr/doctype/employee_checkin/employee_checkin.json
index d340527..15ec7c0 100644
--- a/erpnext/hr/doctype/employee_checkin/employee_checkin.json
+++ b/erpnext/hr/doctype/employee_checkin/employee_checkin.json
@@ -1,6 +1,6 @@
 {
  "allow_import": 1,
- "autoname": "ATT-CKIN-.MM.-.YYYY.-.######",
+ "autoname": "EMP-CKIN-.MM.-.YYYY.-.######",
  "creation": "2019-06-10 11:56:34.536413",
  "doctype": "DocType",
  "engine": "InnoDB",
@@ -119,7 +119,7 @@
    "label": "Shift Actual End"
   }
  ],
- "modified": "2019-06-10 11:56:34.536413",
+ "modified": "2019-06-10 15:33:22.731697",
  "modified_by": "Administrator",
  "module": "HR",
  "name": "Employee Checkin",
diff --git a/erpnext/hr/doctype/employee_checkin/employee_checkin.py b/erpnext/hr/doctype/employee_checkin/employee_checkin.py
index 997897b..b0e15d9 100644
--- a/erpnext/hr/doctype/employee_checkin/employee_checkin.py
+++ b/erpnext/hr/doctype/employee_checkin/employee_checkin.py
@@ -28,6 +28,8 @@
 	def fetch_shift(self):
 		shift_actual_timings = get_actual_start_end_datetime_of_shift(self.employee, get_datetime(self.time), True)
 		if shift_actual_timings[0] and shift_actual_timings[1]:
+			if shift_actual_timings[2].shift_type.determine_check_in_and_check_out == 'Strictly based on Log Type in Employee Checkin' and not self.log_type and not self.skip_auto_attendance:
+				frappe.throw(_('Log Type is required for check-ins falling in the shift: {0}.').format(shift_actual_timings[2].shift_type.name))
 			if not self.attendance:
 				self.shift = shift_actual_timings[2].shift_type.name
 				self.shift_actual_start = shift_actual_timings[0]
diff --git a/erpnext/hr/doctype/shift_assignment/shift_assignment.py b/erpnext/hr/doctype/shift_assignment/shift_assignment.py
index 5b732c4..40c78cd 100644
--- a/erpnext/hr/doctype/shift_assignment/shift_assignment.py
+++ b/erpnext/hr/doctype/shift_assignment/shift_assignment.py
@@ -115,11 +115,12 @@
 					break
 		else:
 			direction = '<' if next_shift_direction == 'reverse' else '>'
+			sort_order = 'desc' if next_shift_direction == 'reverse' else 'asc'
 			dates = frappe.db.get_all('Shift Assignment',
 				'date',
 				{'employee':employee, 'date':(direction, for_date), 'docstatus': '1'},
 				as_list=True,
-				limit=MAX_DAYS)
+				limit=MAX_DAYS, order_by="date "+sort_order)
 			for date in dates:
 				shift_details = get_employee_shift(employee, date[0], consider_default_shift, None)
 				if shift_details:
diff --git a/erpnext/hr/doctype/shift_type/shift_type.js b/erpnext/hr/doctype/shift_type/shift_type.js
index feae889..e633545 100644
--- a/erpnext/hr/doctype/shift_type/shift_type.js
+++ b/erpnext/hr/doctype/shift_type/shift_type.js
@@ -3,6 +3,16 @@
 
 frappe.ui.form.on('Shift Type', {
 	refresh: function(frm) {
-
+		frm.add_custom_button(
+			'Mark Auto Attendance',
+			() => frm.call({
+				doc: frm.doc,
+				method: 'process_auto_attendance',
+				freeze: true,
+				callback: () => {
+					frappe.msgprint(__("Attendance has been marked as per employee check-ins"));
+				}
+			})
+		);
 	}
 });
diff --git a/erpnext/hr/doctype/shift_type/shift_type.py b/erpnext/hr/doctype/shift_type/shift_type.py
index b77d224..eaf6b1e 100644
--- a/erpnext/hr/doctype/shift_type/shift_type.py
+++ b/erpnext/hr/doctype/shift_type/shift_type.py
@@ -8,7 +8,7 @@
 
 import frappe
 from frappe.model.document import Document
-from frappe.utils import cint, getdate
+from frappe.utils import cint, getdate, get_datetime
 from erpnext.hr.doctype.shift_assignment.shift_assignment import get_actual_start_end_datetime_of_shift, get_employee_shift
 from erpnext.hr.doctype.employee_checkin.employee_checkin import mark_attendance_and_link_log, calculate_working_hours
 from erpnext.hr.doctype.attendance.attendance import mark_absent
@@ -53,9 +53,9 @@
 		date_of_joining, relieving_date, employee_creation = frappe.db.get_value("Employee", employee, ["date_of_joining", "relieving_date", "creation"])
 		if not date_of_joining:
 			date_of_joining = employee_creation.date()
-		start_date = max(self.process_attendance_after, date_of_joining)
-		actual_shift_datetime = get_actual_start_end_datetime_of_shift(employee, self.last_sync_of_checkin, True)
-		last_shift_time = actual_shift_datetime[0] if actual_shift_datetime[0] else self.last_sync_of_checkin
+		start_date = max(getdate(self.process_attendance_after), date_of_joining)
+		actual_shift_datetime = get_actual_start_end_datetime_of_shift(employee, get_datetime(self.last_sync_of_checkin), True)
+		last_shift_time = actual_shift_datetime[0] if actual_shift_datetime[0] else get_datetime(self.last_sync_of_checkin)
 		prev_shift = get_employee_shift(employee, last_shift_time.date()-timedelta(days=1), True, 'reverse')
 		if prev_shift:
 			end_date = min(prev_shift.start_datetime.date(), relieving_date) if relieving_date else prev_shift.start_datetime.date()
@@ -64,10 +64,11 @@
 		holiday_list_name = self.holiday_list
 		if not holiday_list_name:
 			holiday_list_name = get_holiday_list_for_employee(employee, False)
-		for date in get_filtered_date_list(employee, start_date, end_date, holiday_list=holiday_list_name):
+		dates = get_filtered_date_list(employee, start_date, end_date, holiday_list=holiday_list_name)
+		for date in dates:
 			shift_details = get_employee_shift(employee, date, True)
 			if shift_details and shift_details.shift_type.name == self.name:
-				mark_absent(employee, date)
+				mark_absent(employee, date, self.name)
 
 	def get_assigned_employee(self, from_date=None, consider_default_shift=False):
 		filters = {'date':('>=', from_date), 'shift_type': self.name, 'docstatus': '1'}
diff --git a/erpnext/hr/doctype/shift_type/shift_type_dashboard.py b/erpnext/hr/doctype/shift_type/shift_type_dashboard.py
index 91dfbad..0a49dda 100644
--- a/erpnext/hr/doctype/shift_type/shift_type_dashboard.py
+++ b/erpnext/hr/doctype/shift_type/shift_type_dashboard.py
@@ -2,11 +2,11 @@
 from frappe import _
 
 def get_data():
-     return {
-        'fieldname': 'shift_type',
-        'transactions': [
-            {
-                'items': ['Shift Request', 'Shift Assignment']
-            }
-        ],
-    }
\ No newline at end of file
+	return {
+		'fieldname': 'shift',
+		'transactions': [
+			{
+				'items': ['Attendance', 'Employee Checkin', 'Shift Request', 'Shift Assignment']
+			}
+		]
+	}