Skip to content

Commit 982224e

Browse files
authored
Merge pull request #1718 from frappe/version-14-hotfix
chore: release v14
2 parents 8a63566 + a668653 commit 982224e

File tree

4 files changed

+53
-11
lines changed

4 files changed

+53
-11
lines changed

hrms/hr/utils.py

+13-4
Original file line numberDiff line numberDiff line change
@@ -515,16 +515,25 @@ def check_effective_date(from_date, today, frequency, allocate_on_day):
515515

516516

517517
def get_salary_assignments(employee, payroll_period):
518-
start_date, end_date = frappe.db.get_value(
519-
"Payroll Period", payroll_period, ["start_date", "end_date"]
520-
)
521-
assignments = frappe.db.get_all(
518+
start_date, end_date = frappe.db.get_value("Payroll Period", payroll_period, ["start_date", "end_date"])
519+
assignments = frappe.get_all(
522520
"Salary Structure Assignment",
523521
filters={"employee": employee, "docstatus": 1, "from_date": ["between", (start_date, end_date)]},
524522
fields=["*"],
525523
order_by="from_date",
526524
)
527525

526+
if not assignments:
527+
# if no assignments found for the given period
528+
# get the last one assigned before the period that is still active
529+
assignments = frappe.get_all(
530+
"Salary Structure Assignment",
531+
filters={"employee": employee, "docstatus": 1, "from_date": ["<=", start_date]},
532+
fields=["*"],
533+
order_by="from_date desc",
534+
limit=1,
535+
)
536+
528537
return assignments
529538

530539

hrms/payroll/doctype/employee_tax_exemption_declaration/test_employee_tax_exemption_declaration.py

+5-3
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,8 @@ def test_india_hra_exemption(self):
132132
frappe.flags.country = "India"
133133

134134
employee = frappe.get_value("Employee", {"user_id": "[email protected]"}, "name")
135-
setup_hra_exemption_prerequisites("Monthly", employee)
135+
# structure assigned before payroll period should still be considered as active
136+
setup_hra_exemption_prerequisites("Monthly", employee, from_date=add_months(PAYROLL_PERIOD_START, -1))
136137

137138
declaration = frappe.get_doc(
138139
{
@@ -321,7 +322,7 @@ def test_india_hra_exemption_with_bimonthly_payroll_frequency(self):
321322
# reset
322323
frappe.flags.country = current_country
323324

324-
def test_india_hra_exemption_with_multiple_salary_structure_assignments(self):
325+
def test_india_hra_exemption_with_multiple_assignments(self):
325326
from hrms.payroll.doctype.salary_slip.test_salary_slip import create_tax_slab
326327
from hrms.payroll.doctype.salary_structure.test_salary_structure import (
327328
create_salary_structure_assignment,
@@ -471,7 +472,7 @@ def create_exemption_category():
471472
).insert()
472473

473474

474-
def setup_hra_exemption_prerequisites(frequency, employee=None):
475+
def setup_hra_exemption_prerequisites(frequency, employee=None, from_date=None):
475476
from hrms.payroll.doctype.salary_slip.test_salary_slip import create_tax_slab
476477
from hrms.payroll.doctype.salary_structure.test_salary_structure import make_salary_structure
477478

@@ -499,6 +500,7 @@ def setup_hra_exemption_prerequisites(frequency, employee=None):
499500
company="_Test Company",
500501
currency="INR",
501502
payroll_period=payroll_period,
503+
from_date=from_date,
502504
)
503505

504506
frappe.db.set_value(

hrms/payroll/report/income_tax_computation/income_tax_computation.py

+28-3
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ def get_last_salary_slip(self, employee):
160160
"docstatus": 1,
161161
"start_date": ["between", [self.payroll_period_start_date, self.payroll_period_end_date]],
162162
},
163-
["start_date", "end_date", "salary_structure", "payroll_frequency"],
163+
["name", "start_date", "end_date", "salary_structure", "payroll_frequency"],
164164
order_by="start_date desc",
165165
as_dict=1,
166166
)
@@ -423,9 +423,12 @@ def get_applicable_tax(self):
423423
tax_slab = emp_details.get("income_tax_slab")
424424
if tax_slab:
425425
tax_slab = frappe.get_cached_doc("Income Tax Slab", tax_slab)
426-
employee_dict = frappe.get_doc("Employee", emp).as_dict()
426+
eval_globals, eval_locals = self.get_data_for_eval(emp, emp_details)
427427
tax_amount = calculate_tax_by_tax_slab(
428-
emp_details["total_taxable_amount"], tax_slab, eval_globals=None, eval_locals=employee_dict
428+
emp_details["total_taxable_amount"],
429+
tax_slab,
430+
eval_globals=eval_globals,
431+
eval_locals=eval_locals,
429432
)
430433
else:
431434
tax_amount = 0.0
@@ -434,6 +437,28 @@ def get_applicable_tax(self):
434437
tax_amount = rounded(tax_amount)
435438
emp_details["applicable_tax"] = tax_amount
436439

440+
def get_data_for_eval(self, emp: str, emp_details: dict) -> tuple:
441+
last_ss = self.get_last_salary_slip(emp)
442+
443+
if last_ss:
444+
salary_slip = frappe.get_cached_doc("Salary Slip", last_ss.name)
445+
else:
446+
salary_slip = frappe.new_doc("Salary Slip")
447+
salary_slip.employee = emp
448+
salary_slip.salary_structure = emp_details.salary_structure
449+
salary_slip.start_date = self.payroll_period_start_date
450+
salary_slip.payroll_frequency = frappe.db.get_value(
451+
"Salary Structure", emp_details.salary_structure, "payroll_frequency"
452+
)
453+
salary_slip.end_date = get_start_end_dates(
454+
salary_slip.payroll_frequency, salary_slip.start_date
455+
).end_date
456+
salary_slip.process_salary_structure()
457+
458+
eval_locals, __ = salary_slip.get_data_for_eval()
459+
460+
return salary_slip.whitelisted_globals, eval_locals
461+
437462
def get_total_deducted_tax(self):
438463
self.add_column("Total Tax Deducted")
439464

hrms/regional/india/utils.py

+7-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,13 @@ def calculate_annual_eligible_hra_exemption(doc):
3030
_("Salary Structure must be submitted before submission of {0}").format(doc.doctype)
3131
)
3232

33-
assignment_dates = [assignment.from_date for assignment in assignments]
33+
period_start_date = frappe.db.get_value("Payroll Period", doc.payroll_period, "start_date")
34+
35+
assignment_dates = []
36+
for assignment in assignments:
37+
# if assignment is before payroll period, use period start date to get the correct days
38+
assignment.from_date = max(assignment.from_date, period_start_date)
39+
assignment_dates.append(assignment.from_date)
3440

3541
for idx, assignment in enumerate(assignments):
3642
if has_hra_component(assignment.salary_structure, hra_component):

0 commit comments

Comments
 (0)