Beispiel #1
0
	def validate_remaining_benefit_amount(self):
		# check salary structure earnings have flexi component (sum of max_benefit_amount)
		# without pro-rata which satisfy the remaining_benefit
		# else pro-rata component for the amount
		# again comes the same validation and satisfy or throw
		benefit_components = []
		if self.employee_benefits:
			for employee_benefit in self.employee_benefits:
				benefit_components.append(employee_benefit.earning_component)
		salary_struct_name = get_assigned_salary_structure(self.employee, self.date)
		if salary_struct_name:
			non_pro_rata_amount = 0
			pro_rata_amount = 0
			salary_structure = frappe.get_doc("Salary Structure", salary_struct_name)
			if salary_structure.earnings:
				for earnings in salary_structure.earnings:
					if earnings.is_flexible_benefit == 1 and earnings.salary_component not in benefit_components:
						pay_against_benefit_claim, max_benefit_amount = frappe.db.get_value("Salary Component", earnings.salary_component, ["pay_against_benefit_claim", "max_benefit_amount"])
						if pay_against_benefit_claim != 1:
							pro_rata_amount += max_benefit_amount
						else:
							non_pro_rata_amount += max_benefit_amount

			if pro_rata_amount == 0  and non_pro_rata_amount == 0:
				frappe.throw(_("Please add the remaining benefits {0} to any of the existing component").format(self.remaining_benefit))
			elif non_pro_rata_amount > 0 and non_pro_rata_amount < rounded(self.remaining_benefit):
				frappe.throw(_("You can claim only an amount of {0}, the rest amount {1} should be in the application as pro-rata component").format(
					non_pro_rata_amount, self.remaining_benefit - non_pro_rata_amount))
			elif non_pro_rata_amount == 0:
				frappe.throw(_("Please add the remaining benefits {0} to the application as pro-rata component").format(
					self.remaining_benefit))
    def validate_non_pro_rata_benefit_claim(self, max_benefits,
                                            payroll_period):
        claimed_amount = self.claimed_amount
        pro_rata_amount = self.get_pro_rata_amount_in_application(
            payroll_period.name)
        if not pro_rata_amount:
            pro_rata_amount = 0
            # Get pro_rata_amount if there is no application,
            # get salary structure for the date and calculate pro-rata amount
            sal_struct_name = get_assigned_salary_structure(
                self.employee, self.claim_date)
            if sal_struct_name:
                sal_struct = frappe.get_doc("Salary Structure",
                                            sal_struct_name)
                pro_rata_amount = get_benefit_pro_rata_ratio_amount(
                    self.employee, self.claim_date, sal_struct)

        claimed_amount += get_previous_claimed_amount(self.employee,
                                                      payroll_period,
                                                      non_pro_rata=True)
        if max_benefits < pro_rata_amount + claimed_amount:
            frappe.throw(
                _("Maximum benefit of employee {0} exceeds {1} by the sum {2} of benefit application pro-rata component\
			amount and previous claimed amount").format(
                    self.employee, max_benefits,
                    pro_rata_amount + claimed_amount - max_benefits))
Beispiel #3
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\
         - get_unused_leaves(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
Beispiel #4
0
def get_max_benefits(employee, on_date):
	sal_struct = get_assigned_salary_structure(employee, on_date)
	if sal_struct:
		max_benefits = frappe.db.get_value("Salary Structure", sal_struct, "max_benefits")
		if max_benefits > 0:
			return max_benefits
	return False
Beispiel #5
0
def get_earning_components_max_benefits(employee, date, earning_component):
	salary_structure = get_assigned_salary_structure(employee, date)
	amount = frappe.db.sql("""
			select amount
			from `tabSalary Detail`
			where parent = %s and is_flexible_benefit = 1
			and salary_component = %s
			order by name
		""", salary_structure, earning_component)

	return amount if amount else 0
Beispiel #6
0
def create_leave_encashment(leave_allocation):
    ''' Creates leave encashment for the given allocations '''
    for allocation in leave_allocation:
        if not get_assigned_salary_structure(allocation.employee,
                                             allocation.to_date):
            continue
        leave_encashment = frappe.get_doc(
            dict(doctype="Leave Encashment",
                 leave_period=allocation.leave_period,
                 employee=allocation.employee,
                 leave_type=allocation.leave_type,
                 encashment_date=allocation.to_date))
        leave_encashment.insert(ignore_permissions=True)
Beispiel #7
0
def get_earning_components(doctype, txt, searchfield, start, page_len, filters):
	if len(filters) < 2:
		return {}

	salary_structure = get_assigned_salary_structure(filters['employee'], filters['date'])

	if salary_structure:
		return frappe.db.sql("""
			select salary_component
			from `tabSalary Detail`
			where parent = %s and is_flexible_benefit = 1
			order by name
		""", salary_structure)
	else:
		frappe.throw(_("Salary Structure not found for employee {0} and date {1}")
			.format(filters['employee'], filters['date']))
Beispiel #8
0
def get_max_benefits_remaining(employee, on_date, payroll_period):
    max_benefits = get_max_benefits(employee, on_date)
    if max_benefits and max_benefits > 0:
        have_depends_on_payment_days = False
        per_day_amount_total = 0
        payroll_period_days = get_payroll_period_days(on_date, on_date,
                                                      employee)[1]
        payroll_period_obj = frappe.get_doc("Payroll Period", payroll_period)

        # Get all salary slip flexi amount in the payroll period
        prev_sal_slip_flexi_total = get_sal_slip_total_benefit_given(
            employee, payroll_period_obj)

        if prev_sal_slip_flexi_total > 0:
            # Check salary structure hold depends_on_payment_days component
            # If yes then find the amount per day of each component and find the sum
            sal_struct_name = get_assigned_salary_structure(employee, on_date)
            if sal_struct_name:
                sal_struct = frappe.get_doc("Salary Structure",
                                            sal_struct_name)
                for sal_struct_row in sal_struct.get("earnings"):
                    salary_component = frappe.get_doc(
                        "Salary Component", sal_struct_row.salary_component)
                    if salary_component.depends_on_payment_days == 1 and salary_component.pay_against_benefit_claim != 1:
                        have_depends_on_payment_days = True
                        benefit_amount = get_benefit_amount_based_on_pro_rata(
                            sal_struct, salary_component.max_benefit_amount)
                        amount_per_day = benefit_amount / payroll_period_days
                        per_day_amount_total += amount_per_day

            # Then the sum multiply with the no of lwp in that period
            # Include that amount to the prev_sal_slip_flexi_total to get the actual
            if have_depends_on_payment_days and per_day_amount_total > 0:
                holidays = get_holidays_for_employee(
                    employee, payroll_period_obj.start_date, on_date)
                working_days = date_diff(on_date,
                                         payroll_period_obj.start_date) + 1
                leave_days = calculate_lwp(employee,
                                           payroll_period_obj.start_date,
                                           holidays, working_days)
                leave_days_amount = leave_days * per_day_amount_total
                prev_sal_slip_flexi_total += leave_days_amount

            return max_benefits - prev_sal_slip_flexi_total
    return max_benefits
Beispiel #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