
    siϔ                        d dl Z d dlZd dlZd dlZd dlZd dlmZmZmZmZ d dl	Z
d dlZd dlmZ d dlmZ d dlmZ d dlmZ d dlmZ d dlmZ d d	lmZ d d
lmZmZmZmZ d dlm Z  d dl!m"Z" d dl#m$Z$ d dl%m&Z& d dl'm(Z) d dl*m+Z+m,Z,m-Z-m.Z. d dl/m0Z0m1Z1 d dl2m3Z3 d dl4m5Z5 d dl6m7Z7m8Z8 i dddddddddddddddd d!dd"d#d$d!dd"d%d d&dd"d'dd(ddd)dd(ddd*d+d,ddd-d+d.ddd/d+d0ddd1d2d3ddd4d2d5ddd6dd7ddd8dd7ddd9dd:ddd;dd<ddd=d>ddd?d@id?d@id?d2id?d@idAZ9dB Z: ejv                  dC e<e:             dpdDZ=dqdEZ>dqdFZ?dqdGZ@dH ZAdI ZBdJ ZCdKdKdKdLgaDdM ZEdN ZFdO ZGdP ZHdQ ZIdReJdSeKdTeLfdUZMdV ZNdqdWZOdX ZPdY ZQdZ ZRd[ ZSdrd\ZTd] ZUd^ ZVd_ ZWd` ZXda ZYdbedcedTeJfddZZde Z[df Z\dg Z]dh Z^di Z_dj Z`dk Zai dldmfdnZbdo Zcy)s    N)datedatetimetime	timedelta)apps)settings)Group)finders)ObjectDoesNotExist)	Paginator)models)
ForeignKeyManyToManyFieldOneToOneFieldQ)Lower)ModelChoiceField)HttpResponse)render_to_string)gettext)CompanyCompanyLeavesDynamicPaginationHolidays)EmployeeEmployeeWorkInformation)NESTED_SUBORDINATE_VISIBILITY_thread_locals)HORILLA_DATE_FORMATSHORILLA_TIME_FORMATSoffline_employees
attendancezemployee.view_employeeT)apppermneed_reporting_manageronline_employeesoverall_leave_chartleavezleave.view_leaverequest)r$   r%   hired_candidatesrecruitmentzrecruitment.view_candidate)r$   r%   need_stage_manageronboarding_candidates
onboardingrecruitment_analyticszrecruitment.view_recruitmentattendance_analyticzattendance.view_attendancehours_chartobjective_statuspmszpms.view_employeeobjectivekey_result_statuszpms.view_employeekeyresultfeedback_statuszpms.view_feedbackshift_request_approvebasezbase.change_shiftrequestwork_type_request_approvezbase.change_worktyperequestovertime_approvezattendance.change_attendanceattendance_validateleave_request_approvezleave.change_leaverequestleave_allocation_approvez#leave.change_leaveallocationrequestassetzasset.change_assetrequestr$   employee)asset_request_approveemployees_chartgender_chartdepartment_chartemployee_work_infoc                     t         j                  j                  | j                  j	                               j                         S )z@
    Restrict Group users_count to selected company context
    )employee_user_id__in)r   objectsfilteruser_setallcount)selfs    0/var/www/python-projects/worksol/base/methods.pyusers_countrM      s4     ""8I8I8K"LRRTT    rM   c                 <   | j                   }|j                  |      r|S | s|S t        r| j                   j                  j                  g}t        di | d|i}	  |j                  di | d|ij                  | dd      }|j                         sn|}|t        di | d|iz  }R|j                  |      S t        j                  j                  |      j                         }|r| d}	 |j                  di |	|i}|S |j                  |      }|S )	J
    This method is used to filter out subordinates queryset element.
    .__employee_work_info__reporting_manager_id__inT__idflatemployee_user_id*__employee_work_info__reporting_manager_id)5employee_id__employee_work_info__reporting_manager_id )userhas_permr   employee_getidr   rG   values_listexistsr   rF   first)
