Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: release v14 #2075

Merged
merged 10 commits into from
Aug 15, 2024
29 changes: 27 additions & 2 deletions hrms/hr/doctype/employee_checkin/employee_checkin.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,31 @@
// For license information, please see license.txt

frappe.ui.form.on("Employee Checkin", {
// setup: (frm) => {
// }
refresh: async (frm) => {
if (!frm.doc.__islocal) frm.trigger("add_fetch_shift_button");
},

add_fetch_shift_button(frm) {
if (frm.doc.attendace) return;
frm.add_custom_button(__("Fetch Shift"), function () {
const previous_shift = frm.doc.shift;
frappe.call({
method: "fetch_shift",
doc: frm.doc,
freeze: true,
freeze_message: __("Fetching Shift"),
callback: function () {
if (previous_shift === frm.doc.shift) return;
frm.dirty();
frm.save();
frappe.show_alert({
message: __("Shift has been successfully updated to {0}.", [
frm.doc.shift,
]),
indicator: "green",
});
},
});
});
},
});
58 changes: 36 additions & 22 deletions hrms/hr/doctype/employee_checkin/employee_checkin.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,30 +35,33 @@ def validate_duplicate_log(self):
_("This employee already has a log with the same timestamp.{0}").format("<Br>" + doc_link)
)

@frappe.whitelist()
def fetch_shift(self):
shift_actual_timings = get_actual_start_end_datetime_of_shift(
self.employee, get_datetime(self.time), True
)
if shift_actual_timings:
if (
shift_actual_timings.shift_type.determine_check_in_and_check_out
== "Strictly based on Log Type in Employee Checkin"
and not self.log_type
and not self.skip_auto_attendance
):
frappe.throw(
_("Log Type is required for check-ins falling in the shift: {0}.").format(
shift_actual_timings.shift_type.name
)
)
if not self.attendance:
self.shift = shift_actual_timings.shift_type.name
self.shift_actual_start = shift_actual_timings.actual_start
self.shift_actual_end = shift_actual_timings.actual_end
self.shift_start = shift_actual_timings.start_datetime
self.shift_end = shift_actual_timings.end_datetime
else:
if not (
shift_actual_timings := get_actual_start_end_datetime_of_shift(
self.employee, get_datetime(self.time), True
)
):
self.shift = None
return

if (
shift_actual_timings.shift_type.determine_check_in_and_check_out
== "Strictly based on Log Type in Employee Checkin"
and not self.log_type
and not self.skip_auto_attendance
):
frappe.throw(
_("Log Type is required for check-ins falling in the shift: {0}.").format(
shift_actual_timings.shift_type.name
)
)
if not self.attendance:
self.shift = shift_actual_timings.shift_type.name
self.shift_actual_start = shift_actual_timings.actual_start
self.shift_actual_end = shift_actual_timings.actual_end
self.shift_start = shift_actual_timings.start_datetime
self.shift_end = shift_actual_timings.end_datetime


@frappe.whitelist()
Expand Down Expand Up @@ -111,6 +114,17 @@ def add_log_based_on_employee_field(
return doc


@frappe.whitelist()
def bulk_fetch_shift(checkins: list[str] | str) -> None:
if isinstance(checkins, str):
checkins = frappe.json.loads(checkins)
for d in checkins:
doc = frappe.get_doc("Employee Checkin", d)
doc.fetch_shift()
doc.flags.ignore_validate = True
doc.save()


def mark_attendance_and_link_log(
logs,
attendance_status,
Expand Down
14 changes: 14 additions & 0 deletions hrms/hr/doctype/employee_checkin/employee_checkin_list.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
frappe.listview_settings["Employee Checkin"] = {
onload: function (listview) {
listview.page.add_action_item(__("Fetch Shifts"), () => {
const checkins = listview.get_checked_items().map((checkin) => checkin.name);
frappe.call({
method: "hrms.hr.doctype.employee_checkin.employee_checkin.bulk_fetch_shift",
freeze: true,
args: {
checkins,
},
});
});
},
};
35 changes: 35 additions & 0 deletions hrms/hr/doctype/employee_checkin/test_employee_checkin.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

from hrms.hr.doctype.employee_checkin.employee_checkin import (
add_log_based_on_employee_field,
bulk_fetch_shift,
calculate_working_hours,
mark_attendance_and_link_log,
)
Expand Down Expand Up @@ -457,6 +458,40 @@ def test_consecutive_shift_assignments_overlapping_within_grace_period(self):
log = make_checkin(employee, timestamp)
self.assertEqual(log.shift, shift2.name)

def test_bulk_fetch_shift(self):
emp1 = make_employee("[email protected]", company="_Test Company")
emp2 = make_employee("[email protected]", company="_Test Company")

# 8 - 12
shift1 = setup_shift_type(shift_type="Shift 1")
# 12:30 - 16:30
shift2 = setup_shift_type(shift_type="Shift 2", start_time="12:30:00", end_time="16:30:00")

frappe.db.set_value("Employee", emp1, "default_shift", shift1.name)
frappe.db.set_value("Employee", emp2, "default_shift", shift1.name)

date = getdate()
timestamp = datetime.combine(date, get_time("12:30:00"))

log1 = make_checkin(emp1, timestamp)
self.assertEqual(log1.shift, shift1.name)
log2 = make_checkin(emp2, timestamp)
self.assertEqual(log2.shift, shift1.name)

mark_attendance_and_link_log([log2], "Present", date)

make_shift_assignment(shift2.name, emp1, date)
make_shift_assignment(shift2.name, emp2, date)

bulk_fetch_shift([log1.name, log2.name])

log1.reload()
# shift changes according to the new assignment
self.assertEqual(log1.shift, shift2.name)
log2.reload()
# shift does not change since attendance is already marked
self.assertEqual(log2.shift, shift1.name)


def make_n_checkins(employee, n, hours_to_reverse=1):
logs = [make_checkin(employee, now_datetime() - timedelta(hours=hours_to_reverse, minutes=n + 1))]
Expand Down
21 changes: 11 additions & 10 deletions hrms/hr/doctype/expense_claim/expense_claim.js
Original file line number Diff line number Diff line change
Expand Up @@ -282,17 +282,18 @@ frappe.ui.form.on("Expense Claim", {
}
});
},

