Merge branch 'develop' into membership-fixes

This commit is contained in:
Shivam Mishra 2020-06-12 07:27:20 +00:00 committed by GitHub
commit 3bf18509ba
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 47 additions and 14 deletions

View File

@ -14,6 +14,9 @@ frappe.treeview_settings["Account"] = {
on_change: function() { on_change: function() {
var me = frappe.treeview_settings['Account'].treeview; var me = frappe.treeview_settings['Account'].treeview;
var company = me.page.fields_dict.company.get_value(); var company = me.page.fields_dict.company.get_value();
if (!company) {
frappe.throw(__("Please set a Company"));
}
frappe.call({ frappe.call({
method: "erpnext.accounts.doctype.account.account.get_root_company", method: "erpnext.accounts.doctype.account.account.get_root_company",
args: { args: {

View File

@ -19,11 +19,15 @@
"attendance_date", "attendance_date",
"company", "company",
"department", "department",
"shift",
"attendance_request", "attendance_request",
"amended_from", "details_section",
"shift",
"in_time",
"out_time",
"column_break_18",
"late_entry", "late_entry",
"early_exit" "early_exit",
"amended_from"
], ],
"fields": [ "fields": [
{ {
@ -172,13 +176,36 @@
"fieldname": "early_exit", "fieldname": "early_exit",
"fieldtype": "Check", "fieldtype": "Check",
"label": "Early Exit" "label": "Early Exit"
},
{
"fieldname": "details_section",
"fieldtype": "Section Break",
"label": "Details"
},
{
"depends_on": "shift",
"fieldname": "in_time",
"fieldtype": "Datetime",
"label": "In Time",
"read_only": 1
},
{
"depends_on": "shift",
"fieldname": "out_time",
"fieldtype": "Datetime",
"label": "Out Time",
"read_only": 1
},
{
"fieldname": "column_break_18",
"fieldtype": "Column Break"
} }
], ],
"icon": "fa fa-ok", "icon": "fa fa-ok",
"idx": 1, "idx": 1,
"is_submittable": 1, "is_submittable": 1,
"links": [], "links": [],
"modified": "2020-04-11 11:40:14.319496", "modified": "2020-05-29 13:51:37.177231",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "HR", "module": "HR",
"name": "Attendance", "name": "Attendance",

View File

@ -72,7 +72,7 @@ def add_log_based_on_employee_field(employee_field_value, timestamp, device_id=N
return doc return doc
def mark_attendance_and_link_log(logs, attendance_status, attendance_date, working_hours=None, late_entry=False, early_exit=False, shift=None): def mark_attendance_and_link_log(logs, attendance_status, attendance_date, working_hours=None, late_entry=False, early_exit=False, in_time=None, out_time=None, shift=None):
"""Creates an attendance and links the attendance to the Employee Checkin. """Creates an attendance and links the attendance to the Employee Checkin.
Note: If attendance is already present for the given date, the logs are marked as skipped and no exception is thrown. Note: If attendance is already present for the given date, the logs are marked as skipped and no exception is thrown.
@ -100,7 +100,9 @@ def mark_attendance_and_link_log(logs, attendance_status, attendance_date, worki
'company': employee_doc.company, 'company': employee_doc.company,
'shift': shift, 'shift': shift,
'late_entry': late_entry, 'late_entry': late_entry,
'early_exit': early_exit 'early_exit': early_exit,
'in_time': in_time,
'out_time': out_time
} }
attendance = frappe.get_doc(doc_dict).insert() attendance = frappe.get_doc(doc_dict).insert()
attendance.submit() attendance.submit()

View File

@ -28,13 +28,14 @@ class ShiftType(Document):
logs = frappe.db.get_list('Employee Checkin', fields="*", filters=filters, order_by="employee,time") logs = frappe.db.get_list('Employee Checkin', fields="*", filters=filters, order_by="employee,time")
for key, group in itertools.groupby(logs, key=lambda x: (x['employee'], x['shift_actual_start'])): for key, group in itertools.groupby(logs, key=lambda x: (x['employee'], x['shift_actual_start'])):
single_shift_logs = list(group) single_shift_logs = list(group)
attendance_status, working_hours, late_entry, early_exit = self.get_attendance(single_shift_logs) attendance_status, working_hours, late_entry, early_exit, in_time, out_time = self.get_attendance(single_shift_logs)
mark_attendance_and_link_log(single_shift_logs, attendance_status, key[1].date(), working_hours, late_entry, early_exit, self.name) mark_attendance_and_link_log(single_shift_logs, attendance_status, key[1].date(), working_hours, late_entry, early_exit, in_time, out_time, self.name)
for employee in self.get_assigned_employee(self.process_attendance_after, True): for employee in self.get_assigned_employee(self.process_attendance_after, True):
self.mark_absent_for_dates_with_no_attendance(employee) self.mark_absent_for_dates_with_no_attendance(employee)
def get_attendance(self, logs): def get_attendance(self, logs):
"""Return attendance_status, working_hours for a set of logs belonging to a single shift. """Return attendance_status, working_hours, late_entry, early_exit, in_time, out_time
for a set of logs belonging to a single shift.
Assumtion: Assumtion:
1. These logs belongs to an single shift, single employee and is not in a holiday date. 1. These logs belongs to an single shift, single employee and is not in a holiday date.
2. Logs are in chronological order 2. Logs are in chronological order
@ -48,10 +49,10 @@ class ShiftType(Document):
early_exit = True early_exit = True
if self.working_hours_threshold_for_absent and total_working_hours < self.working_hours_threshold_for_absent: if self.working_hours_threshold_for_absent and total_working_hours < self.working_hours_threshold_for_absent:
return 'Absent', total_working_hours, late_entry, early_exit return 'Absent', total_working_hours, late_entry, early_exit, in_time, out_time
if self.working_hours_threshold_for_half_day and total_working_hours < self.working_hours_threshold_for_half_day: if self.working_hours_threshold_for_half_day and total_working_hours < self.working_hours_threshold_for_half_day:
return 'Half Day', total_working_hours, late_entry, early_exit return 'Half Day', total_working_hours, late_entry, early_exit, in_time, out_time
return 'Present', total_working_hours, late_entry, early_exit return 'Present', total_working_hours, late_entry, early_exit, in_time, out_time
def mark_absent_for_dates_with_no_attendance(self, employee): def mark_absent_for_dates_with_no_attendance(self, employee):
"""Marks Absents for the given employee on working days in this shift which have no attendance marked. """Marks Absents for the given employee on working days in this shift which have no attendance marked.

View File

@ -8,7 +8,7 @@ from frappe.utils import getdate, flt
def execute(filters=None): def execute(filters=None):
if not filters: filters = {} if not filters: filters = {}
float_preceision = frappe.db.get_default("float_preceision") float_precision = frappe.db.get_default("float_precision")
condition = get_condition(filters) condition = get_condition(filters)
@ -25,7 +25,7 @@ def execute(filters=None):
data = [] data = []
for item in items: for item in items:
total_outgoing = flt(consumed_item_map.get(item.name, 0)) + flt(delivered_item_map.get(item.name,0)) total_outgoing = flt(consumed_item_map.get(item.name, 0)) + flt(delivered_item_map.get(item.name,0))
avg_daily_outgoing = flt(total_outgoing / diff, float_preceision) avg_daily_outgoing = flt(total_outgoing / diff, float_precision)
reorder_level = (avg_daily_outgoing * flt(item.lead_time_days)) + flt(item.safety_stock) reorder_level = (avg_daily_outgoing * flt(item.lead_time_days)) + flt(item.safety_stock)
data.append([item.name, item.item_name, item.item_group, item.brand, item.description, data.append([item.name, item.item_name, item.item_group, item.brand, item.description,