Example #1
0
def get_data(filters, leave_types):
	user = frappe.session.user
	allocation_records_based_on_to_date = get_leave_allocation_records(filters.to_date)
	allocation_records_based_on_from_date = get_leave_allocation_records(filters.from_date)

	active_employees = frappe.get_all("Employee", 
		filters = { "status": "Active", "company": filters.company}, 
		fields = ["name", "employee_name", "department", "user_id"])
	
	data = []
	for employee in active_employees:
		leave_approvers = get_approvers(employee.department)
		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_approved_leaves_for_period(employee.name, leave_type,
					filters.from_date, filters.to_date)

				# opening balance
				opening = get_leave_balance_on(employee.name, leave_type, filters.from_date,
					allocation_records_based_on_from_date.get(employee.name, frappe._dict()))

				# closing balance
				closing = get_leave_balance_on(employee.name, leave_type, filters.to_date,
					allocation_records_based_on_to_date.get(employee.name, frappe._dict()))

				row += [opening, leaves_taken, closing]

			data.append(row)
		
	return data
def get_data(filters, leave_types):
	user = frappe.session.user
	allocation_records_based_on_to_date = get_leave_allocation_records(filters.to_date)
	allocation_records_based_on_from_date = get_leave_allocation_records(filters.from_date)

	active_employees = frappe.get_all("Employee", 
		filters = { "status": "Active", "company": filters.company}, 
		fields = ["name", "employee_name", "department", "user_id"])
	
	data = []
	for employee in active_employees:
		leave_approvers = [l.leave_approver for l in frappe.db.sql("""select leave_approver from `tabEmployee Leave Approver` where parent = %s""",
							(employee.name),as_dict=True)]
		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_approved_leaves_for_period(employee.name, leave_type,
					filters.from_date, filters.to_date)

				# opening balance
				opening = get_leave_balance_on(employee.name, leave_type, filters.from_date,
					allocation_records_based_on_from_date.get(employee.name, frappe._dict()))

				# closing balance
				closing = get_leave_balance_on(employee.name, leave_type, filters.to_date,
					allocation_records_based_on_to_date.get(employee.name, frappe._dict()))

				row += [opening, leaves_taken, closing]
			
			data.append(row)
		
	return data
Example #3
0
	def test_earned_leaves_creation(self):
		leave_period = get_leave_period()
		employee = get_employee()
		leave_type = 'Test Earned Leave Type'
		if not frappe.db.exists('Leave Type', leave_type):
			frappe.get_doc(dict(
				leave_type_name = leave_type,
				doctype = 'Leave Type',
				is_earned_leave = 1,
				earned_leave_frequency = 'Monthly',
				rounding = 0.5,
				max_leaves_allowed = 6
			)).insert()
		leave_policy = frappe.get_doc({
			"doctype": "Leave Policy",
			"leave_policy_details": [{"leave_type": leave_type, "annual_allocation": 6}]
		}).insert()
		frappe.db.set_value("Employee", employee.name, "leave_policy", leave_policy.name)

		allocate_leaves(employee, leave_period, leave_type, 0, eligible_leaves = 12)

		from erpnext.hr.utils import allocate_earned_leaves
		i = 0
		while(i<14):
			allocate_earned_leaves()
			i += 1
		self.assertEqual(get_leave_balance_on(employee.name, leave_type, nowdate()), 6)

		# validate earned leaves creation without maximum leaves
		frappe.db.set_value('Leave Type', leave_type, 'max_leaves_allowed', 0)
		i = 0
		while(i<6):
			allocate_earned_leaves()
			i += 1
		self.assertEqual(get_leave_balance_on(employee.name, leave_type, nowdate()), 9)