requestquerysetr%   fieldrZ   current_managersall_subordinatessub_managersmanagerfilter_expressions
             rL   filtersubordinatesri      st    <<D}}T$LL%%((
  
'GHJZ
 *8?? gKLN^ kUG4.tk4	 
  &&(+ !gKLl!   /00%%t%<BBDG$g%OP"8??B&7%AB>E  H OrN   c                     | j                   }|j                  |      r|S |j                  | j                   j                        }|S )rP   employee_id)rZ   r[   rG   r\   ra   rb   r%   rZ   s       rL   filter_own_recordsrn      s=     <<D}}T7<<+D+DEHOrN   c                 z    | j                   }|j                  |      r|S t        | ||      t        | ||      z  }|S )zb
    This method is used to filter out subordinates queryset along with own queryset element.
    )rZ   r[   rn   ri   rm   s       rL   #filter_own_and_subordinate_recordesrp      sG     <<D}}T!'8T:=O4> H OrN   c                    | j                   }|j                  |      r|S | s|S t        r| j                   j                  j                  g}t        |      }	 |j                  |      j                  dd      }|j                         sn|}|t        |      z  }F|j                  |      j                         S t        j                  j                  |      j                         }|j                  |      }|S )z[
    This method is used to filter out all subordinates in the entire reporting chain.
    ),employee_work_info__reporting_manager_id__inTr]   rS   rU   (employee_work_info__reporting_manager_id)rZ   r[   r   r\   r]   r   rG   r^   r_   distinctr   rF   r`   )ra   rb   r%   rZ   rd   re   rf   rg   s           rL   filtersubordinatesemployeemodelrv      s    <<D}}T$ LL%%((
 9I

 #??=M + k$Tk*   &&(+=I!   /099;;%%t%<BBDGPHOrN   c                     	 | j                   }|j                  j                  j                         j	                         S #  Y yxY w)zX
    This method is used to check weather the employee is reporting manager or not.
    F)rZ   r\   reporting_managerrI   r_   )ra   rZ   s     rL   is_reportingmanagerry      s>    ||  22668??AAs   =A   Ac                    | j                   }|j                  |      r|S t        j                  j	                  |      j                         }t        j                  j	                  |      }||j                  d   _        |S NrU   rs   rl   rZ   r[   r   rF   rG   r`   fieldsrb   ra   formr%   rZ   rg   rb   s         rL   choosesubordinatesr     sp    
 <<D}}T%%t%<BBDG&&PW&XH*2DKK'KrN   c                    | j                   }|j                  |      r|S t        j                  j	                  |      j                         }t        j                  j	                  |      }||j                  d   _        |S r{   r|   r~   s         rL   choosesubordinatesemployeemodelr     sn    <<D}}T%%t%<BBDG&&PW&XH*2DKK'KrN    r]   rc   orderingc                    | j                   j                  }t        D cg c]  }|d   |k(  s| }}|r|d   nd}||ddd}t        j                  |       | j                  j                  |      }| j                  j                  |      j                  |      }d}	|,|dk7  r&|j                  d      }
|j                  j                  }||d<   |d	z  dk(  rd|d
<   |}	n
d|d
<   d| }	|
D ]  }|j                  |      }t        |t        j                        r|j                  j                  }Et        |t        j                         r3|j#                  t%        |            }|j'                  |d
    d      }|j'                  |d
    |       } t        D cg c]  }|d   |k7  s| c}at        j                  |       t)        | di        |	| j*                  d<   |S c c}w c c}w )z>
    This method is used to sort query set by asc or desc
    r]   r   N-r   r   __rc      r   )lower_titler   sort_optionorder)rZ   r]   orderingListappendGETgetgetlistrJ   splitmodel_meta	get_field
isinstancer   r   related_model	CharFieldannotater   order_bysetattrr   )ra   rb   keyr]   xfiltered_listr   sortby
sort_countr   field_parts
model_metapartrc   items                  rL   r   r   *  s   
 
