コード例 #1
0
	def setUp(self):
		create_loan_accounts()
		create_loan_type("Home Loan", 500000, 9.2, 0, 1, 0, 'Cash', 'Payment Account - _TC', 'Loan Account - _TC',
			'Interest Income Account - _TC', 'Penalty Income Account - _TC', 'Repay Over Number of Periods', 18)
		self.applicant = make_employee("*****@*****.**", "_Test Company")
		make_salary_structure("Test Salary Structure Loan", "Monthly", employee=self.applicant, currency='INR')
		self.create_loan_application()
コード例 #2
0
def setup_hra_exemption_prerequisites(frequency, employee=None):
	from erpnext.payroll.doctype.salary_slip.test_salary_slip import create_tax_slab
	from erpnext.payroll.doctype.salary_structure.test_salary_structure import make_salary_structure

	payroll_period = create_payroll_period(name="_Test Payroll Period", company="_Test Company")
	if not employee:
		employee = frappe.get_value("Employee", {"user_id": "*****@*****.**"}, "name")

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

	make_salary_structure(
		f"{frequency} Structure for HRA Exemption",
		frequency,
		employee=employee,
		company="_Test Company",
		currency="INR",
		payroll_period=payroll_period,
	)

	frappe.db.set_value(
		"Company", "_Test Company", {"basic_component": "Basic Salary", "hra_component": "HRA"}
	)
コード例 #3
0
	def setUp(self):
		create_loan_accounts()
		create_loan_type("Personal Loan", 500000, 8.4,
			is_term_loan=1,
			mode_of_payment='Cash',
			payment_account='Payment Account - _TC',
			loan_account='Loan Account - _TC',
			interest_income_account='Interest Income Account - _TC',
			penalty_income_account='Penalty Income Account - _TC')

		create_loan_type("Stock Loan", 2000000, 13.5, 25, 1, 5, 'Cash', 'Payment Account - _TC', 'Loan Account - _TC',
			'Interest Income Account - _TC', 'Penalty Income Account - _TC')

		create_loan_type("Demand Loan", 2000000, 13.5, 25, 0, 5, 'Cash', 'Payment Account - _TC', 'Loan Account - _TC',
			'Interest Income Account - _TC', 'Penalty Income Account - _TC')

		create_loan_security_type()
		create_loan_security()

		create_loan_security_price("Test Security 1", 500, "Nos", get_datetime() , get_datetime(add_to_date(nowdate(), hours=24)))
		create_loan_security_price("Test Security 2", 250, "Nos", get_datetime() , get_datetime(add_to_date(nowdate(), hours=24)))

		self.applicant1 = make_employee("*****@*****.**")
		make_salary_structure("Test Salary Structure Loan", "Monthly", employee=self.applicant1, currency='INR', company="_Test Company")
		if not frappe.db.exists("Customer", "_Test Loan Customer"):
			frappe.get_doc(get_customer_dict('_Test Loan Customer')).insert(ignore_permissions=True)

		self.applicant2 = frappe.db.get_value("Customer", {'name': '_Test Loan Customer'}, 'name')

		create_loan(self.applicant1, "Personal Loan", 280000, "Repay Over Number of Periods", 20)
コード例 #4
0
    def test_payroll_entry(self):  # pylint: disable=no-self-use
        company = erpnext.get_default_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)

        employee = frappe.db.get_value("Employee", {"company": company})
        company_doc = frappe.get_doc("Company", company)
        make_salary_structure(
            "_Test Salary Structure",
            "Monthly",
            employee,
            company=company,
            currency=company_doc.default_currency,
        )
        dates = get_start_end_dates("Monthly", nowdate())
        if not frappe.db.get_value("Salary Slip", {
                "start_date": dates.start_date,
                "end_date": dates.end_date
        }):
            make_payroll_entry(
                start_date=dates.start_date,
                end_date=dates.end_date,
                payable_account=company_doc.default_payroll_payable_account,
                currency=company_doc.default_currency,
            )
