
    8{jW                      T    d dl Z d dlmZmZmZmZ d Z G d dej                        Zy)    N)_apifieldsmodelsc                     |dk(  rt        d      S |dk(  rt        d      S |dk(  r)d } ||       ||      }}|r	|r| d| S t        d      S | xs d	}|d
kD  rt        dt        |            S t        d      S )a  Python port of the Dashboard's own JS _formatLeavePeriod() (dashboard_
    action.js) -- an email can't load browser-side JS, so this is kept in
    sync by hand, same convention as xeno_leave's Analysis checklist email
    port. Must stay word-for-word equivalent to the JS version.
first_halfzHalf Day - AMsecond_halfzHalf Day - PM	part_timec                 ~    | s| dk7  ryt        |       }t        | |z
  dz        }|dk  rdnd}|dz  xs d}d|||fz  S )Nr    <      ampmz
%d:%02d %s)intround)
hour_floath24mperiodh12s        (xeno_hr_dashboard/models/hr_dashboard.pyfmt12z(_xeno_format_leave_period.<locals>.fmt12   sW    */j/CzC'2-.A 2XT4F(.bC36"222    z - z	Part Timer      z%s daysz1 day)r   r   )number_of_daysrequest_unit	hour_fromhour_tor   ftdayss           r   _xeno_format_leave_periodr#      s    
 |#!!}$!!{"	3 Yw1 Q!Cs|:AkN:QD(,q1Yd$@aj@r   c                   \    e Zd ZdZdZej                  d        Zej                  d        Zy)XenoHrDashboardzxeno.hr.dashboarda   Admin/HR overview dashboard data, mirrors XENHR's DashboardController::adminDashboard. No stored data of its own -- a thin aggregation layer over hr.employee/hr.leave/xeno.attendance.report so the Dashboard, System Access and Monthly Attendance screens never disagree on the same numbers.c           
         t         j                  j                         }| j                  d   j	                  dg      }| j                  d   j	                  dg      }| j                  d   }| j                  d   }|j                         j                         }i }g }t        ddd      D ]&  }	|t        j                  |		      z
  }
|
j                  |
j                  f}||vr  |j                         j                  | ||<   ||   }|
j                  d
      }|
j                         dk\  }||d   v }t               }|d   D ]F  }t        |j!                  d      xs d      }|j!                  d|z        s6|j#                  |       H |s|s||z  }t%        |      }|j'                  ||
j                  d      |t)        ||z
  d      d       ) |d   }||d   |d   ||dS )aq  Stat cards + weekly bar chart. 'Present' for a day = at least
        one scan (app or biometric, already merged by
        xeno.attendance.report's HRSystem SP call) OR an auto-fill-exempt
        employee on a working day -- exactly the same "present" xeno_
        attendance's own Monthly/My Attendance pages use, on purpose.
        'Absent' is XENHR's own (unadjusted) total-minus-present, matching
        DashboardController::adminDashboard exactly rather than "fixing" it
        to exclude leave/weekends -- that's a real XENHR behavior, not a
        bug, and this dashboard is meant to read the same as XENHR did.hr.employee)active=Thr.leave)statein)confirm	validate1zxeno.attendance.reportzxeno.attendance.auto.rule   r"   z%Y-%m-%d   holidaysrowsemployee_coder   z%s.Inz%ar   )datedaypresentabsentr8   r9   )total_employeespresent_todayabsent_todaypending_leavesweekly_attendance)datetimer6   todayenvsearch_countsudoget_auto_fill_codesrange	timedeltayearmonthget_month_reportstrftimeweekdaysetstrgetaddlenappendmax)selfr@   r:   r=   ReportAutoRuleauto_fill_codesmonth_cacheweeklydeltar7   keydatadatestr
is_weekend
is_holidaypresent_codesrowcoder8   today_entrys                        r   get_admin_statszXenoHrDashboard.get_admin_stats(   s    ##%((=1>>@U?VW*-::679 238878"--/==?1b"% 	E(,,%88C88SYY'C+%#A6;;=#A#A3#GC s#Dll:.G!+J D$44JEMF| ,377?39r:777W,-!%%d+, j0-(GMM||D)"o7;	 '	4 Rj.(3'1,!'
 	
r   c                    | j                   d   j                         j                  ddd|fdd|fgg d      }t        |D ch c]  }|d   s	|d   d	    c}      }|rE| j                   d
   j                         j                  dd|fgg d      D ci c]  }|d   |
 c}ni }d }g }|D ]  }	|j	                  |	d   d	   i       }