Example #4
0
    def test_earned_leaves_creation(self):

        frappe.db.sql('''delete from `tabLeave Period`''')
        frappe.db.sql('''delete from `tabLeave Policy Assignment`''')
        frappe.db.sql('''delete from `tabLeave Allocation`''')
        frappe.db.sql('''delete from `tabLeave Ledger Entry`''')

        leave_period = get_leave_period()
        employee = get_employee()
        leave_type = 'Test Earned Leave Type'
        frappe.delete_doc_if_exists("Leave Type",
                                    'Test Earned Leave Type',
                                    force=1)
        frappe.get_doc(
            dict(leave_type_name=leave_type,
                 doctype='Leave Type',
                 is_earned_leave=1,
                 earned_leave_frequency='Monthly',
                 rounding=0.5,
                 max_leaves_allowed=6)).insert()

        leave_policy = frappe.get_doc({
            "doctype":
            "Leave Policy",
            "leave_policy_details": [{
                "leave_type": leave_type,
                "annual_allocation": 6
            }]
        }).insert()

        data = {
            "assignment_based_on": "Leave Period",
            "leave_policy": leave_policy.name,
            "leave_period": leave_period.name
        }

        leave_policy_assignments = create_assignment_for_multiple_employees(
            [employee.name], frappe._dict(data))

        frappe.get_doc(
            "Leave Policy Assignment",
            leave_policy_assignments[0]).grant_leave_alloc_for_employee()

        from erpnext.hr.utils import allocate_earned_leaves
        i = 0
        while (i < 14):
            allocate_earned_leaves()
            i += 1
        self.assertEqual(
            get_leave_balance_on(employee.name, leave_type, nowdate()), 6)

        # validate earned leaves creation without maximum leaves
        frappe.db.set_value('Leave Type', leave_type, 'max_leaves_allowed', 0)
        i = 0
        while (i < 6):
            allocate_earned_leaves()
            i += 1
        self.assertEqual(
            get_leave_balance_on(employee.name, leave_type, nowdate()), 9)
Example #5
0
	def test_earned_leaves_creation(self):

		frappe.db.sql("""delete from `tabLeave Period`""")
		frappe.db.sql("""delete from `tabLeave Policy Assignment`""")
		frappe.db.sql("""delete from `tabLeave Allocation`""")
		frappe.db.sql("""delete from `tabLeave Ledger Entry`""")

		leave_period = get_leave_period()
		employee = get_employee()
		leave_type = "Test Earned Leave Type"
		frappe.delete_doc_if_exists("Leave Type", "Test Earned Leave Type", force=1)
		frappe.get_doc(
			dict(
				leave_type_name=leave_type,
				doctype="Leave Type",
				is_earned_leave=1,
				earned_leave_frequency="Monthly",
				rounding=0.5,
				max_leaves_allowed=6,
			)
		).insert()

		leave_policy = frappe.get_doc(
			{
				"doctype": "Leave Policy",
				"title": "Test Leave Policy",
				"leave_policy_details": [{"leave_type": leave_type, "annual_allocation": 6}],
			}
		).insert()

		data = {
			"assignment_based_on": "Leave Period",
			"leave_policy": leave_policy.name,
			"leave_period": leave_period.name,
		}

		leave_policy_assignments = create_assignment_for_multiple_employees(
			[employee.name], frappe._dict(data)
		)

		from erpnext.hr.utils import allocate_earned_leaves

		i = 0
		while i < 14:
			allocate_earned_leaves()
			i += 1
		self.assertEqual(get_leave_balance_on(employee.name, leave_type, nowdate()), 6)

		# validate earned leaves creation without maximum leaves
		frappe.db.set_value("Leave Type", leave_type, "max_leaves_allowed", 0)
		i = 0
		while i < 6:
			allocate_earned_leaves()
			i += 1
		self.assertEqual(get_leave_balance_on(employee.name, leave_type, nowdate()), 9)
Example #6
0
def get_data(filters, leave_types):
    dates = frappe.db.sql(
        '''select
									year_start_date, year_end_date
							from 
								`tabFiscal Year`
							where name = %s''', filters.fiscal_year)
    start_date = dates[0][0]
    end_date = dates[0][1]
    allocation_records_based_on_to_date_prev_year = get_leave_allocation_records(
        frappe.utils.add_days(start_date, -1))
    allocation_records_based_on_to_date = get_leave_allocation_records(
        end_date)
    allocation_records_based_on_from_date = get_leave_allocation_records(
        start_date)

    active_employees = frappe.get_all(
        "Employee",
        filters={
            "status": "Active",
            "company": filters.company
        },
        fields=["name", "employee_name", "department", "user_id"])

    data = []
    for employee in active_employees:
        row = [employee.name, employee.employee_name, employee.department]
        for leave_type in leave_types:
            # leaves taken
            leaves_taken = get_approved_leaves_for_period(
                employee.name, leave_type, start_date, end_date)
            #prev_year_opening
            prev_year_end_date = frappe.utils.add_days(start_date, -1)
            prev_year_opening = get_leave_balance_on(
                employee.name, leave_type, prev_year_end_date,
                allocation_records_based_on_to_date_prev_year.get(
                    employee.name, frappe._dict()))
            # opening balance
            opening = get_total_allocated_leaves(employee.name, leave_type,
                                                 end_date)
            added_leave_bal = 0
            if (opening - prev_year_opening) > 0:
                added_leave_bal = opening - prev_year_opening
            # closing balance
            closing = get_leave_balance_on(
                employee.name, leave_type, end_date,
                allocation_records_based_on_to_date.get(
                    employee.name, frappe._dict()))

            row += [prev_year_opening, added_leave_bal, leaves_taken, closing]

        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
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
	def test_earned_leave(self):
		leave_period = get_leave_period()
		employee = get_employee()
		leave_type = 'Test Earned Leave Type'
		if not frappe.db.exists('Leave Type', leave_type):
			frappe.get_doc(dict(
				leave_type_name = leave_type,
				doctype = 'Leave Type',
				is_earned_leave = 1,
				earned_leave_frequency = 'Monthly',
				rounding = 0.5,
				max_leaves_allowed = 6
			)).insert()
		leave_policy = frappe.get_doc({
			"doctype": "Leave Policy",
			"leave_policy_details": [{"leave_type": leave_type, "annual_allocation": 6}]
		}).insert()
		frappe.db.set_value("Employee", employee.name, "leave_policy", leave_policy.name)

		allocate_leaves(employee, leave_period, leave_type, 0, eligible_leaves = 12)

		from erpnext.hr.utils import allocate_earned_leaves
		i = 0
		while(i<14):
			allocate_earned_leaves()
			i += 1
		self.assertEqual(get_leave_balance_on(employee.name, leave_type, nowdate()), 6)
