Skip to content

Commit f34c033

Browse files
authored
Merge pull request #1777 from frappe/version-14-hotfix
chore: release v14
2 parents 77bb054 + 2f9ff31 commit f34c033

File tree

16 files changed

+111
-170
lines changed

16 files changed

+111
-170
lines changed

hrms/hr/doctype/shift_assignment/shift_assignment.py

+2-23
Original file line numberDiff line numberDiff line change
@@ -80,33 +80,12 @@ def get_overlapping_dates(self):
8080
& (shift.docstatus == 1)
8181
& (shift.name != self.name)
8282
& (shift.status == "Active")
83+
& ((shift.end_date >= self.start_date) | (shift.end_date.isnull()))
8384
)
8485
)
8586

8687
if self.end_date:
87-
query = query.where(
88-
Criterion.any(
89-
[
90-
Criterion.any(
91-
[
92-
shift.end_date.isnull(),
93-
((self.start_date >= shift.start_date) & (self.start_date <= shift.end_date)),
94-
]
95-
),
96-
Criterion.any(
97-
[
98-
((self.end_date >= shift.start_date) & (self.end_date <= shift.end_date)),
99-
shift.start_date.between(self.start_date, self.end_date),
100-
]
101-
),
102-
]
103-
)
104-
)
105-
else:
106-
query = query.where(
107-
shift.end_date.isnull()
108-
| ((self.start_date >= shift.start_date) & (self.start_date <= shift.end_date))
109-
)
88+
query = query.where(shift.start_date <= self.end_date)
11089

11190
return query.run(as_dict=True)
11291

hrms/hr/doctype/shift_assignment/test_shift_assignment.py

+10-54
Original file line numberDiff line numberDiff line change
@@ -23,39 +23,18 @@ def setUp(self):
2323
frappe.db.delete("Shift Assignment")
2424
frappe.db.delete("Shift Type")
2525

26-
def test_make_shift_assignment(self):
27-
setup_shift_type(shift_type="Day Shift")
28-
shift_assignment = frappe.get_doc(
29-
{
30-
"doctype": "Shift Assignment",
31-
"shift_type": "Day Shift",
32-
"company": "_Test Company",
33-
"employee": "_T-Employee-00001",
34-
"start_date": nowdate(),
35-
}
36-
).insert()
37-
shift_assignment.submit()
38-
39-
self.assertEqual(shift_assignment.docstatus, 1)
40-
4126
def test_overlapping_for_ongoing_shift(self):
4227
# shift should be Ongoing if Only start_date is present and status = Active
4328
setup_shift_type(shift_type="Day Shift")
44-
shift_assignment_1 = frappe.get_doc(
45-
{
46-
"doctype": "Shift Assignment",
47-
"shift_type": "Day Shift",
48-
"company": "_Test Company",
49-
"employee": "_T-Employee-00001",
50-
"start_date": nowdate(),
51-
"status": "Active",
52-
}
53-
).insert()
54-
shift_assignment_1.submit()
29+
make_shift_assignment("Day Shift", "_T-Employee-00001", nowdate())
5530

56-
self.assertEqual(shift_assignment_1.docstatus, 1)
31+
# shift ends before ongoing shift starts
32+
non_overlapping_shift = make_shift_assignment(
33+
"Day Shift", "_T-Employee-00001", add_days(nowdate(), -1), add_days(nowdate(), -1)
34+
)
35+
self.assertEqual(non_overlapping_shift.docstatus, 1)
5736

