Skip to content

Commit

Permalink
Merge pull request #2134 from frappe/mergify/bp/version-15-hotfix/pr-…
Browse files Browse the repository at this point in the history
…2133

fix: query for payroll cost centers should only consider the latest salary assignment (backport #2133)
  • Loading branch information
ruchamahabal authored Aug 29, 2024
2 parents ea19cac + 182de68 commit 1a786db
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 9 deletions.
23 changes: 14 additions & 9 deletions hrms/payroll/doctype/payroll_entry/payroll_entry.py
Original file line number Diff line number Diff line change
Expand Up @@ -470,18 +470,23 @@ def get_payroll_cost_centers_for_employee(self, employee, salary_structure):
if not self.employee_cost_centers.get(employee):
SalaryStructureAssignment = frappe.qb.DocType("Salary Structure Assignment")
EmployeeCostCenter = frappe.qb.DocType("Employee Cost Center")

assignment_subquery = (
frappe.qb.from_(SalaryStructureAssignment)
.select(SalaryStructureAssignment.name)
.where(
(SalaryStructureAssignment.employee == employee)
& (SalaryStructureAssignment.salary_structure == salary_structure)
& (SalaryStructureAssignment.docstatus == 1)
& (SalaryStructureAssignment.from_date <= self.end_date)
)
.orderby(SalaryStructureAssignment.from_date, order=frappe.qb.desc)
.limit(1)
)
cost_centers = dict(
(
frappe.qb.from_(SalaryStructureAssignment)
.join(EmployeeCostCenter)
.on(SalaryStructureAssignment.name == EmployeeCostCenter.parent)
frappe.qb.from_(EmployeeCostCenter)
.select(EmployeeCostCenter.cost_center, EmployeeCostCenter.percentage)
.where(
(SalaryStructureAssignment.employee == employee)
& (SalaryStructureAssignment.docstatus == 1)
& (SalaryStructureAssignment.salary_structure == salary_structure)
)
.where(EmployeeCostCenter.parent == assignment_subquery)
).run(as_list=True)
)

Expand Down
52 changes: 52 additions & 0 deletions hrms/payroll/doctype/payroll_entry/test_payroll_entry.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ def setUp(self):
"Payroll Entry",
"Salary Structure",
"Salary Structure Assignment",
"Employee Cost Center",
"Payroll Employee Detail",
"Additional Salary",
]:
Expand Down Expand Up @@ -181,6 +182,57 @@ def test_payroll_entry_with_employee_cost_center(self):

self.assertEqual(je_entries, expected_je)

@change_settings("Payroll Settings", {"process_payroll_accounting_entry_based_on_employee": 0})
def test_employee_cost_center_breakup(self):
"""Test only the latest salary structure assignment is considered for cost center breakup"""
COMPANY = "_Test Company"
COST_CENTERS = {"_Test Cost Center - _TC": 60, "_Test Cost Center 2 - _TC": 40}
department = create_department("Cost Center Test")
employee = make_employee("[email protected]", department=department, company=COMPANY)
salary_structure = make_salary_structure(
"_Test Salary Structure 2",
"Monthly",
employee,
company=COMPANY,
)

# update cost centers in salary structure assignment for employee
new_assignment = frappe.db.get_value(
"Salary Structure Assignment",
{"employee": employee, "salary_structure": salary_structure.name, "docstatus": 1},
"name",
)
new_assignment = frappe.get_doc("Salary Structure Assignment", new_assignment)
new_assignment.payroll_cost_centers = []
for cost_center, percentage in COST_CENTERS.items():
new_assignment.append(
"payroll_cost_centers", {"cost_center": cost_center, "percentage": percentage}
)
new_assignment.save()

# make an old salary structure assignment to test and ensure old cost center mapping is excluded
old_assignment = frappe.copy_doc(new_assignment)
old_assignment.from_date = add_months(new_assignment.from_date, -1)
old_assignment.payroll_cost_centers = []
old_assignment.append("payroll_cost_centers", {"cost_center": "Main - _TC", "percentage": 100})
old_assignment.submit()

dates = get_start_end_dates("Monthly", nowdate())
pe = make_payroll_entry(
start_date=dates.start_date,
end_date=dates.end_date,
payable_account="_Test Payroll Payable - _TC",
currency="INR",
department=department,
company="_Test Company",
payment_account="Cash - _TC",
cost_center="Main - _TC",
)

# only new cost center breakup is considered
cost_centers = pe.get_payroll_cost_centers_for_employee(employee, "_Test Salary Structure 2")
self.assertEqual(cost_centers, COST_CENTERS)

def test_get_end_date(self):
self.assertEqual(get_end_date("2017-01-01", "monthly"), {"end_date": "2017-01-31"})
self.assertEqual(get_end_date("2017-02-01", "monthly"), {"end_date": "2017-02-28"})
Expand Down

0 comments on commit 1a786db

Please sign in to comment.