示例#1
0
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)))
示例#2
0
    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))
示例#3
0
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))
示例#4
0
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)))
示例#5
0
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)
示例#7
0
    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))
示例#8
0
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)))
示例#9
0
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}
示例#11
0
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)
示例#12
0
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)))
示例#13
0
    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
示例#14
0
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"))
示例#15
0
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