Example #10
0
def validate_balance_leaves(self):
    if self.from_date and self.to_date:
        """
		overriding starts
		"""
        self.total_leave_days = get_number_of_leave_days(
            self.employee, self.leave_type, self.from_date, self.to_date,
            self.half_day, self.half_day_date, self.hourly,
            self.hourly_day_date, self.hours)
        """
		overriding ends
		"""

    if self.total_leave_days <= 0:
        frappe.throw(
            _("The day(s) on which you are applying for leave are holidays"))

    if not is_lwp(self.leave_type):
        self.leave_balance = get_leave_balance_on(
            self.employee,
            self.leave_type,
            self.from_date,
            docname=self.name,
            consider_all_leaves_in_the_allocation_period=True)

        if self.status != "Rejected" and self.leave_balance < self.total_leave_days:
            if frappe.db.get_value("Leave Type", self.leave_type,
                                   "allow_negative"):
                frappe.msgprint(
                    _("Note: There is not enough leave balance for Leave Type {0}"
                      ).format(self.leave_type))
            else:
                frappe.throw(
                    _("There is not enough leave balance for Leave Type {0}").
                    format(self.leave_type))
Example #11
0
def make_leave_application():
    allocated_leaves = frappe.get_all("Leave Allocation",
                                      fields=['employee', 'leave_type'])

    for allocated_leave in allocated_leaves:
        leave_balance = get_leave_balance_on(
            allocated_leave.employee,
            allocated_leave.leave_type,
            frappe.flags.current_date,
            consider_all_leaves_in_the_allocation_period=True)
        if leave_balance != 0:
            if leave_balance == 1:
                to_date = frappe.flags.current_date
            else:
                to_date = add_days(frappe.flags.current_date,
                                   random.randint(0, leave_balance - 1))

            leave_application = frappe.get_doc({
                "doctype": "Leave Application",
                "employee": allocated_leave.employee,
                "from_date": frappe.flags.current_date,
                "to_date": to_date,
                "leave_type": allocated_leave.leave_type,
                "status": "Approved"
            })
            try:
                leave_application.insert()
                leave_application.submit()
                frappe.db.commit()
            except (OverlapError, AttendanceAlreadyMarkedError):
                frappe.db.rollback()
Example #12
0
def validate_balance_leaves(employee, leave_type, from_date, to_date, half_day,
                            half_day_date, status):
    total_leave_days = 0
    if from_date and to_date:
        total_leave_days = get_number_of_leave_days(employee, leave_type,
                                                    from_date, to_date,
                                                    half_day, half_day_date)

        if total_leave_days == 0:
            return "The day(s) on which you are applying for leave are holidays. You need not apply for leave."

        if not is_lwp(leave_type):
            leave_balance = get_leave_balance_on(
                employee,
                leave_type,
                from_date,
                consider_all_leaves_in_the_allocation_period=True)

            if status != "Rejected" and leave_balance < total_leave_days:
                if frappe.db.get_value("Leave Type", leave_type,
                                       "allow_negative"):
                    return "Note: There is not enough leave balance for Leave Type {0}".format(
                        leave_type)
                else:
                    return "There is not enough leave balance for Leave Type {0}".format(
                        leave_type)
    return total_leave_days
