From 1e1b7fc74f5087cd13e61c21fbbeaa1882e93bfa Mon Sep 17 00:00:00 2001 From: anoop Date: Fri, 11 May 2018 20:22:05 +0530 Subject: [PATCH] 13615 - Leave Encashment, creating Additional Salary Component on submit and validations pending --- .../leave_encashment/leave_encashment.js | 34 ++++++++++- .../leave_encashment/leave_encashment.json | 41 +++++++++++-- .../leave_encashment/leave_encashment.py | 59 ++++++++++++++++++- 3 files changed, 128 insertions(+), 6 deletions(-) diff --git a/erpnext/hr/doctype/leave_encashment/leave_encashment.js b/erpnext/hr/doctype/leave_encashment/leave_encashment.js index 0556756f92..701c2f0f31 100644 --- a/erpnext/hr/doctype/leave_encashment/leave_encashment.js +++ b/erpnext/hr/doctype/leave_encashment/leave_encashment.js @@ -2,7 +2,39 @@ // For license information, please see license.txt frappe.ui.form.on('Leave Encashment', { + setup: function(frm) { + frm.set_query("leave_type", function() { + return { + filters: { + allow_encashment: 1 + } + } + }) + }, refresh: function(frm) { - + cur_frm.set_intro(""); + if(frm.doc.__islocal && !in_list(frappe.user_roles, "Employee")) { + frm.set_intro(__("Fill the form and save it")); + } + }, + employee: function(frm) { + frm.trigger("get_leave_details_for_encashment"); + }, + leave_type: function(frm) { + frm.trigger("get_leave_details_for_encashment"); + }, + encashment_date: function(frm) { + frm.trigger("get_leave_details_for_encashment"); + }, + get_leave_details_for_encashment: function(frm) { + if(frm.doc.docstatus==0 && frm.doc.employee && frm.doc.leave_type) { + return frappe.call({ + method: "get_leave_details_for_encashment", + doc: frm.doc, + callback: function(r) { + frm.refresh_fields(); + } + }); + } } }); diff --git a/erpnext/hr/doctype/leave_encashment/leave_encashment.json b/erpnext/hr/doctype/leave_encashment/leave_encashment.json index 22f0b20fdb..3f04090377 100644 --- a/erpnext/hr/doctype/leave_encashment/leave_encashment.json +++ b/erpnext/hr/doctype/leave_encashment/leave_encashment.json @@ -171,6 +171,38 @@ "translatable": 0, "unique": 0 }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "leave_allocation", + "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": "Leave Allocation", + "length": 0, + "no_copy": 0, + "options": "Leave Allocation", + "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_on_submit": 0, @@ -308,7 +340,7 @@ "ignore_xss_filter": 0, "in_filter": 0, "in_global_search": 0, - "in_list_view": 0, + "in_list_view": 1, "in_standard_filter": 0, "label": "Encashment Amount", "length": 0, @@ -332,7 +364,8 @@ "bold": 0, "collapsible": 0, "columns": 0, - "fieldname": "payroll_date", + "default": "Today", + "fieldname": "encashment_date", "fieldtype": "Date", "hidden": 0, "ignore_user_permissions": 0, @@ -341,7 +374,7 @@ "in_global_search": 0, "in_list_view": 0, "in_standard_filter": 0, - "label": "Payroll Date", + "label": "Encashment Date", "length": 0, "no_copy": 0, "permlevel": 0, @@ -368,7 +401,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2018-04-14 15:35:51.428448", + "modified": "2018-05-11 19:15:17.460624", "modified_by": "Administrator", "module": "HR", "name": "Leave Encashment", diff --git a/erpnext/hr/doctype/leave_encashment/leave_encashment.py b/erpnext/hr/doctype/leave_encashment/leave_encashment.py index 5966a0ba7a..1e2c3b9dce 100644 --- a/erpnext/hr/doctype/leave_encashment/leave_encashment.py +++ b/erpnext/hr/doctype/leave_encashment/leave_encashment.py @@ -4,7 +4,64 @@ from __future__ import unicode_literals import frappe +from frappe import _ from frappe.model.document import Document +from frappe.utils import getdate, nowdate, flt +from erpnext.hr.utils import set_employee_name +from erpnext.hr.doctype.leave_application.leave_application import get_leave_balance_on +from erpnext.hr.doctype.salary_structure_assignment.salary_structure_assignment import get_assigned_salary_structure class LeaveEncashment(Document): - pass + def validate(self): + set_employee_name(self) + self.get_leave_details_for_encashment() + + if not self.encashment_date: + self.encashment_date = getdate(nowdate()) + + def before_submit(self): + if self.encashment_amount <= 0: + frappe.throw(_("You can only submit Leave Encashment for a valid encashment amount")) + + def on_submit(self): + if not self.leave_allocation: + self.leave_allocation = self.get_leave_allocation() + + #ToDo: Create Additional Salary Component + + # Set encashed leaves in Allocation + frappe.db.set_value("Leave Allocation", self.leave_allocation, "total_leaves_encashed", + frappe.db.get_value('Leave Allocation', self.leave_allocation, 'total_leaves_encashed') + self.encashable_days) + + def on_cancel(self): + # ToDo: Cancel Additional Salary Component + if self.leave_allocation: + frappe.db.set_value("Leave Allocation", self.leave_allocation, "total_leaves_encashed", + frappe.db.get_value('Leave Allocation', self.leave_allocation, 'total_leaves_encashed') - self.encashable_days) + + def get_leave_details_for_encashment(self): + salary_structure = get_assigned_salary_structure(self.employee, self.encashment_date or getdate(nowdate())) + if not salary_structure: + frappe.throw(_("No Salary Structure assigned for Employee {0} on given date {1}").format(self.employee, self.encashment_date)) + + if not frappe.db.get_value("Leave Type", self.leave_type, 'allow_encashment'): + frappe.throw(_("Leave Type {0} is not encashable").format(self.leave_type)) + + self.leave_balance = get_leave_balance_on(self.employee, self.leave_type, + self.encashment_date or getdate(nowdate()), consider_all_leaves_in_the_allocation_period=True) + + encashable_days = self.leave_balance - frappe.db.get_value('Leave Type', self.leave_type, 'encashment_threshold_days') + self.encashable_days = encashable_days if encashable_days > 0 else 0 + + per_day_encashment = frappe.db.get_value('Salary Structure', salary_structure , 'leave_encashment_amount_per_day') + self.encashment_amount = self.encashable_days * per_day_encashment if per_day_encashment > 0 else 0 + + self.leave_allocation = self.get_leave_allocation() + return True + + def get_leave_allocation(self): + leave_allocation = frappe.db.sql("""select name from `tabLeave Allocation` where '{0}' + between from_date and to_date and docstatus=1 and leave_type='{1}' + and employee= '{2}'""".format(self.encashment_date or getdate(nowdate()), self.leave_type, self.employee)) + + return leave_allocation[0][0] if leave_allocation else None