feat: get carry forwarded leaves via ledger entries

This commit is contained in:
Mangesh-Khairnar 2019-05-09 19:43:35 +05:30
parent 2b421c39b5
commit 679371e397
4 changed files with 293 additions and 871 deletions

View File

@ -34,33 +34,36 @@ frappe.ui.form.on("Leave Allocation", {
}, },
carry_forwarded_leaves: function(frm) { carry_forwarded_leaves: function(frm) {
frm.set_value("total_leaves_allocated", flt(frm.doc.carry_forwarded_leaves)); frm.set_value("total_leaves_allocated",
flt(frm.doc.carry_forwarded_leaves) + flt(frm.doc.new_leaves_allocated));
}, },
new_leaves_allocated: function(frm) { new_leaves_allocated: function(frm) {
frm.set_value("total_leaves_allocated", flt(frm.doc.new_leaves_allocated)); frm.set_value("total_leaves_allocated",
flt(frm.doc.carry_forwarded_leaves) + flt(frm.doc.new_leaves_allocated));
}, },
calculate_total_leaves_allocated: function(frm) { calculate_total_leaves_allocated: function(frm) {
if (cint(frm.doc.carry_forward) === 1 && frm.doc.leave_type && frm.doc.employee) { if (cint(frm.doc.carry_forward) == 1 && frm.doc.leave_type && frm.doc.employee) {
return frappe.call({ return frappe.call({
method: "erpnext.hr.doctype.leave_allocation.leave_allocation.get_carry_forwarded_leaves", method: "erpnext.hr.doctype.leave_allocation.leave_allocation.get_carry_forwarded_leaves",
args: { args: {
"employee": frm.doc.employee, "employee": frm.doc.employee,
"leave_type": frm.doc.leave_type,
"date": frm.doc.from_date, "date": frm.doc.from_date,
"leave_type": frm.doc.leave_type,
"carry_forward": frm.doc.carry_forward
}, },
callback: function(r) { callback: function(r) {
if (!r.exc && r.message) { if (!r.exc && r.message) {
frm.set_value("new_leaves_allocated", 0);
frm.set_value('carry_forwarded_leaves', r.message); frm.set_value('carry_forwarded_leaves', r.message);
frm.set_value("total_leaves_allocated", flt(r.message)); frm.set_value("total_leaves_allocated",
flt(r.message) + flt(frm.doc.new_leaves_allocated));
} }
} }
}) })
} else if (cint(frm.doc.carry_forward) === 0) { } else if (cint(frm.doc.carry_forward) == 0) {
frm.set_value("carry_forwarded_leaves", 0); frm.set_value("carry_forwarded_leaves", 0);
frm.set_value("total_leaves_allocated", flt(frm.doc.new_leaves_allocated)); frm.set_value("total_leaves_allocated", flt(frm.doc.new_leaves_allocated));
} }
} }
}) })

View File