t
        j                  j                  |	d         }t
        j                  j                  |	d         t        j                  d      z   }|j                  |
j	                  d      xs |	d   d   |
j	                  d      xs d|
j	                  d      r|
d   d   nd|	d   r|	d   d   ndt        |	d   |	d   |	d   |	d          ||       ||      |	d   dk(  d        | j                   d   j                         j                  ddd|fd d|fgg d!      }t        |D ch c]  }|d   s	|d   d	    c}      }|rE| j                   d
   j                         j                  dd|fgg d      D ci c]  }|d   |
 c}ni }|D ]  }|j	                  |d   d	   i       }
t
        j                  j                  |d         }t
        j                  j                  |d          t        j                  d      z   }|j                  |
j	                  d      xs |d   d   |
j	                  d      xs d|
j	                  d      r|
d   d   ndd"t        |d   d#d$d$       ||       ||      |d   d%k(  d        |S c c}w c c}w c c}w c c}w )&a  Server-side port of the Dashboard's own "Employee Attendance
        Report" widget query (dashboard_action.js's loadLeaveAttendance()) --
        approved/pending leaves covering date_str. Used by the daily email
        cron (hr_dashboard_email.py) so the emailed table is built from the
        exact same rule as what HR sees live on the page; kept in sync by
        hand since the widget itself stays client-side JS.r*   )r+   r,   )r-   r.   validaterequest_date_fromz<=request_date_toz>=)	employee_idholiday_status_idrf   rg   r   xeno_request_unitrequest_hour_fromrequest_hour_tor+   rh   r   r'   idr,   )namedepartment_id	job_titlec                 $    | j                  d      S )Nz%d %b %Y)rJ   )ds    r   fmt_datez;XenoHrDashboard.get_leave_attendance_rows.<locals>.fmt_datex   s    ::j))r   r   r1   rn   rp   -ro   ri   r   rj   rk   rl   r+   re   )rn   position
department
leave_typetotal_leave_days
leave_dateback_to_work_dateapprovedzhr.business.trip)r+   r,   )r-   acknowledged	date_fromdate_to)rh   r}   r~   r   r+   zBusiness Trip . BTfull_dayNr|   )rA   rC   search_readlistrN   r   Datefrom_stringr?   rF   rQ   r#   )rS   date_strleaveslemp_idse	emp_by_idrs   r4   leaveemp
leave_fromback_to_worktripsr!   trip_emp_idstrip_emp_by_idtrip	trip_froms                      r   get_leave_attendance_rowsz)XenoHrDashboard.get_leave_attendance_rowsa   s    *%**,88E$dH5"D(3
e
 VPq?O-(+PQ  !% 7 < < > J Jg&')O!Q
AdGQJ
  	
	*  	E--m 4Q 7<C007J1KLJ!;;2259J3KLxOaOaghOiiLKKB5+?+BGGK07C9<9Qc/215WZ?DEX?Ye$78;_b$=*+U3F-G-.6G0H%J 'z2%-l%;!'Nj8 		, +,113??<dH-D(+
 O
 %TQ1]CSQ}-a0TU  !% 7 < < > J Jl+,.T!V
AdGQJ
  " 	  	D $$T-%8%;R@C//[0ABI!;;224	?ChFXFX^_F``LKKA4+>q+AGGK07C9<9Qc/215WZ2$=dCS>TV`bfhl$m&y1%-l%; M^;	 			 w Q
N U
s$   
M 
M M%?
M*

M*M/N)	__name__
__module____qualname___name_descriptionr   modelrc   r    r   r   r%   r%      sE    E	I  	YY6
 6
p 	YYK Kr   r%   )	r?   odoor   r   r   r   r#   AbstractModelr%   r   r   r   <module>r      s(     ' 'A0Of** Or   