def setUp(self): make_employee("*****@*****.**") make_employee("*****@*****.**") create_payroll_period() create_exemption_category() frappe.db.sql( """delete from `tabEmployee Tax Exemption Declaration`""")
def test_employee_salary_slip_read_permission(self): make_employee("*****@*****.**") salary_slip_test_employee = make_employee_salary_slip( "*****@*****.**", "Monthly") frappe.set_user("*****@*****.**") self.assertTrue(salary_slip_test_employee.has_permission("read"))
def test_new_employee_creation(self): make_employee("*****@*****.**") transfer = frappe.get_doc({ "doctype": "Employee Transfer", "employee": frappe.get_value("Employee", {"user_id": "*****@*****.**"}, "name"), "create_new_employee_id": 1, "transfer_date": getdate(), "transfer_details": [{ "property": "Designation", "current": "Software Developer", "new": "Project Manager", "fieldname": "designation", }], }).insert() transfer.submit() self.assertTrue(transfer.new_employee_id) self.assertEqual( frappe.get_value("Employee", transfer.new_employee_id, "status"), "Active") self.assertEqual( frappe.get_value("Employee", transfer.employee, "status"), "Left")
def test_payroll_frequency(self): fiscal_year = get_fiscal_year(nowdate(), company=erpnext.get_default_company())[0] month = "%02d" % getdate(nowdate()).month m = get_month_details(fiscal_year, month) for payroll_frequency in [ "Monthly", "Bimonthly", "Fortnightly", "Weekly", "Daily" ]: make_employee(payroll_frequency + "*****@*****.**") ss = make_employee_salary_slip( payroll_frequency + "*****@*****.**", payroll_frequency) if payroll_frequency == "Monthly": self.assertEqual(ss.end_date, m['month_end_date']) elif payroll_frequency == "Bimonthly": if getdate(ss.start_date).day <= 15: self.assertEqual(ss.end_date, m['month_mid_end_date']) else: self.assertEqual(ss.end_date, m['month_end_date']) elif payroll_frequency == "Fortnightly": self.assertEqual(ss.end_date, add_days(nowdate(), 13)) elif payroll_frequency == "Weekly": self.assertEqual(ss.end_date, add_days(nowdate(), 6)) elif payroll_frequency == "Daily": self.assertEqual(ss.end_date, nowdate())
def test_shift_assignment_calendar(self): employee1 = make_employee("*****@*****.**", company="_Test Company") employee2 = make_employee("*****@*****.**", company="_Test Company") date = nowdate() shift_1 = frappe.get_doc({ "doctype": "Shift Assignment", "shift_type": "Day Shift", "company": "_Test Company", "employee": employee1, "start_date": date, "status": "Active", }).submit() frappe.get_doc({ "doctype": "Shift Assignment", "shift_type": "Day Shift", "company": "_Test Company", "employee": employee2, "start_date": date, "status": "Active", }).submit() events = get_events( start=date, end=date, filters=[["Shift Assignment", "employee", "=", employee1, False]]) self.assertEqual(len(events), 1) self.assertEqual(events[0]["name"], shift_1.name)
def create_employee_grievance(): grievance_type = create_grievance_type() emp_1 = make_employee("*****@*****.**", company="_Test Company") emp_2 = make_employee("*****@*****.**", company="_Test Company") grievance = frappe.new_doc("Employee Grievance") grievance.subject = "Test Employee Grievance" grievance.raised_by = emp_1 grievance.date = today() grievance.grievance_type = grievance_type grievance.grievance_against_party = "Employee" grievance.grievance_against = emp_2 grievance.description = "test descrip" # set cause grievance.cause_of_grievance = "test cause" # resolution details grievance.resolution_date = today() grievance.resolution_detail = "test resolution detail" grievance.resolved_by = "*****@*****.**" grievance.employee_responsible = emp_2 grievance.status = "Resolved" grievance.save() grievance.submit() return grievance
def test_salary_slip_with_holidays_included(self): no_of_days = self.get_no_of_days() frappe.db.set_value("Payroll Settings", None, "include_holidays_in_total_working_days", 1) make_employee("*****@*****.**") frappe.db.set_value( "Employee", frappe.get_value( "Employee", { "employee_name": "*****@*****.**" }, "name"), "relieving_date", None) frappe.db.set_value( "Employee", frappe.get_value( "Employee", { "employee_name": "*****@*****.**" }, "name"), "status", "Active") ss = make_employee_salary_slip( "*****@*****.**", "Monthly", "Test Salary Slip With Holidays Included") self.assertEqual(ss.total_working_days, no_of_days[0]) self.assertEqual(ss.payment_days, no_of_days[0]) self.assertEqual(ss.earnings[0].amount, 50000) self.assertEqual(ss.earnings[1].amount, 3000) self.assertEqual(ss.gross_pay, 78000)
def test_vacancies_fulfilled(self): make_employee( "*****@*****.**", company="_Test Opening Company", designation="Designer" ) staffing_plan = frappe.get_doc( { "doctype": "Staffing Plan", "company": "_Test Opening Company", "name": "Test", "from_date": getdate(), "to_date": add_days(getdate(), 10), } ) staffing_plan.append( "staffing_details", {"designation": "Designer", "vacancies": 1, "estimated_cost_per_position": 50000}, ) staffing_plan.insert() staffing_plan.submit() self.assertEqual(staffing_plan.staffing_details[0].number_of_positions, 2) # allows creating 1 job opening as per vacancy opening_1 = get_job_opening() opening_1.insert() # vacancies as per staffing plan already fulfilled via job opening and existing employee count opening_2 = get_job_opening(job_title="Designer New") self.assertRaises(frappe.ValidationError, opening_2.insert) # allows updating existing job opening opening_1.status = "Closed" opening_1.save()
def test_salary_slip_with_holidays_excluded(self): no_of_days = self.get_no_of_days() frappe.db.set_value("HR Settings", None, "include_holidays_in_total_working_days", 0) make_employee("*****@*****.**") frappe.db.set_value( "Employee", frappe.get_value("Employee", {"employee_name": "*****@*****.**"}, "name"), "relieving_date", None) frappe.db.set_value( "Employee", frappe.get_value("Employee", {"employee_name": "*****@*****.**"}, "name"), "status", "Active") ss = make_employee_salary_slip("*****@*****.**", "Monthly") self.assertEqual(ss.total_working_days, no_of_days[0] - no_of_days[1]) self.assertEqual(ss.payment_days, no_of_days[0] - no_of_days[1]) self.assertEqual(ss.earnings[0].amount, 50000) self.assertEqual(ss.earnings[0].default_amount, 50000) self.assertEqual(ss.earnings[1].amount, 3000) self.assertEqual(ss.deductions[0].amount, 5000) self.assertEqual(ss.deductions[1].amount, 5000) self.assertEqual(ss.gross_pay, 78000) self.assertEqual(ss.net_pay, 67418.0)
def setUp(self): make_employee("*****@*****.**", company="_Test Company") make_employee("*****@*****.**", company="_Test Company") create_payroll_period(company="_Test Company") create_exemption_category() frappe.db.delete("Employee Tax Exemption Declaration") frappe.db.delete("Salary Structure Assignment")
def test_expense_approver_perms(self): user = "******" make_employee(user, "_Test Company") # check doc shared payable_account = get_payable_account("_Test Company") expense_claim = make_expense_claim(payable_account, 300, 200, "_Test Company", "Travel Expenses - _TC", do_not_submit=True) expense_claim.expense_approver = user expense_claim.save() self.assertTrue(expense_claim.name in frappe.share.get_shared( "Expense Claim", user)) # check shared doc revoked expense_claim.reload() expense_claim.expense_approver = "*****@*****.**" expense_claim.save() self.assertTrue(expense_claim.name not in frappe.share.get_shared( "Expense Claim", user)) expense_claim.reload() expense_claim.expense_approver = user expense_claim.save() frappe.set_user(user) expense_claim.reload() expense_claim.status = "Approved" expense_claim.submit() frappe.set_user("Administrator")
def test_work_anniversary_reminders(self): make_employee( "*****@*****.**", date_of_joining="1998" + frappe.utils.nowdate()[4:], company="_Test Company", ) from erpnext.hr.doctype.employee.employee_reminders import ( get_employees_having_an_event_today, send_work_anniversary_reminders, ) employees_having_work_anniversary = get_employees_having_an_event_today( "work_anniversary") employees = employees_having_work_anniversary.get( "_Test Company") or [] user_ids = [] for entry in employees: user_ids.append(entry.user_id) self.assertTrue("*****@*****.**" in user_ids) hr_settings = frappe.get_doc("HR Settings", "HR Settings") hr_settings.send_work_anniversary_reminders = 1 hr_settings.save() send_work_anniversary_reminders() email_queue = frappe.db.sql("""select * from `tabEmail Queue`""", as_dict=True) self.assertTrue( "Subject: Work Anniversary Reminder" in email_queue[0].message)
def setUp(self): for dt in ["Salary Slip", "Salary Structure", "Salary Structure Assignment"]: frappe.db.sql("delete from `tab%s`" % dt) self.make_holiday_list() frappe.db.set_value("Company", erpnext.get_default_company(), "default_holiday_list", "Salary Structure Test Holiday List") make_employee("*****@*****.**") make_employee("*****@*****.**")
def setUp(self): for dt in ["Salary Slip", "Salary Structure", "Salary Structure Assignment"]: frappe.db.sql("delete from `tab%s`" % dt) self.make_holiday_list() frappe.db.set_value("Company", erpnext.get_default_company(), "default_holiday_list", "Salary Structure Test Holiday List") make_employee("*****@*****.**") make_employee("*****@*****.**")
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)
def test_email_salary_slip(self): frappe.db.sql("delete from `tabEmail Queue`") frappe.db.set_value("HR Settings", None, "email_salary_slip_to_employee", 1) make_employee("*****@*****.**") ss = make_employee_salary_slip("*****@*****.**", "Monthly") ss.submit() email_queue = frappe.db.sql("""select name from `tabEmail Queue`""") self.assertTrue(email_queue)
def test_email_salary_slip(self): frappe.db.sql("delete from `tabEmail Queue`") hr_settings = frappe.get_doc("HR Settings", "HR Settings") hr_settings.email_salary_slip_to_employee = 1 hr_settings.save() make_employee("*****@*****.**") ss = make_employee_salary_slip("*****@*****.**", "Monthly") ss.submit() email_queue = frappe.db.sql("""select name from `tabEmail Queue`""") self.assertTrue(email_queue)
def test_email_salary_slip(self): frappe.db.sql("delete from `tabEmail Queue`") frappe.db.set_value("Payroll Settings", None, "email_salary_slip_to_employee", 1) make_employee("*****@*****.**") ss = make_employee_salary_slip("*****@*****.**", "Monthly", "Test Salary Slip Email") ss.company = "_Test Company" ss.save() ss.submit() email_queue = frappe.db.sql("""select name from `tabEmail Queue`""") self.assertTrue(email_queue)
def test_email_salary_slip(self): frappe.db.sql("delete from `tabEmail Queue`") hr_settings = frappe.get_doc("HR Settings", "HR Settings") hr_settings.email_salary_slip_to_employee = 1 hr_settings.save() make_employee("*****@*****.**") ss = make_employee_salary_slip("*****@*****.**", "Monthly") ss.submit() email_queue = frappe.db.sql("""select name from `tabEmail Queue`""") self.assertTrue(email_queue)
def test_payment_days(self): no_of_days = self.get_no_of_days() # Holidays not included in working days frappe.db.set_value("Payroll Settings", None, "include_holidays_in_total_working_days", 1) # set joinng date in the same month make_employee("*****@*****.**") if getdate(nowdate()).day >= 15: relieving_date = getdate(add_days(nowdate(), -10)) date_of_joining = getdate(add_days(nowdate(), -10)) elif getdate(nowdate()).day < 15 and getdate(nowdate()).day >= 5: date_of_joining = getdate(add_days(nowdate(), -3)) relieving_date = getdate(add_days(nowdate(), -3)) elif getdate(nowdate()).day < 5 and not getdate(nowdate()).day == 1: date_of_joining = getdate(add_days(nowdate(), -1)) relieving_date = getdate(add_days(nowdate(), -1)) elif getdate(nowdate()).day == 1: date_of_joining = getdate(nowdate()) relieving_date = getdate(nowdate()) frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name": "*****@*****.**"}, "name"), "date_of_joining", date_of_joining) frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name": "*****@*****.**"}, "name"), "relieving_date", None) frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name": "*****@*****.**"}, "name"), "status", "Active") ss = make_employee_salary_slip( "*****@*****.**", "Monthly", "Test Payment Days") self.assertEqual(ss.total_working_days, no_of_days[0]) self.assertEqual( ss.payment_days, (no_of_days[0] - getdate(date_of_joining).day + 1)) # set relieving date in the same month frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name": "*****@*****.**"}, "name"), "date_of_joining", (add_days(nowdate(), -60))) frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name": "*****@*****.**"}, "name"), "relieving_date", relieving_date) frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name": "*****@*****.**"}, "name"), "status", "Left") ss.save() self.assertEqual(ss.total_working_days, no_of_days[0]) self.assertEqual(ss.payment_days, getdate(relieving_date).day) frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name": "*****@*****.**"}, "name"), "relieving_date", None) frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name": "*****@*****.**"}, "name"), "status", "Active")
def setUpClass(cls): # Create test employee cls.test_emp1 = make_employee("*****@*****.**", "_Test Company") cls.test_emp2 = make_employee("*****@*****.**", "_Test Company") # Create test project cls.test_project = make_project({"project_name": "_Test Project"}) # Create test timesheets cls.create_test_timesheets() frappe.db.set_value("HR Settings", "HR Settings", "standard_working_hours", 9)
def test_payment_days(self): no_of_days = self.get_no_of_days() # Holidays not included in working days frappe.db.set_value("HR Settings", None, "include_holidays_in_total_working_days", 1) # set joinng date in the same month make_employee("*****@*****.**") if getdate(nowdate()).day >= 15: date_of_joining = getdate(add_days(nowdate(),-10)) relieving_date = getdate(add_days(nowdate(),-10)) elif getdate(nowdate()).day < 15 and getdate(nowdate()).day >= 5: date_of_joining = getdate(add_days(nowdate(),-3)) relieving_date = getdate(add_days(nowdate(),-3)) elif getdate(nowdate()).day < 5 and not getdate(nowdate()).day == 1: date_of_joining = getdate(add_days(nowdate(),-1)) relieving_date = getdate(add_days(nowdate(),-1)) elif getdate(nowdate()).day == 1: date_of_joining = getdate(nowdate()) relieving_date = getdate(nowdate()) frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name":"*****@*****.**"}, "name"), "date_of_joining", date_of_joining) frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name":"*****@*****.**"}, "name"), "relieving_date", None) frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name":"*****@*****.**"}, "name"), "status", "Active") ss = make_employee_salary_slip("*****@*****.**", "Monthly") self.assertEqual(ss.total_working_days, no_of_days[0]) self.assertEqual(ss.payment_days, (no_of_days[0] - getdate(date_of_joining).day + 1)) # set relieving date in the same month frappe.db.set_value("Employee",frappe.get_value("Employee", {"employee_name":"*****@*****.**"}, "name"), "date_of_joining", (add_days(nowdate(),-60))) frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name":"*****@*****.**"}, "name"), "relieving_date", relieving_date) frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name":"*****@*****.**"}, "name"), "status", "Left") ss.save() self.assertEqual(ss.total_working_days, no_of_days[0]) self.assertEqual(ss.payment_days, getdate(relieving_date).day) frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name":"*****@*****.**"}, "name"), "relieving_date", None) frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name":"*****@*****.**"}, "name"), "status", "Active")
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)
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)
def test_salary_structures_assignment(self): company_currency = erpnext.get_default_currency() salary_structure = make_salary_structure("Salary Structure Sample", "Monthly", currency=company_currency) employee = "*****@*****.**" employee_doc_name = make_employee(employee) # clear the already assigned stuctures frappe.db.sql( """delete from `tabSalary Structure Assignment` where employee=%s and salary_structure=%s """, ("*****@*****.**", salary_structure.name), ) # test structure_assignment salary_structure.assign_salary_structure(employee=employee_doc_name, from_date="2013-01-01", base=5000, variable=200) salary_structure_assignment = frappe.get_doc( "Salary Structure Assignment", { "employee": employee_doc_name, "from_date": "2013-01-01" }) self.assertEqual(salary_structure_assignment.docstatus, 1) self.assertEqual(salary_structure_assignment.base, 5000) self.assertEqual(salary_structure_assignment.variable, 200)
def setUp(self): frappe.db.delete("Leave Period") frappe.db.delete("Leave Allocation") frappe.db.delete("Leave Ledger Entry") emp_id = make_employee("*****@*****.**", company="_Test Company") self.employee = frappe.get_doc("Employee", emp_id)
def test_gratuity_based_on_all_previous_slabs_via_payment_entry(self): """ Range | Fraction 0-1 | 0 1-5 | 0.7 5-0 | 1 """ from erpnext.accounts.doctype.payment_entry.payment_entry import get_payment_entry doj = add_days(getdate(), -(6 * 365)) relieving_date = getdate() employee = make_employee( "*****@*****.**", company="_Test Company", date_of_joining=doj, relieving_date=relieving_date, ) sal_slip = create_salary_slip("*****@*****.**") rule = get_gratuity_rule("Rule Under Limited Contract (UAE)") set_mode_of_payment_account() gratuity = create_gratuity(expense_account="Payment Account - _TC", mode_of_payment="Cash", employee=employee) # work experience calculation employee_total_workings_days = (get_datetime(relieving_date) - get_datetime(doj)).days experience = floor(employee_total_workings_days / rule.total_working_days_per_year) self.assertEqual(gratuity.current_work_experience, experience) # amount calculation component_amount = frappe.get_all( "Salary Detail", filters={ "docstatus": 1, "parent": sal_slip, "parentfield": "earnings", "salary_component": "Basic Salary", }, fields=["amount"], limit=1, ) gratuity_amount = ((0 * 1) + (4 * 0.7) + (1 * 1)) * component_amount[0].amount self.assertEqual(flt(gratuity_amount, 2), flt(gratuity.amount, 2)) self.assertEqual(gratuity.status, "Unpaid") pe = get_payment_entry("Gratuity", gratuity.name) pe.reference_no = "123467" pe.reference_date = getdate() pe.submit() gratuity.reload() self.assertEqual(gratuity.status, "Paid") self.assertEqual(flt(gratuity.paid_amount, 2), flt(gratuity.amount, 2))
def test_salary_structure_deduction_based_on_gross_pay(self): emp = make_employee("*****@*****.**") sal_struct = make_salary_structure("Salary Structure 2", "Monthly", dont_submit=True) sal_struct.earnings = [sal_struct.earnings[0]] sal_struct.earnings[0].amount_based_on_formula = 1 sal_struct.earnings[0].formula = "base" sal_struct.deductions = [sal_struct.deductions[0]] sal_struct.deductions[0].amount_based_on_formula = 1 sal_struct.deductions[0].condition = "gross_pay > 100" sal_struct.deductions[0].formula = "gross_pay * 0.2" sal_struct.submit() assignment = create_salary_structure_assignment( emp, "Salary Structure 2") ss = make_salary_slip(sal_struct.name, employee=emp) self.assertEqual(assignment.base * 0.2, ss.deductions[0].amount)
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 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') 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") 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))))
def test_timesheet_not_overlapping_with_continuous_timelogs(self): emp = make_employee("*****@*****.**") update_activity_type("_Test Activity Type") timesheet = frappe.new_doc("Timesheet") timesheet.employee = emp timesheet.append( "time_logs", { "billable": 1, "activity_type": "_Test Activity Type", "from_time": now_datetime(), "to_time": now_datetime() + datetime.timedelta(hours=3), "company": "_Test Company", }, ) timesheet.append( "time_logs", { "billable": 1, "activity_type": "_Test Activity Type", "from_time": now_datetime() + datetime.timedelta(hours=3), "to_time": now_datetime() + datetime.timedelta(hours=4), "company": "_Test Company", }, ) timesheet.save() # should not throw an error
def test_mark_attendance_and_link_log(self): employee = make_employee( "*****@*****.**") logs = make_n_checkins(employee, 3) mark_attendance_and_link_log(logs, 'Skip', nowdate()) log_names = [log.name for log in logs] logs_count = frappe.db.count('Employee Checkin', { 'name': ['in', log_names], 'skip_auto_attendance': 1 }) self.assertEqual(logs_count, 3) logs = make_n_checkins(employee, 4, 2) now_date = nowdate() frappe.db.delete('Attendance', {'employee': employee}) attendance = mark_attendance_and_link_log(logs, 'Present', now_date, 8.2) log_names = [log.name for log in logs] logs_count = frappe.db.count('Employee Checkin', { 'name': ['in', log_names], 'attendance': attendance.name }) self.assertEqual(logs_count, 4) attendance_count = frappe.db.count( 'Attendance', { 'status': 'Present', 'working_hours': 8.2, 'employee': employee, 'attendance_date': now_date }) self.assertEqual(attendance_count, 1)
def test_employee_history(self): employee = make_employee( "*****@*****.**", company="Test Company", date_of_birth=getdate("30-09-1980"), date_of_joining=getdate("01-10-2021"), department="Accounts - TC", designation="Accountant", ) transfer = create_employee_transfer(employee) count = 0 department = ["Accounts - TC", "Management - TC"] designation = ["Accountant", "Manager"] dt = [getdate("01-10-2021"), getdate()] employee = frappe.get_doc("Employee", employee) for data in employee.internal_work_history: self.assertEqual(data.department, department[count]) self.assertEqual(data.designation, designation[count]) self.assertEqual(data.from_date, dt[count]) count = count + 1 transfer.cancel() employee.reload() for data in employee.internal_work_history: self.assertEqual(data.designation, designation[0]) self.assertEqual(data.department, department[0]) self.assertEqual(data.from_date, dt[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)
def test_salary_slip_with_holidays_included(self): no_of_days = self.get_no_of_days() frappe.db.set_value("HR Settings", None, "include_holidays_in_total_working_days", 1) make_employee("*****@*****.**") frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name":"*****@*****.**"}, "name"), "relieving_date", None) frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name":"*****@*****.**"}, "name"), "status", "Active") ss = make_employee_salary_slip("*****@*****.**", "Monthly") self.assertEqual(ss.total_working_days, no_of_days[0]) self.assertEqual(ss.payment_days, no_of_days[0]) self.assertEqual(ss.earnings[0].amount, 25000) self.assertEqual(ss.earnings[1].amount, 3000) self.assertEqual(ss.deductions[0].amount, 5000) self.assertEqual(ss.deductions[1].amount, 5000) self.assertEqual(ss.gross_pay, 40500) self.assertEqual(ss.net_pay, 29918)
def test_loan_repayment_salary_slip(self): from erpnext.hr.doctype.loan.test_loan import create_loan_type, create_loan applicant = make_employee("*****@*****.**") create_loan_type("Car Loan", 500000, 6.4) loan = create_loan(applicant, "Car Loan", 11000, "Repay Over Number of Periods", 20) loan.repay_from_salary = 1 loan.submit() ss = make_employee_salary_slip("*****@*****.**", "Monthly") ss.submit() self.assertEqual(ss.total_loan_repayment, 582) self.assertEqual(ss.net_pay, (flt(ss.gross_pay) - (flt(ss.total_deduction) + flt(ss.total_loan_repayment))))
def test_payroll_frequency(self): fiscal_year = get_fiscal_year(nowdate(), company=erpnext.get_default_company())[0] month = "%02d" % getdate(nowdate()).month m = get_month_details(fiscal_year, month) for payroll_frequency in ["Monthly", "Bimonthly", "Fortnightly", "Weekly", "Daily"]: make_employee(payroll_frequency + "*****@*****.**") ss = make_employee_salary_slip(payroll_frequency + "*****@*****.**", payroll_frequency) if payroll_frequency == "Monthly": self.assertEqual(ss.end_date, m['month_end_date']) elif payroll_frequency == "Bimonthly": if getdate(ss.start_date).day <= 15: self.assertEqual(ss.end_date, m['month_mid_end_date']) else: self.assertEqual(ss.end_date, m['month_end_date']) elif payroll_frequency == "Fortnightly": self.assertEqual(ss.end_date, add_days(nowdate(),13)) elif payroll_frequency == "Weekly": self.assertEqual(ss.end_date, add_days(nowdate(),6)) elif payroll_frequency == "Daily": self.assertEqual(ss.end_date, nowdate())
def test_salary_structures_assignment(self): salary_structure = make_salary_structure("Salary Structure Sample", "Monthly") employee = "*****@*****.**" employee_doc_name = make_employee(employee) # clear the already assigned stuctures frappe.db.sql('''delete from `tabSalary Structure Assignment` where employee=%s and salary_structure=%s ''', ("*****@*****.**",salary_structure.name)) #test structure_assignment salary_structure.assign_salary_structure(employee=employee_doc_name,from_date='2013-01-01',base=5000,variable=200) salary_structure_assignment = frappe.get_doc("Salary Structure Assignment",{'employee':employee_doc_name, 'from_date':'2013-01-01'}) self.assertEqual(salary_structure_assignment.docstatus, 1) self.assertEqual(salary_structure_assignment.base, 5000) self.assertEqual(salary_structure_assignment.variable, 200)
def test_loan(self): branch = "Test Employee Branch" applicant = make_employee("*****@*****.**") company = erpnext.get_default_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() loan = create_loan(applicant, "Personal Loan", 280000, "Repay Over Number of Periods", 20) loan.repay_from_salary = 1 loan.submit() salary_structure = "Test Salary Structure for Loan" make_salary_structure(salary_structure, "Monthly", employee_doc.name) dates = get_start_end_dates('Monthly', nowdate()) make_payroll_entry(start_date=dates.start_date, end_date=dates.end_date, branch=branch) 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)
def test_movement_for_serialized_asset(self): asset_item = "Test Serialized Asset Item" pr = make_purchase_receipt(item_code=asset_item, rate = 1000, qty=3, location = "Mumbai") asset_name = frappe.db.get_value('Asset', {'purchase_receipt': pr.name}, 'name') asset = frappe.get_doc('Asset', asset_name) month_end_date = get_last_day(nowdate()) asset.available_for_use_date = nowdate() if nowdate() != month_end_date else add_days(nowdate(), -15) asset.calculate_depreciation = 1 asset.append("finance_books", { "expected_value_after_useful_life": 200, "depreciation_method": "Straight Line", "total_number_of_depreciations": 3, "frequency_of_depreciation": 10, "depreciation_start_date": month_end_date }) asset.submit() serial_nos = frappe.db.get_value('Asset Movement', {'reference_name': pr.name}, 'serial_no') mov1 = create_asset_movement(asset=asset_name, purpose = 'Transfer', company=asset.company, source_location = "Mumbai", target_location="Pune", serial_no=serial_nos) self.assertEqual(mov1.target_location, "Pune") serial_no = frappe.db.get_value('Serial No', {'asset': asset_name}, 'name') employee = make_employee("*****@*****.**") create_asset_movement(asset=asset_name, purpose = 'Transfer', company=asset.company, serial_no=serial_no, to_employee=employee) self.assertEqual(frappe.db.get_value('Serial No', serial_no, 'employee'), employee) create_asset_movement(asset=asset_name, purpose = 'Transfer', company=asset.company, serial_no=serial_no, from_employee=employee, to_employee="_T-Employee-00001") self.assertEqual(frappe.db.get_value('Serial No', serial_no, 'location'), "Pune") mov4 = create_asset_movement(asset=asset_name, purpose = 'Transfer', company=asset.company, source_location = "Pune", target_location="Nagpur", serial_no=serial_nos) self.assertEqual(mov4.target_location, "Nagpur") self.assertEqual(frappe.db.get_value('Serial No', serial_no, 'location'), "Nagpur") self.assertEqual(frappe.db.get_value('Serial No', serial_no, 'employee'), "_T-Employee-00001")
def test_date_range(self): employee = make_employee("*****@*****.**") employee_doc = frappe.get_doc("Employee", employee) date_of_joining = "2018-01-02" relieving_date = "2018-01-03" from_date = "2018-01-01" to_date = "2018-01-04" employee_doc.date_of_joining = date_of_joining employee_doc.relieving_date = relieving_date employee_doc.save() args = { "from_date": from_date, "to_date": to_date } data = get_data(args) filtered_data = [] for row in data: if row[1] == employee: filtered_data.append(row) for row in filtered_data: self.assertTrue(getdate(row[3]) >= getdate(date_of_joining) and getdate(row[3]) <= getdate(relieving_date))
def test_leave_balance_value_and_amount(self): employee = "*****@*****.**" leave_type = "_Test Leave Type Encashment" # create the leave policy leave_policy = frappe.get_doc({ "doctype": "Leave Policy", "leave_policy_details": [{ "leave_type": leave_type, "annual_allocation": 10 }] }).insert() leave_policy.submit() # create employee, salary structure and assignment employee = make_employee(employee) frappe.db.set_value("Employee", employee, "leave_policy", leave_policy.name) salary_structure = make_salary_structure("Salary Structure for Encashment", "Monthly", employee, other_details={"leave_encashment_amount_per_day": 50}) # create the leave period and assign the leaves leave_period = create_leave_period(add_months(today(), -3), add_months(today(), 3)) leave_period.grant_leave_allocation(employee=employee) leave_encashment = frappe.get_doc(dict( doctype = 'Leave Encashment', employee = employee, leave_type = leave_type, leave_period = leave_period.name, payroll_date = today() )).insert() self.assertEqual(leave_encashment.leave_balance, 10) self.assertEqual(leave_encashment.encashable_days, 5) self.assertEqual(leave_encashment.encashment_amount, 250) leave_encashment.submit() self.assertTrue(frappe.db.get_value("Leave Encashment", leave_encashment.name, "additional_salary"))
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`""") payroll_period = create_payroll_period() create_tax_slab(payroll_period) 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.hr.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) # total taxable income 586000, 250000 @ 5%, 86000 @ 20% ie. 12500 + 17200 annual_tax = 29700 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-1"] = create_proof_submission(employee, payroll_period, 50000) data["proof-2"] = create_proof_submission(employee, payroll_period, 70000) # 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, 8300) 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, 50000) data["additional-2"] = create_additional_salary(employee, payroll_period, 100000) 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, 25700) 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 setUp(self): make_employee("*****@*****.**") make_employee("*****@*****.**") create_payroll_period() create_exemption_category() frappe.db.sql("""delete from `tabEmployee Tax Exemption Declaration`""")
def setUp(self): make_employee("*****@*****.**") make_employee("*****@*****.**") frappe.db.sql("""delete from `tabEmployee Transfer`""")
def test_employee_salary_slip_read_permission(self): make_employee("*****@*****.**") salary_slip_test_employee = make_employee_salary_slip("*****@*****.**", "Monthly") frappe.set_user("*****@*****.**") self.assertTrue(salary_slip_test_employee.has_permission("read"))