示例#1
0
def make_salary_structure_for_timesheet(employee, company=None):
    salary_structure_name = "Timesheet Salary Structure Test"
    frequency = "Monthly"

    if not frappe.db.exists("Salary Component", "Timesheet Component"):
        frappe.get_doc({
            "doctype": "Salary Component",
            "salary_component": "Timesheet Component"
        }).insert()

    salary_structure = make_salary_structure(salary_structure_name,
                                             frequency,
                                             company=company,
                                             dont_submit=True)
    salary_structure.salary_component = "Timesheet Component"
    salary_structure.salary_slip_based_on_timesheet = 1
    salary_structure.hour_rate = 50.0
    salary_structure.save()
    salary_structure.submit()

    if not frappe.db.get_value("Salary Structure Assignment", {
            "employee": employee,
            "docstatus": 1
    }):
        frappe.db.set_value("Employee", employee, "date_of_joining",
                            add_months(nowdate(), -5))
        create_salary_structure_assignment(employee, salary_structure.name)

    return salary_structure
示例#2
0
    def test_multi_currency_payroll_entry(self):  # pylint: disable=no-self-use
        company = erpnext.get_default_company()
        employee = make_employee("*****@*****.**",
                                 company=company)
        for data in frappe.get_all('Salary Component', fields=["name"]):
            if not frappe.db.get_value('Salary Component Account', {
                    'parent': data.name,
                    'company': company
            }, 'name'):
                get_salary_component_account(data.name)

        company_doc = frappe.get_doc('Company', company)
        salary_structure = make_salary_structure(
            "_Test Multi Currency Salary Structure",
            "Monthly",
            company=company,
            currency='USD')
        create_salary_structure_assignment(employee,
                                           salary_structure.name,
                                           company=company,
                                           currency='USD')
        frappe.db.sql(
            """delete from `tabSalary Slip` where employee=%s""",
            (frappe.db.get_value(
                "Employee",
                {"user_id": "*****@*****.**"})))
        salary_slip = get_salary_slip(
            "*****@*****.**", "Monthly",
            "_Test Multi Currency Salary Structure")
        dates = get_start_end_dates('Monthly', nowdate())
        payroll_entry = make_payroll_entry(
            start_date=dates.start_date,
            end_date=dates.end_date,
            payable_account=company_doc.default_payroll_payable_account,
            currency='USD',
            exchange_rate=70)
        payroll_entry.make_payment_entry()

        salary_slip.load_from_db()

        payroll_je = salary_slip.journal_entry
        if payroll_je:
            payroll_je_doc = frappe.get_doc('Journal Entry', payroll_je)

            self.assertEqual(salary_slip.base_gross_pay,
                             payroll_je_doc.total_debit)
            self.assertEqual(salary_slip.base_gross_pay,
                             payroll_je_doc.total_credit)

        payment_entry = frappe.db.sql('''
			Select ifnull(sum(je.total_debit),0) as total_debit, ifnull(sum(je.total_credit),0) as total_credit from `tabJournal Entry` je, `tabJournal Entry Account` jea
			Where je.name = jea.parent
			And jea.reference_name = %s
			''', (payroll_entry.name),
                                      as_dict=1)

        self.assertEqual(salary_slip.base_net_pay,
                         payment_entry[0].total_debit)
        self.assertEqual(salary_slip.base_net_pay,
                         payment_entry[0].total_credit)
示例#3
0
def make_salary_structure_for_timesheet(employee):
    salary_structure_name = "Timesheet Salary Structure Test"
    frequency = "Monthly"

    salary_structure = make_salary_structure(
        salary_structure_name, frequency, dont_submit=True)
    salary_structure.salary_component = "Timesheet Component"
    salary_structure.salary_slip_based_on_timesheet = 1
    salary_structure.hour_rate = 50.0
    salary_structure.save()
    salary_structure.submit()

    if not frappe.db.get_value("Salary Structure Assignment",
                               {'employee': employee, 'docstatus': 1}):
        frappe.db.set_value('Employee', employee, 'date_of_joining',
                            add_months(nowdate(), -5))
        create_salary_structure_assignment(employee, salary_structure.name)

    return salary_structure