58-
shift_assignment = frappe.get_doc(
37+
overlapping_shift = frappe.get_doc(
5938
{
6039
"doctype": "Shift Assignment",
6140
"shift_type": "Day Shift",
@@ -64,23 +43,11 @@ def test_overlapping_for_ongoing_shift(self):
6443
"start_date": add_days(nowdate(), 2),
6544
}
6645
)
67-
68-
self.assertRaises(OverlappingShiftError, shift_assignment.save)
46+
self.assertRaises(OverlappingShiftError, overlapping_shift.save)
6947

7048
def test_multiple_shift_assignments_for_same_date(self):
7149
setup_shift_type(shift_type="Day Shift")
72-
shift_assignment_1 = frappe.get_doc(
73-
{
74-
"doctype": "Shift Assignment",
75-
"shift_type": "Day Shift",
76-
"company": "_Test Company",
77-
"employee": "_T-Employee-00001",
78-
"start_date": nowdate(),
79-
"end_date": add_days(nowdate(), 30),
80-
"status": "Active",
81-
}
82-
).insert()
83-
shift_assignment_1.submit()
50+
make_shift_assignment("Day Shift", "_T-Employee-00001", nowdate(), add_days(nowdate(), 30))
8451

8552
setup_shift_type(shift_type="Night Shift", start_time="19:00:00", end_time="23:00:00")
8653
shift_assignment_2 = frappe.get_doc(
@@ -103,18 +70,7 @@ def test_multiple_shift_assignments_for_same_date(self):
10370
def test_overlapping_for_fixed_period_shift(self):
10471
# shift should is for Fixed period if Only start_date and end_date both are present and status = Active
10572
setup_shift_type(shift_type="Day Shift")
106-
shift_assignment_1 = frappe.get_doc(
107-
{
108-
"doctype": "Shift Assignment",
109-
"shift_type": "Day Shift",
110-
"company": "_Test Company",
111-
"employee": "_T-Employee-00001",
112-
"start_date": nowdate(),
113-
"end_date": add_days(nowdate(), 30),
114-
"status": "Active",
115-
}
116-
).insert()
117-
shift_assignment_1.submit()
73+
make_shift_assignment("Day Shift", "_T-Employee-00001", nowdate(), add_days(nowdate(), 30))
11874

11975
# it should not allowed within period of any shift.
12076
shift_assignment_3 = frappe.get_doc(

hrms/hr/doctype/shift_request/shift_request.py

+7-24
Original file line numberDiff line numberDiff line change
@@ -97,33 +97,16 @@ def get_overlapping_dates(self):
9797
query = (
9898
frappe.qb.from_(shift)
9999
.select(shift.name, shift.shift_type)
100-
.where((shift.employee == self.employee) & (shift.docstatus < 2) & (shift.name != self.name))
100+
.where(
101+
(shift.employee == self.employee)
102+
& (shift.docstatus < 2)
103+
& (shift.name != self.name)
104+
& ((shift.to_date >= self.from_date) | (shift.to_date.isnull()))
105+
)
101106
)
102107

103108
if self.to_date:
104-
query = query.where(
105-
Criterion.any(
106-
[
107-
Criterion.any(
108-
[
109-
shift.to_date.isnull(),
110-
((self.from_date >= shift.from_date) & (self.from_date <= shift.to_date)),
111-
]
112-
),
113-
Criterion.any(
114-
[
115-
((self.to_date >= shift.from_date) & (self.to_date <= shift.to_date)),
116-
shift.from_date.between(self.from_date, self.to_date),
117-
]
118-
),
119-
]
120-
)
121-
)
122-
else:
123-
query = query.where(
124-
shift.to_date.isnull()
125-
| ((self.from_date >= shift.from_date) & (self.from_date <= shift.to_date))
126-
)
109+
query = query.where(shift.from_date <= self.to_date)
127110

128111
return query.run(as_dict=True)
129112

hrms/payroll/doctype/payroll_period/payroll_period.js

+31-1
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,35 @@
22
// For license information, please see license.txt
33

44
frappe.ui.form.on("Payroll Period", {
5-
refresh: function (frm) {},
5+
onload: function (frm) {
6+
frm.trigger("set_start_date");
7+
},
8+
9+
set_start_date: function (frm) {
10+
if (!frm.doc.__islocal) return;
11+
12+
frappe.db
13+
.get_list("Payroll Period", {
14+
fields: ["end_date"],
15+
order_by: "end_date desc",
16+
limit: 1,
17+
})
18+
.then((result) => {
19+
// set start date based on end date of the last payroll period if found
20+
// else set it based on the current fiscal year's start date
21+
if (result.length) {
22+
const last_end_date = result[0].end_date;
23+
frm.set_value("start_date", frappe.datetime.add_days(last_end_date, 1));
24+
} else {
25+
frm.set_value("start_date", frappe.defaults.get_default("year_start_date"));
26+
}
27+
});
28+
},
29+
30+
start_date: function (frm) {
31+
frm.set_value(
32+
"end_date",
33+
frappe.datetime.add_days(frappe.datetime.add_months(frm.doc.start_date, 12), -1),
34+
);
35+
},
636
});

hrms/payroll/doctype/payroll_period/payroll_period.json

+3-4
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
}
5454
],
5555
"links": [],
56-
"modified": "2024-05-05 14:50:12.419714",
56+
"modified": "2024-05-07 17:27:51.903593",
5757
"modified_by": "Administrator",
5858
"module": "Payroll",
5959
"name": "Payroll Period",
@@ -105,8 +105,7 @@
105105
"write": 1
106106
}
107107
],
108-
"quick_entry": 1,
109-
"sort_field": "modified",
108+
"sort_field": "creation",
110109
"sort_order": "DESC",
111110
"track_changes": 1
112-
}
111+
}

