@@ -22,21 +22,21 @@ def execute(filters: Filters | None = None) -> tuple:
2222 if filters .to_date <= filters .from_date :
2323 frappe .throw (_ ('"From Date" can not be greater than or equal to "To Date"' ))
2424
25- columns = get_columns ()
25+ columns = get_columns (filters )
2626 data = get_data (filters )
2727 charts = get_chart_data (data , filters )
2828 return columns , data , None , charts
2929
3030
31- def get_columns () -> list [dict ]:
32- return [
33- {
34- "label " : _ ( "Leave Type" ) ,
35- "fieldtype " : "Link " ,
36- "fieldname " : "leave_type" ,
37- "width " : 200 ,
38- "options" : "Leave Type" ,
39- },
31+ def get_columns (filters : Filters ) -> list [dict ]:
32+ leave_type_column = {
33+ "label" : _ ( "Leave Type" ),
34+ "fieldtype " : "Link" ,
35+ "fieldname " : "leave_type " ,
36+ "width " : 200 ,
37+ "options " : "Leave Type" ,
38+ }
39+ employee_columns = [
4040 {
4141 "label" : _ ("Employee" ),
4242 "fieldtype" : "Link" ,
@@ -51,6 +51,22 @@ def get_columns() -> list[dict]:
5151 "width" : 100 ,
5252 "options" : "employee" ,
5353 },
54+ {
55+ "label" : _ ("Branch" ),
56+ "fieldtype" : "Link" ,
57+ "fieldname" : "branch" ,
58+ "width" : 120 ,
59+ "options" : "Branch" ,
60+ },
61+ ]
62+
63+ if filters .get ("consolidate_by" ) == "Employee" :
64+ first_columns = [* employee_columns , leave_type_column ]
65+ else :
66+ first_columns = [leave_type_column , * employee_columns ]
67+
68+ return [
69+ * first_columns ,
5470 {
5571 "label" : _ ("Opening Balance" ),
5672 "fieldtype" : "float" ,
@@ -89,54 +105,79 @@ def get_data(filters: Filters) -> list:
89105 active_employees = get_employees (filters )
90106
91107 precision = cint (frappe .db .get_single_value ("System Settings" , "float_precision" ))
92- consolidate_leave_types = len (active_employees ) > 1 and filters .consolidate_leave_types
93- row = None
108+
109+ consolidate_by = filters .get ("consolidate_by" )
110+ if not consolidate_by and filters .get ("consolidate_leave_types" ):
111+ consolidate_by = "Leave Type"
112+
113+ consolidate_leave_types = len (active_employees ) > 1 and consolidate_by == "Leave Type"
114+ consolidate_by_employee = len (leave_types ) > 1 and consolidate_by == "Employee"
94115
95116 data = []
96117
118+ if consolidate_by_employee :
119+ for employee in active_employees :
120+ data .append (
121+ {
122+ "employee" : employee .name ,
123+ "employee_name" : employee .employee_name ,
124+ "branch" : employee .branch ,
125+ }
126+ )
127+
128+ for leave_type in leave_types :
129+ row = get_leave_balance_row (employee , leave_type , filters , precision )
130+ del row .employee
131+ del row .employee_name
132+ del row .branch
133+ data .append (row )
134+
135+ return data
136+
97137 for leave_type in leave_types :
98138 if consolidate_leave_types :
99139 data .append ({"leave_type" : leave_type })
100- else :
101- row = frappe ._dict ({"leave_type" : leave_type })
102140
103141 for employee in active_employees :
142+ row = get_leave_balance_row (employee , leave_type , filters , precision )
104143 if consolidate_leave_types :
105- row = frappe ._dict ()
106- else :
107- row = frappe ._dict ({"leave_type" : leave_type })
144+ del row .leave_type
145+ data .append (row )
108146
109- row .employee = employee .name
110- row .employee_name = employee .employee_name
147+ return data
111148
112- leaves_taken = (
113- get_leaves_for_period (employee .name , leave_type , filters .from_date , filters .to_date ) * - 1
114- )
115149
116- new_allocation , expired_leaves , carry_forwarded_leaves = get_allocated_and_expired_leaves (
117- filters .from_date , filters .to_date , employee .name , leave_type
118- )
119- on_allocation_boundary = is_opening_balance_on_allocation_boundary (
120- employee .name , leave_type , filters
121- )
122- opening = get_opening_balance (
123- employee .name , leave_type , filters , carry_forwarded_leaves , on_allocation_boundary
124- )
125- allocated_leaves = new_allocation + carry_forwarded_leaves
126- if on_allocation_boundary :
127- allocated_leaves -= carry_forwarded_leaves
128-
129- row .leaves_allocated = flt (allocated_leaves , precision )
130- row .leaves_expired = flt (expired_leaves , precision )
131- row .opening_balance = flt (opening , precision )
132- row .leaves_taken = flt (leaves_taken , precision )
133-
134- closing = allocated_leaves + opening - (row .leaves_expired + leaves_taken )
135- row .closing_balance = flt (closing , precision )
136- row .indent = 1
137- data .append (row )
150+ def get_leave_balance_row (employee : dict , leave_type : str , filters : Filters , precision : int ) -> frappe ._dict :
151+ row = frappe ._dict (
152+ leave_type = leave_type ,
153+ employee = employee .name ,
154+ employee_name = employee .employee_name ,
155+ branch = employee .branch ,
156+ )
138157
139- return data
158+ leaves_taken = get_leaves_for_period (employee .name , leave_type , filters .from_date , filters .to_date ) * - 1
159+
160+ new_allocation , expired_leaves , carry_forwarded_leaves = get_allocated_and_expired_leaves (
161+ filters .from_date , filters .to_date , employee .name , leave_type
162+ )
163+ on_allocation_boundary = is_opening_balance_on_allocation_boundary (employee .name , leave_type , filters )
164+ opening = get_opening_balance (
165+ employee .name , leave_type , filters , carry_forwarded_leaves , on_allocation_boundary
166+ )
167+ allocated_leaves = new_allocation + carry_forwarded_leaves
168+ if on_allocation_boundary :
169+ allocated_leaves -= carry_forwarded_leaves
170+
171+ row .leaves_allocated = flt (allocated_leaves , precision )
172+ row .leaves_expired = flt (expired_leaves , precision )
173+ row .opening_balance = flt (opening , precision )
174+ row .leaves_taken = flt (leaves_taken , precision )
175+
176+ closing = allocated_leaves + opening - (row .leaves_expired + leaves_taken )
177+ row .closing_balance = flt (closing , precision )
178+ row .indent = 1
179+
180+ return row
140181
141182
142183def get_leave_types () -> list [str ]:
@@ -147,7 +188,7 @@ def get_leave_types() -> list[str]:
147188def get_employees (filters : Filters ) -> list [dict ]:
148189 conditions = {}
149190
150- for field in ["company" , "department" ]:
191+ for field in ["company" , "department" , "branch" ]:
151192 if filters .get (field ):
152193 conditions [field ] = filters .get (field )
153194
@@ -160,7 +201,7 @@ def get_employees(filters: Filters) -> list[dict]:
160201 return frappe .get_list (
161202 "Employee" ,
162203 filters = conditions ,
163- fields = ["name" , "employee_name" , "department" ],
204+ fields = ["name" , "employee_name" , "department" , "branch" ],
164205 )
165206
166207
0 commit comments