B !->1$2Q>M>#0}QdH

 	H%[[__S!F$$S)//7JEflll4(^^))
 #>Q#&HZ E#%HZ xLE 		TD((.E%!2!23"0066
eV%5%56'00U6]0KH'00HZ4H3I1UVH'00HZ4H3I&1RSH		T *6Jdr9IJH%G]B'#(G OW ?L Ks   G-G-%G23G2c                      t        j                  dd      } t        j                  dd      }t        j                  dd      }| |k(  s
||k(  s|| k(  r
t                d|  d| d| dS )Nr      zrgba(z, z , 0.7))randomrandintrandom_color_generator)rgbs      rL   r   r   `  sf    q#Aq#Aq#AAva16 1#Rs"QCw''rN   c                     g d}| t        |      kD  r5t        | t        |      z
        D ]  }|j                  t                       g }t        |       D ]"  }|j                  ||t        |      z            $ |S )N)zrgba(255, 99, 132, 1)zrgba(54, 162, 235, 1)zrgba(255, 206, 86, 1)zrgba(75, 192, 192, 1)zrgba(153, 102, 255, 1)zrgba(255, 159, 64, 1))lenranger   r   )
num_colorscolor_paletteicolorss       rL   generate_colorsr   k  s    M C&&zC$667 	;A  !7!9:	; F: =mAM(:$:;<= MrN   c                 d   t        j                         }g }|D ]P  }|j                  j                  D ]5  }t	        |t
              s|j                  | k(  s$|j                  |        P R |D ]  }|j                  j                         }|D ]  }t	        |t
              s|j                         }|j                  }	||v s5||   }
t        |
d         } |j                  j                  di |	|ij                         }t        |      g||<     | j                  j                         }|D cg c]&  }t	        |t
        xs t               r|j                  ( }}|D cg c]	  }||v s| }}|D ]  }		 ||	   D cg c]  }t        |       }}| j                  j#                  |	      j$                  j&                  }|j                  j                  |      }|D cg c]  }t        |       }}|||	<    |D cg c]  }t	        |t,              s|j                  ! }}|D cg c]	  }||v s| }}|D ]  }		 | j                  j#                  |	      j$                  j&                  }||	   D cg c]  }t        |       }}|j                  j                  |      }|D cg c]  }t        |       c}||	<    |D cg c]*  }d|v r$|j/                  d      s|j/                  d      s|, }}|D ]B  }|j1                  d      }||   }|dgk7  s |dgk7  s'|dgk7  s.t3        | ||      }|>|||<   D d	|v rF|d	   d   }| j                  j                  |
      j                         }t        |      }|d	= |g|d<   |j5                         D cg c]  \  }}|dgk(  s|dv sd|v r| }}}d|vrd|v r|d= |D ]  }||=  |S c c}w c c}w c c}w c c}w # t(        t*        f$ r Y w xY wc c}w c c}w c c}w c c}w # t(        t*        f$ r Y w xY wc c}w c c}}w )Nr   id__inr   gtelteunknowntruefalser]   r]   Object)r   orderbyviewpagegroup_bytargetrpageinstances_ids
asset_listvpageopageclick_idcsrfmiddlewaretokenassign_sortbyrequest_sortbyasset_underdynamic_pagesearchsearch_fieldrY   )r   
get_modelsr   r}   r   r   r   r   
get_fieldsrelated_query_namenameintrF   rG   r`   strr   r   remote_fieldr   r   
ValueErrorr   endswithr   get_nested_instancesitems)r   	data_dict
all_modelsrelated_modelsother_modelrc   r   related_model_fieldsrelated_name
field_namerelated_id_list
related_idfiltered_instancemodel_fieldsforeign_key_field_namesr   present_foreign_key_field_namesvaluefield_valuesrelated_instancesinstancerelated_stringsmany_to_many_field_names present_many_to_many_field_namesnested_fieldsfield_namesnested_instancer]   objectkeys_to_removes                                 rL   get_key_instancesr     s   "J N "  &&-- 	E%,1D1D1M%%k2		 ( G,22==? * 	GE%,$779"ZZ
  9,&/&=O!$_Q%7!8J )E(=(=(D(D )%z2)eg &
 033D/E.FIl+%	GG4 ;;))+L "eZ8=9 	

  /'#2B'# ' 6 
	4=j4IJ5CJJLJ "KK11*=JJPPM !. 5 5 < <L < Q >OOs8}OOO %4Ij!* !- 
