2929 get_leave_allocation_records ,
3030 get_leave_balance_on ,
3131 get_leave_details ,
32+ get_new_and_cf_leaves_taken ,
3233)
3334from hrms .hr .doctype .leave_policy_assignment .leave_policy_assignment import (
3435 create_assignment_for_multiple_employees ,
@@ -97,6 +98,9 @@ def setUp(self):
9798 from_date = get_year_start (getdate ())
9899 to_date = get_year_ending (getdate ())
99100 self .holiday_list = make_holiday_list (from_date = from_date , to_date = to_date )
101+ list_without_weekly_offs = make_holiday_list (
102+ "Holiday List w/o Weekly Offs" , from_date = from_date , to_date = to_date , add_weekly_offs = False
103+ )
100104
101105 if not frappe .db .exists ("Leave Type" , "_Test Leave Type" ):
102106 frappe .get_doc (
@@ -922,8 +926,12 @@ def test_get_leave_details_for_dashboard(self):
922926 self .assertEqual (leave_allocation ["leaves_pending_approval" ], 1 )
923927 self .assertEqual (leave_allocation ["remaining_leaves" ], 26 )
924928
925- @set_holiday_list ("Salary Slip Test Holiday List " , "_Test Company" )
929+ @set_holiday_list ("Holiday List w/o Weekly Offs " , "_Test Company" )
926930 def test_leave_details_with_expired_cf_leaves (self ):
931+ """Tests leave details:
932+ Case 1: All leaves available before cf leave expiry
933+ Case 2: Remaining Leaves after cf leave expiry
934+ """
927935 employee = get_employee ()
928936 leave_type = create_leave_type (
929937 leave_type_name = "_Test_CF_leave_expiry" ,
@@ -936,11 +944,11 @@ def test_leave_details_with_expired_cf_leaves(self):
936944 "Leave Ledger Entry" , {"transaction_name" : leave_alloc .name , "is_carry_forward" : 1 }, "to_date"
937945 )
938946
939- # all leaves available before cf leave expiry
947+ # case 1: all leaves available before cf leave expiry
940948 leave_details = get_leave_details (employee .name , add_days (cf_expiry , - 1 ))
941949 self .assertEqual (leave_details ["leave_allocation" ][leave_type .name ]["remaining_leaves" ], 30.0 )
942950
943- # cf leaves expired
951+ # case 2: cf leaves expired
944952 leave_details = get_leave_details (employee .name , add_days (cf_expiry , 1 ))
945953 expected_data = {
946954 "total_leaves" : 30.0 ,
@@ -949,6 +957,119 @@ def test_leave_details_with_expired_cf_leaves(self):
949957 "leaves_pending_approval" : 0.0 ,
950958 "remaining_leaves" : 15.0 ,
951959 }
960+
961+ self .assertEqual (leave_details ["leave_allocation" ][leave_type .name ], expected_data )
962+
963+ @set_holiday_list ("Holiday List w/o Weekly Offs" , "_Test Company" )
964+ def test_leave_details_with_application_across_cf_expiry (self ):
965+ """Tests leave details with leave application across cf expiry, such that:
966+ cf leaves are partially expired and partially consumed
967+ """
968+ employee = get_employee ()
969+ leave_type = create_leave_type (
970+ leave_type_name = "_Test_CF_leave_expiry" ,
971+ is_carry_forward = 1 ,
972+ expire_carry_forwarded_leaves_after_days = 90 ,
973+ ).insert ()
974+
975+ leave_alloc = create_carry_forwarded_allocation (employee , leave_type )
976+ cf_expiry = frappe .db .get_value (
977+ "Leave Ledger Entry" , {"transaction_name" : leave_alloc .name , "is_carry_forward" : 1 }, "to_date"
978+ )
979+
980+ # leave application across cf expiry
981+ application = make_leave_application (
982+ employee .name ,
983+ cf_expiry ,
984+ add_days (cf_expiry , 3 ),
985+ leave_type .name ,
986+ )
987+
988+ leave_details = get_leave_details (employee .name , add_days (cf_expiry , 4 ))
989+ expected_data = {
990+ "total_leaves" : 30.0 ,
991+ "expired_leaves" : 14.0 ,
992+ "leaves_taken" : 4.0 ,
993+ "leaves_pending_approval" : 0.0 ,
994+ "remaining_leaves" : 12.0 ,
995+ }
996+
997+ self .assertEqual (leave_details ["leave_allocation" ][leave_type .name ], expected_data )
998+
999+ @set_holiday_list ("Holiday List w/o Weekly Offs" , "_Test Company" )
1000+ def test_leave_details_with_application_across_cf_expiry_2 (self ):
1001+ """Tests the same case as above but with leave days greater than cf leaves allocated"""
1002+ employee = get_employee ()
1003+ leave_type = create_leave_type (
1004+ leave_type_name = "_Test_CF_leave_expiry" ,
1005+ is_carry_forward = 1 ,
1006+ expire_carry_forwarded_leaves_after_days = 90 ,
1007+ ).insert ()
1008+
1009+ leave_alloc = create_carry_forwarded_allocation (employee , leave_type )
1010+ cf_expiry = frappe .db .get_value (
1011+ "Leave Ledger Entry" , {"transaction_name" : leave_alloc .name , "is_carry_forward" : 1 }, "to_date"
1012+ )
1013+
1014+ # leave application across cf expiry, 20 days leave
1015+ application = make_leave_application (
1016+ employee .name ,
1017+ add_days (cf_expiry , - 16 ),
1018+ add_days (cf_expiry , 3 ),
1019+ leave_type .name ,
1020+ )
1021+
1022+ # 15 cf leaves and 5 new leaves should be consumed
1023+ # after adjustment of the actual days breakup (17 and 3) because only 15 cf leaves have been allocated
1024+ new_leaves_taken , cf_leaves_taken = get_new_and_cf_leaves_taken (leave_alloc , cf_expiry )
1025+ self .assertEqual (new_leaves_taken , - 5.0 )
1026+ self .assertEqual (cf_leaves_taken , - 15.0 )
1027+
1028+ leave_details = get_leave_details (employee .name , add_days (cf_expiry , 4 ))
1029+ expected_data = {
1030+ "total_leaves" : 30.0 ,
1031+ "expired_leaves" : 0 ,
1032+ "leaves_taken" : 20.0 ,
1033+ "leaves_pending_approval" : 0.0 ,
1034+ "remaining_leaves" : 10.0 ,
1035+ }
1036+
1037+ self .assertEqual (leave_details ["leave_allocation" ][leave_type .name ], expected_data )
1038+
1039+ @set_holiday_list ("Holiday List w/o Weekly Offs" , "_Test Company" )
1040+ def test_leave_details_with_application_after_cf_expiry (self ):
1041+ """Tests leave details with leave application after cf expiry, such that:
1042+ cf leaves are completely expired and only newly allocated leaves are consumed
1043+ """
1044+ employee = get_employee ()
1045+ leave_type = create_leave_type (
1046+ leave_type_name = "_Test_CF_leave_expiry" ,
1047+ is_carry_forward = 1 ,
1048+ expire_carry_forwarded_leaves_after_days = 90 ,
1049+ ).insert ()
1050+
1051+ leave_alloc = create_carry_forwarded_allocation (employee , leave_type )
1052+ cf_expiry = frappe .db .get_value (
1053+ "Leave Ledger Entry" , {"transaction_name" : leave_alloc .name , "is_carry_forward" : 1 }, "to_date"
1054+ )
1055+
1056+ # leave application after cf expiry
1057+ application = make_leave_application (
1058+ employee .name ,
1059+ add_days (cf_expiry , 1 ),
1060+ add_days (cf_expiry , 4 ),
1061+ leave_type .name ,
1062+ )
1063+
1064+ leave_details = get_leave_details (employee .name , add_days (cf_expiry , 4 ))
1065+ expected_data = {
1066+ "total_leaves" : 30.0 ,
1067+ "expired_leaves" : 15.0 ,
1068+ "leaves_taken" : 4.0 ,
1069+ "leaves_pending_approval" : 0.0 ,
1070+ "remaining_leaves" : 11.0 ,
1071+ }
1072+
9521073 self .assertEqual (leave_details ["leave_allocation" ][leave_type .name ], expected_data )
9531074
9541075 @set_holiday_list ("Salary Slip Test Holiday List" , "_Test Company" )
@@ -975,6 +1096,7 @@ def test_get_leave_allocation_records(self):
9751096 "unused_leaves" : 15.0 ,
9761097 "new_leaves_allocated" : 15.0 ,
9771098 "leave_type" : leave_type .name ,
1099+ "employee" : employee .name ,
9781100 }
9791101 self .assertEqual (details .get (leave_type .name ), expected_data )
9801102
0 commit comments