コード例 #5
0
ファイル: test_payroll_entry.py プロジェクト: giangdn/teama
    def test_loan(self):
        branch = "Test Employee Branch"
        applicant = make_employee(
            "*****@*****.**", company="_Test Company")
        company = "_Test Company"
        holiday_list = make_holiday("test holiday for loan")

        company_doc = frappe.get_doc('Company', company)
        if not company_doc.default_payroll_payable_account:
            company_doc.default_payroll_payable_account = frappe.db.get_value('Account',
                                                                              {'company': company, 'root_type': 'Liability', 'account_type': ''}, 'name')
            company_doc.save()

        if not frappe.db.exists('Branch', branch):
            frappe.get_doc({
                'doctype': 'Branch',
                'branch': branch
            }).insert()

        employee_doc = frappe.get_doc('Employee', applicant)
        employee_doc.branch = branch
        employee_doc.holiday_list = holiday_list
        employee_doc.save()

        salary_structure = "Test Salary Structure for Loan"
        make_salary_structure(salary_structure, "Monthly", employee=employee_doc.name,
                              company="_Test Company", currency=company_doc.default_currency)

        loan = create_loan(applicant, "Car Loan", 280000, "Repay Over Number of Periods",
                           20, posting_date=add_months(nowdate(), -1))
        loan.repay_from_salary = 1
        loan.submit()

        make_loan_disbursement_entry(
            loan.name, loan.loan_amount, disbursement_date=add_months(nowdate(), -1))

        process_loan_interest_accrual_for_term_loans(posting_date=nowdate())

        dates = get_start_end_dates('Monthly', nowdate())
        make_payroll_entry(company="_Test Company", start_date=dates.start_date, payable_account=company_doc.default_payroll_payable_account,
                           currency=company_doc.default_currency, end_date=dates.end_date, branch=branch, cost_center="Main - _TC", payment_account="Cash - _TC")

        name = frappe.db.get_value('Salary Slip',
                                   {'posting_date': nowdate(), 'employee': applicant}, 'name')

        salary_slip = frappe.get_doc('Salary Slip', name)
        for row in salary_slip.loans:
            if row.loan == loan.name:
                interest_amount = (280000 * 8.4)/(12*100)
                principal_amount = loan.monthly_repayment_amount - interest_amount
                self.assertEqual(row.interest_amount, interest_amount)
                self.assertEqual(row.principal_amount, principal_amount)
                self.assertEqual(row.total_payment,
                                 interest_amount + principal_amount)

        if salary_slip.docstatus == 0:
            frappe.delete_doc('Salary Slip', name)
コード例 #6
0
    def test_loan_repayment_salary_slip(self):
        from erpnext.loan_management.doctype.loan.test_loan import create_loan_type, create_loan, make_loan_disbursement_entry, create_loan_accounts
        from erpnext.loan_management.doctype.process_loan_interest_accrual.process_loan_interest_accrual import process_loan_interest_accrual_for_term_loans
        from erpnext.payroll.doctype.salary_structure.test_salary_structure import make_salary_structure

        applicant = make_employee("*****@*****.**",
                                  company="_Test Company")

        create_loan_accounts()

        create_loan_type(
            "Car Loan",
            500000,
            8.4,
            is_term_loan=1,
            mode_of_payment='Cash',
            payment_account='Payment Account - _TC',
            loan_account='Loan Account - _TC',
            interest_income_account='Interest Income Account - _TC',
            penalty_income_account='Penalty Income Account - _TC')

        payroll_period = create_payroll_period(name="_Test Payroll Period 1",
                                               company="_Test Company")

        make_salary_structure("Test Loan Repayment Salary Structure",
                              "Monthly",
                              employee=applicant,
                              currency='INR',
                              payroll_period=payroll_period)

        frappe.db.sql("delete from tabLoan")
        loan = create_loan(applicant,
                           "Car Loan",
                           11000,
                           "Repay Over Number of Periods",
                           20,
                           posting_date=add_months(nowdate(), -1))
        loan.repay_from_salary = 1
        loan.submit()

        make_loan_disbursement_entry(loan.name,
                                     loan.loan_amount,
                                     disbursement_date=add_months(
                                         nowdate(), -1))

        process_loan_interest_accrual_for_term_loans(posting_date=nowdate())

        ss = make_employee_salary_slip(
            "*****@*****.**", "Monthly",
            "Test Loan Repayment Salary Structure")
        ss.submit()

        self.assertEqual(ss.total_loan_repayment, 592)
        self.assertEqual(
            ss.net_pay,
            (flt(ss.gross_pay) -
             (flt(ss.total_deduction) + flt(ss.total_loan_repayment))))