5/0R

   
 0(3)3C($ ( 7 
	!KK11*=JJPPM4=j4IJ5CJJLJ !. 5 5 < <L < Q DU$UxS]$UIj!" 3;s||E23<<;N 	M 
  
1iio ~YK'(	)25+|TO*!0	#
1 yt_Q%%%,224VdO%h	( $//+CYK

& S - 	N 2 y Y&.) cNW' K P #J/ 		 ( K %V"J/ 		.s   2+O#	O-O9O' OAO'#O"5O'O=O=,	P6P6P8P
"P,P>P
/P'P,
O''O:9O:
PP$#P$c                    	 | }|D ]5  }	 |j                   j                  |      }	 j                  j                  }7 |D cg c]  }|dk7  s	t	        |       }}|j
                  j                  |      }|D 	cg c]  }	t        |	       }
}	d|v r|
j                  dd       |
S #  Y xY w#  Y xY wc c}w c c}	w # t        t        f$ r Y y w xY w)Nnot_setr   r   )r   r   r   r   r   rF   rG   r   insertr   r   )r   r   r   r   r   related_fieldr   
object_idsr   r   results              rL   r   r     s    % 	J - 3 3 = =j I - : : @ @	 /;QUey>Pc%jQ
Q)1188
8K0ABH#h-BB$MM!Y'QB 
+ sV   C  B(B/C  
B6B6"C  <B;C  (B,*C  /B31C   CCnumbersinput_numberreturnc                     |}|}	 | j                  |      }|dkD  r	| |dz
     }n| d   }|dz   t        |       k(  r| d   }n|t        |       k  r	| |dz      }n| d   }||fS #  Y ||fS xY w)zB
    This method is used to find previous and next of numbers
    r      )indexr   )r   r   previous_numbernext_numberr  s        rL   closest_numbersr  2  s     #OKl+19%eai0O%bkO19G$!!*KS\!!%!),K!!*K [))[))s   AA! !A(c                     t         j                  j                  |      j                         }|r"|j                  r|j                  j
                  nd}|r"|j                  r|j                  j                  nd}t        | t              rtt        j                  t        |       j                  d      d   d      j                         }t        j                         D ]  \  }}||k(  s|j                  |      }  | S t!        |       t"        k(  rbt        j                  t        |       d      j#                         }t%        j                         D ]  \  }}||k(  s|j                  |      }  | S t        | t              rt        |       } | S )Nrk   zHH:mmzMMM. D, YYYY.r   z%H:%M:%S%Y-%m-%d)r   rF   rG   r`   
company_idtime_formatdate_formatr   r   r   strptimer   r   r!   r   strftimetyper   r    )	r   r>   	work_infor
  r  check_in_timeformat_nameformat_string
start_dates	            rL   format_export_valuer  I  sl   '//6686LRRTI -- 	((  -- 	((  % ))#e**:*:3*?*BJOTTV +?*D*D*F 	>&Kk)%..}=	> L 
e	&&s5z:>CCE
*>*D*D*F 	;&Kk)"++M:	; L 
E8	$E
LrN   c           
         i dt        d      dt        d      dt        d      dt        d      d	t        d
      dt        d      dt        d      dt        d      dt        d      dt        d      dt        d      dt        d      dt        d      dt        d      dt        d      dt        d      dt        d       t        d!      t        d"      t        d#      t        d$      t        d%      t        d&      t        d'      d(}| j                  j                  }g }t        j                         j                  d)      }	| d*|	 d+}i }
 |       }|j                  j                         } || j                        j                  }|rt        | ||      }| j                  j                  d,      }|se|j                  d,   j                  }| j                  j                  d-      }t        j                   |      }|j"                  j%                  |.      }|j                  d,   j&                  D ]$  }|d/   }|d0   }||v s|j)                  ||f       & |D ]  \  }}||v sg |
