@@ -111,6 +111,19 @@ def on_submit(self):
111111 self .notify_employee ()
112112
113113 self .create_leave_ledger_entry ()
114+ # create a reverse ledger entry for backdated leave applications for whom expiry entry already exists
115+ leave_allocation = self .get_leave_allocation ()
116+ if not leave_allocation :
117+ return
118+ to_date = leave_allocation .get ("to_date" )
119+ can_expire = not frappe .db .get_value ("Leave Type" , self .leave_type , "is_carry_forward" )
120+
121+ if to_date < getdate () and can_expire :
122+ args = frappe ._dict (
123+ leaves = self .total_leave_days , from_date = to_date , to_date = to_date , is_carry_forward = 0
124+ )
125+ create_leave_ledger_entry (self , args )
126+
114127 self .reload ()
115128
116129 def before_cancel (self ):
@@ -250,6 +263,22 @@ def validate_back_dated_application(self):
250263 ).format (formatdate (future_allocation [0 ].from_date ), future_allocation [0 ].name )
251264 )
252265
266+ def get_leave_allocation (self ):
267+ date = self .posting_date or getdate ()
268+ LeaveAllocation = frappe .qb .DocType ("Leave Allocation" )
269+ leave_allocation = (
270+ frappe .qb .from_ (LeaveAllocation )
271+ .select (LeaveAllocation .to_date )
272+ .where (
273+ ((LeaveAllocation .from_date <= date ) & (date <= LeaveAllocation .to_date ))
274+ & (LeaveAllocation .docstatus == 1 )
275+ & (LeaveAllocation .leave_type == self .leave_type )
276+ & (LeaveAllocation .employee == self .employee )
277+ )
278+ ).run (as_dict = True )
279+
280+ return leave_allocation [0 ] if leave_allocation else None
281+
253282 def update_attendance (self ):
254283 if self .status != "Approved" :
255284 return
0 commit comments