hrms/payroll/doctype/salary_slip/salary_slip.py

+1
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ def __init__(self, *args, **kwargs):
6464
"float": float,
6565
"long": int,
6666
"round": round,
67+
"rounded": rounded,
6768
"date": date,
6869
"getdate": getdate,
6970
"ceil": ceil,

hrms/payroll/doctype/salary_structure_assignment/salary_structure_assignment.js

+36
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,15 @@ frappe.ui.form.on("Salary Structure Assignment", {
5858
frm.doc.__onload.earning_and_deduction_entries_does_not_exists;
5959
frm.trigger("set_earnings_and_taxation_section_visibility");
6060
}
61+
62+
if (frm.doc.docstatus === 1)
63+
frm.add_custom_button(
64+
__("Preview Salary Slip"),
65+
function () {
66+
frm.trigger("preview_salary_slip");
67+
},
68+
__("Actions"),
69+
);
6170
},
6271

6372
employee: function (frm) {
@@ -82,6 +91,33 @@ frappe.ui.form.on("Salary Structure Assignment", {
8291
}
8392
},
8493

94+
preview_salary_slip: function (frm) {
95+
frappe.db.get_value(
96+
"Salary Structure",
97+
frm.doc.salary_structure,
98+
"salary_slip_based_on_timesheet",
99+
(r) => {
100+
const print_format = r.salary_slip_based_on_timesheet
101+
? "Salary Slip based on Timesheet"
102+
: "Salary Slip Standard";
103+
frappe.call({
104+
method: "hrms.payroll.doctype.salary_structure.salary_structure.make_salary_slip",
105+
args: {
106+
source_name: frm.doc.salary_structure,
107+
employee: frm.doc.employee,
108+
as_print: 1,
109+
print_format: print_format,
110+
for_preview: 1,
111+
},
112+
callback: function (r) {
113+
const new_window = window.open();
114+
new_window.document.write(r.message);
115+
},
116+
});
117+
},
118+
);
119+
},
120+
85121
set_payroll_cost_centers: function (frm) {
86122
if (frm.doc.payroll_cost_centers && frm.doc.payroll_cost_centers.length < 1) {
87123
frappe.call({

hrms/payroll/module_onboarding/payroll/payroll.json

+3-9
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,15 @@
1010
"creation": "2020-06-01 12:10:52.560472",
1111
"docstatus": 0,
1212
"doctype": "Module Onboarding",
13-
"documentation_url": "https://docs.erpnext.com/docs/user/manual/en/human-resources/payroll-entry",
13+
"documentation_url": "https://frappehr.com/docs/v14/en/payroll-entry",
1414
"idx": 0,
1515
"is_complete": 0,
16-
"modified": "2020-07-08 14:06:13.994310",
16+
"modified": "2024-05-07 17:44:05.258878",
1717
"modified_by": "Administrator",
1818
"module": "Payroll",
1919
"name": "Payroll",
2020
"owner": "Administrator",
2121
"steps": [
22-
{
23-
"step": "Create Employee"
24-
},
2522
{
2623
"step": "Create Salary Component"
2724
},
@@ -32,10 +29,7 @@
3229
"step": "Create Income Tax Slab"
3330
},
3431
{
35-
"step": "Create Salary Structure"
36-
},
37-
{
38-
"step": "Assign Salary Structure"
32+
"step": "Create & Assign Salary Structure"
3933
},
4034
{
4135
"step": "Create Salary Slip"

hrms/payroll/onboarding_step/assign_salary_structure/assign_salary_structure.json

-19
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
{
22
"action": "Create Entry",
3-
"creation": "2020-06-01 11:57:54.527808",
3+
"creation": "2024-01-11 13:25:28.533290",
44
"docstatus": 0,
55
"doctype": "Onboarding Step",
66
"idx": 0,
77
"is_complete": 0,
8-
"is_mandatory": 1,
98
"is_single": 0,
109
"is_skipped": 0,
11-
"modified": "2020-06-01 11:57:54.527808",
10+
"modified": "2024-05-07 17:34:43.473732",
1211
"modified_by": "Administrator",
13-
"name": "Create Salary Structure",
12+
"name": "Create & Assign Salary Structure",
1413
"owner": "Administrator",
1514
"reference_document": "Salary Structure",
15+
"show_form_tour": 0,
1616
"show_full_form": 1,
17-
"title": "Create Salary Structure",
17+
"title": "Create & Assign Salary Structure",
1818
"validate_action": 1
1919
}

hrms/payroll/onboarding_step/create_employee/create_employee.json

-19
This file was deleted.

0 commit comments

Comments
 (0)