def get_data(filters, leave_types):

    allocation_records_based_on_to_date = get_leave_allocation_records(
        filters.to_date)

    active_employees = frappe.get_all(
        "Employee",
        filters={
            "status": "Active",
            "company": filters.company
        },
        fields=["name", "employee_name", "department"])

    data = []
    for employee in active_employees:
        row = [employee.name, employee.employee_name, employee.department]

        for leave_type in leave_types:
            # leaves taken
            leaves_taken = get_approved_leaves_for_period(
                employee.name, leave_type, filters.from_date, filters.to_date)

            # closing balance
            closing = get_leave_balance_on(
                employee.name, leave_type, filters.to_date,
                allocation_records_based_on_to_date.get(
                    employee.name, frappe._dict()))

            row += [leaves_taken, closing]

        data.append(row)

    return data
Example #14
0
    def test_leave_grant(self):
        leave_type = "_Test Leave Type"

        # create the leave policy
        leave_policy = frappe.get_doc({
            "doctype":
            "Leave Policy",
            "leave_policy_details": [{
                "leave_type": leave_type,
                "annual_allocation": 20
            }]
        }).insert()
        leave_policy.submit()

        # create employee and assign the leave period
        employee = "*****@*****.**"
        employee_doc_name = make_employee(employee)
        frappe.db.set_value("Employee", employee_doc_name, "leave_policy",
                            leave_policy.name)

        # clear the already allocated leave
        frappe.db.sql(
            '''delete from `tabLeave Allocation` where employee=%s''',
            "*****@*****.**")

        # create the leave period
        leave_period = create_leave_period(add_months(today(), -3),
                                           add_months(today(), 3))

        # test leave_allocation
        leave_period.grant_leave_allocation(employee=employee_doc_name)
        self.assertEqual(
            get_leave_balance_on(employee_doc_name, leave_type, today()), 20)
Example #15
0
def make_leave_application():
	allocated_leaves = frappe.get_all("Leave Allocation", fields=['employee', 'leave_type'])
	
	for allocated_leave in allocated_leaves:
		leave_balance = get_leave_balance_on(allocated_leave.employee, allocated_leave.leave_type, frappe.flags.current_date,
			consider_all_leaves_in_the_allocation_period=True)
		if leave_balance != 0:
			if leave_balance == 1:
				to_date = frappe.flags.current_date
			else:
				to_date = add_days(frappe.flags.current_date, random.randint(0, leave_balance-1))
				
			leave_application = frappe.get_doc({
				"doctype": "Leave Application",
				"employee": allocated_leave.employee,
				"from_date": frappe.flags.current_date,
				"to_date": to_date,
				"leave_type": allocated_leave.leave_type,
				"status": "Approved"
			})
			try:
				leave_application.insert()
				leave_application.submit()
				frappe.db.commit()
			except (OverlapError):
				frappe.db.rollback()
Example #16
0
    def get_record(self, filters):
        allocation_records_based_on_to_date = get_leave_allocation_records(
            filters.get('to_date'))
        data, active_employees = [], frappe.get_all(
            "Employee",
            filters={"status": "Active"},
            fields=["name", "employee_name", "department"])
        for employee in active_employees:
            row = [
                employee.name, employee.employee_name, employee.department,
                self.get_days_spent(employee.name)
            ]
            # if leave type is selected in the filter
            # leaves taken
            leaves_taken = get_approved_leaves_for_period(
                employee.name, filters.get('leave_type'),
                filters.get('from_date'), filters.get('to_date'))
            # closing balance
            closing = get_leave_balance_on(
                employee.name, filters.get('leave_type'),
                filters.get('to_date'),
                allocation_records_based_on_to_date.get(
                    employee.name, frappe._dict()))

            row += [leaves_taken, closing]
            data.append(row)

        print(data)
    def test_leave_balance_on_submit(self):
        ''' check creation of leave allocation on submission of compensatory leave request '''
        employee = get_employee()
        mark_attendance(employee)
        compensatory_leave_request = get_compensatory_leave_request(
            employee.name)

        before = get_leave_balance_on(employee.name,
                                      compensatory_leave_request.leave_type,
                                      today())
        compensatory_leave_request.submit()

        self.assertEqual(
            get_leave_balance_on(employee.name,
                                 compensatory_leave_request.leave_type,
                                 add_days(today(), 1)), before + 1)