@ -1,736 +1,231 @@
{ {
"allow_copy": 0, "allow_import": 1,
"allow_events_in_timeline": 0, "autoname": "naming_series:",
"allow_guest_to_view": 0, "creation": "2013-02-20 19:10:38",
"allow_import": 1, "doctype": "DocType",
"allow_rename": 0, "document_type": "Setup",
"autoname": "naming_series:", "engine": "InnoDB",
"beta": 0, "field_order": [
"creation": "2013-02-20 19:10:38", "naming_series",
"custom": 0, "employee",
"docstatus": 0, "employee_name",
"doctype": "DocType", "department",
"document_type": "Setup", "column_break1",
"editable_grid": 0, "leave_type",
"engine": "InnoDB", "from_date",
"fields": [ "to_date",
{ "section_break_6",
"allow_bulk_edit": 0, "new_leaves_allocated",
"allow_in_quick_entry": 0, "carry_forward",
"allow_on_submit": 0, "carry_forwarded_leaves",
"bold": 0, "total_leaves_allocated",
"collapsible": 0, "total_leaves_encashed",
"columns": 0, "column_break_10",
"default": "", "compensatory_request",
"fieldname": "naming_series", "leave_period",
"fieldtype": "Select", "amended_from",
"hidden": 0, "notes",
"ignore_user_permissions": 0, "description"
"ignore_xss_filter": 0, ],
"in_filter": 0, "fields": [
"in_global_search": 0, {
"in_list_view": 0, "fieldname": "naming_series",
"in_standard_filter": 0, "fieldtype": "Select",
"label": "Series", "label": "Series",
"length": 0, "no_copy": 1,
"no_copy": 1, "options": "HR-LAL-.YYYY.-",
"options": "HR-LAL-.YYYY.-", "print_hide": 1,
"permlevel": 0, "reqd": 1,
"precision": "", "set_only_once": 1
"print_hide": 1, },
"print_hide_if_no_value": 0, {
"read_only": 0, "fieldname": "employee",
"remember_last_selected_value": 0, "fieldtype": "Link",
"report_hide": 0, "in_global_search": 1,
"reqd": 1, "in_list_view": 1,
"search_index": 0, "in_standard_filter": 1,
"set_only_once": 1, "label": "Employee",
"translatable": 0, "oldfieldname": "employee",
"unique": 0 "oldfieldtype": "Link",
}, "options": "Employee",
{ "reqd": 1,
"allow_bulk_edit": 0, "search_index": 1
"allow_in_quick_entry": 0, },
"allow_on_submit": 0, {
"bold": 0, "fetch_from": "employee.employee_name",
"collapsible": 0, "fieldname": "employee_name",
"columns": 0, "fieldtype": "Data",
"fieldname": "employee", "in_global_search": 1,
"fieldtype": "Link", "in_list_view": 1,
"hidden": 0, "label": "Employee Name",
"ignore_user_permissions": 0, "read_only": 1,
"ignore_xss_filter": 0, "search_index": 1
"in_filter": 0, },
"in_global_search": 1, {
"in_list_view": 1, "fetch_from": "employee.department",
"in_standard_filter": 1, "fieldname": "department",
"label": "Employee", "fieldtype": "Link",
"length": 0, "label": "Department",
"no_copy": 0, "options": "Department",
"oldfieldname": "employee", "read_only": 1
"oldfieldtype": "Link", },
"options": "Employee", {
"permlevel": 0, "fieldname": "column_break1",
"print_hide": 0, "fieldtype": "Column Break",
"print_hide_if_no_value": 0, "width": "50%"
"read_only": 0, },
"remember_last_selected_value": 0, {
"report_hide": 0, "fieldname": "leave_type",
"reqd": 1, "fieldtype": "Link",
"search_index": 1, "in_list_view": 1,
"set_only_once": 0, "in_standard_filter": 1,
"translatable": 0, "label": "Leave Type",
"unique": 0 "oldfieldname": "leave_type",
}, "oldfieldtype": "Link",
{ "options": "Leave Type",
"allow_bulk_edit": 0, "reqd": 1,
"allow_in_quick_entry": 0, "search_index": 1
"allow_on_submit": 0, },
"bold": 0, {
"collapsible": 0, "fieldname": "from_date",
"columns": 0, "fieldtype": "Date",
"fetch_from": "employee.employee_name", "label": "From Date",
"fieldname": "employee_name", "reqd": 1
"fieldtype": "Data", },
"hidden": 0, {
"ignore_user_permissions": 0, "fieldname": "to_date",
"ignore_xss_filter": 0, "fieldtype": "Date",
"in_filter": 0, "label": "To Date",
"in_global_search": 1, "reqd": 1
"in_list_view": 1, },
"in_standard_filter": 0, {
"label": "Employee Name", "fieldname": "section_break_6",
"length": 0, "fieldtype": "Section Break",
"no_copy": 0, "label": "Allocation"
"permlevel": 0, },
"print_hide": 0, {
"print_hide_if_no_value": 0, "allow_on_submit": 1,
"read_only": 1, "bold": 1,
"remember_last_selected_value": 0, "fieldname": "new_leaves_allocated",
"report_hide": 0, "fieldtype": "Float",
"reqd": 0, "label": "New Leaves Allocated"
"search_index": 1, },
"set_only_once": 0, {
"translatable": 0, "fieldname": "carry_forward",
"unique": 0 "fieldtype": "Check",
}, "label": "Add unused leaves from previous allocations"
{ },
"allow_bulk_edit": 0, {
"allow_in_quick_entry": 0, "depends_on": "carry_forward",
"allow_on_submit": 0, "fieldname": "carry_forwarded_leaves",
"bold": 0, "fieldtype": "Float",
"collapsible": 0, "label": "Unused leaves",
"columns": 0, "read_only": 1
"fetch_from": "employee.department", },
"fieldname": "department", {
"fieldtype": "Link", "allow_on_submit": 1,
"hidden": 0, "fieldname": "total_leaves_allocated",
"ignore_user_permissions": 0, "fieldtype": "Float",
"ignore_xss_filter": 0, "label": "Total Leaves Allocated",
"in_filter": 0, "read_only": 1,
"in_global_search": 0, "reqd": 1
"in_list_view": 0, },
"in_standard_filter": 0, {
"label": "Department", "depends_on": "eval:doc.total_leaves_encashed>0",
"length": 0, "fieldname": "total_leaves_encashed",
"no_copy": 0, "fieldtype": "Float",
"options": "Department", "label": "Total Leaves Encashed",
"permlevel": 0, "read_only": 1
"precision": "", },
"print_hide": 0, {
"print_hide_if_no_value": 0, "fieldname": "column_break_10",
"read_only": 1, "fieldtype": "Column Break"
"remember_last_selected_value": 0, },
"report_hide": 0, {
"reqd": 0, "fieldname": "compensatory_request",
"search_index": 0, "fieldtype": "Link",
"set_only_once": 0, "label": "Compensatory Leave Request",
"translatable": 0, "options": "Compensatory Leave Request",
"unique": 0 "read_only": 1
}, },
{ {
"allow_bulk_edit": 0, "fieldname": "leave_period",
"allow_in_quick_entry": 0, "fieldtype": "Link",
"allow_on_submit": 0, "in_standard_filter": 1,
"bold": 0, "label": "Leave Period",
"collapsible": 0, "options": "Leave Period",
"columns": 0, "read_only": 1
"fieldname": "column_break1", },
"fieldtype": "Column Break", {
"hidden": 0, "fieldname": "amended_from",
"ignore_user_permissions": 0, "fieldtype": "Link",
"ignore_xss_filter": 0, "ignore_user_permissions": 1,
"in_filter": 0, "label": "Amended From",
"in_global_search": 0, "no_copy": 1,
"in_list_view": 0, "oldfieldname": "amended_from",
"in_standard_filter": 0, "oldfieldtype": "Data",
"length": 0, "options": "Leave Allocation",
"no_copy": 0, "print_hide": 1,
"permlevel": 0, "read_only": 1
"print_hide": 0, },
"print_hide_if_no_value": 0, {
"read_only": 0, "collapsible": 1,
"remember_last_selected_value": 0, "fieldname": "notes",
"report_hide": 0, "fieldtype": "Section Break",
"reqd": 0, "label": "Notes"
"search_index": 0, },
"set_only_once": 0, {
"translatable": 0, "fieldname": "description",
"unique": 0, "fieldtype": "Small Text",
"width": "50%" "label": "Description",
}, "oldfieldname": "reason",
{ "oldfieldtype": "Small Text",
"allow_bulk_edit": 0, "width": "300px"
"allow_in_quick_entry": 0, }
"allow_on_submit": 0, ],
"bold": 0, "icon": "fa fa-ok",
"collapsible": 0, "idx": 1,
"columns": 0, "is_submittable": 1,
"fieldname": "leave_type", "modified": "2019-05-09 19:06:33.659196",
"fieldtype": "Link", "modified_by": "Administrator",
"hidden": 0, "module": "HR",
"ignore_user_permissions": 0, "name": "Leave Allocation",
"ignore_xss_filter": 0, "owner": "Administrator",
"in_filter": 0, "permissions": [
"in_global_search": 0, {
"in_list_view": 1, "amend": 1,
"in_standard_filter": 1, "cancel": 1,
"label": "Leave Type", "create": 1,
"length": 0, "delete": 1,
"no_copy": 0, "email": 1,
"oldfieldname": "leave_type", "print": 1,
"oldfieldtype": "Link", "read": 1,
"options": "Leave Type", "report": 1,
"permlevel": 0, "role": "HR User",
"print_hide": 0, "share": 1,
"print_hide_if_no_value": 0, "submit": 1,
"read_only": 0, "write": 1
"remember_last_selected_value": 0, },
"report_hide": 0, {
"reqd": 1, "amend": 1,
"search_index": 1, "cancel": 1,
"set_only_once": 0, "create": 1,
"translatable": 0, "delete": 1,
"unique": 0 "email": 1,
}, "export": 1,
{ "import": 1,
"allow_bulk_edit": 0, "print": 1,
"allow_in_quick_entry": 0, "read": 1,
"allow_on_submit": 0, "report": 1,
"bold": 0, "role": "HR Manager",
"collapsible": 0, "share": 1,
"columns": 0, "submit": 1,
"fieldname": "from_date", "write": 1
"fieldtype": "Date", }
"hidden": 0, ],
"ignore_user_permissions": 0, "search_fields": "employee,employee_name,leave_type,total_leaves_allocated",
"ignore_xss_filter": 0, "show_name_in_global_search": 1,
"in_filter": 0, "sort_field": "modified",
"in_global_search": 0, "sort_order": "DESC",
"in_list_view": 0, "timeline_field": "employee"
"in_standard_filter": 0, }
"label": "From Date",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "to_date",
"fieldtype": "Date",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "To Date",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "section_break_6",
"fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Allocation",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 1,
"bold": 1,
"collapsible": 0,
"columns": 0,
"fieldname": "new_leaves_allocated",
"fieldtype": "Float",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "New Leaves Allocated",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"description": "",
"fieldname": "carry_forward",
"fieldtype": "Check",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Add unused leaves from previous allocations",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "carry_forward",
"fieldname": "carry_forwarded_leaves",
"fieldtype": "Float",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Unused leaves",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 1,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "total_leaves_allocated",
"fieldtype": "Float",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Total Leaves Allocated",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "eval:doc.total_leaves_encashed>0",
"fieldname": "total_leaves_encashed",
"fieldtype": "Float",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Total Leaves Encashed",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_10",
"fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "compensatory_request",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Compensatory Leave Request",
"length": 0,
"no_copy": 0,
"options": "Compensatory Leave Request",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "leave_period",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 1,
"label": "Leave Period",
"length": 0,
"no_copy": 0,
"options": "Leave Period",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "amended_from",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 1,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Amended From",
"length": 0,
"no_copy": 1,
"oldfieldname": "amended_from",
"oldfieldtype": "Data",
"options": "Leave Allocation",
"permlevel": 0,
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 1,
"columns": 0,
"fieldname": "notes",
"fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Notes",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "description",
"fieldtype": "Small Text",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Description",
"length": 0,
"no_copy": 0,
"oldfieldname": "reason",
"oldfieldtype": "Small Text",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0,
"width": "300px"
}
],
"has_web_view": 0,
"hide_heading": 0,
"hide_toolbar": 0,
"icon": "fa fa-ok",
"idx": 1,
"image_view": 0,
"in_create": 0,
"is_submittable": 1,
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2019-01-30 11:28:09.360525",
"modified_by": "Administrator",
"module": "HR",
"name": "Leave Allocation",
"owner": "Administrator",
"permissions": [
{
"amend": 1,
"cancel": 1,
"create": 1,
"delete": 1,
"email": 1,
"export": 0,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "HR User",
"set_user_permissions": 0,
"share": 1,
"submit": 1,
"write": 1
},
{
"amend": 1,
"cancel": 1,
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"if_owner": 0,
"import": 1,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "HR Manager",
"set_user_permissions": 0,
"share": 1,
"submit": 1,
"write": 1
}
],
"quick_entry": 0,
"read_only": 0,
"read_only_onload": 0,
"search_fields": "employee,employee_name,leave_type,total_leaves_allocated",
"show_name_in_global_search": 1,
"sort_field": "modified",
"sort_order": "DESC",
"timeline_field": "employee",
"track_changes": 0,
"track_seen": 0,
"track_views": 0
}

