Skip to content

Commit

Permalink
fix:requested Changes
Browse files Browse the repository at this point in the history
  • Loading branch information
Anurag810 committed Oct 15, 2020
1 parent 34c3f19 commit 4d67cff
Show file tree
Hide file tree
Showing 10 changed files with 98 additions and 70 deletions.
2 changes: 1 addition & 1 deletion erpnext/hooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@
"erpnext.setup.doctype.email_digest.email_digest.send",
"erpnext.manufacturing.doctype.bom_update_tool.bom_update_tool.update_latest_price_in_all_boms",
"erpnext.hr.doctype.leave_ledger_entry.leave_ledger_entry.process_expired_allocation",
"erpnext.hr.doctype.leave_policy_assignment.leave_policy_assignment.automatic_allocate_leaves_based_on_leave_policy",
"erpnext.hr.doctype.leave_policy_assignment.leave_policy_assignment.automatically_allocate_leaves_based_on_leave_policy",
"erpnext.hr.utils.generate_leave_encashment",
"erpnext.hr.utils.allocate_earned_leaves",
"erpnext.hr.utils.grant_leaves_automatically",
Expand Down
9 changes: 4 additions & 5 deletions erpnext/hr/doctype/hr_settings/hr_settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"show_leaves_of_all_department_members_in_calendar",
"auto_leave_encashment",
"restrict_backdated_leave_application",
"automatic_allocate_leaves_based_on_leave_policy",
"automatically_allocate_leaves_based_on_leave_policy",
"hiring_settings",
"check_vacancies"
],
Expand Down Expand Up @@ -129,17 +129,16 @@
},
{
"default": "0",
"fieldname": "automatic_allocate_leaves_based_on_leave_policy",
"fieldname": "automatically_allocate_leaves_based_on_leave_policy",
"fieldtype": "Check",
"label": "Automatic Allocate Leaves Based On Leave Policy"
"label": "Automatically Allocate Leaves Based On Leave Policy"
}
],
"icon": "fa fa-cog",
"idx": 1,
"index_web_pages_for_search": 1,
"issingle": 1,
"links": [],
"modified": "2020-08-19 14:30:28.995324",
"modified": "2020-10-15 14:57:06.760461",
"modified_by": "Administrator",
"module": "HR",
"name": "HR Settings",
Expand Down
2 changes: 1 addition & 1 deletion erpnext/hr/doctype/leave_allocation/leave_allocation.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ def update_leave_policy_assignments_when_no_allocations_left(self):
"leave_policy_assignment": self.leave_policy_assignment
})
if len(allocations) == 0:
frappe.db.set_value("Leave Policy Assignment", self.leave_policy_assignment ,"already_allocated", 0)
frappe.db.set_value("Leave Policy Assignment", self.leave_policy_assignment ,"leaves_allocated", 0)