|<   |D ]  }|}|j+                  d1      }|D ]  }t-        ||d       }| n |d2u rt        d3      }n|d4u rt        d5      }||v r||   }|d6k(  rd7}|d8k(  rt        |j/                               }t1        ||      }|
|   j)                  |         t3        j4                  |
9      }|j6                  j9                  d: t2        j:                  d d d d f   ;      }t=        d<=      }d>| d?|d@<   t3        j>                  |dAB      }|jA                  |d4dCD       |jB                  dC   }|jE                  dEdF       |jG                          |S )GNmaleMalefemaleFemaleotherOtherdraftDraftactiveActiveexpiredExpired
terminated
TerminatedweeklyWeeklymonthlyMonthlyafterAftersemi_monthlyzSemi-MonthlyhourlyHourlydailyDailyfull_dayzFull Day
first_halfz
First Halfsecond_halfzSecond Half	RequestedApproved	CancelledRejectedzCancelled & Rejectedz	Late Comez	Early Out)	requestedapproved	cancelledrejectedcancelled_and_rejected	late_come	early_outr  _z.xlsxselected_fieldsidsr   r   r   r   TYesFNoNone month)datac                      y)Nztext-align: centerrY   )r   s    rL   <lambda>zexport_data.<locals>.<lambda>      rN   )subsetzapplication/ms-excelcontent_typezattachment; filename=""Content-Disposition
xlsxwriter)engineSheet1)r  
sheet_namezA:Z   )$r=  rZ   r\   r   todayr  r   r   r   qsri   r   r}   initialr   jsonloadsrF   rG   choicesr   r   getattrtitler  pd	DataFramestyleapplymap
IndexSlicer   ExcelWriterto_excelsheets
set_columnclose)ra   r   
form_classfilter_class	file_namer%   fields_mappingr>   selected_columns
today_datedata_exportr   r   export_objectsr>  r?  id_listrc   r   r   r   verbose_nameobjnested_attributesattr
data_framestyled_data_frameresponsewriter	worksheets                                 rL   export_datarw  m  s   &	!H+ 	7 	7	
 	!H+ 	1Y< 	ao 	!H+ 	1Y< 	7 	.) 	!H+ 	7 	1Y< 	AjM  	ao!" 	q'#$ {^jM{^jM"#$:";{^{^1N4 ||((H&&z2J+Qzl%0IK<D;;))+L!'++.11N+G^TJkk))*;<O++&78@@kkooe$**S/--W-=./77 2aAhO###UCL1	2 %5 8 
L((*K%% 8$.$4$4T$:!- D#E46E} D=eHEe^dGEN**51EF?E(ekkm,E ,E8<L)007)882 ;/J"((11&r}}QT/B 2  )?@H(>yk&KH"#^^H\:FvUxHh'I#
LLNOrN   c                 >   t        t        dd      }|r|j                  j                  d      nd}t	        j
                  d      }ddi|rddindd}| j                         D ]  }t        |t              s|j                  j                  }|j                  }|dk(  r)|r'|d	k7  r"|j                  j                  |
      |_	        d|j                  |      x}" |j                  j                  di ||_	        |j                  j                         |_	         | S )zU
    Reloads querysets in the form based on active filters and selected company.
    ra   Nselected_companyr+   	is_activeT)r   	Candidater   rI   r   rY   )rY  r   sessionr   r   is_installedvaluesr   r   rb   r   __name__rF   rG   rI   )	r}   ra   ry  recruitment_installedmodel_filtersrc   r   
model_namefilterss	            rL   reload_querysetr    s    ni6GBIw**+=>t --m< $',Ak4(tM
  1%!12$$^^