View File

@ -8,6 +8,7 @@ from frappe import _
from frappe.model.document import Document from frappe.model.document import Document
from erpnext.hr.utils import set_employee_name, get_leave_period from erpnext.hr.utils import set_employee_name, get_leave_period
from erpnext.hr.doctype.leave_application.leave_application import get_approved_leaves_for_period from erpnext.hr.doctype.leave_application.leave_application import get_approved_leaves_for_period
from erpnext.hr.doctype.leave_ledger_entry.leave_ledger_entry import create_leave_ledger_entry
class OverlapError(frappe.ValidationError): pass class OverlapError(frappe.ValidationError): pass
class BackDatedAllocationError(frappe.ValidationError): pass class BackDatedAllocationError(frappe.ValidationError): pass
@ -18,66 +19,62 @@ class ValueMultiplierError(frappe.ValidationError): pass
class LeaveAllocation(Document): class LeaveAllocation(Document):
def validate(self): def validate(self):
self.validate_period() self.validate_period()
self.validate_lwp() self.validate_new_leaves_allocated_value()
set_employee_name(self)
self.set_total_leaves_allocated()
self.validate_allocation_overlap() self.validate_allocation_overlap()
self.validate_back_dated_allocation() self.validate_back_dated_allocation()
self.set_total_leaves_allocated()
self.validate_total_leaves_allocated() self.validate_total_leaves_allocated()
self.validate_leaves_allocated_value() self.validate_lwp()
set_employee_name(self)
self.validate_leave_allocation_days() self.validate_leave_allocation_days()
def validate_leave_allocation_days(self): def validate_leave_allocation_days(self):
new_leaves = self.new_leaves_allocated if not self.carry_forward else self.carry_forwarded_leaves company = frappe.db.get_value("Employee", self.employee, "company")
max_leaves, leaves_allocated = self.get_max_leaves_with_leaves_allocated_for_leave_type(flt(new_leaves)) leave_period = get_leave_period(self.from_date, self.to_date, company)
max_leaves_allowed = frappe.db.get_value("Leave Type", self.leave_type, "max_leaves_allowed")
if max_leaves_allowed > 0:
leave_allocated = 0
if leave_period:
leave_allocated = get_leave_allocation_for_period(self.employee, self.leave_type, leave_period[0].from_date, leave_period[0].to_date)
leave_allocated += self.new_leaves_allocated
if leave_allocated > max_leaves_allowed:
frappe.throw(_("Total allocated leaves are more days than maximum allocation of {0} leave type for employee {1} in the period")\
.format(self.leave_type, self.employee))
if leaves_allocated > max_leaves: def on_submit(self):
frappe.throw(_("Total allocated leaves are more days than maximum allocation of {0} leave type for employee {1} in the period")\ create_leave_ledger_entry(self)
.format(self.leave_type, self.employee))
def on_cancel(self):
create_leave_ledger_entry(self)
def on_update_after_submit(self): def on_update_after_submit(self):
self.validate_new_leaves_allocated_value() self.validate_new_leaves_allocated_value()
self.set_total_leaves_allocated() self.set_total_leaves_allocated()
frappe.db.set(self,'total_leaves_allocated', flt(self.total_leaves_allocated)) frappe.db.set(self,'carry_forwarded_leaves', flt(self.carry_forwarded_leaves))
frappe.db.set(self,'total_leaves_allocated',flt(self.total_leaves_allocated))
self.validate_against_leave_applications() self.validate_against_leave_applications()
def validate_period(self): def validate_period(self):
allocation_period = date_diff(self.to_date, self.from_date) if date_diff(self.to_date, self.from_date) <= 0:
if allocation_period <= 0:
frappe.throw(_("To date cannot be before from date")) frappe.throw(_("To date cannot be before from date"))
# check if the allocation period is more than the expiry allows for carry forwarded allocation
if self.carry_forward:
expiry_days = get_days_to_expiry_for_leave_type(self.leave_type)
if allocation_period > flt(expiry_days) and expiry_days:
frappe.throw(_("Leave allocation period cannot exceed carry forward expiry limit"))
def validate_lwp(self): def validate_lwp(self):
if frappe.db.get_value("Leave Type", self.leave_type, "is_lwp"): if frappe.db.get_value("Leave Type", self.leave_type, "is_lwp"):
frappe.throw(_("Leave Type {0} cannot be allocated since it is leave without pay").format(self.leave_type)) frappe.throw(_("Leave Type {0} cannot be allocated since it is leave without pay").format(self.leave_type))
def validate_leaves_allocated_value(self): def validate_new_leaves_allocated_value(self):
"""validate that leave allocation is in multiples of 0.5""" """validate that leave allocation is in multiples of 0.5"""
if flt(self.new_leaves_allocated) % 0.5: if flt(self.new_leaves_allocated) % 0.5:
frappe.throw(_("Leaves must be allocated in multiples of 0.5"), ValueMultiplierError) frappe.throw(_("Leaves must be allocated in multiples of 0.5"), ValueMultiplierError)
def validate_allocation_overlap(self): def validate_allocation_overlap(self):
leave_allocation = frappe.db.sql(""" leave_allocation = frappe.db.sql("""
SELECT select name from `tabLeave Allocation`
name where employee=%s and leave_type=%s and docstatus=1
FROM `tabLeave Allocation` and to_date >= %s and from_date <= %s""",
WHERE (self.employee, self.leave_type, self.from_date, self.to_date))
employee=%s
AND leave_type=%s
AND docstatus=1
AND carry_forward={0}
AND to_date >= %s
AND from_date <= %s""" #nosec
.format(self.carry_forward), (self.employee, self.leave_type, self.from_date, self.to_date))
if leave_allocation: if leave_allocation:
frappe.msgprint(_("{0} already allocated for Employee {1} for period {2} to {3}") frappe.msgprint(_("{0} already allocated for Employee {1} for period {2} to {3}")
@ -97,20 +94,18 @@ class LeaveAllocation(Document):
BackDatedAllocationError) BackDatedAllocationError)
def set_total_leaves_allocated(self): def set_total_leaves_allocated(self):
if self.carry_forward: self.carry_forwarded_leaves = get_carry_forwarded_leaves(self.employee,
self.set_carry_forwarded_leaves() self.leave_type, self.from_date, self.carry_forward)
self.total_leaves_allocated = flt(self.carry_forwarded_leaves)
else:
self.total_leaves_allocated = flt(self.new_leaves_allocated)
if not self.total_leaves_allocated and not frappe.db.get_value("Leave Type", self.leave_type, "is_earned_leave")\ self.total_leaves_allocated = flt(self.carry_forwarded_leaves) + flt(self.new_leaves_allocated)
and not frappe.db.get_value("Leave Type", self.leave_type, "is_compensatory"):
if not self.total_leaves_allocated and not frappe.db.get_value("Leave Type", self.leave_type, "is_earned_leave") and not frappe.db.get_value("Leave Type", self.leave_type, "is_compensatory"):
frappe.throw(_("Total leaves allocated is mandatory for Leave Type {0}".format(self.leave_type))) frappe.throw(_("Total leaves allocated is mandatory for Leave Type {0}".format(self.leave_type)))
def validate_total_leaves_allocated(self): def validate_total_leaves_allocated(self):
# Adding a day to include To Date in the difference # Adding a day to include To Date in the difference
date_difference = date_diff(self.to_date, self.from_date) + 1 date_difference = date_diff(self.to_date, self.from_date) + 1
if date_difference < flt(self.total_leaves_allocated): if date_difference < self.total_leaves_allocated:
frappe.throw(_("Total allocated leaves are more than days in the period"), OverAllocationError) frappe.throw(_("Total allocated leaves are more than days in the period"), OverAllocationError)
def validate_against_leave_applications(self): def validate_against_leave_applications(self):
@ -123,43 +118,16 @@ class LeaveAllocation(Document):
else: else:
frappe.throw(_("Total allocated leaves {0} cannot be less than already approved leaves {1} for the period").format(self.total_leaves_allocated, leaves_taken), LessAllocationError) frappe.throw(_("Total allocated leaves {0} cannot be less than already approved leaves {1} for the period").format(self.total_leaves_allocated, leaves_taken), LessAllocationError)
def set_carry_forwarded_leaves(self):
self.carry_forwarded_leaves = get_carry_forwarded_leaves(self.employee, self.leave_type, self.from_date)
max_leaves, leaves_allocated = self.get_max_leaves_with_leaves_allocated_for_leave_type(self.carry_forwarded_leaves)
if leaves_allocated > max_leaves:
self.carry_forwarded_leaves = max_leaves - (leaves_allocated - self.carry_forwarded_leaves)
def get_max_leaves_with_leaves_allocated_for_leave_type(self, new_leaves):
''' compare new leaves allocated with max leaves '''
company = frappe.db.get_value("Employee", self.employee, "company")
leaves_allocated = 0
leave_period = get_leave_period(self.from_date, self.to_date, company)
max_leaves_allowed = frappe.db.get_value("Leave Type", self.leave_type, "max_leaves_allowed")
if max_leaves_allowed > 0:
if leave_period:
leaves_allocated = get_leave_allocation_for_period(self.employee, self.leave_type, leave_period[0].from_date, leave_period[0].to_date)
leaves_allocated += new_leaves
return max_leaves_allowed, leaves_allocated
def get_leave_allocation_for_period(employee, leave_type, from_date, to_date): def get_leave_allocation_for_period(employee, leave_type, from_date, to_date):
leave_allocated = 0 leave_allocated = 0
leave_allocations = frappe.db.sql(""" leave_allocations = frappe.db.sql("""
SELECT select employee, leave_type, from_date, to_date, total_leaves_allocated
employee, from `tabLeave Allocation`
leave_type, where employee=%(employee)s and leave_type=%(leave_type)s
from_date, and docstatus=1
to_date, and (from_date between %(from_date)s and %(to_date)s
total_leaves_allocated or to_date between %(from_date)s and %(to_date)s
FROM `tabLeave Allocation` or (from_date < %(from_date)s and to_date > %(to_date)s))
WHERE
employee=%(employee)s
AND leave_type=%(leave_type)s
AND docstatus=1
AND (from_date BETWEEN %(from_date)s AND %(to_date)s
OR to_date BETWEEN %(from_date)s AND %(to_date)s
OR (from_date < %(from_date)s AND to_date > %(to_date)s))
""", { """, {
"from_date": from_date, "from_date": from_date,
"to_date": to_date, "to_date": to_date,
@ -174,43 +142,14 @@ def get_leave_allocation_for_period(employee, leave_type, from_date, to_date):
return leave_allocated return leave_allocated
@frappe.whitelist() @frappe.whitelist()
def get_carry_forwarded_leaves(employee, leave_type, date): def get_carry_forwarded_leaves(employee, leave_type, date, carry_forward=None):
''' Calculates carry forwarded days based on previous unused leave allocations ''' leave_records = frappe.get_all("Leave Ledger Entry",
carry_forwarded_leaves = 0 filters={'Employee':employee,
expiry_days = get_days_to_expiry_for_leave_type(leave_type) 'leave_type':leave_type,
validate_carry_forward(leave_type) 'to_date':("<=", date)},
filters = { fields=['leaves'])
"employee": employee,
"leave_type": leave_type,
"docstatus": 1,
"to_date": ("<", date)
}
limit = 2
# check number of days to expire, ignore expiry for default value 0 return sum(record.get("leaves") for record in leave_records)
if expiry_days:
filters.update(carry_forward=0)
limit = 1
previous_allocation = frappe.get_all("Leave Allocation",
filters=filters,
fields=["name","from_date","to_date","total_leaves_allocated"],
order_by="to_date desc",
limit=limit)
if previous_allocation:
leaves_taken = get_approved_leaves_for_period(employee, leave_type,
previous_allocation[0].from_date, previous_allocation[0].to_date)
carry_forwarded_leaves = flt(previous_allocation[0].total_leaves_allocated) - flt(leaves_taken)
return carry_forwarded_leaves
def get_days_to_expiry_for_leave_type(leave_type):
''' returns days to expiry for a provided leave type '''
return frappe.db.get_value("Leave Type",
filters={"leave_type_name": leave_type, "is_carry_forward": 1},
fieldname="carry_forward_leave_expiry")
def validate_carry_forward(leave_type): def validate_carry_forward(leave_type):
if not frappe.db.get_value("Leave Type", leave_type, "is_carry_forward"): if not frappe.db.get_value("Leave Type", leave_type, "is_carry_forward"):

View File

@ -114,22 +114,7 @@ def create_leave_allocation(employee, leave_type, new_leaves_allocated, leave_ty
allocation.leave_period = leave_period.name allocation.leave_period = leave_period.name
if carry_forward_leaves: if carry_forward_leaves:
if leave_type_details.get(leave_type).is_carry_forward: if leave_type_details.get(leave_type).is_carry_forward:
create_carry_forward_leaves_allocation(employee, leave_type, leave_type_details, leave_period, carry_forward_leaves) allocation.carry_forward = carry_forward_leaves
allocation.save(ignore_permissions=True) allocation.save(ignore_permissions = True)
allocation.submit() allocation.submit()
return allocation.name return allocation.name
def create_carry_forward_leaves_allocation(employee, leave_type, leave_type_details, leave_period, carry_forward_leaves):
carry_forwarded_leaves = get_carry_forwarded_leaves(employee, leave_type, leave_period.from_date)
if not carry_forwarded_leaves:
return
allocation = frappe.new_doc("Leave Allocation")
allocation.employee = employee
allocation.leave_type = leave_type
allocation.from_date = leave_period.from_date
allocation.to_date = add_days(leave_period.from_date, leave_type_details.carry_forward_leave_expiry) if not leave_type_details.carry_forward_leave_expiry else leave_period.to_date
allocation.leave_period = leave_period.name
allocation.carry_forward = carry_forward_leaves
allocation.carry_forwarded_leaves = carry_forwarded_leaves
allocation.save(ignore_permissions=True)
allocation.submit()