示例#1
0
def calculate_leaves_details(filters, leave_type, employee):
    ledger_entries = get_leave_ledger_entries(filters.from_date,
                                              filters.to_date, employee.name,
                                              leave_type)

    #Leaves Deducted consist of both expired and leaves taken
    leaves_deducted = get_leaves_for_period(
        employee.name, leave_type, filters.from_date, filters.to_date) * -1

    # removing expired leaves
    leaves_taken = leaves_deducted - remove_expired_leave(ledger_entries)

    opening = get_leave_balance_on(employee.name, leave_type,
                                   filters.from_date)

    new_allocation, expired_allocation = get_allocated_and_expired_leaves(
        ledger_entries, filters.from_date, filters.to_date)

    #removing leaves taken from expired_allocation
    expired_leaves = max(expired_allocation - leaves_taken, 0)

    #Formula for calculating  closing balance
    closing = max(opening + new_allocation - (leaves_taken + expired_leaves),
                  0)

    return [opening, new_allocation, expired_leaves, leaves_taken, closing]
示例#2
0
def get_allocated_and_expired_leaves(
	from_date: str, to_date: str, employee: str, leave_type: str
) -> Tuple[float, float, float]:
	new_allocation = 0
	expired_leaves = 0
	carry_forwarded_leaves = 0

	records = get_leave_ledger_entries(from_date, to_date, employee, leave_type)

	for record in records:
		# new allocation records with `is_expired=1` are created when leave expires
		# these new records should not be considered, else it leads to negative leave balance
		if record.is_expired:
			continue

		if record.to_date < getdate(to_date):
			# leave allocations ending before to_date, reduce leaves taken within that period
			# since they are already used, they won't expire
			expired_leaves += record.leaves
			expired_leaves += get_leaves_for_period(employee, leave_type, record.from_date, record.to_date)

		if record.from_date >= getdate(from_date):
			if record.is_carry_forward:
				carry_forwarded_leaves += record.leaves
			else:
				new_allocation += record.leaves

	return new_allocation, expired_leaves, carry_forwarded_leaves
示例#3
0
def expire_carried_forward_allocation(allocation):
	"""Expires remaining leaves in the on carried forward allocation"""
	from erpnext.hr.doctype.leave_application.leave_application import get_leaves_for_period

	leaves_taken = get_leaves_for_period(
		allocation.employee,
		allocation.leave_type,
		allocation.from_date,
		allocation.to_date,
		skip_expired_leaves=False,
	)
	leaves = flt(allocation.leaves) + flt(leaves_taken)

	# allow expired leaves entry to be created
	if leaves > 0:
		args = frappe._dict(
			transaction_name=allocation.name,
			transaction_type="Leave Allocation",
			leaves=allocation.leaves * -1,
			is_carry_forward=allocation.is_carry_forward,
			is_expired=1,
			from_date=allocation.to_date,
			to_date=allocation.to_date,
		)
		create_leave_ledger_entry(allocation, args)
def get_data(filters):
	leave_types = frappe.db.sql_list("SELECT `name` FROM `tabLeave Type` ORDER BY `name` ASC")

	conditions = get_conditions(filters)

	user = frappe.session.user
	department_approver_map = get_department_leave_approver_map(filters.get('department'))

	active_employees = frappe.get_list('Employee',
		filters=conditions,
		fields=['name', 'employee_name', 'department', 'user_id', 'leave_approver'])

	data = []

	for leave_type in leave_types:
		if len(active_employees) > 1:
			data.append({
				'leave_type': leave_type
			})
		else:
			row = frappe._dict({
				'leave_type': leave_type
			})

		for employee in active_employees:

			leave_approvers = department_approver_map.get(employee.department_name, []).append(employee.leave_approver)

			if (leave_approvers and len(leave_approvers) and user in leave_approvers) or (user in ["Administrator", employee.user_id]) \
				or ("HR Manager" in frappe.get_roles(user)):
				if len(active_employees) > 1:
					row = frappe._dict()
				row.employee = employee.name,
				row.employee_name = employee.employee_name

				leaves_taken = get_leaves_for_period(employee.name, leave_type,
					filters.from_date, filters.to_date) * -1

				new_allocation, expired_leaves = get_allocated_and_expired_leaves(filters.from_date, filters.to_date, employee.name, leave_type)


				opening = get_leave_balance_on(employee.name, leave_type, add_days(filters.from_date, -1)) #allocation boundary condition

				row.leaves_allocated = new_allocation
				row.leaves_expired = expired_leaves - leaves_taken if expired_leaves - leaves_taken > 0 else 0
				row.opening_balance = opening
				row.leaves_taken = leaves_taken

				# not be shown on the basis of days left it create in user mind for carry_forward leave
				row.closing_balance = (new_allocation + opening - (row.leaves_expired + leaves_taken))


				row.indent = 1
				data.append(row)
				new_leaves_allocated = 0


	return data