"'7<LPU<U"]]115E1FEN&**:66gC1U]]11<G<EN"]]..0EN1 MrN   c                     	 t        |t              r|j                  j                  | k(  S | |j                  j                  j                  k(  S #  Y yxY wNF)r   r   rC   reporting_manager_idrl   r>   r   s     rL   check_managerr    sO    h)..CCxOO8//BBWWWWs   (A "A Ac                 Z    	 t        |t              r| |k(  S | |j                  k(  S #  Y yxY wr  )r   r   rl   r  s     rL   check_ownerr    s7    h)x''8////s   & & *c                 R   | j                  d      s| S d} t        j                  |       }|r1t        |t        t
        f      s|g}t	        d |D              }|d   }nt        j                  }t        j                  }t        j                  }t        j                  }| j                  |      r1t        j                  j                  || j                  |d            }n| S t        j                  dk(  r| S t        j                  j!                  |      st#        dd      |S )	z`
    Convert HTML URIs to absolute system paths so xhtml2pdf can access those
    resources
    z/staticz!payroll/fonts/Poppins_Regular.ttfc              3   Z   K   | ]#  }t         j                  j                  |       % y wN)ospathrealpath).0r  s     rL   	<genexpr>z link_callback.<locals>.<genexpr>
  s     @bgg&&t,@s   )+r   r   ntzmedia URI must start with z or )
startswithr
   findr   listtupler   
STATIC_URLSTATIC_ROOT	MEDIA_URL
MEDIA_ROOTr  r  joinreplacer   isfileRuntimeError)urirelr   r  sUrlsRootmUrlmRoots           rL   link_callbackr    s    
 >>)$

-C\\#F&4-0XF@@@ay ""$$!!##>>$77<<s{{4'<=DJ	ww$
77>>$4NOOKrN   c                 P    |sdn|}|r| }nt        | |      }t        |d|      }|S )NDocumentT)templatehtmlfilename)r   template_pdf)template_pathcontextr  rZ  r  rt  s         rL   generate_pdfr  =  s2    #JEw7TuEHOrN   c                      ddl m}  t        | dd       }|j                  }t        j
                  j                  |      j                         }d}|r|j                  }|S )Nr   r   ra   )user_id2   )	horilla.horilla_middlewaresr   rY  rZ   r   rF   rG   r`   
pagination)r   ra   rZ   r   rJ   s        rL   get_paginationr  J  sT    :ni6G<<D$$++D+9??ADELrN   c                 P    t        | t                     }|j                  |      } | S )z!
    Common paginator method
    )r   r  get_page)rb   page_number	paginators      rL   paginator_qryr  V  s(     (N$45I!!+.HOrN   c                     t         j                  j                  t        | |       t        d| j                  | j
                        z        j                         }|r|S dS )z
    Check if the given date is a holiday.
    Args:
        date (datetime.date): The date to check.
    Returns:
        Holidays or bool: The Holidays object if the date is a holiday, otherwise False.
    start_date__lteend_date__gteT)	recurringstart_date__monthstart_date__dayF)r   rF   rG   r   rD  dayr`   )r   holidays     rL   
