Пример #1
0
	def calculate_component_amounts(self):
		if not getattr(self, '_salary_structure_doc', None):
			self._salary_structure_doc = frappe.get_doc('Salary Structure', self.salary_structure)

		data = self.get_data_for_eval()

		for key in ('earnings', 'deductions'):
			for struct_row in self._salary_structure_doc.get(key):
				amount = self.eval_condition_and_formula(struct_row, data)
				if amount and struct_row.statistical_component == 0:
					self.update_component_row(struct_row, amount, key)
				if key=="deductions" and struct_row.variable_based_on_taxable_salary:
					tax_row, amount = self.calculate_pro_rata_tax(struct_row.salary_component)
					if tax_row and amount:
						self.update_component_row(frappe._dict(tax_row), amount, key)

		additional_components = get_additional_salary_component(self.employee, self.start_date, self.end_date)
		if additional_components:
			for additional_component in additional_components:
				additional_component = frappe._dict(additional_component)
				amount = self.update_amount_for_other_component(frappe._dict(additional_component.struct_row).salary_component, additional_component.amount)
				self.update_component_row(frappe._dict(additional_component.struct_row), amount, "earnings")

		max_benefits = self._salary_structure_doc.get("max_benefits")
		if max_benefits > 0:
			employee_benefits = get_employee_benefit_application(self)
			if employee_benefits:
				for employee_benefit in employee_benefits:
					benefit_component = frappe._dict(employee_benefit)
					amount = self.update_amount_for_other_component(frappe._dict(benefit_component.struct_row).salary_component, benefit_component.amount)
					self.update_component_row(frappe._dict(benefit_component.struct_row), amount, "earnings")
			else:
				default_flexi_compenent = frappe.db.exists(
					'Salary Component',
					{
						'is_flexible_benefit': 1,
						'is_pro_rata_applicable': 1,
						'flexi_default': 1
					}
				)
				if default_flexi_compenent:
					flexi_struct_row = self.create_flexi_struct_row(default_flexi_compenent)
					payroll_period_days = get_payroll_period_days(self.start_date, self.end_date, self.company)
					amount = self.update_amount_for_other_component(default_flexi_compenent, get_amount(payroll_period_days, self.start_date, self.end_date, max_benefits))
					self.update_component_row(flexi_struct_row, amount, "earnings")
				else:
					frappe.throw(_("Configure default flexible benefit salary component for apply pro-rata benefit"))

			benefit_claims = get_employee_benefit_claim(self)
			if benefit_claims:
				for benefit_claim in benefit_claims:
					benefit_component = frappe._dict(benefit_claim)
					amount = self.update_amount_for_other_component(frappe._dict(benefit_component.struct_row).salary_component, benefit_component.amount)
					self.update_component_row(frappe._dict(benefit_component.struct_row), amount, "earnings")
