fix(UX): record reason for skipping attendance or marking absent for auto attendance (#30846)
This commit is contained in:
@@ -5,7 +5,7 @@
|
|||||||
import frappe
|
import frappe
|
||||||
from frappe import _
|
from frappe import _
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
from frappe.utils import cint, get_datetime
|
from frappe.utils import cint, get_datetime, get_link_to_form
|
||||||
|
|
||||||
from erpnext.hr.doctype.shift_assignment.shift_assignment import (
|
from erpnext.hr.doctype.shift_assignment.shift_assignment import (
|
||||||
get_actual_start_end_datetime_of_shift,
|
get_actual_start_end_datetime_of_shift,
|
||||||
@@ -127,19 +127,17 @@ def mark_attendance_and_link_log(
|
|||||||
log_names = [x.name for x in logs]
|
log_names = [x.name for x in logs]
|
||||||
employee = logs[0].employee
|
employee = logs[0].employee
|
||||||
if attendance_status == "Skip":
|
if attendance_status == "Skip":
|
||||||
frappe.db.sql(
|
skip_attendance_in_checkins(log_names)
|
||||||
"""update `tabEmployee Checkin`
|
|
||||||
set skip_auto_attendance = %s
|
|
||||||
where name in %s""",
|
|
||||||
("1", log_names),
|
|
||||||
)
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
elif attendance_status in ("Present", "Absent", "Half Day"):
|
elif attendance_status in ("Present", "Absent", "Half Day"):
|
||||||
employee_doc = frappe.get_doc("Employee", employee)
|
employee_doc = frappe.get_doc("Employee", employee)
|
||||||
if not frappe.db.exists(
|
duplicate = frappe.db.exists(
|
||||||
"Attendance",
|
"Attendance",
|
||||||
{"employee": employee, "attendance_date": attendance_date, "docstatus": ("!=", "2")},
|
{"employee": employee, "attendance_date": attendance_date, "docstatus": ("!=", "2")},
|
||||||
):
|
)
|
||||||
|
|
||||||
|
if not duplicate:
|
||||||
doc_dict = {
|
doc_dict = {
|
||||||
"doctype": "Attendance",
|
"doctype": "Attendance",
|
||||||
"employee": employee,
|
"employee": employee,
|
||||||
@@ -155,6 +153,12 @@ def mark_attendance_and_link_log(
|
|||||||
}
|
}
|
||||||
attendance = frappe.get_doc(doc_dict).insert()
|
attendance = frappe.get_doc(doc_dict).insert()
|
||||||
attendance.submit()
|
attendance.submit()
|
||||||
|
|
||||||
|
if attendance_status == "Absent":
|
||||||
|
attendance.add_comment(
|
||||||
|
text=_("Employee was marked Absent for not meeting the working hours threshold.")
|
||||||
|
)
|
||||||
|
|
||||||
frappe.db.sql(
|
frappe.db.sql(
|
||||||
"""update `tabEmployee Checkin`
|
"""update `tabEmployee Checkin`
|
||||||
set attendance = %s
|
set attendance = %s
|
||||||
@@ -163,12 +167,10 @@ def mark_attendance_and_link_log(
|
|||||||
)
|
)
|
||||||
return attendance
|
return attendance
|
||||||
else:
|
else:
|
||||||
frappe.db.sql(
|
skip_attendance_in_checkins(log_names)
|
||||||
"""update `tabEmployee Checkin`
|
if duplicate:
|
||||||
set skip_auto_attendance = %s
|
add_comment_in_checkins(log_names, duplicate)
|
||||||
where name in %s""",
|
|
||||||
("1", log_names),
|
|
||||||
)
|
|
||||||
return None
|
return None
|
||||||
else:
|
else:
|
||||||
frappe.throw(_("{} is an invalid Attendance Status.").format(attendance_status))
|
frappe.throw(_("{} is an invalid Attendance Status.").format(attendance_status))
|
||||||
@@ -237,3 +239,29 @@ def time_diff_in_hours(start, end):
|
|||||||
|
|
||||||
def find_index_in_dict(dict_list, key, value):
|
def find_index_in_dict(dict_list, key, value):
|
||||||
return next((index for (index, d) in enumerate(dict_list) if d[key] == value), None)
|
return next((index for (index, d) in enumerate(dict_list) if d[key] == value), None)
|
||||||
|
|
||||||
|
|
||||||
|
def add_comment_in_checkins(log_names, duplicate):
|
||||||
|
text = _("Auto Attendance skipped due to duplicate attendance record: {}").format(
|
||||||
|
get_link_to_form("Attendance", duplicate)
|
||||||
|
)
|
||||||
|
|
||||||
|
for name in log_names:
|
||||||
|
frappe.get_doc(
|
||||||
|
{
|
||||||
|
"doctype": "Comment",
|
||||||
|
"comment_type": "Comment",
|
||||||
|
"reference_doctype": "Employee Checkin",
|
||||||
|
"reference_name": name,
|
||||||
|
"content": text,
|
||||||
|
}
|
||||||
|
).insert(ignore_permissions=True)
|
||||||
|
|
||||||
|
|
||||||
|
def skip_attendance_in_checkins(log_names):
|
||||||
|
EmployeeCheckin = frappe.qb.DocType("Employee Checkin")
|
||||||
|
(
|
||||||
|
frappe.qb.update(EmployeeCheckin)
|
||||||
|
.set("skip_auto_attendance", 1)
|
||||||
|
.where(EmployeeCheckin.name.isin(log_names))
|
||||||
|
).run()
|
||||||
|
|||||||
@@ -139,7 +139,17 @@ class ShiftType(Document):
|
|||||||
for date in dates:
|
for date in dates:
|
||||||
shift_details = get_employee_shift(employee, date, True)
|
shift_details = get_employee_shift(employee, date, True)
|
||||||
if shift_details and shift_details.shift_type.name == self.name:
|
if shift_details and shift_details.shift_type.name == self.name:
|
||||||
mark_attendance(employee, date, "Absent", self.name)
|
attendance = mark_attendance(employee, date, "Absent", self.name)
|
||||||
|
if attendance:
|
||||||
|
frappe.get_doc(
|
||||||
|
{
|
||||||
|
"doctype": "Comment",
|
||||||
|
"comment_type": "Comment",
|
||||||
|
"reference_doctype": "Attendance",
|
||||||
|
"reference_name": attendance,
|
||||||
|
"content": frappe._("Employee was marked Absent due to missing Employee Checkins."),
|
||||||
|
}
|
||||||
|
).insert(ignore_permissions=True)
|
||||||
|
|
||||||
def get_assigned_employee(self, from_date=None, consider_default_shift=False):
|
def get_assigned_employee(self, from_date=None, consider_default_shift=False):
|
||||||
filters = {"start_date": (">", from_date), "shift_type": self.name, "docstatus": "1"}
|
filters = {"start_date": (">", from_date), "shift_type": self.name, "docstatus": "1"}
|
||||||
|
|||||||
Reference in New Issue
Block a user