is_holidayr  _  sY     %%	$d3
ddjj$((
S	T eg  7(5(rN   c                 (   | j                  d      }| j                  |j                         z   }|dz
  dz  }| j                         }t        j                  j                  t        d|      t        ||      z        j                         }|r|S dS )z
    Check if the given date is a company leave.
    Args:
        input_date (datetime.date): The date to check.
    Returns:
        CompanyLeaves or bool: The CompanyLeaves object if the date is a company leave, otherwise False.
    r   )r     N)based_on_weekbased_on_week_dayF)r  r  weekdayr   rF   rG   r   r`   )
input_datefirst_day_of_monthadjusted_daydate_week_nodate_week_daycompany_leaves         rL   is_company_leaver  o  s     $+++2+3355  !1$*L&&(M "))00	-	
 &-
	
 eg  *=4u4rN   c                     g }|| z
  }t        |j                  dz         D ]"  }| t        |      z   }|j                  |       $ |S )a  
    Returns a list of all dates within a given date range.

    Args:
        start_date (date): The start date of the range.
        end_date (date): The end date of the range.

    Returns:
        list: A list of date objects representing all dates within the range.

    Example:
        start_date = date(2023, 1, 1)
        end_date = date(2023, 1, 10)
        date_range = get_date_range(start_date, end_date)

    r   )days)r   r  r   r   )r  end_date	date_listdeltar   current_dates         rL   get_date_ranger    sT    " Iz!E5::>" '!I1$55&' rN   range_start	range_endc                 B   t        | |      }t               }|D ]  }|t        ||      z  } t        j                  j	                  |      }t        g       }|D ]/  }|t        t        |j                  |j                              z  }1 t        t        |            S )zF
    :return: this functions returns a list of all holiday dates.
    )r  r  r  )	r  r   r   rF   rG   setr  r  r  )r  r  pay_range_datesquery
check_dateholidaysholiday_datesr  s           rL   get_holiday_datesr    s     %iPOCE% I
:ZHHI&&u-HGM 
%'*<*<wGWGWX

 M"##rN   c                 R   t         j                  j                         }g }|D ]{  }|j                  }|j                  }t        dd      D ]P  }|t        j                  d       t        j                  | |      }|t        |         }|D 	cg c]
  }	|	dk7  s	|	 }
}	|
D ]c  }	t        j                  |  d|dd|	dd      j                         }|j                         t        |      k(  sN||vsS|j                  |       e t        j                  d       t        j                  | |      }|D ]d  }|t        |         dk7  st        j                  |  d|dd|t        |         dd      j                         }||vsT|j                  |       f S ~ |S c c}	w )zJ
    :return: This function returns a list of all company leave dates
    r         r   r   02r  )r   rF   rI   r  r  r   calendarsetfirstweekdaymonthcalendarr   r   r  r   r  r   )yearcompany_leavescompany_leave_datesr  r  r  rD  month_calendarweeksr  weekdays_in_weeks
leave_dateweeks                rL   get_company_leave_datesr    s    #**..0N' C%33);;1b\ 	CE(((+!)!7!7e!D&s='9:49$FSSAXS$F!$F, ?C!)!2!2&%1SH5z"df  #**,4E0FF&.AA+22:>? ((+!)!7!7e!D* CDC 123q8%-%6%6#fAeBZqc:K6L1Mb0QR&& $& # &-@@/66zBC)	CC> - %Gs   
F$F$c                 |   t        | |      }t        t        t        | j                        t        |j                        z               |z   }t        | |      }t        t        |            D cg c]  }| |cxk  r|k  rn n| }}t        t        |      t        |      z
        }t        |      }|||dS c c}w )z
    This method is used to calculate the total working days, total leave, worked days on that period

    Args:
        start_date (_type_): the start date from the data needed
        end_date (_type_): the end date till the date needed
    )total_working_daysworking_days_onr  )r  r  r  r  r  r  r   )r  r  r  r  
date_ranger   working_days_between_rangesr  s           rL   get_working_daysr    s     &j(;M
 	'
8)(--89	
 	   
H5J 012)) 	  #'s:=P9Q'Q"R89 162 s   /B9c                     | }| j                   dz   }| j                  }|dkD  rd}|dz   }|j                  }t        j                  ||      d   }t        ||      }t        |||      S )Nr      )r  rD  r  )rD  r  r  r  
monthrangeminr   )date_obj	date_copyrD  r  r  total_days_in_months         rL   get_next_month_same_dater     sp    INNQE==Drzax
--C"--dE:1=
c&
'CCu400rN   c                 r    | j                   j                  }t        j                  j	                  |      }|S )rP   rs   )rZ   r\   r   rF   rG   )ra   rZ   subordinatess      rL   get_subordinatesr    s9     <<$$D##**15 + L rN   c                     t        j                         D ],  \  }}	 t        j                  | |      j	                  d      c S  t        d|        # t
        $ r Y Hw xY w)Nr  zInvalid date format: )r    r   r   r  r  r   )date_strr  r  s      rL   format_dater  '  sm     ';&@&@&B "]	$$X}=FFzRR
 ,XJ7
88  		s   $A	AAc                 0    t        j                  |       } | S )z.
    Method to validate the dynamic value
    )astliteral_eval)r   s    rL   eval_validater
  2  s     U#ELrN   c                      ddl m t        j                  d      rddlm nd  fd}|D cg c]  } ||d         s| c}S c c}w )z
    Check which dashboard charts the user has permission to view.
    Args:
        request: Django request object
        charts: list of (chart_name, ...) tuples
    r   )ry   r+   )is_stagemanagerc                      yr  rY   )us    rL   rG  z(check_chart_permission.<locals>.<lambda>F  rH  rN   c                 Z   t         j                  |       }|syt        j                  |d         sy|j                  d      }|rj                  j                  |      ry|j                  d      r j                        ry|j                  d      r j                        ry| S )NFr$   r%   Tr&   r,   )CHART_CONFIGr   r   r}  rZ   r[   )
chart_nameconfigr%   ry   r  ra   s      rL   has_chart_accessz0check_chart_permission.<locals>.has_chart_accessH  s    !!*-   / zz&!GLL))$/ ::./4G4U ::*+0M xrN   )base.templatetags.basefiltersry   r   r}  +recruitment.templatetags.recruitmentfiltersr  )ra   chartsr  chartry   r  s   `   @@rL   check_chart_permissionr  :  sF     B'O)2  &De)9%()CEDDDs   AAFzpayslip.pdfc                     	 d}| d|  }dddddddddd	d

}t        j                  |d|      }t        |d      }d| |d<   |S # t        $ r#}	t        dt	        |	       d      cY d}	~	S d}	~	ww xY w)ae  
    Generate a PDF file from an HTML template and context data.

    Args:
        template_path (str): The path to the HTML template.
        context (dict): The context data to render the template.
        html (bool): If True, return raw HTML instead of a PDF.

    Returns:
        HttpResponse: A response with the generated PDF file or raw HTML.
    zf<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