get_taxes: function (frm) {
if (frm.doc.taxes) {
frappe.call({
method: "calculate_taxes",
doc: frm.doc,
callback: () => {
refresh_field("taxes");
frm.trigger("update_employee_advance_claimed_amount");
},
});
}
if (!frm.doc.taxes.length) return;

frappe.call({
method: "calculate_taxes",
doc: frm.doc,
callback: () => {
refresh_field("taxes");
frm.trigger("update_employee_advance_claimed_amount");
},
});
},

get_advances: function (frm) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@
},
{
"hidden": 0,
"is_query_report": 0,
"is_query_report": 1,
"label": "Daily Work Summary Replies",
"link_count": 0,
"link_to": "Daily Work Summary Replies",
Expand Down Expand Up @@ -287,7 +287,7 @@
"type": "Link"
}
],
"modified": "2022-09-16 11:35:33.462001",
"modified": "2024-08-11 11:35:33.462001",
"modified_by": "Administrator",
"module": "HR",
"name": "Employee Lifecycle",
Expand Down Expand Up @@ -350,4 +350,4 @@
}
],
"title": "Employee Lifecycle"
}
}
10 changes: 5 additions & 5 deletions hrms/hr/workspace/expense_claims/expense_claims.json
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@
},
{
"hidden": 0,
"is_query_report": 0,
"is_query_report": 1,
"label": "Accounts Receivable",
"link_count": 0,
"link_to": "Accounts Receivable",
Expand All @@ -179,7 +179,7 @@
},
{
"hidden": 0,
"is_query_report": 0,
"is_query_report": 1,
"label": "Accounts Payable",
"link_count": 0,
"link_to": "Accounts Payable",
Expand All @@ -189,7 +189,7 @@
},
{
"hidden": 0,
"is_query_report": 0,
"is_query_report": 1,
"label": "General Ledger",
"link_count": 0,
"link_to": "General Ledger",
Expand Down Expand Up @@ -256,7 +256,7 @@
"type": "Link"
}
],
"modified": "2024-02-05 09:10:45.636550",
"modified": "2024-08-11 11:40:45.636550",
"modified_by": "Administrator",
"module": "HR",
"name": "Expense Claims",
Expand Down Expand Up @@ -295,4 +295,4 @@
}
],
"title": "Expense Claims"
}
}
6 changes: 3 additions & 3 deletions hrms/hr/workspace/hr/hr.json
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@
},
{
"hidden": 0,
"is_query_report": 0,
"is_query_report": 1,
"label": "Employee Exits",
"link_count": 0,
"link_to": "Employee Exits",
Expand Down Expand Up @@ -385,7 +385,7 @@
"type": "Link"
}
],
"modified": "2022-12-06 16:55:59.080694",
"modified": "2024-10-10 16:55:59.080694",
"modified_by": "Administrator",
"module": "HR",
"name": "HR",
Expand Down Expand Up @@ -449,4 +449,4 @@
}
],
"title": "HR"
}
}
10 changes: 5 additions & 5 deletions hrms/payroll/workspace/salary_payout/salary_payout.json
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@
},
{
"hidden": 0,
"is_query_report": 0,
"is_query_report": 1,
"label": "General Ledger",
"link_count": 0,
"link_to": "General Ledger",
Expand All @@ -328,7 +328,7 @@
},
{
"hidden": 0,
"is_query_report": 0,
"is_query_report": 1,
"label": "Accounts Payable",
"link_count": 0,
"link_to": "Accounts Payable",
Expand All @@ -338,7 +338,7 @@
},
{
"hidden": 0,
"is_query_report": 0,
"is_query_report": 1,
"label": "Accounts Receivable",
"link_count": 0,
"link_to": "Accounts Receivable",
Expand Down Expand Up @@ -385,7 +385,7 @@
"type": "Link"
}
],
"modified": "2022-09-21 12:27:38.631110",
"modified": "2024-08-11 11:45:37.351654",
"modified_by": "Administrator",
"module": "Payroll",
"name": "Salary Payout",
Expand Down Expand Up @@ -423,4 +423,4 @@
}
],
"title": "Salary Payout"
}
}
Loading