示例#5
0
def get_data(filters: Filters) -> List:
	leave_types = frappe.db.get_list("Leave Type", pluck="name", order_by="name")
	conditions = get_conditions(filters)

	user = frappe.session.user
	department_approver_map = get_department_leave_approver_map(filters.get("department"))

	active_employees = frappe.get_list(
		"Employee",
		filters=conditions,
		fields=["name", "employee_name", "department", "user_id", "leave_approver"],
	)

	data = []

	for leave_type in leave_types:
		if len(active_employees) > 1:
			data.append({"leave_type": leave_type})
		else:
			row = frappe._dict({"leave_type": leave_type})

		for employee in active_employees:

			leave_approvers = department_approver_map.get(employee.department_name, []).append(
				employee.leave_approver
			)

			if (
				(leave_approvers and len(leave_approvers) and user in leave_approvers)
				or (user in ["Administrator", employee.user_id])
				or ("HR Manager" in frappe.get_roles(user))
			):
				if len(active_employees) > 1:
					row = frappe._dict()
				row.employee = employee.name
				row.employee_name = employee.employee_name

				leaves_taken = (
					get_leaves_for_period(employee.name, leave_type, filters.from_date, filters.to_date) * -1
				)

				new_allocation, expired_leaves, carry_forwarded_leaves = get_allocated_and_expired_leaves(
					filters.from_date, filters.to_date, employee.name, leave_type
				)
				opening = get_opening_balance(employee.name, leave_type, filters, carry_forwarded_leaves)

				row.leaves_allocated = new_allocation
				row.leaves_expired = expired_leaves
				row.opening_balance = opening
				row.leaves_taken = leaves_taken

				# not be shown on the basis of days left it create in user mind for carry_forward leave
				row.closing_balance = new_allocation + opening - (row.leaves_expired + leaves_taken)
				row.indent = 1
				data.append(row)

	return data
def get_data(filters, leave_types):
    user = frappe.session.user
    conditions = get_conditions(filters)

    if filters.to_date <= filters.from_date:
        frappe.throw(_("From date can not be greater than than To date"))

    if filters.to_date <= filters.from_date:
        frappe.throw(_("From date can not be greater than than To date"))

    active_employees = frappe.get_all("Employee",
                                      filters=conditions,
                                      fields=[
                                          "name", "employee_name",
                                          "department", "user_id",
                                          "leave_approver"
                                      ])

    department_approver_map = get_department_leave_approver_map(
        filters.get('department'))

    data = []
    for employee in active_employees:
        leave_approvers = department_approver_map.get(employee.department_name,
                                                      [])
        if employee.leave_approver:
            leave_approvers.append(employee.leave_approver)

        if (len(leave_approvers) and user in leave_approvers) or (user in [
                "Administrator", employee.user_id
        ]) or ("HR Manager" in frappe.get_roles(user)):
            row = [employee.name, employee.employee_name, employee.department]

            for leave_type in leave_types:
                # leaves taken
                leaves_taken = get_leaves_for_period(employee.name, leave_type,
                                                     filters.from_date,
                                                     filters.to_date) * -1

                # opening balance
                opening = get_leave_balance_on(employee.name, leave_type,
                                               filters.from_date)

                # closing balance
                closing = get_leave_balance_on(employee.name, leave_type,
                                               filters.to_date)

                row += [opening, leaves_taken, closing]

            data.append(row)

    return data