def get_benefit_component_amount(employee, start_date, end_date, struct_row,
                                 sal_struct, period_length, frequency):
    payroll_period, period_factor, actual_payroll_days = get_payroll_period_days(
        start_date, end_date, employee)

    if not payroll_period:
        frappe.msgprint(
            _("Start and end dates not in a valid Payroll Period, cannot calculate {0}."
              ).format(struct_row.salary_component))
        return False

    # Considering there is only one application for a year
    benefit_application_name = frappe.db.sql(
        """
		select name
		from `tabEmployee Benefit Application`
		where
			payroll_period=%(payroll_period)s
			and employee=%(employee)s
			and docstatus = 1
	""", {
            'employee': employee,
            'payroll_period': payroll_period
        })

    if frappe.db.get_value("Salary Component", struct_row.salary_component,
                           "depends_on_payment_days") != 1:
        if frequency == "Monthly" and actual_payroll_days in range(360, 370):
            period_length = 1
            period_factor = 12

    if period_factor:
        # If there is application for benefit then fetch the amount from the application.
        # else Split the max benefits to the pro-rata components with the ratio of their max_benefit_amount
        if benefit_application_name:
            benefit_application = frappe.get_doc(
                "Employee Benefit Application", benefit_application_name[0][0])
            return get_benefit_amount(benefit_application, struct_row,
                                      period_factor, period_length)

        # TODO: Check if there is benefit claim for employee then pro-rata divide the rest of amount (Late Benefit Application)
        else:
            component_max = frappe.db.get_value("Salary Component",
                                                struct_row.salary_component,
                                                "max_benefit_amount")
            if component_max:
                benefit_amount = get_benefit_pro_rata_ratio_amount(
                    sal_struct, component_max)
                return get_amount(period_factor, benefit_amount, period_length)
    return False
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)[0]
        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_pro_rata_ratio_amount(
                            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
def get_benefit_component_amount(employee, start_date, end_date, struct_row, sal_struct, period_length, frequency):
	payroll_period, period_factor, actual_payroll_days = get_payroll_period_days(start_date, end_date, employee)

	if not payroll_period:
		frappe.msgprint(_("Start and end dates not in a valid Payroll Period, cannot calculate {0}.")
			.format(struct_row.salary_component))
		return False

	# Considering there is only one application for a year
	benefit_application_name = frappe.db.sql("""
		select name
		from `tabEmployee Benefit Application`
		where
			payroll_period=%(payroll_period)s
			and employee=%(employee)s
			and docstatus = 1
	""", {
		'employee': employee,
		'payroll_period': payroll_period
	})

	if frappe.db.get_value("Salary Component", struct_row.salary_component, "depends_on_payment_days") != 1:
		if frequency == "Monthly" and actual_payroll_days in range(360, 370):
			period_length = 1
			period_factor = 12

	if period_factor:
		# If there is application for benefit then fetch the amount from the application.
		# else Split the max benefits to the pro-rata components with the ratio of their max_benefit_amount
		if benefit_application_name:
			benefit_application = frappe.get_doc("Employee Benefit Application", benefit_application_name[0][0])
			return get_benefit_amount(benefit_application, struct_row, period_factor, period_length)

		# TODO: Check if there is benefit claim for employee then pro-rata divide the rest of amount (Late Benefit Application)
		else:
			component_max = frappe.db.get_value("Salary Component", struct_row.salary_component, "max_benefit_amount")
			if component_max:
				benefit_amount = get_benefit_pro_rata_ratio_amount(sal_struct, component_max)
				return get_amount(period_factor, benefit_amount, period_length)
	return False
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)[0]
		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_pro_rata_ratio_amount(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
Пример #6
0
    def calculate_component_amounts(self):
        if not getattr(self, '_salary_structure_doc', None):
            self._salary_structure_doc = frappe.get_doc(
                'Salary Structure', self.salary_structure)

        data = self.get_data_for_eval()

        for key in ('earnings', 'deductions'):
            for struct_row in self._salary_structure_doc.get(key):
                amount = self.eval_condition_and_formula(struct_row, data)
                if amount and struct_row.statistical_component == 0:
                    self.update_component_row(struct_row, amount, key)
                if key == "deductions" and struct_row.variable_based_on_taxable_salary:
                    tax_row, amount = self.calculate_pro_rata_tax(
                        struct_row.salary_component)
                    if tax_row and amount:
                        self.update_component_row(frappe._dict(tax_row),
                                                  amount, key)

        additional_components = get_additional_salary_component(
            self.employee, self.start_date, self.end_date)
        if additional_components:
            for additional_component in additional_components:
                additional_component = frappe._dict(additional_component)
                amount = self.update_amount_for_other_component(
                    frappe._dict(
                        additional_component.struct_row).salary_component,
                    additional_component.amount)
                self.update_component_row(
                    frappe._dict(additional_component.struct_row), amount,
                    "earnings")

        max_benefits = self._salary_structure_doc.get("max_benefits")
        if max_benefits > 0:
            employee_benefits = get_employee_benefit_application(self)
            if employee_benefits:
                for employee_benefit in employee_benefits:
                    benefit_component = frappe._dict(employee_benefit)
                    amount = self.update_amount_for_other_component(
                        frappe._dict(
                            benefit_component.struct_row).salary_component,
                        benefit_component.amount)
                    self.update_component_row(
                        frappe._dict(benefit_component.struct_row), amount,
                        "earnings")
            else:
                default_flexi_compenent = frappe.db.exists(
                    'Salary Component', {
                        'is_flexible_benefit': 1,
                        'is_pro_rata_applicable': 1,
                        'flexi_default': 1
                    })
                if default_flexi_compenent:
                    flexi_struct_row = self.create_flexi_struct_row(
                        default_flexi_compenent)
                    payroll_period_days = get_payroll_period_days(
                        self.start_date, self.end_date, self.company)
                    amount = self.update_amount_for_other_component(
                        default_flexi_compenent,
                        get_amount(payroll_period_days, self.start_date,
                                   self.end_date, max_benefits))
                    self.update_component_row(flexi_struct_row, amount,
                                              "earnings")
                else:
                    frappe.throw(
                        _("Configure default flexible benefit salary component for apply pro-rata benefit"
                          ))

            benefit_claims = get_employee_benefit_claim(self)
            if benefit_claims:
                for benefit_claim in benefit_claims:
                    benefit_component = frappe._dict(benefit_claim)
                    amount = self.update_amount_for_other_component(
                        frappe._dict(
                            benefit_component.struct_row).salary_component,
                        benefit_component.amount)
                    self.update_component_row(
                        frappe._dict(benefit_component.struct_row), amount,
                        "earnings")