fix: update leave allocation after submit (#26191)
* fix: update leave allocation after submit v13 * fix: test * fix: test
This commit is contained in:
parent
81d164134d
commit
6a9798f305
@ -110,6 +110,7 @@
|
|||||||
"label": "Allocation"
|
"label": "Allocation"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"allow_on_submit": 1,
|
||||||
"bold": 1,
|
"bold": 1,
|
||||||
"fieldname": "new_leaves_allocated",
|
"fieldname": "new_leaves_allocated",
|
||||||
"fieldtype": "Float",
|
"fieldtype": "Float",
|
||||||
@ -235,7 +236,7 @@
|
|||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2021-04-14 15:28:26.335104",
|
"modified": "2021-06-03 15:28:26.335104",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "HR",
|
"module": "HR",
|
||||||
"name": "Leave Allocation",
|
"name": "Leave Allocation",
|
||||||
|
@ -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_ledger_entry.leave_ledger_entry import expire_allocation, create_leave_ledger_entry
|
from erpnext.hr.doctype.leave_ledger_entry.leave_ledger_entry import expire_allocation, create_leave_ledger_entry
|
||||||
|
from erpnext.hr.doctype.leave_application.leave_application import get_approved_leaves_for_period
|
||||||
|
|
||||||
class OverlapError(frappe.ValidationError): pass
|
class OverlapError(frappe.ValidationError): pass
|
||||||
class BackDatedAllocationError(frappe.ValidationError): pass
|
class BackDatedAllocationError(frappe.ValidationError): pass
|
||||||
@ -55,6 +56,43 @@ class LeaveAllocation(Document):
|
|||||||
if self.carry_forward:
|
if self.carry_forward:
|
||||||
self.set_carry_forwarded_leaves_in_previous_allocation(on_cancel=True)
|
self.set_carry_forwarded_leaves_in_previous_allocation(on_cancel=True)
|
||||||
|
|
||||||
|
def on_update_after_submit(self):
|
||||||
|
if self.has_value_changed("new_leaves_allocated"):
|
||||||
|
self.validate_against_leave_applications()
|
||||||
|
leaves_to_be_added = self.new_leaves_allocated - self.get_existing_leave_count()
|
||||||
|
args = {
|
||||||
|
"leaves": leaves_to_be_added,
|
||||||
|
"from_date": self.from_date,
|
||||||
|
"to_date": self.to_date,
|
||||||
|
"is_carry_forward": 0
|
||||||
|
}
|
||||||
|
create_leave_ledger_entry(self, args, True)
|
||||||
|
|
||||||
|
def get_existing_leave_count(self):
|
||||||
|
ledger_entries = frappe.get_all("Leave Ledger Entry",
|
||||||
|
filters={
|
||||||
|
"transaction_type": "Leave Allocation",
|
||||||
|
"transaction_name": self.name,
|
||||||
|
"employee": self.employee,
|
||||||
|
"company": self.company,
|
||||||
|
"leave_type": self.leave_type
|
||||||
|
},
|
||||||
|
pluck="leaves")
|
||||||
|
total_existing_leaves = 0
|
||||||
|
for entry in ledger_entries:
|
||||||
|
total_existing_leaves += entry
|
||||||
|
|
||||||
|
return total_existing_leaves
|
||||||
|
|
||||||
|
def validate_against_leave_applications(self):
|
||||||
|
leaves_taken = get_approved_leaves_for_period(self.employee, self.leave_type,
|
||||||
|
self.from_date, self.to_date)
|
||||||
|
if flt(leaves_taken) > flt(self.total_leaves_allocated):
|
||||||
|
if frappe.db.get_value("Leave Type", self.leave_type, "allow_negative"):
|
||||||
|
frappe.msgprint(_("Note: Total allocated leaves {0} shouldn't be less than already approved leaves {1} for the period").format(self.total_leaves_allocated, leaves_taken))
|
||||||
|
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)
|
||||||
|
|
||||||
def update_leave_policy_assignments_when_no_allocations_left(self):
|
def update_leave_policy_assignments_when_no_allocations_left(self):
|
||||||
allocations = frappe.db.get_list("Leave Allocation", filters = {
|
allocations = frappe.db.get_list("Leave Allocation", filters = {
|
||||||
"docstatus": 1,
|
"docstatus": 1,
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import frappe
|
import frappe
|
||||||
|
import erpnext
|
||||||
import unittest
|
import unittest
|
||||||
from frappe.utils import nowdate, add_months, getdate, add_days
|
from frappe.utils import nowdate, add_months, getdate, add_days
|
||||||
from erpnext.hr.doctype.leave_type.test_leave_type import create_leave_type
|
from erpnext.hr.doctype.leave_type.test_leave_type import create_leave_type
|
||||||
@ -164,6 +165,51 @@ class TestLeaveAllocation(unittest.TestCase):
|
|||||||
leave_allocation.cancel()
|
leave_allocation.cancel()
|
||||||
self.assertFalse(frappe.db.exists("Leave Ledger Entry", {'transaction_name':leave_allocation.name}))
|
self.assertFalse(frappe.db.exists("Leave Ledger Entry", {'transaction_name':leave_allocation.name}))
|
||||||
|
|
||||||
|
def test_leave_addition_after_submit(self):
|
||||||
|
frappe.db.sql("delete from `tabLeave Allocation`")
|
||||||
|
frappe.db.sql("delete from `tabLeave Ledger Entry`")
|
||||||
|
|
||||||
|
leave_allocation = create_leave_allocation()
|
||||||
|
leave_allocation.submit()
|
||||||
|
self.assertTrue(leave_allocation.total_leaves_allocated, 15)
|
||||||
|
leave_allocation.new_leaves_allocated = 40
|
||||||
|
leave_allocation.submit()
|
||||||
|
self.assertTrue(leave_allocation.total_leaves_allocated, 40)
|
||||||
|
|
||||||
|
def test_leave_subtraction_after_submit(self):
|
||||||
|
frappe.db.sql("delete from `tabLeave Allocation`")
|
||||||
|
frappe.db.sql("delete from `tabLeave Ledger Entry`")
|
||||||
|
leave_allocation = create_leave_allocation()
|
||||||
|
leave_allocation.submit()
|
||||||
|
self.assertTrue(leave_allocation.total_leaves_allocated, 15)
|
||||||
|
leave_allocation.new_leaves_allocated = 10
|
||||||
|
leave_allocation.submit()
|
||||||
|
self.assertTrue(leave_allocation.total_leaves_allocated, 10)
|
||||||
|
|
||||||
|
def test_against_leave_application_validation_after_submit(self):
|
||||||
|
frappe.db.sql("delete from `tabLeave Allocation`")
|
||||||
|
frappe.db.sql("delete from `tabLeave Ledger Entry`")
|
||||||
|
|
||||||
|
leave_allocation = create_leave_allocation()
|
||||||
|
leave_allocation.submit()
|
||||||
|
self.assertTrue(leave_allocation.total_leaves_allocated, 15)
|
||||||
|
employee = frappe.get_doc("Employee", frappe.db.sql_list("select name from tabEmployee limit 1")[0])
|
||||||
|
leave_application = frappe.get_doc({
|
||||||
|
"doctype": 'Leave Application',
|
||||||
|
"employee": employee.name,
|
||||||
|
"leave_type": "_Test Leave Type",
|
||||||
|
"from_date": add_months(nowdate(), 2),
|
||||||
|
"to_date": add_months(add_days(nowdate(), 10), 2),
|
||||||
|
"company": erpnext.get_default_company() or "_Test Company",
|
||||||
|
"docstatus": 1,
|
||||||
|
"status": "Approved",
|
||||||
|
"leave_approver": 'test@example.com'
|
||||||
|
})
|
||||||
|
leave_application.submit()
|
||||||
|
leave_allocation.new_leaves_allocated = 8
|
||||||
|
leave_allocation.total_leaves_allocated = 8
|
||||||
|
self.assertRaises(frappe.ValidationError, leave_allocation.submit)
|
||||||
|
|
||||||
def create_leave_allocation(**args):
|
def create_leave_allocation(**args):
|
||||||
args = frappe._dict(args)
|
args = frappe._dict(args)
|
||||||
|
|
||||||
|
@ -178,7 +178,7 @@ def get_allocated_and_expired_leaves(from_date, to_date, employee, leave_type):
|
|||||||
is_carry_forward, is_expired
|
is_carry_forward, is_expired
|
||||||
FROM `tabLeave Ledger Entry`
|
FROM `tabLeave Ledger Entry`
|
||||||
WHERE employee=%(employee)s AND leave_type=%(leave_type)s
|
WHERE employee=%(employee)s AND leave_type=%(leave_type)s
|
||||||
AND docstatus=1 AND leaves>0
|
AND docstatus=1
|
||||||
AND (from_date between %(from_date)s AND %(to_date)s
|
AND (from_date between %(from_date)s AND %(to_date)s
|
||||||
OR to_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))
|
OR (from_date < %(from_date)s AND to_date > %(to_date)s))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user