コード例 #7
0
	def test_payroll_entry_with_employee_cost_center(self): # pylint: disable=no-self-use
		for data in frappe.get_all('Salary Component', fields = ["name"]):
			if not frappe.db.get_value('Salary Component Account',
				{'parent': data.name, 'company': "_Test Company"}, 'name'):
				get_salary_component_account(data.name)

		if not frappe.db.exists('Department', "cc - _TC"):
			frappe.get_doc({
				'doctype': 'Department',
				'department_name': "cc",
				"company": "_Test Company"
			}).insert()

		frappe.db.sql("""delete from `tabEmployee` where employee_name='*****@*****.**' """)
		frappe.db.sql("""delete from `tabEmployee` where employee_name='*****@*****.**' """)
		frappe.db.sql("""delete from `tabSalary Structure` where name='_Test Salary Structure 1' """)
		frappe.db.sql("""delete from `tabSalary Structure` where name='_Test Salary Structure 2' """)

		employee1 = make_employee("*****@*****.**", payroll_cost_center="_Test Cost Center - _TC",
			department="cc - _TC", company="_Test Company")
		employee2 = make_employee("*****@*****.**", payroll_cost_center="_Test Cost Center 2 - _TC",
			department="cc - _TC", company="_Test Company")

		if not frappe.db.exists("Account", "_Test Payroll Payable - _TC"):
				create_account(account_name="_Test Payroll Payable",
					company="_Test Company", parent_account="Current Liabilities - _TC")

		if not frappe.db.get_value("Company", "_Test Company", "default_payroll_payable_account") or \
			frappe.db.get_value("Company", "_Test Company", "default_payroll_payable_account") != "_Test Payroll Payable - _TC":
				frappe.db.set_value("Company", "_Test Company", "default_payroll_payable_account",
					"_Test Payroll Payable - _TC")
		currency=frappe.db.get_value("Company", "_Test Company", "default_currency")
		make_salary_structure("_Test Salary Structure 1", "Monthly", employee1, company="_Test Company", currency=currency, test_tax=False)
		make_salary_structure("_Test Salary Structure 2", "Monthly", employee2, company="_Test Company", currency=currency, test_tax=False)

		dates = get_start_end_dates('Monthly', nowdate())
		if not frappe.db.get_value("Salary Slip", {"start_date": dates.start_date, "end_date": dates.end_date}):
			pe = make_payroll_entry(start_date=dates.start_date, end_date=dates.end_date, payable_account="_Test Payroll Payable - _TC",
				currency=frappe.db.get_value("Company", "_Test Company", "default_currency"), department="cc - _TC", company="_Test Company", payment_account="Cash - _TC", cost_center="Main - _TC")
			je = frappe.db.get_value("Salary Slip", {"payroll_entry": pe.name}, "journal_entry")
			je_entries = frappe.db.sql("""
				select account, cost_center, debit, credit
				from `tabJournal Entry Account`
				where parent=%s
				order by account, cost_center
			""", je)
			expected_je = (
				('_Test Payroll Payable - _TC', 'Main - _TC', 0.0, 155600.0),
				('Salary - _TC', '_Test Cost Center - _TC', 78000.0, 0.0),
				('Salary - _TC', '_Test Cost Center 2 - _TC', 78000.0, 0.0),
				('Salary Deductions - _TC', '_Test Cost Center - _TC', 0.0, 200.0),
				('Salary Deductions - _TC', '_Test Cost Center 2 - _TC', 0.0, 200.0)
			)

			self.assertEqual(je_entries, expected_je)
コード例 #8
0
    def create_records(self):
        self.employee = make_employee(
            "*****@*****.**",
            company="_Test Company",
            date_of_joining=getdate("01-10-2021"),
        )

        self.payroll_period = create_payroll_period(
            name="_Test Payroll Period 1", company="_Test Company")

        self.income_tax_slab = create_tax_slab(
            self.payroll_period,
            allow_tax_exemption=True,
            effective_date=getdate("2019-04-01"),
            company="_Test Company",
        )
        salary_structure = make_salary_structure(
            "Monthly Salary Structure Test Income Tax Computation",
            "Monthly",
            employee=self.employee,
            company="_Test Company",
            currency="INR",
            payroll_period=self.payroll_period,
            test_tax=True,
        )

        create_exemption_declaration(self.employee, self.payroll_period.name)

        create_salary_slips_for_payroll_period(self.employee,
                                               salary_structure.name,
                                               self.payroll_period,
                                               deduct_random=False,
                                               num=3)
