def is_self_rated(name): try: return frappe.db.get_value("Appraisal Template", {"name": name}, ["self_rating_allowed"]) except Exception as err: ErrorHandler.log_error(str(err)) frappe.throw(("Error: {}".format(err)))
def update_non_aggregative(self, employee, date): _date = datetime.strptime(date, "%Y-%m-%d") year = int(datetime.strftime(_date, "%Y")) month = int(datetime.strftime(_date, "%m")) penalty_list = frappe.get_all( "Employee Attendance Penalties", { "year": year, "month": month, "employee": employee['name'], "type": "penalty" }, ["name"]) if len(penalty_list) == 0: return {} try: penalty = frappe.get_doc("Employee Attendance Penalties", penalty_list[0]["name"]) if (penalty): penalty.value = employee['total_late_arrival'] penalty.penalty = (employee['total_late_arrival'] * employee['policy_multiplier']) penalty.instance = employee['total_late_instance'] penalty.attendance_policy_rules = employee['policy_rule_id'] penalty.save() return penalty except Exception as err: ErrorHandler.log_error(str(err))
def hide_icons(doctype, event_name): ''' Hiding all standard icons except those which we defined for Employee ''' blocked_module = ['Help', 'Website', 'Learn', 'Contacts', 'Tools'] try: site_dir = get_site_path() desktop_icons_list = get_desktop_icons_list(site_dir) hide_list = list(set(get_all_icons()) - set(desktop_icons_list)) update_icons(hide_list, doctype.email) for report_list in custom_query_report_icons(site_dir): if frappe.db.exists('Desktop Icon', { "owner": doctype.email, "module_name": report_list }): desktop_icon = frappe.get_doc('Desktop Icon', { "owner": doctype.email, "module_name": report_list }) desktop_icon._report = report_list desktop_icon.save() for block_module in blocked_module: if frappe.db.exists('Desktop Icon', { "owner": doctype.email, "module_name": block_module }): blocked_doc = frappe.get_doc('Desktop Icon', { "owner": doctype.email, 'module_name': block_module }) blocked_doc.blocked = 1 blocked_doc.save() except Exception as err: ErrorHandler.log_error(str(err))
def refusal_reason(document_name, reason=""): try: data = frappe.get_doc("Appraisal", document_name) data.reason_for_refusal = reason data.save() except Exception as err: ErrorHandler.log_error(str(err)) frappe.throw(("Error: {}".format(err)))
def get_employee_details(employee): try: joining, emp_type = frappe.db.get_value( "Employee", {"employee": employee}, ["date_of_joining", "employment_type"]) return { "joining": frappe.utils.formatdate(joining), "emp_type": emp_type } except Exception as err: ErrorHandler.log_error(str(err)) frappe.throw(("Error: {}".format(err)))
def add_or_update_attendance(emp_obj=dict(), obj=dict()): attendance_id = frappe.db.get_value( "Attendance", { "employee": emp_obj.get("name"), "attendance_date": obj.get("attendance_date"), "docstatus": 1 }, "name") try: if attendance_id is not None: attendance_doc = frappe.get_doc("Attendance", attendance_id) new_att_doc = frappe.copy_doc(attendance_doc) new_att_doc.amended_from = attendance_doc.name attendance_doc.flags.ignore_permissions = True attendance_doc.cancel() else: new_att_doc = frappe.new_doc("Attendance") new_att_doc.employee = emp_obj.get("name") new_att_doc.attendance_date = obj.get("attendance_date") if obj.get("status") is not None: new_att_doc.status = obj.get("status") if obj.get("shift_start_time") is not None and obj.get( "shift_start_time"): new_att_doc.shift_start_time = str( datetime.strptime(obj.get("shift_start_time"), '%Y-%m-%d %H:%M:%S').time()) if obj.get("shift_end_time") is not None and obj.get("shift_end_time"): new_att_doc.shift_end_time = str( datetime.strptime(obj.get("shift_end_time"), '%Y-%m-%d %H:%M:%S').time()) if obj.get("attendance_status") is not None and obj.get( "attendance_status"): new_att_doc.attendance_status = obj.get("attendance_status") if (new_att_doc.check_in or new_att_doc.check_out ) and new_att_doc.status == ATTENDANCE_STATUS_ABSENT: new_att_doc.status = ATTENDANCE_STATUS_PRESENT new_att_doc.modified_by = frappe.session.user new_att_doc.set_by_cron = 0 new_att_doc.flags.ignore_permissions = True result = new_att_doc.save() new_att_doc.submit() return True, { "record": new_att_doc, "name": new_att_doc.name, "object_id": obj.get("object_id") } except Exception as err: ErrorHandler.log_error(str(err)) return False, str(err)
def calculate_non_aggregative(self, employee, date): _date = datetime.strptime(date, "%Y-%m-%d") year = datetime.strftime(_date, "%Y") month = datetime.strftime(_date, "%m") _type = POLICY_TYPE_REWARD if employee['policy_multiplier'] > 0: _type = POLICY_TYPE_PENALTY """ check if type penalty and allow penalty not is marked or check if type reward and allow reward not is not marked then dont add record """ if ( _type == POLICY_TYPE_PENALTY and bool(employee["allow_penalty_deduction"]) == False \ or _type == POLICY_TYPE_REWARD and bool(employee["allow_reward"]) == False): return False try: penalty = frappe.get_doc({ "doctype": "Employee Attendance Penalties", "year": year, "month": month, "employee": employee['name'], "value": employee['total_late_arrival'], "penalty": (employee['total_late_arrival'] * employee['policy_multiplier']), "instance": employee['total_late_instance'], "attendance_policy_rules": employee['policy_rule_id'], "type": _type, "comments": 'added by script' }) penalty.insert() return penalty except Exception as err: ErrorHandler.log_error(str(err))
def validate_due_days(employee, kra_template): try: joining = frappe.db.get_value("Employee", {"name": employee}, ["date_of_joining"]) today = datetime.date.today() diff = today - joining due_days = frappe.db.get_value("Appraisal Template", {"name": kra_template}, ["appraisal_due_days"]) if (due_days > diff.days): return False return True except Exception as err: ErrorHandler.log_error(str(err)) frappe.throw(("Error: {}".format(err)))
def validate_dates(doctype, event_name): ''' validate cutoff dates ''' try: date_obj = datetime.datetime.now() la_date = str_to_date(date_obj.strftime("%Y-%m-%d"), '%Y-%m-%d') processding_date = str_to_date( date_obj.strftime("%Y-%m-") + str(get_config_by_name('MONTH_PROCESSING_DATE', '20')), '%Y-%m-%d') restrict_leave_date = str_to_date( date_obj.strftime("%Y-%m-") + str(get_config_by_name('RESTRICTED_LEAVES_DATE', '22')), '%Y-%m-%d') from_date = str_to_date(doctype.from_date, '%Y-%m-%d') to_date = str_to_date(doctype.to_date, '%Y-%m-%d') except Exception as err: print(err) ErrorHandler.log_error(str(err)) ''' if there is creation date then we consider creation date as leave application date la_date ''' if hasattr(doctype, 'creation'): la_date = str_to_date(get_datetime(doctype.creation), '%Y-%m-%d') new_la = False if hasattr(doctype, '__islocal'): new_la = True ''' Check advance privilege and validate dates of cutoff''' if (check_advance_privilege_by_name( get_config_by_name('ADVANCE_PRIV_APPLY_LEAVE_AFTER_CUTOFF_DATE')) == False and new_la == True): if (la_date >= restrict_leave_date and (from_date <= processding_date or to_date <= processding_date)): frappe.throw( _("You cannot apply for a previous day leave after the cutoff date" )) elif ( (from_date <= processding_date - dateutil.relativedelta.relativedelta(months=1) or to_date <= processding_date - dateutil.relativedelta.relativedelta(months=1))): frappe.throw( _("You cannot apply for a previous day leave after the cutoff date" )) #TODO: Make validation configurable ''' Check advance privilege Validation for casual leave '''
def add_update_doc(self, employee, att_id=None): attendance = None if att_id != None: # because document with doc status 1 cannot be updated unlock_doc("Attendance", att_id) try: # updating attendance document with updated attributes attendance = frappe.get_doc("Attendance", att_id) for attr, value in employee.__dict__.iteritems(): if (value != None): attendance.__dict__[attr] = value attendance.save() except Exception as err: ErrorHandler.log_error(str(err)) return {"error": err} else: data = dict() data["doctype"] = "Attendance" try: for attr, value in employee.__dict__.iteritems(): if (value != None): data[attr] = value attendance = frappe.get_doc(data) attendance.insert() except Exception as err: ErrorHandler.log_error(str(err)) return {"error": err} return {"success": attendance}
def create_attendance_log(doc,event): try: _at_log = frappe.get_doc({"doctype": "Attendance Log"}) attendance_data = frappe.get_doc("Attendance", doc.name) filelds_to_copy = ["employee", "employee_name", "status", "leave_type", "attendance_date", "company", "department", "attendance_request", "attendance_status", "shift_start_time", "shift_end_time", "check_in", "check_out", "late_arrival", "left_early", "working_hours", "empghr_employee_attendance_pull_id", "empghr_employee_line_manager_pull_id"] copy_fields( _at_log, attendance_data,filelds_to_copy ) _at_log.attendance_name = doc.name _at_log.insert() except Exception as err: ErrorHandler.log_error(str(err)) frappe.throw(err)
def update_leave_approver(employee, leave_approver): employee_detail = frappe.db.get_value('Employee', leave_approver, ['user_id', 'employee_name']) if (employee_detail): if employee_detail[0] is not None: try: frappe.db.sql( """ UPDATE `tabLeave Application` la SET la.leave_approver = %(user_id)s , la.leave_approver_name = %(employee_name)s WHERE la.employee = %(employee)s AND la.docstatus = 0 """, ({ "user_id": employee_detail[0], "employee_name": employee_detail[1], "employee": employee })) except Exception as err: ErrorHandler.log_error(str(err)) frappe.throw(_("Unable to update leave approver")) else: frappe.throw( _("No user id linked with employee {0}".format( leave_approver)))
def process_adjustment(self, penalty_list): penalty_ids = list() employee_ids = list() indexed_list = dict() errors = list() year = None month = None if not frappe.db.exists("Leave Type", "Earned Leave"): try: doc = frappe.get_doc({ "doctype": "Leave Type", "leave_type_name": "Earned Leave", "display_name": "Earned", "is_earned_leave": 1 }) doc.save() except Exception as err: frappe.throw(_("Unable to create earned leaves type")) for penalty in penalty_list: indexed_list[penalty["id"]] = penalty penalty_ids.append(penalty["id"]) _sql = """ SELECT ap.year, ap.month, ap.employee, ap.attendance_policy_rules, ap.name FROM `tabEmployee Attendance Penalties` ap LEFT JOIN `tabAttendance Penalties Processed` app ON app.employee = ap.employee AND app.month = ap.month AND app.year = ap.year WHERE app.name IS NULL AND ap.name IN ({}) GROUP BY ap.employee """.format("'" + "','".join(penalty_ids) + "'") penalties = frappe.db.sql(_sql, as_dict=True) if len(penalties) > 0: for penalty in penalties: employee_ids.append(penalty["employee"]) year = penalty["year"] month = penalty["month"] try: if "adjustment" in indexed_list[ penalty["name"]] and indexed_list[ penalty["name"]]["adjustment"]: adjustment = frappe.get_doc({ "doctype": "Employee Attendance Penalties", "year": penalty["year"], "month": penalty["month"], "employee": penalty['employee'], "value": (-1 * int(indexed_list[penalty["name"]]["adjustment"])), "penalty": (-1 * int(indexed_list[penalty["name"]]["adjustment"])), "attendance_policy_rules": penalty['attendance_policy_rules'], "comments": 'Adjusted by .', "type": "adjustment" }) adjustment.insert() frappe.get_doc({ "doctype": "Attendance Penalties Processed", "month": month, "year": year, "employee": penalty["employee"] }).insert() except Exception as err: errors.append("{0} ---> {1}.".format( err, penalty["employee"])) ErrorHandler.log_error(str(err)) att_policies = AttendancePolicies() result = att_policies.update_leave_quota(year, month, employee_ids) if (result): for error in result: errors.append("{0}".format(error)) return errors
def assign_employee_shift(employee, shift_type): if shift_type == None: return _today = datetime.today() today_date = _today.strftime("%Y-%m-%d") month = _today.strftime("%m") year = _today.strftime("%Y") attendace_processed = frappe.db.get_value("Attendance Penalties Processed", filters={ "employee": employee, "month": month, "year": year }) if attendace_processed != None: today_date = """{0}-{1}-{2}""".format(year, month, MONTHLY_ATTENDANCE_DATE) emp_future_leaves = frappe.db.sql( """select * from `tabLeave Application` where employee = %s and (from_date >= %s OR to_date >= %s) and docstatus = 1""", (employee, today_date, today_date)) if len(emp_future_leaves) > 0: frappe.throw( _("You cannot add/change shift because employee have applied for future leave" )) _df_start_time = get_config_by_name("default_shift_start_time", "09:00:00") _df_end_time = get_config_by_name("default_shift_end_time", "18:00:00") try: emp_attendance_list = frappe.db.sql(""" SELECT att.name, att.attendance_date, IF(st.start_time IS NULL,%(start_time)s,st.start_time) as start_time, IF(st.end_time IS NULL,%(end_time)s,st.end_time) as end_time, IF(h.name IS NULL AND ch.name IS NULL AND erch.name IS NULL, "On", "Off") as attendance_status, IF(h.name IS NULL AND ch.name IS NULL AND erch.name IS NULL, "Absent", "Present") as status FROM `tabAttendance` att LEFT JOIN `tabEmployee` emp ON att.employee = emp.name LEFT JOIN `tabShift Type` st ON st.name = %(shift_name)s LEFT JOIN `tabHoliday List` hl ON hl.name = emp.holiday_list LEFT JOIN `tabHoliday` h ON h.parent = hl.name AND h.holiday_date = att.attendance_date LEFT JOIN `tabCompany` c ON c.name = emp.company LEFT JOIN `tabHoliday List` chl ON chl.name = c.default_holiday_list LEFT JOIN `tabHoliday` ch ON ch.parent = chl.name AND ch.holiday_date = att.attendance_date LEFT JOIN `tabHoliday List` erhl ON erhl.name = st.holiday_list LEFT JOIN `tabHoliday` erch ON erch.parent = erhl.name AND erch.holiday_date = att.attendance_date WHERE att.attendance_date > %(today_date)s AND att.docstatus = 1 AND att.employee = %(employee)s """, { "shift_name": shift_type, "start_time": _df_start_time, "end_time": _df_end_time, "employee": employee, "today_date": today_date }, as_dict=True) except Exception as err: ErrorHandler.log_error(str(err)) frappe.throw(_("did not find roster against new employee shift")) if len(emp_attendance_list) > 0: _att_list = [emp_sh["name"] for emp_sh in emp_attendance_list] unlock_doc_list("Attendance", _att_list) for attendance in emp_attendance_list: try: emp_att = frappe.get_doc("Attendance", attendance["name"]) emp_att.shift_start_time = attendance["start_time"] emp_att.shift_end_time = attendance["end_time"] emp_att.status = attendance["status"] emp_att.attendance_status = attendance["attendance_status"] emp_att.docstatus = 1 emp_att.save() except Exception as err: ErrorHandler.log_error(str(err)) frappe.throw(_("There is an error while updating Attendance"))
def allot_leaves(doctype, probationary=False): date_obj = datetime.datetime.now() total_days_in_year = 365 joining_date = str_to_date(doctype.date_of_joining, "%Y-%m-%d") j_year = joining_date.year curr_year = conf_year = date_obj.year system_launching_year = get_config_by_name('SYSTEM_LAUNCH_YEAR', 2019) if (j_year < system_launching_year): j_year = system_launching_year if probationary: confirmation_date = str_to_date(doctype.final_confirmation_date, "%Y-%m-%d") conf_year = confirmation_date.year while conf_year >= j_year: leave_period_start = year_start = str_to_date( date_obj.strftime(str(j_year) + "-01-01"), "%Y-%m-%d") year_end = str_to_date(date_obj.strftime(str(j_year) + "-12-31"), "%Y-%m-%d") if (joining_date > year_start): leave_days = flt(total_days_in_year - get_date_diff_in_days(year_start, joining_date)) leave_period_start = joining_date else: leave_days = total_days_in_year if probationary and conf_year == j_year: if conf_year == joining_date.year: leave_days = flt( get_date_diff_in_days(joining_date, confirmation_date)) else: leave_days = flt( get_date_diff_in_days(year_start, confirmation_date)) leaves = get_auto_assigned_leaves_detail(probationary) for leave in leaves: if (leave and leave.max_leaves_allowed > 0): alloted_leave_balance = round( flt(leave_days * leave.max_leaves_allowed) / total_days_in_year, 2) Leave_allocation_obj = frappe.get_doc( {"doctype": "Leave Allocation"}) Leave_allocation_obj.employee = doctype.employee Leave_allocation_obj.leave_type = leave.name Leave_allocation_obj.from_date = leave_period_start Leave_allocation_obj.to_date = year_end Leave_allocation_obj.new_leaves_allocated = alloted_leave_balance alloted_leave_by_type = get_leave_allocation_record( doctype.employee, leave.name, leave_period_start, year_end) if (alloted_leave_balance > 0): if (not alloted_leave_by_type): Leave_allocation_obj.docstatus = 1 Leave_allocation_obj.flags.ignore_permissions = True try: Leave_allocation_obj.insert() except Exception as err: frappe.throw(_(err)) ErrorHandler.log_error(str(err)) elif (alloted_leave_by_type and leave.prorated_on_probation): if alloted_leave_by_type[ 0].total_leaves_allocated != alloted_leave_balance: la_doc = frappe.get_doc( "Leave Allocation", alloted_leave_by_type[0].name) la_doc.update({ "new_leaves_allocated": alloted_leave_balance }) la_doc.flags.ignore_permissions = True la_doc.save() j_year = j_year + 1