def validate_period(self):
if date_diff(self.to_date, self.from_date) <= 0:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,15 @@ frappe.ui.form.on('Leave Policy Assignment', {
},

refresh: function(frm) {
if(frm.doc.docstatus === 1 && frm.doc.already_allocated === 0){
if(frm.doc.docstatus === 1 && frm.doc.leaves_allocated === 0){
frm.add_custom_button(__("Grant Leave"), function() {

frappe.call({
doc: frm.doc,
method: "grant_leave_alloc_for_employee",
callback: function(r) {
let leave_allocations = r.message;

let msg = __("Leaves has been granted successfully");
msg += "<br><table class='table table-bordered'>";
msg += "<tr><th>"+__('Leave Type')+"</th><th>"+__("Leave Allocation")+"</th><th>"+__("Leaves Granted")+"</th><tr>";
for (let key in leave_allocations){

msg += "<tr><th>"+key+"</th><td>"+leave_allocations[key]["name"]+"</td><td>"+leave_allocations[key]["leaves"]+"</td></tr>";
}
msg += "</table>";
let msg = frm.events.get_success_message(leave_allocations);
frappe.msgprint(msg);
cur_frm.refresh();
}
Expand All @@ -32,6 +24,18 @@ frappe.ui.form.on('Leave Policy Assignment', {
}
},

get_success_message: function(leave_allocations){
let msg = __("Leaves has been granted successfully");
msg += "<br><table class='table table-bordered'>";
msg += "<tr><th>"+__('Leave Type')+"</th><th>"+__("Leave Allocation")+"</th><th>"+__("Leaves Granted")+"</th><tr>";
for (let key in leave_allocations){

msg += "<tr><th>"+key+"</th><td>"+leave_allocations[key]["name"]+"</td><td>"+leave_allocations[key]["leaves"]+"</td></tr>";
}
msg += "</table>";
return msg;
},

assignment_based_on: function(frm) {
if (frm.doc.assignment_based_on) {
frm.events.set_effective_date(frm);
Expand All @@ -51,17 +55,17 @@ frappe.ui.form.on('Leave Policy Assignment', {
if (frm.doc.assignment_based_on == "Leave Period" && frm.doc.leave_period){
frappe.model.with_doc("Leave Period", frm.doc.leave_period, function (){

let from_date = frappe.model.get_value("Leave Period", cur_frm.doc.leave_period, "from_date");
let to_date = frappe.model.get_value("Leave Period", cur_frm.doc.leave_period, "to_date");
let from_date = frappe.model.get_value("Leave Period", frm.doc.leave_period, "from_date");
let to_date = frappe.model.get_value("Leave Period", frm.doc.leave_period, "to_date");
frm.set_value("effective_from", from_date);
frm.set_value("effective_to", to_date);

});
}else if (frm.doc.assignment_based_on == "Joining Date" && frm.doc.employee){
frappe.model.with_doc("Employee", frm.doc.employee, function (){
let from_date = frappe.model.get_value("Employee", cur_frm.doc.employee, "date_of_joining");
let from_date = frappe.model.get_value("Employee", frm.doc.employee, "date_of_joining");
frm.set_value("effective_from", from_date);
frm.set_value("effective_to", frappe.datetime.add_months(cur_frm.doc.effective_from, 12));
frm.set_value("effective_to", frappe.datetime.add_months(frm.doc.effective_from, 12));
});
}
frm.refresh();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"leave_period",
"effective_from",
"effective_to",
"already_allocated",
"leaves_allocated",
"amended_from"
],
"fields": [
Expand Down Expand Up @@ -103,21 +103,44 @@
},
{
"default": "0",
"fieldname": "already_allocated",
"fieldname": "leaves_allocated",
"fieldtype": "Check",
"hidden": 1,
"label": "Already Allocated"
"label": "Leaves Allocated"
}
],
"index_web_pages_for_search": 1,
"is_submittable": 1,
"links": [],
"modified": "2020-08-20 15:27:34.206601",
"modified": "2020-10-15 15:18:15.227848",
"modified_by": "Administrator",
"module": "HR",
"name": "Leave Policy Assignment",
"owner": "Administrator",
"permissions": [
{
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"print": 1,
"read": 1,
"report": 1,
"role": "HR Manager",
"share": 1,
"write": 1
},
{
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"print": 1,
"read": 1,
"report": 1,
"role": "HR User",
"share": 1,
"write": 1
},
{
"create": 1,
"delete": 1,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,30 +19,25 @@ def validate(self):

def set_dates(self):
if self.assignment_based_on == "Leave Period":
self.effective_from = frappe.db.get_value("Leave Period", self.leave_period, "from_date")
self.effective_to = frappe.db.get_value("Leave Period", self.leave_period, "to_date")
self.effective_from, self.effective_to = frappe.db.get_value("Leave Period", self.leave_period, ["from_date", "to_date"])
elif self.assignment_based_on == "Joining Date":
self.effective_from = frappe.db.get_value("Employee", self.employee, "date_of_joining")

def validate_policy_assignment_overlap(self):
leave_policy_assignments = frappe.db.sql("""
SELECT
name
FROM `tabLeave Policy Assignment`
WHERE
employee=%s
AND name <> %s
AND docstatus=1
AND effective_to >= %s
AND effective_from <= %s""",
(self.employee, self.name, self.effective_from, self.effective_to), as_dict = 1)
leave_policy_assignments = frappe.get_all("Leave Policy Assignment", filters = {
"employee": self.employee,
"name": ("!=", self.name),
"docstatus": 1,
"effective_to": (">=", self.effective_from),
"effective_from": ("<=", self.effective_to)
})

if len(leave_policy_assignments):
frappe.throw(_("Leave Policy: {0} already assigned for Employee {1} for period {2} to {3}")
.format(bold(self.leave_policy), bold(self.employee), bold(formatdate(self.effective_from)), bold(formatdate(self.effective_to))))

def grant_leave_alloc_for_employee(self):
if self.already_allocated:
if self.leaves_allocated:
frappe.throw(_("Leave already have been assigned for this Leave Policy Assignment"))
else:
leave_allocations = {}
Expand All @@ -60,7 +55,7 @@ def grant_leave_alloc_for_employee(self):

leave_allocations[leave_policy_detail.leave_type] = {"name": leave_allocation, "leaves": new_leaves_allocated}

self.db_set("already_allocated", 1)
self.db_set("leaves_allocated", 1)
return leave_allocations

def create_leave_allocation(self, leave_type, new_leaves_allocated, leave_type_details, date_of_joining):
Expand All @@ -69,14 +64,8 @@ def create_leave_allocation(self, leave_type, new_leaves_allocated, leave_type_d
if self.carry_forward and not leave_type_details.get(leave_type).is_carry_forward:
carry_forward = 0

# Calculate leaves at pro-rata basis for employees joining after the beginning of the given leave period
if getdate(date_of_joining) > getdate(self.effective_from):
remaining_period = ((date_diff(self.effective_to, date_of_joining) + 1) / (date_diff(self.effective_to, self.effective_from) + 1))
new_leaves_allocated = ceil(new_leaves_allocated * remaining_period)

# Earned Leaves and Compensatory Leaves are allocated by scheduler, initially allocate 0
if leave_type_details.get(leave_type).is_earned_leave == 1 or leave_type_details.get(leave_type).is_compensatory == 1:
new_leaves_allocated = 0
new_leaves_allocated = self.get_new_leaves(leave_type, new_leaves_allocated,
leave_type_details, date_of_joining)

allocation = frappe.get_doc(dict(
doctype="Leave Allocation",
Expand All @@ -94,6 +83,18 @@ def create_leave_allocation(self, leave_type, new_leaves_allocated, leave_type_d
allocation.submit()
return allocation.name, new_leaves_allocated

def get_new_leaves(self, leave_type, new_leaves_allocated, leave_type_details, date_of_joining):
# Calculate leaves at pro-rata basis for employees joining after the beginning of the given leave period
if getdate(date_of_joining) > getdate(self.effective_from):
remaining_period = ((date_diff(self.effective_to, date_of_joining) + 1) / (date_diff(self.effective_to, self.effective_from) + 1))
new_leaves_allocated = ceil(new_leaves_allocated * remaining_period)

# Earned Leaves and Compensatory Leaves are allocated by scheduler, initially allocate 0
if leave_type_details.get(leave_type).is_earned_leave == 1 or leave_type_details.get(leave_type).is_compensatory == 1:
new_leaves_allocated = 0

return new_leaves_allocated

@frappe.whitelist()
def grant_leave_for_multiple_employees(leave_policy_assignments):
leave_policy_assignments = json.loads(leave_policy_assignments)
Expand All @@ -105,9 +106,9 @@ def grant_leave_for_multiple_employees(leave_policy_assignments):
not_granted.append(assignment)

if len(not_granted):
msg = "Leave not Granted for Assignments:"+ bold(comma_and(not_granted)) + ". Please Check documents"
msg = _("Leave not Granted for Assignments:")+ bold(comma_and(not_granted)) + _(". Please Check documents")
else:
msg = "Leave granted Successfully"
msg = _("Leave granted Successfully")
frappe.msgprint(msg)

@frappe.whitelist()
Expand Down Expand Up @@ -136,23 +137,20 @@ def create_assignment_for_multiple_employees(employees, data):
return docs_name


def automatic_allocate_leaves_based_on_leave_policy():
def automatically_allocate_leaves_based_on_leave_policy():
today = getdate()
automatic_allocate_leaves_based_on_leave_policy = frappe.db.get_single_value(
'HR Settings', 'automatic_allocate_leaves_based_on_leave_policy'
automatically_allocate_leaves_based_on_leave_policy = frappe.db.get_single_value(
'HR Settings', 'automatically_allocate_leaves_based_on_leave_policy'
)

pending_assignments = frappe.get_list(
"Leave Policy Assignment",
filters = {"docstatus": 1, "already_allocated": 0, "effective_from": today}
filters = {"docstatus": 1, "leaves_allocated": 0, "effective_from": today}
)

if len(pending_assignments) and automatic_allocate_leaves_based_on_leave_policy:
if len(pending_assignments) and automatically_allocate_leaves_based_on_leave_policy:
for assignment in pending_assignments:
try:
frappe.get_doc("Leave Policy Assignment", assignment.name).grant_leave_alloc_for_employee()
except:
pass
frappe.get_doc("Leave Policy Assignment", assignment.name).grant_leave_alloc_for_employee()


def get_leave_type_details():
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ frappe.listview_settings['Leave Policy Assignment'] = {
return {
filters: {
docstatus: ['=', 1],
already_allocated: ['=', 0]
leaves_allocated: ['=', 0]
}
};
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class TestLeavePolicyAssignment(unittest.TestCase):

def setUp(self):
for dt in ["Leave Application", "Leave Allocation", "Leave Policy Assignment", "Leave Ledger Entry"]:
frappe.db.sql("DELETE FROM `tab%s`" % dt) #nosec
frappe.db.sql("DELETE FROM `tab%s`" % dt)

def test_grant_leaves(self):
leave_period = get_leave_period()
Expand All @@ -36,7 +36,7 @@ def test_grant_leaves(self):
leave_policy_assignment_doc.grant_leave_alloc_for_employee()
leave_policy_assignment_doc.reload()

self.assertEqual(leave_policy_assignment_doc.already_allocated, 1)
self.assertEqual(leave_policy_assignment_doc.leaves_allocated, 1)

leave_allocation = frappe.get_list("Leave Allocation", filters={
"employee": employee.name,
Expand Down Expand Up @@ -76,7 +76,7 @@ def test_allow_to_grant_all_leave_after_cancellation_of_every_leave_allocation(s


# every leave is allocated no more leave can be granted now
self.assertEqual(leave_policy_assignment_doc.already_allocated, 1)
self.assertEqual(leave_policy_assignment_doc.leaves_allocated, 1)

leave_allocation = frappe.get_list("Leave Allocation", filters={
"employee": employee.name,
Expand All @@ -94,6 +94,10 @@ def test_allow_to_grant_all_leave_after_cancellation_of_every_leave_allocation(s


# User are now allowed to grant leave
self.assertEqual(leave_policy_assignment_doc.already_allocated, 0)
self.assertEqual(leave_policy_assignment_doc.leaves_allocated, 0)

def tearDown(self):
for dt in ["Leave Application", "Leave Allocation", "Leave Policy Assignment", "Leave Ledger Entry"]:
frappe.db.sql("DELETE FROM `tab%s`" % dt)


4 changes: 2 additions & 2 deletions erpnext/hr/doctype/leave_type/leave_type.json
Original file line number Diff line number Diff line change
Expand Up @@ -188,16 +188,16 @@
{
"default": "0",
"depends_on": "eval:doc.is_earned_leave",
"description": "If checked, leave will be granted on the day of joining every month.",
"fieldname": "based_on_date_of_joining",
"fieldtype": "Check",
"label": "Based On Date Of Joining"
}
],
"icon": "fa fa-flag",
"idx": 1,
"index_web_pages_for_search": 1,
"links": [],
"modified": "2020-08-21 15:41:07.435203",
"modified": "2020-10-15 15:49:47.555105",
"modified_by": "Administrator",
"module": "HR",
"name": "Leave Type",
Expand Down
6 changes: 3 additions & 3 deletions erpnext/hr/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -475,8 +475,8 @@ def get_previous_claimed_amount(employee, payroll_period, non_pro_rata=False, co
return total_claimed_amount

def grant_leaves_automatically():
automatic_allocate_leaves_based_on_leave_policy = frappe.db.get_singles_value("HR Settings", "automatic_allocate_leaves_based_on_leave_policy")
if automatic_allocate_leaves_based_on_leave_policy:
lpa = frappe.db.get_all("Leave Policy Assignment", filters={"effective_from": getdate(), "docstatus": 1, "already_allocated":0})
automatically_allocate_leaves_based_on_leave_policy = frappe.db.get_singles_value("HR Settings", "automatically_allocate_leaves_based_on_leave_policy")
if automatically_allocate_leaves_based_on_leave_policy:
lpa = frappe.db.get_all("Leave Policy Assignment", filters={"effective_from": getdate(), "docstatus": 1, "leaves_allocated":0})
for assignment in lpa:
frappe.get_doc("Leave Policy Assignment", assignment.name).grant_leave_alloc_for_employee()

0 comments on commit 4d67cff

Please sign in to comment.