')
+ .appendTo(frm.fields_dict.employees_html.wrapper);
+ }
+ frm.EmployeeSelector = new erpnext.EmployeeSelector(frm, frm.employee_area, r.message['unmarked'])
+ }
+ else{
+ hide_field('unmarked_attendance_section')
+ }
+
+ if(r.message['marked'].length > 0){
+ unhide_field('marked_attendance_section')
+ if(!frm.marked_employee_area){
+
+ frm.marked_employee_area = $('
')
+ .appendTo(frm.fields_dict.marked_attendance_html.wrapper);
+ }
+ frm.MarkedEmployee = new erpnext.MarkedEmployee(frm, frm.marked_employee_area, r.message['marked'])
+ }
+ else{
+ hide_field('marked_attendance_section')
+ }
+ }
+ });
+ }
+ }
+}
+
+erpnext.MarkedEmployee = Class.extend({
+ init: function(frm, wrapper, employee) {
+ this.wrapper = wrapper;
+ this.frm = frm;
+ this.make(frm, employee);
+ },
+ make: function(frm, employee) {
+ var me = this;
+ $(this.wrapper).empty();
+
+ $.each(employee, function(i, m) {
+ var attendance_icon = "'icon-check'"
+ if(m.status == "Absent") {
+ attendance_icon="'icon-check-empty'"
+ }
+ else if(m.status == "Half Day"){
+ attendance_icon = "'icon-check-minus'"
+ }
+ $(repl('
\
+ \
+
', {employee: m.employee_name, icon: attendance_icon})).appendTo(me.wrapper);
+ });
+ }
+});
+
+
+erpnext.EmployeeSelector = Class.extend({
+ init: function(frm, wrapper, employee) {
+ this.wrapper = wrapper;
+ this.frm = frm;
+ this.make(frm, employee);
+ },
+ make: function(frm, employee) {
+ var me = this;
+
+ $(this.wrapper).empty();
+ var employee_toolbar = $('
\
+ \
+ \
+
').appendTo($(this.wrapper));
+
+ var mark_employee_toolbar = $('
\
+ \
+ \
+
')
+
+ employee_toolbar.find(".btn-add")
+ .html(__('Check all'))
+ .on("click", function() {
+ $(me.wrapper).find('input[type="checkbox"]').each(function(i, check) {
+ if(!$(check).is(":checked")) {
+ check.checked = true;
+ }
+ });
+ });
+
+ employee_toolbar.find(".btn-remove")
+ .html(__('Uncheck all'))
+ .on("click", function() {
+ $(me.wrapper).find('input[type="checkbox"]').each(function(i, check) {
+ if($(check).is(":checked")) {
+ check.checked = false;
+ }
+ });
+ });
+
+ mark_employee_toolbar.find(".btn-mark-present")
+ .html(__('Mark Present'))
+ .on("click", function() {
+ var employee_present = [];
+ $(me.wrapper).find('input[type="checkbox"]').each(function(i, check) {
+ if($(check).is(":checked")) {
+ employee_present.push(employee[i]);
+ }
+ });
+ frappe.call({
+ method: "erpnext.hr.doctype.employee_attendance_tool.employee_attendance_tool.mark_employee_attendance",
+ args:{
+ "employee_list":employee_present,
+ "status":"Present",
+ "date":frm.doc.date,
+ "company":frm.doc.company
+ },
+
+ callback: function(r) {
+ erpnext.employee_attendance_tool.load_employees(frm);
+
+ }
+ });
+ });
+
+ mark_employee_toolbar.find(".btn-mark-absent")
+ .html(__('Mark Absent'))
+ .on("click", function() {
+ var employee_absent = [];
+ $(me.wrapper).find('input[type="checkbox"]').each(function(i, check) {
+ if($(check).is(":checked")) {
+ employee_absent.push(employee[i]);
+ }
+ });
+ frappe.call({
+ method: "erpnext.hr.doctype.employee_attendance_tool.employee_attendance_tool.mark_employee_attendance",
+ args:{
+ "employee_list":employee_absent,
+ "status":"Absent",
+ "date":frm.doc.date,
+ "company":frm.doc.company
+ },
+
+ callback: function(r) {
+ erpnext.employee_attendance_tool.load_employees(frm);
+
+ }
+ });
+ });
+
+
+ mark_employee_toolbar.find(".btn-mark-half-day")
+ .html(__('Mark Half Day'))
+ .on("click", function() {
+ var employee_half_day = [];
+ $(me.wrapper).find('input[type="checkbox"]').each(function(i, check) {
+ if($(check).is(":checked")) {
+ employee_half_day.push(employee[i]);
+ }
+ });
+ frappe.call({
+ method: "erpnext.hr.doctype.employee_attendance_tool.employee_attendance_tool.mark_employee_attendance",
+ args:{
+ "employee_list":employee_half_day,
+ "status":"Half Day",
+ "date":frm.doc.date,
+ "company":frm.doc.company
+ },
+
+ callback: function(r) {
+ erpnext.employee_attendance_tool.load_employees(frm);
+
+ }
+ });
+ });
+
+
+ $.each(employee, function(i, m) {
+ $(repl('
', {employee: m.employee_name})).appendTo(me.wrapper);
+
+
+
+ });
+
+ mark_employee_toolbar.appendTo($(this.wrapper));
+
+
+ }
+});
+
+
diff --git a/erpnext/hr/doctype/employee_attendance_tool/employee_attendance_tool.json b/erpnext/hr/doctype/employee_attendance_tool/employee_attendance_tool.json
new file mode 100644
index 00000000000..f31bcf8e990
--- /dev/null
+++ b/erpnext/hr/doctype/employee_attendance_tool/employee_attendance_tool.json
@@ -0,0 +1,275 @@
+{
+ "allow_copy": 1,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "creation": "2016-01-27 14:59:47.849379",
+ "custom": 0,
+ "docstatus": 0,
+ "doctype": "DocType",
+ "document_type": "",
+ "fields": [
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "default": "Today",
+ "fieldname": "date",
+ "fieldtype": "Date",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Date",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "fieldname": "department",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Department",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Department",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "fieldname": "column_break_3",
+ "fieldtype": "Column Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "fieldname": "branch",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Branch",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Branch",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "fieldname": "company",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Company",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Company",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "depends_on": "date",
+ "fieldname": "unmarked_attendance_section",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Unmarked Attendance",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "fieldname": "employees_html",
+ "fieldtype": "HTML",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Employees HTML",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "depends_on": "date",
+ "fieldname": "marked_attendance_section",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Marked Attendance",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "fieldname": "marked_attendance_html",
+ "fieldtype": "HTML",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Marked Attendance HTML",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ }
+ ],
+ "hide_heading": 1,
+ "hide_toolbar": 1,
+ "idx": 0,
+ "in_create": 0,
+ "in_dialog": 0,
+ "is_submittable": 0,
+ "issingle": 1,
+ "istable": 0,
+ "max_attachments": 0,
+ "modified": "2016-01-29 02:14:36.034952",
+ "modified_by": "Administrator",
+ "module": "HR",
+ "name": "Employee Attendance Tool",
+ "name_case": "",
+ "owner": "Administrator",
+ "permissions": [
+ {
+ "amend": 0,
+ "apply_user_permissions": 0,
+ "cancel": 0,
+ "create": 1,
+ "delete": 0,
+ "email": 0,
+ "export": 0,
+ "if_owner": 0,
+ "import": 0,
+ "permlevel": 0,
+ "print": 0,
+ "read": 1,
+ "report": 0,
+ "role": "HR Manager",
+ "set_user_permissions": 0,
+ "share": 0,
+ "submit": 0,
+ "write": 1
+ }
+ ],
+ "read_only": 0,
+ "read_only_onload": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC"
+}
\ No newline at end of file
diff --git a/erpnext/hr/doctype/employee_attendance_tool/employee_attendance_tool.py b/erpnext/hr/doctype/employee_attendance_tool/employee_attendance_tool.py
new file mode 100644
index 00000000000..622b0d95dba
--- /dev/null
+++ b/erpnext/hr/doctype/employee_attendance_tool/employee_attendance_tool.py
@@ -0,0 +1,52 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+import copy
+import json
+from frappe.model.document import Document
+
+
+class EmployeeAttendanceTool(Document):
+ pass
+
+
+@frappe.whitelist()
+def get_employees(date, department=None, branch=None, company=None):
+ attendance_not_marked = []
+ attendance_marked = []
+ employee_list = frappe.get_list("Employee", fields=["employee", "employee_name"], filters={
+ "status": "Active", "department": department, "branch": branch, "company": company}, order_by="employee_name")
+ marked_employee = {}
+ for emp in frappe.get_list("Attendance", fields=["employee", "status"],
+ filters={"att_date": date}):
+ marked_employee[emp['employee']] = emp['status']
+
+ for employee in employee_list:
+ employee['status'] = marked_employee.get(employee['employee'])
+ if employee['employee'] not in marked_employee:
+ attendance_not_marked.append(employee)
+ else:
+ attendance_marked.append(employee)
+ return {
+ "marked": attendance_marked,
+ "unmarked": attendance_not_marked
+ }
+
+
+@frappe.whitelist()
+def mark_employee_attendance(employee_list, status, date, company=None):
+ employee_list = json.loads(employee_list)
+ for employee in employee_list:
+ attendance = frappe.new_doc("Attendance")
+ attendance.employee = employee['employee']
+ attendance.employee_name = employee['employee_name']
+ attendance.att_date = date
+ attendance.status = status
+ if company:
+ attendance.company = company
+ else:
+ attendance.company = frappe.db.get_value("Employee", employee['employee'], "Company")
+ attendance.submit()