示例#4
0
	def test_tax_for_payroll_period(self):
		data = {}
		# test the impact of tax exemption declaration, tax exemption proof submission
		# and deduct check boxes in annual tax calculation
		# as per assigned salary structure 40500 in monthly salary so 236000*5/100/12
		frappe.db.sql("""delete from `tabPayroll Period`""")
		frappe.db.sql("""delete from `tabSalary Component`""")
		frappe.db.sql("""delete from `tabAdditional Salary`""")

		payroll_period = create_payroll_period()

		create_tax_slab(payroll_period, allow_tax_exemption=True)

		employee = make_employee("*****@*****.**")
		delete_docs = [
			"Salary Slip",
			"Additional Salary",
			"Employee Tax Exemption Declaration",
			"Employee Tax Exemption Proof Submission",
			"Employee Benefit Claim",
			"Salary Structure Assignment"
		]
		for doc in delete_docs:
			frappe.db.sql("delete from `tab%s` where employee='%s'" % (doc, employee))

		from erpnext.payroll.doctype.salary_structure.test_salary_structure import \
			make_salary_structure, create_salary_structure_assignment
		salary_structure = make_salary_structure("Stucture to test tax", "Monthly",
			other_details={"max_benefits": 100000}, test_tax=True)
		create_salary_structure_assignment(employee, salary_structure.name,
			payroll_period.start_date)

		# create salary slip for whole period deducting tax only on last period
		# to find the total tax amount paid
		create_salary_slips_for_payroll_period(employee, salary_structure.name,
			payroll_period, deduct_random=False)
		tax_paid = get_tax_paid_in_period(employee)

		annual_tax = 113589.0
		try:
			self.assertEqual(tax_paid, annual_tax)
		except AssertionError:
			print("\nSalary Slip - Annual tax calculation failed\n")
			raise
		frappe.db.sql("""delete from `tabSalary Slip` where employee=%s""", (employee))

		# create exemption declaration so the tax amount varies
		create_exemption_declaration(employee, payroll_period.name)

		# create for payroll deducting in random months
		data["deducted_dates"] = create_salary_slips_for_payroll_period(employee,
			salary_structure.name, payroll_period)
		tax_paid = get_tax_paid_in_period(employee)

		# No proof, benefit claim sumitted, total tax paid, should not change
		try:
			self.assertEqual(tax_paid, annual_tax)
		except AssertionError:
			print("\nSalary Slip - Tax calculation failed on following case\n", data, "\n")
			raise

		# Submit proof for total 120000
		data["proof"] = create_proof_submission(employee, payroll_period, 120000)

		# Submit benefit claim for total 50000
		data["benefit-1"] = create_benefit_claim(employee, payroll_period, 15000, "Medical Allowance")
		data["benefit-2"] = create_benefit_claim(employee, payroll_period, 35000, "Leave Travel Allowance")


		frappe.db.sql("""delete from `tabSalary Slip` where employee=%s""", (employee))
		data["deducted_dates"] = create_salary_slips_for_payroll_period(employee,
			salary_structure.name, payroll_period)
		tax_paid = get_tax_paid_in_period(employee)

		# total taxable income 416000, 166000 @ 5% ie. 8300
		try:
			self.assertEqual(tax_paid, 82389.0)
		except AssertionError:
			print("\nSalary Slip - Tax calculation failed on following case\n", data, "\n")
			raise

		# create additional salary of 150000
		frappe.db.sql("""delete from `tabSalary Slip` where employee=%s""", (employee))
		data["additional-1"] = create_additional_salary(employee, payroll_period, 150000)
		data["deducted_dates"] = create_salary_slips_for_payroll_period(employee,
			salary_structure.name, payroll_period)

		# total taxable income 566000, 250000 @ 5%, 66000 @ 20%, 12500 + 13200
		tax_paid = get_tax_paid_in_period(employee)
		try:
			self.assertEqual(tax_paid, annual_tax)
		except AssertionError:
			print("\nSalary Slip - Tax calculation failed on following case\n", data, "\n")
			raise
		frappe.db.sql("""delete from `tabAdditional Salary` where employee=%s""", (employee))

		# undelete fixture data
		frappe.db.rollback()
	def test_india_hra_exemption_with_multiple_salary_structure_assignments(self):
		from erpnext.payroll.doctype.salary_slip.test_salary_slip import create_tax_slab
		from erpnext.payroll.doctype.salary_structure.test_salary_structure import (
			create_salary_structure_assignment,
			make_salary_structure,
		)

		# set country
		current_country = frappe.flags.country
		frappe.flags.country = "India"

		employee = make_employee("*****@*****.**", company="_Test Company")
		payroll_period = create_payroll_period(name="_Test Payroll Period", company="_Test Company")

		create_tax_slab(
			payroll_period,
			allow_tax_exemption=True,
			currency="INR",
			effective_date=getdate("2019-04-01"),
			company="_Test Company",
		)

		frappe.db.set_value(
			"Company", "_Test Company", {"basic_component": "Basic Salary", "hra_component": "HRA"}
		)

		# salary structure with base 50000, HRA 3000
		make_salary_structure(
			"Monthly Structure for HRA Exemption 1",
			"Monthly",
			employee=employee,
			company="_Test Company",
			currency="INR",
			payroll_period=payroll_period.name,
			from_date=payroll_period.start_date,
		)

		# salary structure with base 70000, HRA = base * 0.2 = 14000
		salary_structure = make_salary_structure(
			"Monthly Structure for HRA Exemption 2",
			"Monthly",
			employee=employee,
			company="_Test Company",
			currency="INR",
			payroll_period=payroll_period.name,
			from_date=payroll_period.start_date,
			dont_submit=True,
		)
		for component_row in salary_structure.earnings:
			if component_row.salary_component == "HRA":
				component_row.amount = 0
				component_row.amount_based_on_formula = 1
				component_row.formula = "base * 0.2"
				break

		salary_structure.submit()

		create_salary_structure_assignment(
			employee,
			salary_structure.name,
			from_date=add_months(payroll_period.start_date, 6),
			company="_Test Company",
			currency="INR",
			payroll_period=payroll_period.name,
			base=70000,
			allow_duplicate=True,
		)

		declaration = frappe.get_doc(
			{
				"doctype": "Employee Tax Exemption Declaration",
				"employee": employee,
				"company": "_Test Company",
				"payroll_period": payroll_period.name,
				"currency": "INR",
				"monthly_house_rent": 50000,
				"rented_in_metro_city": 1,
				"declarations": [
					dict(
						exemption_sub_category="_Test1 Sub Category",
						exemption_category="_Test Category",
						amount=60000,
					),
				],
			}
		).insert()

		# Monthly HRA received = 50000 * 6 months + 70000 * 6 months
		# should set HRA exemption as per actual annual HRA because that's the minimum
		self.assertEqual(declaration.monthly_hra_exemption, 8500)
		self.assertEqual(declaration.annual_hra_exemption, 102000)
		# 50000 Standard Exemption + 102000 HRA exemption
		self.assertEqual(declaration.total_exemption_amount, 152000)

		# reset
		frappe.flags.country = current_country