def get_data(filters, leave_types):

	allocation_records_based_on_to_date = get_leave_allocation_records(filters.to_date)

	active_employees = frappe.get_all("Employee", 
		filters = { "status": "Active", "company": filters.company}, 
		fields = ["name", "employee_name", "department"])
	
	data = []
	for employee in active_employees:
		row = [employee.name, employee.employee_name, employee.department]

		for leave_type in leave_types:	
			# leaves taken
			leaves_taken = get_approved_leaves_for_period(employee.name, leave_type, 
				filters.from_date, filters.to_date)
	
			# closing balance
			closing = get_leave_balance_on(employee.name, leave_type, filters.to_date, 
				allocation_records_based_on_to_date.get(employee.name, frappe._dict()))

			row += [leaves_taken, closing]
			
		data.append(row)
		
	return data
Example #19
0
    def validate(self):
        self.posting_date = today()

        #Update Leave Allocation
        leave_allocation = get_leave_allocation(self.employee, self.leave_type)
        if leave_allocation:
            leave_allocation = frappe.get_doc("Leave Allocation",
                                              leave_allocation.name)
            self.leave_allocation = leave_allocation.name
            #Total Balance
            self.total_balance = get_leave_balance_on(
                self.employee,
                self.leave_type,
                self.posting_date,
                self.posting_date,
                consider_all_leaves_in_the_allocation_period=True)
            #TODO Update info leave_allocation
            self.from_date = leave_allocation.from_date
            self.to_date = leave_allocation.to_date
            self.current_cycle = leave_allocation.total_leaves_allocated

            #Update_leave_ledger_entry
            update_leave_ledger_entry(leave_allocation.name, self.new_balance,
                                      self.total_balance)
        else:
            frappe.throw(_("Can not find match Leave Allocation"))
Example #20
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))

        self.leave_balance = get_leave_balance_on(
            self.employee,
            self.leave_type,
            self.encashment_date or getdate(nowdate()),
            consider_all_leaves_in_the_allocation_period=True)

        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 = self.get_leave_allocation()
        return True
def fix_balance_leave(doc):
    if doc.from_date and doc.to_date:
        doc.total_leave_days = get_number_of_leave_days(
            doc.employee, doc.leave_type, doc.from_date, doc.to_date,
            doc.half_day, doc.half_day_date)

        if doc.total_leave_days <= 0:
            frappe.throw(
                _("The day(s) on which you are applying for leave are holidays. You need not apply for leave."
                  ))

        if not is_lwp(doc.leave_type):
            doc.leave_balance = get_leave_balance_on(
                doc.employee,
                doc.leave_type,
                doc.from_date,
                doc.to_date,
                consider_all_leaves_in_the_allocation_period=True)
            if doc.status != "Rejected" and (
                    doc.leave_balance < doc.total_leave_days
                    or not doc.leave_balance):
                if frappe.db.get_value("Leave Type", doc.leave_type,
                                       "allow_negative"):
                    frappe.msgprint(
                        _("Note: There is not enough leave balance for Leave Type {0}"
                          ).format(doc.leave_type))
                else:
                    frappe.throw(
                        _("There is not enough leave balance for Leave Type {0}"
                          ).format(doc.leave_type))
Example #22
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]
    def test_optional_leave(self):
        leave_period = get_leave_period()
        today = nowdate()
        holiday_list = "Test Holiday List for Optional Holiday"
        employee = get_employee()

        first_sunday = get_first_sunday(self.holiday_list)
        optional_leave_date = add_days(first_sunday, 1)

        if not frappe.db.exists("Holiday List", holiday_list):
            frappe.get_doc(
                dict(
                    doctype="Holiday List",
                    holiday_list_name=holiday_list,
                    from_date=add_months(today, -6),
                    to_date=add_months(today, 6),
                    holidays=[
                        dict(holiday_date=optional_leave_date,
                             description="Test")
                    ],
                )).insert()

        frappe.db.set_value("Leave Period", leave_period.name,
                            "optional_holiday_list", holiday_list)
        leave_type = "Test Optional Type"
        if not frappe.db.exists("Leave Type", leave_type):
            frappe.get_doc(
                dict(leave_type_name=leave_type,
                     doctype="Leave Type",
                     is_optional_leave=1)).insert()

        allocate_leaves(employee, leave_period, leave_type, 10)

        date = add_days(first_sunday, 2)

        leave_application = frappe.get_doc(
            dict(
                doctype="Leave Application",
                employee=employee.name,
                company="_Test Company",
                description="_Test Reason",
                leave_type=leave_type,
                from_date=date,
                to_date=date,
            ))

        # can only apply on optional holidays
        self.assertRaises(NotAnOptionalHoliday, leave_application.insert)

        leave_application.from_date = optional_leave_date
        leave_application.to_date = optional_leave_date
        leave_application.status = "Approved"
        leave_application.insert()
        leave_application.submit()

        # check leave balance is reduced
        self.assertEqual(
            get_leave_balance_on(employee.name, leave_type,
                                 optional_leave_date), 9)
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
Example #25
0
	def test_leave_balance_near_allocaton_expiry(self):
		employee = get_employee()
		leave_type = create_leave_type(
			leave_type_name="_Test_CF_leave_expiry",
			is_carry_forward=1,
			expire_carry_forwarded_leaves_after_days=90)
		leave_type.submit()

		create_carry_forwarded_allocation(employee, leave_type)

		self.assertEqual(get_leave_balance_on(employee.name, leave_type.name, nowdate(), add_days(nowdate(), 8)), 21)