示例#7
0
def get_leave_details(employee, date):
    '''Override white listed function get_leave_details for calculate leaves details
	Because after adding hourly leave funcionality leave balanace, leave used and pending leaves qouta calculted in decimals and 
	this add almost 10+ digits after decimal'''
    allocation_records = get_leave_allocation_records(date, employee).get(
        employee, frappe._dict())
    leave_allocation = {}
    for d in allocation_records:
        allocation = allocation_records.get(d, frappe._dict())
        date = allocation.to_date
        leaves_taken = round(
            get_leaves_for_period(employee,
                                  d,
                                  allocation.from_date,
                                  date,
                                  status="Approved"), 2)
        leaves_pending = round(
            get_leaves_for_period(employee,
                                  d,
                                  allocation.from_date,
                                  date,
                                  status="Open"), 2)
        remaining_leaves = round(
            allocation.total_leaves_allocated - leaves_taken - leaves_pending,
            2)
        leave_allocation[d] = {
            "total_leaves": allocation.total_leaves_allocated,
            "leaves_taken": leaves_taken,
            "pending_leaves": leaves_pending,
            "remaining_leaves": remaining_leaves
        }

    ret = {
        'leave_allocation': leave_allocation,
        'leave_approver': get_leave_approver(employee)
    }

    return ret
def get_data(filters):
    leave_types = frappe.db.sql_list(
        "SELECT `name` FROM `tabLeave Type` ORDER BY `name` ASC")

    conditions = get_conditions(filters)

    user = frappe.session.user
    department_approver_map = get_department_leave_approver_map(
        filters.get('department'))

    active_employees = frappe.get_list('Employee',
                                       filters=conditions,
                                       fields=[
                                           'name', 'employee_name',
                                           'department', 'user_id',
                                           'leave_approver'
                                       ])

    data = []

    for leave_type in leave_types:
        data.append({'leave_type': leave_type})
        for employee in active_employees:

            leave_approvers = department_approver_map.get(
                employee.department_name, []).append(employee.leave_approver)

            if (len(leave_approvers) and user in leave_approvers) or (user in ["Administrator", employee.user_id]) \
             or ("HR Manager" in frappe.get_roles(user)):
                row = frappe._dict({
                    'employee': employee.name,
                    'employee_name': employee.employee_name
                })

                leaves_taken = get_leaves_for_period(employee.name, leave_type,
                                                     filters.from_date,
                                                     filters.to_date) * -1

                opening = get_leave_balance_on(employee.name, leave_type,
                                               filters.from_date)
                closing = get_leave_balance_on(employee.name, leave_type,
                                               filters.to_date)

                row.opening_balance = opening
                row.leaves_taken = leaves_taken
                row.closing_balance = closing
                row.indent = 1
                data.append(row)

    return data
示例#9
0
    def get_leave_details_for_encashment(self):
        salary_structure = get_assigned_salary_structure(
            self.employee, self.encashment_date or getdate(nowdate()))
        if not salary_structure:
            frappe.throw(
                _("No Salary Structure assigned for Employee {0} on given date {1}"
                  ).format(self.employee, self.encashment_date))

        if not frappe.db.get_value("Leave Type", self.leave_type,
                                   "allow_encashment"):
            frappe.throw(
                _("Leave Type {0} is not encashable").format(self.leave_type))

        allocation = self.get_leave_allocation()

        if not allocation:
            frappe.throw(
                _("No Leaves Allocated to Employee: {0} for Leave Type: {1}").
                format(self.employee, self.leave_type))

        self.leave_balance = (
            allocation.total_leaves_allocated -
            allocation.carry_forwarded_leaves_count
            # adding this because the function returns a -ve number
            +
            get_leaves_for_period(self.employee, self.leave_type,
                                  allocation.from_date, self.encashment_date))

        encashable_days = self.leave_balance - frappe.db.get_value(
            "Leave Type", self.leave_type, "encashment_threshold_days")
        self.encashable_days = encashable_days if encashable_days > 0 else 0

        per_day_encashment = frappe.db.get_value(
            "Salary Structure", salary_structure,
            "leave_encashment_amount_per_day")
        self.encashment_amount = (self.encashable_days * per_day_encashment
                                  if per_day_encashment > 0 else 0)

        self.leave_allocation = allocation.name
        return True