A410mmzUTF-8Ni,  g?z[page]/[topage])
z	page-sizez
margin-topzmargin-bottomzmargin-leftzmargin-rightencodingzenable-local-file-accessdpizoomzfooter-centerF)optionszapplication/pdfrJ  zinline; filename=rM  zError generating PDF: i  )status)pdfkitfrom_stringr   	Exceptionr   )
r  r  r  r  bootstrap_csshtml_contentpdf_optionspdfrt  es
             rL   r  r  d  s    K A'8*5  #!"(,.
   ukJ2CD,=hZ*H&' K4SVH=cJJKs   AA 	A3A.(A3.A3c                  @    t        t        j                  dd            S )z
    Function to generate a random 6-digit OTP (One-Time Password).
    Returns:
        str: A 6-digit random OTP as a string.
    i i?B )r   r   r   rY   rN   rL   generate_otpr+    s     v~~ff-..rN   )Nrl   r  )TNT)dr  r  rV  r  r   r   r   r   r   pandasr[  r"  django.appsr   django.confr   django.contrib.auth.modelsr	   django.contrib.staticfilesr
   django.core.exceptionsr   django.core.paginatorr   	django.dbr   django.db.modelsr   r   r   r   django.db.models.functionsr   django.forms.modelsr   django.httpr   django.template.loaderr   django.utils.translationr   r=  base.modelsr   r   r   r   employee.modelsr   r   horilla.horilla_appsr   r  r   horilla.horilla_settingsr    r!   r  rM   add_to_classpropertyri   rn   rp   rv   ry   r   r   r   r   r   r   r   r   r  r   r  r  r  rw  r  r  r  r  r  r  r  r  r  r  r  r  r  r   r  r  r
  r  r  r+  rY   rN   rL   <module>r@     s}   
   	  4 4      , . 5 +  J J , 0 $ 3 1 K K = > 6 O^("&^ ("&^ )^ ,"^( ,")^2 ."3^< ,"&=^F ,"&G^P ,"&Q^Z ,"&[^d #"&e^n *"&o^x  -"&"y^B ."&C^L ."&M^V +"&W^` 5"&!a^l +"&
 z*J' *-{^BU   =(;"7 8/d
'T 3l(.Wt,*T * * *.!H\~< @
	) 5:4$4 $D $T $&%P+\
19'ET $&EM #KL/rN   