def get_leave_balance(employee, date):
    from erpnext.hr.doctype.leave_application.leave_application import (
        get_leave_balance_on,
    )

    carryable_leaves = frappe.get_all("Leave Type", {"is_carry_forward": 1})
    return sum(
        [
            get_leave_balance_on(employee, leave_type, date)
            for leave_type in pluck("name", carryable_leaves)
        ]
    )
Example #27
0
	def test_leave_application_creation_after_expiry(self):
		# test leave balance for carry forwarded allocation
		employee = get_employee()
		leave_type = create_leave_type(
			leave_type_name="_Test_CF_leave_expiry",
			is_carry_forward=1,
			expire_carry_forwarded_leaves_after_days=90)
		leave_type.submit()

		create_carry_forwarded_allocation(employee, leave_type)

		self.assertEquals(get_leave_balance_on(employee.name, leave_type.name, add_days(nowdate(), -85), add_days(nowdate(), -84)), 0)
Example #28
0
	def test_optional_leave(self):
		leave_period = get_leave_period()
		today = nowdate()
		from datetime import date
		holiday_list = 'Test Holiday List for Optional Holiday'
		if not frappe.db.exists('Holiday List', holiday_list):
			frappe.get_doc(dict(
				doctype = 'Holiday List',
				holiday_list_name = holiday_list,
				from_date = add_months(today, -6),
				to_date = add_months(today, 6),
				holidays = [
					dict(holiday_date = today, description = 'Test')
				]
			)).insert()
		employee = get_employee()

		frappe.db.set_value('Leave Period', leave_period.name, 'optional_holiday_list', holiday_list)
		leave_type = 'Test Optional Type'
		if not frappe.db.exists('Leave Type', leave_type):
			frappe.get_doc(dict(
				leave_type_name = leave_type,
				doctype = 'Leave Type',
				is_optional_leave = 1
			)).insert()

		allocate_leaves(employee, leave_period, leave_type, 10)

		date = add_days(today, - 1)

		leave_application = frappe.get_doc(dict(
			doctype = 'Leave Application',
			employee = employee.name,
			company = '_Test Company',
			description = "_Test Reason",
			leave_type = leave_type,
			from_date = date,
			to_date = date,
		))

		# can only apply on optional holidays
		self.assertRaises(NotAnOptionalHoliday, leave_application.insert)

		leave_application.from_date = today
		leave_application.to_date = today
		leave_application.status = "Approved"
		leave_application.insert()
		leave_application.submit()

		# check leave balance is reduced
		self.assertEqual(get_leave_balance_on(employee.name, leave_type, today), 9)
	def test_optional_leave(self):
		leave_period = get_leave_period()
		today = nowdate()
		from datetime import date
		holiday_list = 'Test Holiday List for Optional Holiday'
		if not frappe.db.exists('Holiday List', holiday_list):
			frappe.get_doc(dict(
				doctype = 'Holiday List',
				holiday_list_name = holiday_list,
				from_date = date(date.today().year, 1, 1),
				to_date = date(date.today().year, 12, 31),
				holidays = [
					dict(holiday_date = today, description = 'Test')
				]
			)).insert()
		employee = get_employee()

		frappe.db.set_value('Leave Period', leave_period.name, 'optional_holiday_list', holiday_list)
		leave_type = 'Test Optional Type'
		if not frappe.db.exists('Leave Type', leave_type):
			frappe.get_doc(dict(
				leave_type_name = leave_type,
				doctype = 'Leave Type',
				is_optional_leave = 1
			)).insert()

		allocate_leaves(employee, leave_period, leave_type, 10)

		date = add_days(today, - 1)

		leave_application = frappe.get_doc(dict(
			doctype = 'Leave Application',
			employee = employee.name,
			company = '_Test Company',
			leave_type = leave_type,
			from_date = date,
			to_date = date,
		))

		# can only apply on optional holidays
		self.assertTrue(NotAnOptionalHoliday, leave_application.insert)

		leave_application.from_date = today
		leave_application.to_date = today
		leave_application.status = "Approved"
		leave_application.insert()
		leave_application.submit()

		# check leave balance is reduced
		self.assertEqual(get_leave_balance_on(employee.name, leave_type, today), 9)
