Merge pull request #24523 from rohitwaghchaure/sub-operation-new-branch
Feat: Job Card Enhancements
diff --git a/erpnext/hr/doctype/leave_allocation/leave_allocation.json b/erpnext/hr/doctype/leave_allocation/leave_allocation.json
index ae02c51..3a6539e 100644
--- a/erpnext/hr/doctype/leave_allocation/leave_allocation.json
+++ b/erpnext/hr/doctype/leave_allocation/leave_allocation.json
@@ -110,6 +110,7 @@
"label": "Allocation"
},
{
+ "allow_on_submit": 1,
"bold": 1,
"fieldname": "new_leaves_allocated",
"fieldtype": "Float",
@@ -235,7 +236,7 @@
"index_web_pages_for_search": 1,
"is_submittable": 1,
"links": [],
- "modified": "2021-04-14 15:28:26.335104",
+ "modified": "2021-06-03 15:28:26.335104",
"modified_by": "Administrator",
"module": "HR",
"name": "Leave Allocation",
@@ -277,4 +278,4 @@
"sort_field": "modified",
"sort_order": "DESC",
"timeline_field": "employee"
-}
\ No newline at end of file
+}
diff --git a/erpnext/hr/doctype/leave_allocation/leave_allocation.py b/erpnext/hr/doctype/leave_allocation/leave_allocation.py
index 11302ca..4757cd3 100755
--- a/erpnext/hr/doctype/leave_allocation/leave_allocation.py
+++ b/erpnext/hr/doctype/leave_allocation/leave_allocation.py
@@ -8,6 +8,7 @@
from frappe.model.document import Document
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_application.leave_application import get_approved_leaves_for_period
class OverlapError(frappe.ValidationError): pass
class BackDatedAllocationError(frappe.ValidationError): pass
@@ -55,6 +56,43 @@
if self.carry_forward:
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):
allocations = frappe.db.get_list("Leave Allocation", filters = {
"docstatus": 1,
@@ -225,4 +263,4 @@
def validate_carry_forward(leave_type):
if not frappe.db.get_value("Leave Type", leave_type, "is_carry_forward"):
- frappe.throw(_("Leave Type {0} cannot be carry-forwarded").format(leave_type))
\ No newline at end of file
+ frappe.throw(_("Leave Type {0} cannot be carry-forwarded").format(leave_type))
diff --git a/erpnext/hr/doctype/leave_allocation/test_leave_allocation.py b/erpnext/hr/doctype/leave_allocation/test_leave_allocation.py
index 6e7ae87..bff06e6 100644
--- a/erpnext/hr/doctype/leave_allocation/test_leave_allocation.py
+++ b/erpnext/hr/doctype/leave_allocation/test_leave_allocation.py
@@ -1,5 +1,6 @@
from __future__ import unicode_literals
import frappe
+import erpnext
import unittest
from frappe.utils import nowdate, add_months, getdate, add_days
from erpnext.hr.doctype.leave_type.test_leave_type import create_leave_type
@@ -164,6 +165,51 @@
leave_allocation.cancel()
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):
args = frappe._dict(args)
diff --git a/erpnext/hr/report/employee_leave_balance/employee_leave_balance.py b/erpnext/hr/report/employee_leave_balance/employee_leave_balance.py
index 4dd4570..b8953b3 100644
--- a/erpnext/hr/report/employee_leave_balance/employee_leave_balance.py
+++ b/erpnext/hr/report/employee_leave_balance/employee_leave_balance.py
@@ -178,7 +178,7 @@
is_carry_forward, is_expired
FROM `tabLeave Ledger Entry`
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
OR to_date between %(from_date)s AND %(to_date)s
OR (from_date < %(from_date)s AND to_date > %(to_date)s))