コード例 #9
0
    def setUp(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`""")
        frappe.db.sql("""delete from `tabAdditional Salary`""")

        # create the leave policy
        leave_policy = create_leave_policy(
            leave_type="_Test Leave Type Encashment", annual_allocation=10)
        leave_policy.submit()

        # create employee, salary structure and assignment
        self.employee = make_employee("*****@*****.**")

        self.leave_period = create_leave_period(add_months(today(), -3),
                                                add_months(today(), 3))

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

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

        salary_structure = make_salary_structure(
            "Salary Structure for Encashment",
            "Monthly",
            self.employee,
            other_details={"leave_encashment_amount_per_day": 50},
        )
コード例 #10
0
ファイル: test_timesheet.py プロジェクト: ankush/erpnext
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
コード例 #11
0
	def test_year_to_date_computation(self):
		from erpnext.payroll.doctype.salary_structure.test_salary_structure import make_salary_structure

		applicant = make_employee("*****@*****.**", company="_Test Company")

		payroll_period = create_payroll_period(name="_Test Payroll Period 1", company="_Test Company")

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

		salary_structure = make_salary_structure("Monthly Salary Structure Test for Salary Slip YTD",
			"Monthly", employee=applicant, company="_Test Company", currency="INR", payroll_period=payroll_period)

		# clear salary slip for this employee
		frappe.db.sql("DELETE FROM `tabSalary Slip` where employee_name = '*****@*****.**'")

		create_salary_slips_for_payroll_period(applicant, salary_structure.name,
			payroll_period, deduct_random=False)

		salary_slips = frappe.get_all('Salary Slip', fields=['year_to_date', 'net_pay'], filters={'employee_name':
			'*****@*****.**'}, order_by = 'posting_date')

		year_to_date = 0
		for slip in salary_slips:
			year_to_date += flt(slip.net_pay)
			self.assertEqual(slip.year_to_date, year_to_date)
コード例 #12
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)
コード例 #13
0
    def setUp(self):
        frappe.db.sql('''delete from `tabLeave Period`''')
        frappe.db.sql('''delete from `tabLeave Allocation`''')
        frappe.db.sql('''delete from `tabLeave Ledger Entry`''')
        frappe.db.sql('''delete from `tabAdditional Salary`''')

        # create the leave policy
        leave_policy = create_leave_policy(
            leave_type="_Test Leave Type Encashment", annual_allocation=10)
        leave_policy.submit()

        # create employee, salary structure and assignment
        self.employee = make_employee("*****@*****.**")

        frappe.db.set_value("Employee", self.employee, "leave_policy",
                            leave_policy.name)

        salary_structure = make_salary_structure(
            "Salary Structure for Encashment",
            "Monthly",
            self.employee,
            other_details={"leave_encashment_amount_per_day": 50})

        # create the leave period and assign the leaves
        self.leave_period = create_leave_period(add_months(today(), -3),
                                                add_months(today(), 3))
        self.leave_period.grant_leave_allocation(employee=self.employee)
コード例 #14
0
ファイル: test_employee.py プロジェクト: ankush/erpnext
    def test_employee_status_inactive(self):
        from erpnext.payroll.doctype.salary_slip.test_salary_slip import make_holiday_list
        from erpnext.payroll.doctype.salary_structure.salary_structure import make_salary_slip
        from erpnext.payroll.doctype.salary_structure.test_salary_structure import make_salary_structure

        employee = make_employee("*****@*****.**")
        employee_doc = frappe.get_doc("Employee", employee)
        employee_doc.status = "Inactive"
        employee_doc.save()
        employee_doc.reload()

        make_holiday_list()
        frappe.db.set_value("Company", employee_doc.company,
                            "default_holiday_list",
                            "Salary Slip Test Holiday List")

        frappe.db.sql(
            """delete from `tabSalary Structure` where name='Test Inactive Employee Salary Slip'"""
        )
        salary_structure = make_salary_structure(
            "Test Inactive Employee Salary Slip",
            "Monthly",
            employee=employee_doc.name,
            company=employee_doc.company,
        )
        salary_slip = make_salary_slip(salary_structure.name,
                                       employee=employee_doc.name)

        self.assertRaises(InactiveEmployeeStatusError, salary_slip.save)
コード例 #15
0
def make_employee_salary_slip(user, payroll_frequency, salary_structure=None):
    from erpnext.payroll.doctype.salary_structure.test_salary_structure import make_salary_structure
    if not salary_structure:
        salary_structure = payroll_frequency + " Salary Structure Test for Salary Slip"

    employee = frappe.db.get_value("Employee", {"user_id": user})
    if not frappe.db.exists('Salary Structure', salary_structure):
        salary_structure_doc = make_salary_structure(salary_structure,
                                                     payroll_frequency,
                                                     employee)
    else:
        salary_structure_doc = frappe.get_doc('Salary Structure',
                                              salary_structure)
    salary_slip_name = frappe.db.get_value(
        "Salary Slip",
        {"employee": frappe.db.get_value("Employee", {"user_id": user})})

    if not salary_slip_name:
        salary_slip = make_salary_slip(salary_structure_doc.name,
                                       employee=employee)
        salary_slip.employee_name = frappe.get_value(
            "Employee",
            {"name": frappe.db.get_value("Employee", {"user_id": user})},
            "employee_name")
        salary_slip.payroll_frequency = payroll_frequency
        salary_slip.posting_date = nowdate()
        salary_slip.insert()
    else:
        salary_slip = frappe.get_doc('Salary Slip', salary_slip_name)

    return salary_slip
コード例 #16
0
	def test_component_wise_year_to_date_computation(self):
		from erpnext.payroll.doctype.salary_structure.test_salary_structure import make_salary_structure

		applicant = make_employee("*****@*****.**", company="_Test Company")

		payroll_period = create_payroll_period(name="_Test Payroll Period 1", company="_Test Company")

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

		salary_structure = make_salary_structure("Monthly Salary Structure Test for Salary Slip YTD",
			"Monthly", employee=applicant, company="_Test Company", currency="INR", payroll_period=payroll_period)

		# clear salary slip for this employee
		frappe.db.sql("DELETE FROM `tabSalary Slip` where employee_name = '*****@*****.**'")

		create_salary_slips_for_payroll_period(applicant, salary_structure.name,
			payroll_period, deduct_random=False, num=3)

		salary_slips = frappe.get_all("Salary Slip", fields=["name"], filters={"employee_name":
			"*****@*****.**"}, order_by = "posting_date")

		year_to_date = dict()
		for slip in salary_slips:
			doc = frappe.get_doc("Salary Slip", slip.name)
			for entry in doc.get("earnings"):
				if not year_to_date.get(entry.salary_component):
					year_to_date[entry.salary_component] = 0

				year_to_date[entry.salary_component] += entry.amount
				self.assertEqual(year_to_date[entry.salary_component], entry.year_to_date)
コード例 #17
0
    def test_repay_unclaimed_amount_from_salary(self):
        employee_name = make_employee("*****@*****.**")
        advance = make_employee_advance(
            employee_name, {"repay_unclaimed_amount_from_salary": 1})
        pe = make_payment_entry(advance)
        pe.submit()

        args = {"type": "Deduction"}
        create_salary_component("Advance Salary - Deduction", **args)
        make_salary_structure("Test Additional Salary for Advance Return",
                              "Monthly",
                              employee=employee_name)

        # additional salary for 700 first
        advance.reload()
        additional_salary = create_return_through_additional_salary(advance)
        additional_salary.salary_component = "Advance Salary - Deduction"
        additional_salary.payroll_date = nowdate()
        additional_salary.amount = 700
        additional_salary.insert()
        additional_salary.submit()

        advance.reload()
        self.assertEqual(advance.return_amount, 700)

        # additional salary for remaining 300
        additional_salary = create_return_through_additional_salary(advance)
        additional_salary.salary_component = "Advance Salary - Deduction"
        additional_salary.payroll_date = nowdate()
        additional_salary.amount = 300
        additional_salary.insert()
        additional_salary.submit()

        advance.reload()
        self.assertEqual(advance.return_amount, 1000)
        self.assertEqual(advance.status, "Returned")

        # update advance return amount on additional salary cancellation
        additional_salary.cancel()
        advance.reload()
        self.assertEqual(advance.return_amount, 700)
        self.assertEqual(advance.status, "Paid")
コード例 #18
0
	def test_multi_currency_salary_slip(self):
		from erpnext.payroll.doctype.salary_structure.test_salary_structure import make_salary_structure
		applicant = make_employee("*****@*****.**", company="_Test Company")
		frappe.db.sql("""delete from `tabSalary Structure` where name='Test Multi Currency Salary Slip'""")
		salary_structure = make_salary_structure("Test Multi Currency Salary Slip", "Monthly", employee=applicant, company="_Test Company", currency='USD')
		salary_slip = make_salary_slip(salary_structure.name, employee = applicant)
		salary_slip.exchange_rate = 70
		salary_slip.calculate_net_pay()

		self.assertEqual(salary_slip.gross_pay, 78000)
		self.assertEqual(salary_slip.base_gross_pay, 78000*70)
コード例 #19
0
    def test_payroll_entry(self):  # pylint: disable=no-self-use
        company = erpnext.get_default_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)

        employee = frappe.db.get_value("Employee", {'company': company})
        make_salary_structure("_Test Salary Structure",
                              "Monthly",
                              employee,
                              company=company)
        dates = get_start_end_dates('Monthly', nowdate())
        if not frappe.db.get_value("Salary Slip", {
                "start_date": dates.start_date,
                "end_date": dates.end_date
        }):
            make_payroll_entry(start_date=dates.start_date,
                               end_date=dates.end_date)
コード例 #20
0
 def setUp(self):
     create_loan_accounts()
     create_loan_type(
         "Home Loan",
         500000,
         9.2,
         0,
         1,
         0,
         "Cash",
         "Disbursement Account - _TC",
         "Payment Account - _TC",
         "Loan Account - _TC",
         "Interest Income Account - _TC",
         "Penalty Income Account - _TC",
         "Repay Over Number of Periods",
         18,
     )
     self.applicant = make_employee("*****@*****.**", "_Test Company")
     make_salary_structure("Test Salary Structure Loan",
                           "Monthly",
                           employee=self.applicant,
                           currency="INR")
     self.create_loan_application()
コード例 #21
0
	def test_recurring_additional_salary(self):
		amount = 0
		salary_component = None
		emp_id = make_employee("*****@*****.**")
		frappe.db.set_value("Employee", emp_id, "relieving_date", add_days(nowdate(), 1800))
		salary_structure = make_salary_structure("Test Salary Structure Additional Salary", "Monthly", employee=emp_id)
		add_sal = get_additional_salary(emp_id)

		ss = make_employee_salary_slip("*****@*****.**", "Monthly", salary_structure=salary_structure.name)
		for earning in ss.earnings:
			if earning.salary_component == "Recurring Salary Component":
				amount = earning.amount
				salary_component = earning.salary_component

		self.assertEqual(amount, add_sal.amount)
		self.assertEqual(salary_component, add_sal.salary_component)
コード例 #22
0
    def test_non_recurring_additional_salary(self):
        amount = 0
        salary_component = None
        date = nowdate()

        emp_id = make_employee("*****@*****.**")
        frappe.db.set_value("Employee", emp_id, "relieving_date",
                            add_days(date, 1800))
        salary_structure = make_salary_structure(
            "Test Salary Structure Additional Salary",
            "Monthly",
            employee=emp_id)
        add_sal = get_additional_salary(emp_id,
                                        recurring=False,
                                        payroll_date=date)

        ss = make_employee_salary_slip("*****@*****.**",
                                       "Monthly",
                                       salary_structure=salary_structure.name)

        amount, salary_component = None, None
        for earning in ss.earnings:
            if earning.salary_component == "Recurring Salary Component":
                amount = earning.amount
                salary_component = earning.salary_component
                break

        self.assertEqual(amount, add_sal.amount)
        self.assertEqual(salary_component, add_sal.salary_component)

        # should not show up in next months
        ss.posting_date = add_months(date, 1)
        ss.start_date = ss.end_date = None
        ss.earnings = []
        ss.deductions = []
        ss.save()

        amount, salary_component = None, None
        for earning in ss.earnings:
            if earning.salary_component == "Recurring Salary Component":
                amount = earning.amount
                salary_component = earning.salary_component
                break

        self.assertIsNone(amount)
        self.assertIsNone(salary_component)
コード例 #23
0
	def setUp(self):
		frappe.db.delete("Leave Period")
		frappe.db.delete("Leave Policy Assignment")
		frappe.db.delete("Leave Allocation")
		frappe.db.delete("Leave Ledger Entry")
		frappe.db.delete("Additional Salary")
		frappe.db.delete("Leave Encashment")

		if not frappe.db.exists("Leave Type", "_Test Leave Type Encashment"):
			frappe.get_doc(test_records[2]).insert()

		date = getdate()
		year_start = getdate(get_year_start(date))
		year_end = getdate(get_year_ending(date))

		make_holiday_list("_Test Leave Encashment", year_start, year_end)

		# create the leave policy
		leave_policy = create_leave_policy(
			leave_type="_Test Leave Type Encashment", annual_allocation=10
		)
		leave_policy.submit()

		# create employee, salary structure and assignment
		self.employee = make_employee("*****@*****.**", company="_Test Company")

		self.leave_period = create_leave_period(year_start, year_end, "_Test Company")

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

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

		salary_structure = make_salary_structure(
			"Salary Structure for Encashment",
			"Monthly",
			self.employee,
			other_details={"leave_encashment_amount_per_day": 50},
		)
コード例 #24
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
コード例 #25
0
    def test_payroll_entry_with_employee_cost_center(self):  # pylint: disable=no-self-use
        for data in frappe.get_all("Salary Component", fields=["name"]):
            if not frappe.db.get_value("Salary Component Account", {
                    "parent": data.name,
                    "company": "_Test Company"
            }, "name"):
                get_salary_component_account(data.name)

        if not frappe.db.exists("Department", "cc - _TC"):
            frappe.get_doc({
                "doctype": "Department",
                "department_name": "cc",
                "company": "_Test Company"
            }).insert()

        frappe.db.sql(
            """delete from `tabEmployee` where employee_name='*****@*****.**' """
        )
        frappe.db.sql(
            """delete from `tabEmployee` where employee_name='*****@*****.**' """
        )
        frappe.db.sql(
            """delete from `tabSalary Structure` where name='_Test Salary Structure 1' """
        )
        frappe.db.sql(
            """delete from `tabSalary Structure` where name='_Test Salary Structure 2' """
        )

        employee1 = make_employee(
            "*****@*****.**",
            payroll_cost_center="_Test Cost Center - _TC",
            department="cc - _TC",
            company="_Test Company",
        )
        employee2 = make_employee("*****@*****.**",
                                  department="cc - _TC",
                                  company="_Test Company")

        if not frappe.db.exists("Account", "_Test Payroll Payable - _TC"):
            create_account(
                account_name="_Test Payroll Payable",
                company="_Test Company",
                parent_account="Current Liabilities - _TC",
                account_type="Payable",
            )

        if (not frappe.db.get_value("Company", "_Test Company",
                                    "default_payroll_payable_account")
                or frappe.db.get_value("Company", "_Test Company",
                                       "default_payroll_payable_account") !=
                "_Test Payroll Payable - _TC"):
            frappe.db.set_value("Company", "_Test Company",
                                "default_payroll_payable_account",
                                "_Test Payroll Payable - _TC")
        currency = frappe.db.get_value("Company", "_Test Company",
                                       "default_currency")

        make_salary_structure(
            "_Test Salary Structure 1",
            "Monthly",
            employee1,
            company="_Test Company",
            currency=currency,
            test_tax=False,
        )
        ss = make_salary_structure(
            "_Test Salary Structure 2",
            "Monthly",
            employee2,
            company="_Test Company",
            currency=currency,
            test_tax=False,
        )

        # update cost centers in salary structure assignment for employee2
        ssa = frappe.db.get_value(
            "Salary Structure Assignment",
            {
                "employee": employee2,
                "salary_structure": ss.name,
                "docstatus": 1
            },
            "name",
        )

        ssa_doc = frappe.get_doc("Salary Structure Assignment", ssa)
        ssa_doc.payroll_cost_centers = []
        ssa_doc.append("payroll_cost_centers", {
            "cost_center": "_Test Cost Center - _TC",
            "percentage": 60
        })
        ssa_doc.append("payroll_cost_centers", {
            "cost_center": "_Test Cost Center 2 - _TC",
            "percentage": 40
        })

        ssa_doc.save()

        dates = get_start_end_dates("Monthly", nowdate())
        if not frappe.db.get_value("Salary Slip", {
                "start_date": dates.start_date,
                "end_date": dates.end_date
        }):
            pe = make_payroll_entry(
                start_date=dates.start_date,
                end_date=dates.end_date,
                payable_account="_Test Payroll Payable - _TC",
                currency=frappe.db.get_value("Company", "_Test Company",
                                             "default_currency"),
                department="cc - _TC",
                company="_Test Company",
                payment_account="Cash - _TC",
                cost_center="Main - _TC",
            )
            je = frappe.db.get_value("Salary Slip", {"payroll_entry": pe.name},
                                     "journal_entry")
            je_entries = frappe.db.sql(
                """
				select account, cost_center, debit, credit
				from `tabJournal Entry Account`
				where parent=%s
				order by account, cost_center
			""",
                je,
            )
            expected_je = (
                ("_Test Payroll Payable - _TC", "Main - _TC", 0.0, 155600.0),
                ("Salary - _TC", "_Test Cost Center - _TC", 124800.0, 0.0),
                ("Salary - _TC", "_Test Cost Center 2 - _TC", 31200.0, 0.0),
                ("Salary Deductions - _TC", "_Test Cost Center - _TC", 0.0,
                 320.0),
                ("Salary Deductions - _TC", "_Test Cost Center 2 - _TC", 0.0,
                 80.0),
            )

            self.assertEqual(je_entries, expected_je)
コード例 #26
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()
コード例 #27
0
	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
コード例 #28
0
    def test_loan(self):
        branch = "Test Employee Branch"
        applicant = make_employee("*****@*****.**",
                                  company="_Test Company")
        company = "_Test Company"
        holiday_list = make_holiday("test holiday for loan")

        company_doc = frappe.get_doc("Company", company)
        if not company_doc.default_payroll_payable_account:
            company_doc.default_payroll_payable_account = frappe.db.get_value(
                "Account", {
                    "company": company,
                    "root_type": "Liability",
                    "account_type": ""
                }, "name")
            company_doc.save()

        if not frappe.db.exists("Branch", branch):
            frappe.get_doc({"doctype": "Branch", "branch": branch}).insert()

        employee_doc = frappe.get_doc("Employee", applicant)
        employee_doc.branch = branch
        employee_doc.holiday_list = holiday_list
        employee_doc.save()

        salary_structure = "Test Salary Structure for Loan"
        make_salary_structure(
            salary_structure,
            "Monthly",
            employee=employee_doc.name,
            company="_Test Company",
            currency=company_doc.default_currency,
        )

        if not frappe.db.exists("Loan Type", "Car Loan"):
            create_loan_accounts()
            create_loan_type(
                "Car Loan",
                500000,
                8.4,
                is_term_loan=1,
                mode_of_payment="Cash",
                disbursement_account="Disbursement Account - _TC",
                payment_account="Payment Account - _TC",
                loan_account="Loan Account - _TC",
                interest_income_account="Interest Income Account - _TC",
                penalty_income_account="Penalty Income Account - _TC",
            )

        loan = create_loan(
            applicant,
            "Car Loan",
            280000,
            "Repay Over Number of Periods",
            20,
            posting_date=add_months(nowdate(), -1),
        )
        loan.repay_from_salary = 1
        loan.submit()

        make_loan_disbursement_entry(loan.name,
                                     loan.loan_amount,
                                     disbursement_date=add_months(
                                         nowdate(), -1))
        process_loan_interest_accrual_for_term_loans(posting_date=nowdate())

        dates = get_start_end_dates("Monthly", nowdate())
        make_payroll_entry(
            company="_Test Company",
            start_date=dates.start_date,
            payable_account=company_doc.default_payroll_payable_account,
            currency=company_doc.default_currency,
            end_date=dates.end_date,
            branch=branch,
            cost_center="Main - _TC",
            payment_account="Cash - _TC",
        )

        name = frappe.db.get_value("Salary Slip", {
            "posting_date": nowdate(),
            "employee": applicant
        }, "name")

        salary_slip = frappe.get_doc("Salary Slip", name)
        for row in salary_slip.loans:
            if row.loan == loan.name:
                interest_amount = (280000 * 8.4) / (12 * 100)
                principal_amount = loan.monthly_repayment_amount - interest_amount
                self.assertEqual(row.interest_amount, interest_amount)
                self.assertEqual(row.principal_amount, principal_amount)
                self.assertEqual(row.total_payment,
                                 interest_amount + principal_amount)

        if salary_slip.docstatus == 0:
            frappe.delete_doc("Salary Slip", name)