Example #30
0
def update_leave_balance(employees, date):
    if isinstance(employees, basestring):
        employees = json.loads(employees)
    for emp in employees:
        leave_balance = get_leave_balance_on(
            employee=emp,
            date=date,
            leave_type='Bevorzugter Urlaub',
            consider_all_leaves_in_the_allocation_period=False)
        update = frappe.db.sql(
            """UPDATE `tabEmployee` SET `leave_balance` = '{leave_balance}' WHERE `name` = '{name}'"""
            .format(name=emp, leave_balance=leave_balance),
            as_list=True)

    return True
Example #31
0
def get_data(filters, leave_types):

    allocation_records_based_on_to_date = get_leave_allocation_records(
        filters.to_date)

    active_employees = frappe.get_all(
        "Employee",
        filters={
            "status": "Active",
            "company": filters.company
        },
        fields=["name", "employee_name", "department"],
        order_by="employee_name asc")

    data = []
    for employee in active_employees:
        row = [employee.name, employee.employee_name, employee.department]

        for leave_type in leave_types:
            matched_leave_type = leave_type.lower().replace(' ', '_')
            if filters.get(matched_leave_type):

                # leaves taken
                leaves_taken = get_approved_leaves_for_period(
                    employee.name, leave_type, filters.from_date,
                    filters.to_date)

                # closing balance
                closing = get_leave_balance_on(
                    employee.name, leave_type, filters.to_date,
                    allocation_records_based_on_to_date.get(
                        employee.name, frappe._dict()))

                # annual leave allocated
                allocation_records = allocation_records_based_on_to_date.get(
                    employee.name, frappe._dict())
                allocation = allocation_records.get(leave_type, frappe._dict())
                total_leaves_allocated = flt(allocation.total_leaves_allocated)
                new_leaves_allocated = flt(allocation.new_leaves_allocated)

                row += [
                    new_leaves_allocated, total_leaves_allocated, leaves_taken,
                    closing
                ]

        data.append(row)

    return data
Example #32
0
	def test_leave_balance_near_allocaton_expiry(self):
		employee = get_employee()
		leave_type = create_leave_type(
			leave_type_name="_Test_CF_leave_expiry",
			is_carry_forward=1,
			expire_carry_forwarded_leaves_after_days=90,
		)
		leave_type.insert()

		create_carry_forwarded_allocation(employee, leave_type)
		details = get_leave_balance_on(
			employee.name, leave_type.name, nowdate(), add_days(nowdate(), 8), for_consumption=True
		)

		self.assertEqual(details.leave_balance_for_consumption, 21)
		self.assertEqual(details.leave_balance, 30)
Example #33
0
def get_project_earned_leave_balance(employee,
                                     leave_type,
                                     start_date=getdate(nowdate())):
    leave_type_doc = frappe.get_doc("Leave Type", leave_type)
    if leave_type_doc.is_earned_leave == 0:
        return None

    leave_policy = get_employee_leave_policy(employee)
    if not leave_policy:
        return None

    #current balance
    current_balance = get_leave_balance_on(
        employee,
        leave_type,
        start_date,
        consider_all_leaves_in_the_allocation_period=True)

    #end_balance = get_leave_balance_on(employee, leave_type,
    #	start_date, consider_all_leaves_in_the_allocation_period=True)

    divide_by_frequency = {"Yearly": 1, "Quarterly": 4, "Monthly": 12}

    days_to_project = date_diff(start_date, get_first_day(getdate(nowdate())))
    number_of_months = days_to_project / 30

    annual_allocation = frappe.db.sql(
        """select annual_allocation from `tabLeave Policy Detail`
		where parent=%s and leave_type=%s""",
        (leave_policy.name, leave_type_doc.name))
    if annual_allocation and annual_allocation[0]:
        leaves_per_frequency = flt(
            annual_allocation[0][0]) / divide_by_frequency[
                leave_type_doc.earned_leave_frequency]

    divide_by_frequency = {"Yearly": 12, "Quarterly": 4, "Monthly": 1}
    future_leaves = (number_of_months /
                     divide_by_frequency[leave_type_doc.earned_leave_frequency]
                     ) * leaves_per_frequency

    if leave_type_doc.rounding == "0.5":
        future_leaves = round(future_leaves * 2) / 2
    else:
        future_leaves = round(future_leaves)

    projected_earned_leave_balance = current_balance + future_leaves
    return projected_earned_leave_balance
	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))

		self.leave_balance = get_leave_balance_on(self.employee, self.leave_type,
			self.encashment_date or getdate(nowdate()), consider_all_leaves_in_the_allocation_period=True)

		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 = self.get_leave_allocation()
		return True
