Skip to content

Commit

Permalink
Merge pull request #1523 from frappe/version-14-hotfix
Browse files Browse the repository at this point in the history
chore: release v14
  • Loading branch information
ruchamahabal authored Mar 13, 2024
2 parents ac4ec7b + bf6c4bd commit a046767
Show file tree
Hide file tree
Showing 9 changed files with 93 additions and 14 deletions.
8 changes: 6 additions & 2 deletions hrms/hr/doctype/leave_ledger_entry/leave_ledger_entry.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import frappe
from frappe import _
from frappe.model.document import Document
from frappe.utils import DATE_FORMAT, flt, getdate, today
from frappe.utils import DATE_FORMAT, flt, get_link_to_form, getdate, today


class LeaveLedgerEntry(Document):
Expand Down Expand Up @@ -40,7 +40,11 @@ def validate_leave_allocation_against_leave_application(ledger):
if leave_application_records:
frappe.throw(
_("Leave allocation {0} is linked with the Leave Application {1}").format(
ledger.transaction_name, ", ".join(leave_application_records)
ledger.transaction_name,
", ".join(
get_link_to_form("Leave Application", application)
for application in leave_application_records
),
)
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,22 @@ frappe.listview_settings['Leave Policy Assignment'] = {
{
fieldname: 'assignment_based_on',
fieldtype: 'Select',
options: ["", "Leave Period"],
options: ["", "Leave Period", "Joining Date"],
label: __('Assignment Based On'),
onchange: () => {
if (cur_dialog.fields_dict.assignment_based_on.value === "Leave Period") {
cur_dialog.set_df_property("effective_from", "reqd", 1);
cur_dialog.set_df_property("effective_from", "hidden", 0);
cur_dialog.set_df_property("effective_from", "read_only", 1);
cur_dialog.set_df_property("leave_period", "reqd", 1);
cur_dialog.set_df_property("effective_to", "read_only", 1);
} else if (cur_dialog.fields_dict.assignment_based_on.value === "Joining Date") {
cur_dialog.set_df_property("effective_from", "reqd", 0);
cur_dialog.set_df_property("effective_from", "hidden", 1);
cur_dialog.set_value("effective_from", "");
} else {
cur_dialog.set_df_property("effective_from", "reqd", 1);
cur_dialog.set_df_property("effective_from", "hidden", 0);
cur_dialog.set_df_property("effective_from", "read_only", 0);
cur_dialog.set_df_property("leave_period", "reqd", 0);
cur_dialog.set_df_property("effective_to", "read_only", 0);
Expand Down
5 changes: 4 additions & 1 deletion hrms/hr/doctype/shift_assignment/shift_assignment.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,11 +171,14 @@ def get_shift_assignments(start: str, end: str, filters: str | list | None = Non
if not filters:
filters = []

filters.extend([["start_date", ">=", start], ["end_date", "<=", end], ["docstatus", "=", 1]])
filters.extend([["start_date", "<=", end], ["docstatus", "=", 1]])

or_filters = [["end_date", ">=", start], ["end_date", "is", "not set"]]

return frappe.get_list(
"Shift Assignment",
filters=filters,
or_filters=or_filters,
fields=[
"name",
"start_date",
Expand Down
25 changes: 20 additions & 5 deletions hrms/hr/doctype/shift_assignment/test_shift_assignment.py
Original file line number Diff line number Diff line change
Expand Up @@ -230,17 +230,32 @@ def test_multiple_shift_assignments_for_same_day(self):
def test_calendar(self):
employee1 = make_employee("test_shift_assignment1@example.com", company="_Test Company")
employee2 = make_employee("test_shift_assignment2@example.com", company="_Test Company")
employee3 = make_employee("test_shift_assignment3@example.com", company="_Test Company")

shift_type = setup_shift_type(shift_type="Shift 1", start_time="08:00:00", end_time="12:00:00")
date = getdate()
shift1 = make_shift_assignment(shift_type.name, employee1, date)
make_shift_assignment(shift_type.name, employee2, date)
shift1 = make_shift_assignment(shift_type.name, employee1, date) # 1 day
make_shift_assignment(shift_type.name, employee2, date) # excluded due to employee filter
make_shift_assignment(
shift_type.name, employee3, add_days(date, -3), add_days(date, -2)
) # excluded
shift2 = make_shift_assignment(shift_type.name, employee3, add_days(date, -1), date) # 2 days
shift3 = make_shift_assignment(
shift_type.name, employee3, add_days(date, 1), add_days(date, 2)
) # 2 days
shift4 = make_shift_assignment(
shift_type.name, employee3, add_days(date, 30), add_days(date, 30)
) # 1 day
make_shift_assignment(shift_type.name, employee3, add_days(date, 31)) # excluded

events = get_events(
start=date, end=date, filters=[["Shift Assignment", "employee", "=", employee1, False]]
start=date,
end=add_days(date, 30),
filters=[["Shift Assignment", "employee", "!=", employee2, False]],
)
self.assertEqual(len(events), 1)
self.assertEqual(events[0]["name"], shift1.name)
self.assertEqual(len(events), 6)
for shift in events:
self.assertIn(shift["name"], [shift1.name, shift2.name, shift3.name, shift4.name])

def test_calendar_for_night_shift(self):
employee1 = make_employee("test_shift_assignment1@example.com", company="_Test Company")
Expand Down
2 changes: 1 addition & 1 deletion hrms/hr/page/organizational_chart/organizational_chart.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def get_connections(employee: str, lft: int, rgt: int) -> int:
query = (
frappe.qb.from_(Employee)
.select(Count(Employee.name))
.where((Employee.lft > lft) & (Employee.rgt < rgt))
.where((Employee.lft > lft) & (Employee.rgt < rgt) & (Employee.status == "Active"))
).run()

return query[0][0]
2 changes: 1 addition & 1 deletion hrms/payroll/doctype/payroll_entry/payroll_entry.py
Original file line number Diff line number Diff line change
Expand Up @@ -1367,7 +1367,7 @@ def employee_query(doctype, txt, searchfield, start, page_len, filters):
]
filters.pop("start_date")
filters.pop("end_date")
if filters.get("salary_slip_based_on_timesheet"):
if "salary_slip_based_on_timesheet" in filters:
filters.pop("salary_slip_based_on_timesheet")
filters.pop("payroll_frequency")
filters.pop("payroll_payable_account")
Expand Down
2 changes: 1 addition & 1 deletion hrms/payroll/doctype/salary_slip/salary_slip.py
Original file line number Diff line number Diff line change
Expand Up @@ -670,7 +670,7 @@ def calculate_lwp_ppl_and_absent_days_based_on_attendance(self, holidays, reliev
not consider_marked_attendance_on_holidays
and formatdate(d.attendance_date, "yyyy-mm-dd") in holidays
):
if d.status == "Absent" or (
if d.status in ["Absent", "Half Day"] or (
d.leave_type
and d.leave_type in leave_type_map.keys()
and not leave_type_map[d.leave_type]["include_holiday"]
Expand Down
49 changes: 49 additions & 0 deletions hrms/payroll/doctype/salary_slip/test_salary_slip.py
Original file line number Diff line number Diff line change
Expand Up @@ -556,6 +556,55 @@ def test_consider_marked_attendance_on_holidays_with_unmarked_attendance(self):
# no_of_days - period before DOJ
self.assertEqual(ss.payment_days, no_of_days[0] - 3 - 1)

@change_settings(
"Payroll Settings",
{
"payroll_based_on": "Attendance",
"consider_unmarked_attendance_as": "Present",
"include_holidays_in_total_working_days": 1,
"consider_marked_attendance_on_holidays": 0,
},
)
def test_consider_marked_attendance_on_holidays_with_half_day_on_holiday(self):
from erpnext.setup.doctype.holiday_list.holiday_list import is_holiday

no_of_days = get_no_of_days()
month_start_date, month_end_date = get_first_day(nowdate()), get_last_day(nowdate())
joining_date = add_days(month_start_date, 3)

emp_id = make_employee(
"test_salary_slip_with_holidays_included1@salary.com",
status="Active",
date_of_joining=joining_date,
relieving_date=None,
)

for days in range(date_diff(month_end_date, joining_date) + 1):
date = add_days(joining_date, days)
if not is_holiday("Salary Slip Test Holiday List", date):
mark_attendance(emp_id, date, "Present", ignore_validate=True)

# mark half day on holiday
first_sunday = get_first_sunday(for_date=joining_date, find_after_for_date=True)
mark_attendance(emp_id, first_sunday, "Half Day", ignore_validate=True)

ss = make_employee_salary_slip(
emp_id,
"Monthly",
"Test Salary Slip With Holidays Included",
)

self.assertEqual(ss.total_working_days, no_of_days[0])
# no_of_days - period before DOJ
self.assertEqual(ss.payment_days, no_of_days[0] - 3)

# enable consider marked attendance on holidays
frappe.db.set_single_value("Payroll Settings", "consider_marked_attendance_on_holidays", 1)
ss.save()
self.assertEqual(ss.total_working_days, no_of_days[0])
# no_of_days - period before DOJ - 0.5 LWP on holiday (half day present)
self.assertEqual(ss.payment_days, no_of_days[0] - 3 - 0.5)

@change_settings("Payroll Settings", {"include_holidays_in_total_working_days": 1})
def test_payment_days(self):
from hrms.payroll.doctype.salary_structure.test_salary_structure import (
Expand Down
4 changes: 2 additions & 2 deletions hrms/public/js/erpnext/journal_entry.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ frappe.ui.form.on("Journal Entry", {
]
};

if (in_list(["Sales Invoice", "Purchase Invoice"], jvd.reference_type)) {
if (["Sales Invoice", "Purchase Invoice"].includes(jvd.reference_type)) {
out.filters.push([jvd.reference_type, "outstanding_amount", "!=", 0]);
// Filter by cost center
if (jvd.cost_center) {
Expand All @@ -61,7 +61,7 @@ frappe.ui.form.on("Journal Entry", {
out.filters.push([jvd.reference_type, party_account_field, "=", jvd.account]);
}

if (in_list(["Sales Order", "Purchase Order"], jvd.reference_type)) {
if (["Sales Order", "Purchase Order"].includes(jvd.reference_type)) {
// party_type and party mandatory
frappe.model.validate_missing(jvd, "party_type");
frappe.model.validate_missing(jvd, "party");
Expand Down

0 comments on commit a046767

Please sign in to comment.