Example #35
0
def update_att_status(attname, deptname, employee, date, employee_name):
    from erpnext.hr.doctype.leave_application.leave_application import get_number_of_leave_days, get_leave_balance_on
    doc = frappe.get_doc('Attendance', attname)
    if doc.status != 'On Leave':
        #frappe.db.set_value("Attendance", attname, "status", "On Leave")
        doc.update({'docstatus': 2, 'status': 'On Leave'})
        doc.flags.ignore_validate = True
        doc.flags.ignore_validate_update_after_submit = True
        doc.save(ignore_permissions=True)
    dep_doc = frappe.get_doc('Departure', deptname)
    if dep_doc.status != 'On Leave':
        dep_doc.update({'docstatus': 2, 'status': 'On Leave'})
        dep_doc.flags.ignore_validate = True
        dep_doc.flags.ignore_validate_update_after_submit = True
        dep_doc.save(ignore_permissions=True)
    #add new leave
    if not frappe.db.get_value('Leave Application', {
            'employee': employee,
            'from_date': date
    }) and frappe.db.get_value("Leave Type", _('Annual Leave'), "name"):
        leave = frappe.new_doc('Leave Application')
        leave.employee = employee
        leave.employee_name = employee_name
        leave.leave_type = _('Annual Leave')
        leave.from_date = date
        leave.to_date = date
        leave.total_leave_days = get_number_of_leave_days(
            employee, _('Annual Leave'), date, date)
        leave.status = 'Approved'
        leave.leave_balance = get_leave_balance_on(
            employee,
            _('Annual Leave'),
            date,
            consider_all_leaves_in_the_allocation_period=True)
        leave.description = _('Auto Entry: Discount form Leaves')
        leave.docstatus = 1
        leave.flags.ignore_validate = True
        leave.insert(ignore_permissions=True)

    send_email(employee, _('Auto Entry: Discount form Warning'),
               _('Employee Task Late Warning'))
    return True
Example #36
0
def get_opening_balance(employee: str, leave_type: str, filters: Filters,
                        carry_forwarded_leaves: float) -> float:
    # allocation boundary condition
    # opening balance is the closing leave balance 1 day before the filter start date
    opening_balance_date = add_days(filters.from_date, -1)
    allocation = get_previous_allocation(filters.from_date, leave_type,
                                         employee)

    if (allocation
            and allocation.get("to_date") and opening_balance_date and getdate(
                allocation.get("to_date")) == getdate(opening_balance_date)):
        # if opening balance date is same as the previous allocation's expiry
        # then opening balance should only consider carry forwarded leaves
        opening_balance = carry_forwarded_leaves
    else:
        # else directly get leave balance on the previous day
        opening_balance = get_leave_balance_on(employee, leave_type,
                                               opening_balance_date)

    return opening_balance
def get_data(filters, leave_types):

	allocation_records_based_on_to_date = get_leave_allocation_records(filters.to_date)

	active_employees = frappe.get_all("Employee", 
		filters = { "status": "Active", "company": filters.company}, 
		fields = ["name", "employee_name", "department"],
		order_by = "employee_name asc")
	
	data = []
	for employee in active_employees:
		row = [employee.name, employee.employee_name, employee.department]

		for leave_type in leave_types:	
			matched_leave_type = leave_type.lower().replace(' ','_')
			if filters.get(matched_leave_type):

				# leaves taken
				leaves_taken = get_approved_leaves_for_period(employee.name, leave_type, 
					filters.from_date, filters.to_date)
	
				# closing balance
				closing = get_leave_balance_on(employee.name, leave_type, filters.to_date, 
					allocation_records_based_on_to_date.get(employee.name, frappe._dict()))
			
				# annual leave allocated
				allocation_records = allocation_records_based_on_to_date.get(employee.name, frappe._dict())
				allocation = allocation_records.get(leave_type, frappe._dict())
				total_leaves_allocated = flt(allocation.total_leaves_allocated)
				new_leaves_allocated = flt(allocation.new_leaves_allocated)
				
				row += [new_leaves_allocated, total_leaves_allocated, leaves_taken, closing]
			
		data.append(row)
		
	return data