o
    'hſ                     @   s  d dl mZmZmZmZ d dlmZmZ d dlm	Z	m
Z
 d dlmZ d dlmZmZmZmZmZmZ d dlmZ d dlmZ d dlmZmZmZ d d	lmZmZ d d
lm Z  d dl!m"Z" d dl#m$Z$ d dl%m&Z&m'Z' d dl(m)Z) d dl*Z*d dl+Z+ddl,m-Z-m.Z.m/Z/m0Z0m1Z1m2Z2m3Z3m4Z4 ddl5m6Z6m7Z7m8Z8m9Z9m:Z:m;Z;m<Z<m=Z=m>Z> d dl?m@Z@ d dlAmBZBmCZC d dlDmEZE d dlFZFd dlGmHZH d dlImJZJ d dlKmLZLmMZMmNZNmOZOmPZPmQZQ e  ZRG dd de
ZSG dd de	eZTeedd dd  ZUG d!d" d"e	eZVG d#d$ d$e	eZWG d%d& d&e	eZXG d'd( d(e	eZYG d)d* d*e	eZZG d+d, d,e	eZ[G d-d. d.e	eZ\G d/d0 d0e	eZ]G d1d2 d2e	eZ^G d3d4 d4e	eZ_G d5d6 d6e	eZ`G d7d8 d8e	eZaed9d: Zbed;d< Zceed=d d>d? ZdG d@dA dAeSeZeG dBdC dCeSeZfG dDdE dEeSeZgG dFdG dGeSeZhG dHdI dIeSeZiG dJdK dKeSeZjG dLdM dMeSeZkG dNdO dOeSeZlG dPdQ dQeZmG dRdS dSe	eZnG dTdU dUe	eZoG dVdW dWe	eZpedXdY ZqG dZd[ d[e	eZred\d] Zsed^d_ ZtdS )`    )renderget_object_or_404redirectreverse)login_requireduser_passes_test)LoginRequiredMixinUserPassesTestMixin)messages)ListView
DetailView
CreateView
UpdateView
DeleteViewTemplateView)reverse_lazy)timezone)QSumCount)HttpResponseHttp404)get_user_model)	Paginator)render_to_string)HTMLCSS)FontConfigurationN   )Employee
DepartmentBonus	DeductionPayslipEmployeeInvitationEmployeeDocument
Attendance)	EmployeeFormDepartmentForm	BonusFormDeductionFormEmployeeAccountSetupFormEmployeeDocumentFormCreateUserAccountFormAttendanceFormBulkAttendanceForm)Decimaldate	timedelta)relativedelta)send_invitation_email)PermissionDenied)AdminRequiredMixinEmployeeRequiredMixinhas_admin_accesspermission_requiredhas_permissionget_user_permissionsc                   @   s   e Zd Zdd ZdS )SuperuserRequiredMixinc                 C   s   t | jjdS )Nis_superuser)r;   requestuserself rC   (/var/www/html/optinet_system/hr/views.py	test_func*   s   z SuperuserRequiredMixin.test_funcN)__name__
__module____qualname__rE   rC   rC   rC   rD   r=   )   s    r=   c                       s    e Zd ZdZ fddZ  ZS )HRDashboardViewhr/dashboard.htmlc                    s  t  jd'i |}d|d< ddlm}m} | jj}t|dp-t|do-|j	j
o-|j	j
jdk}||d< |rtjjd	d
 |d< tjjdd |d< tjjddd |d< tjjd	d
dd d |d< | }tjj|d |d< tjj|dd |d< tjj|dd |d< tjj|dd |d< tjdddd d  |d!< t|dr|j	|d< |j	jjdd |d"< |j	jd#d d$ |d%< |j	jdd d |d&< |S )(NzHR Dashboardtitler   r1   hr_adminemployee_profile
Managementis_adminactiveemployment_statustotal_employeesT	is_activetotal_departmentsFis_generatedis_paidpending_payslips-created_at   recent_employees)r2   todays_attendancepresent)r2   statuspresent_todayabsentabsent_todaylate
late_todayemployee-date   recent_attendancetotal_documents-pay_period_start   recent_payslipsmy_recent_attendancerC   )superget_context_datadatetimer2   r3   r?   r@   r;   hasattrrM   
departmentnamer   objectsfiltercountr    r#   order_bytodayr&   select_related	documentspayslipsattendance_records)rB   kwargscontextr2   r3   r@   rO   ry   	__class__rC   rD   rp   1   s8   

  

z HRDashboardView.get_context_data)rF   rG   rH   template_namerp   __classcell__rC   rC   r   rD   rI   .   s    rI   c                 C   
   t | dS )Nhr_dashboard_accessr;   urC   rC   rD   <lambda>\      
 r   c                 C   s   t jjdd }tjjdd }t jjdd }tjjddd }t jjdddd	d
 }tjjdddd	d
 }||||||d}t| d|S )zHR Dashboard viewrP   rQ   TrT   on_leaveFrW   r[   Nr\   )rX   )rS   rV   employees_on_leaverZ   r]   rm   rJ   )r   ru   rv   rw   r    r#   rx   r   )r?   rS   rV   r   rZ   r]   rm   r   rC   rC   rD   hr_dashboard[   s   r   c                       @   e Zd ZeZdZdZdZ fddZdd Z	 fdd	Z
  ZS )
EmployeeListViewzhr/employee_list.html	employees   c                    *   t |jdstt j|g|R i |S Nview_employeer;   r@   r6   ro   dispatchrB   r?   argsr~   r   rC   rD   r   |      zEmployeeListView.dispatchc                 C   s   t j d}| jjd}|r(|t|dt|dB t|dB t|dB }| jjd}|r7|j|d}| jjd}|rF|j|d	}|	d
S )Nrs   search)first_name__icontains)last_name__icontains)employee_id__icontains)email__icontains)department_idr`   rQ   r[   )
r   ru   allrz   r?   GETgetrv   r   rx   )rB   querysetsearch_queryrs   r`   rC   rC   rD   get_queryset   s&   
zEmployeeListView.get_querysetc                    sd   t  jdi |}tjjdd|d< | jjdd|d< | jjdd|d< | jjd	d|d
< |S )NTrT   departmentsr    r   rs   selected_departmentr`   selected_statusrC   )ro   rp   r    ru   rv   r?   r   r   rB   r~   r   r   rC   rD   rp      s   z!EmployeeListView.get_context_data)rF   rG   rH   r   modelr   context_object_namepaginate_byr   r   rp   r   rC   rC   r   rD   r   v   s    r   c                       sX   e Zd ZeZdZdZdZdZ fddZ	 fddZ
 fdd	Zd
d Zdd Z  ZS )EmployeeDetailViewzhr/employee_detail.htmlrf   employee_idc                    r   r   r   r   r   rC   rD   r      r   zEmployeeDetailView.dispatchc                    s   t  jdi |}|  }|jdd d |d< |jjdddd d |d< |jjdddd d |d< |jjddd	d d |d
< |j	sZt
| jj	drZt |d< |S |j	rit
| jj	drit |d< |S )Nrk   r\   rm   TrT   r[   recent_deductionsrecent_bonuses-uploaded_atr{   create_user_accountcreate_user_formreset_employee_passwordreset_password_formrC   )ro   rp   
get_objectr|   rx   
deductionsrv   bonusesr{   r@   r;   r?   r-   r+   )rB   r~   r   rf   r   rC   rD   rp      s      

z#EmployeeDetailView.get_context_datac                    s   |   }d|jv r>t|jdst|d td|jdS t|j}|	 r+| 
||S t|d |  }||d< | |S d|jv r]t|jdsVt|d	 td|jdS | ||jS t j|g|R i |S )
Nr   z3You do not have permission to create user accounts.hr:employee_detailr   z Please correct the errors below.r   reset_passwordr   z7You do not have permission to reset employee passwords.)r   POSTr;   r@   r
   errorr   r   r-   is_validr   rp   render_to_responsereset_user_passwordro   r   )rB   r?   r   r~   rf   formr   r   rC   rD   post   s$   



zEmployeeDetailView.postc                    sv  z|j d r'ddlddl}|j|j d  d fddtdD }n|j d	 }|j}tj	j
|d
 rKt| jd| d td|jdW S d}d}|jr^|jj dv r^d}d}tj	j||j||j|j|d|dd	}||_|  |jr|jjr|j|jj |j d rzLddlm}	 |	 }
|
jdd|j d| d| d| j d d	|jgdd\}}|rt!| jd |j  nt"| jd!|  t#| jd"|  W n: t$y } zt"| jd!t%|  t#| jd"|  W Y d}~nd}~ww t!| jd# t#| jd"|  W n t$y3 } zt| jd$t%|  W Y d}~nd}~ww td|jdS )%z&Create a user account for the employeegenerate_passwordr   N!@#$%^&*r   c                 3       | ]}  V  qd S Nchoice.0_
characterssecretsrC   rD   	<genexpr>       z9EmployeeDetailView.create_user_account.<locals>.<genexpr>   custom_passwordusernamez	Username z is already taken.r   r   
technicianF)
managementadminr   T)	r   emailpassword
first_name	last_nameroleis_staffr>   first_login_required
send_emailEmailServicez%Your OptiNet Account has been Created
                        Dear z,

                        Your employee account has been created successfully.

                        Login Details:
                        - Username: z/
                        - Temporary Password: &
                        - Login URL: /accounts/login/z

                        Please log in and change your password on your first login.

                        Best regards,
                        OptiNet HR Team
                        account_creationsubjectmessagerecipient_list
email_typezGUser account created successfully! Login credentials have been sent to z@User account created successfully, but email could not be sent: zTemporary password: z"User account created successfully!zError creating user account: )&cleaned_datar   stringascii_lettersdigitsjoinranger   Userru   rv   existsr
   r   r?   r   rs   rt   lowercreate_userr   r   r   r@   save
user_groupgroupsaddnotifications.email_servicer   r   	full_namebuild_absolute_urisuccesswarninginfo	Exceptionstr)rB   rf   r   r   r   r   r   r>   r@   r   email_servicer   	error_msgerC   r   rD   r      s   
 


 $z&EmployeeDetailView.create_user_accountc                    sd  |j st| jd td|jdS z|ddk}|dd }|rCdd	ldd	l	}|j
|j d
  d fddtdD }n(|}|sVt| jd td|jdW S t|dk rkt| jd td|jdW S |j | d|j _|j   |ddk}|rzMddlm} | }	|	jdd|j d|j d| d| jd d	|jgdd\}
}|
rt| jd|j  nt| jd|  t| jd|  W n9 ty } zt| jdt|  t| jd|  W Y d	}~nd	}~ww t| jd  t| jd|  W n ty* } zt| jd!t|  W Y d	}~nd	}~ww td|jdS )"z1Reset password for existing employee user accountz)No user account exists for this employee.r   r   generate_new_passwordonr   r   r   Nr   c                 3   r   r   r   r   r   rC   rD   r   N  r   z9EmployeeDetailView.reset_user_password.<locals>.<genexpr>r   z;Please provide a custom password or enable auto-generation.rh   z,Password must be at least 8 characters long.Tr   r   z$Your OptiNet Password has been Resetr   z,

                        Your password has been reset by HR staff.

                        Login Details:
                        - Username: z)
                        - New Password: r   r   z

                        Please log in and change your password on your next login.

                        Best regards,
                        OptiNet HR Team
                        password_resetr   z?Password reset successfully! New credentials have been sent to z:Password reset successfully, but email could not be sent: zNew password: zPassword reset successfully!zError resetting password: )r@   r
   r   r?   r   r   r   stripr   r   r   r   r   r   lenset_passwordr   r   r   r   r   r   r   r   r   r   r   r   r  )rB   rf   	post_datar  custom_reset_passwordr   r   send_reset_emailr   r  r   r  r  rC   r   rD   r   >  st    


 $z&EmployeeDetailView.reset_user_password)rF   rG   rH   r   r   r   r   
slug_fieldslug_url_kwargr   rp   r   r   r   r   rC   rC   r   rD   r      s    ^r   c                       s<   e Zd ZeZeZdZ fddZ fddZ	dd Z
  ZS )EmployeeCreateViewhr/employee_form.htmlc                    r   )Nadd_employeer   r   r   rC   rD   r     r   zEmployeeCreateView.dispatchc                       t  jdi |}d|d< |S )NzAdd New EmployeerK   rC   ro   rp   r   r   rC   rD   rp        z#EmployeeCreateView.get_context_datac                 C      t dd| jjidS Nr   r   r~   r   objectr   rA   rC   rC   rD   get_success_url     z"EmployeeCreateView.get_success_url)rF   rG   rH   r   r   r'   
form_classr   r   rp   r  r   rC   rC   r   rD   r    s    r  c                       sD   e Zd ZeZeZdZdZdZ	 fddZ
 fddZdd Z  ZS )	EmployeeUpdateViewr  r   c                    r   )Nchange_employeer   r   r   rC   rD   r     r   zEmployeeUpdateView.dispatchc                    (   t  jdi |}d| jj |d< |S )NzEdit Employee - rK   rC   )ro   rp   r  r   r   r   rC   rD   rp        z#EmployeeUpdateView.get_context_datac                 C   r  r  r  rA   rC   rC   rD   r    r  z"EmployeeUpdateView.get_success_url)rF   rG   rH   r   r   r'   r  r   r  r  r   rp   r  r   rC   rC   r   rD   r    s    r  c                       s4   e Zd ZeZdZdZdZedZ	 fddZ
  ZS )EmployeeDeleteViewzhr/employee_confirm_delete.htmlr   zhr:employee_listc                    r   )Ndelete_employeer   r   r   rC   rD   r     r   zEmployeeDeleteView.dispatch)rF   rG   rH   r   r   r   r  r  r   success_urlr   r   rC   rC   r   rD   r"    s    r"  c                       s0   e Zd ZeZdZdZ fddZdd Z  Z	S )DepartmentListViewzhr/department_list.htmlr   c                    r   Nview_departmentr   r   r   rC   rD   r     r   zDepartmentListView.dispatchc                 C   s"   t jjtdtdddddS )Nr   rP   )employees__employment_status)rv   )employee_countrt   )r    ru   annotater   r   rx   rA   rC   rC   rD   r     s
   zDepartmentListView.get_queryset)
rF   rG   rH   r    r   r   r   r   r   r   rC   rC   r   rD   r%    s    r%  c                       s4   e Zd ZeZdZdZ fddZ fddZ  Z	S )DepartmentDetailViewzhr/department_detail.htmlrs   c                    r   r&  r   r   r   rC   rD   r     r   zDepartmentDetailView.dispatchc                    s*   t  jdi |}| jjjdd|d< |S )NrP   rQ   r   rC   )ro   rp   r  r   rv   r   r   rC   rD   rp     s   z%DepartmentDetailView.get_context_data)
rF   rG   rH   r    r   r   r   r   rp   r   rC   rC   r   rD   r+    s    r+  c                       <   e Zd ZeZeZdZedZ	 fddZ
 fddZ  ZS )DepartmentCreateViewhr/department_form.htmlhr:department_listc                    r   )Nadd_departmentr   r   r   rC   rD   r     r   zDepartmentCreateView.dispatchc                    r  )NzAdd New DepartmentrK   rC   r  r   r   rC   rD   rp     r  z%DepartmentCreateView.get_context_datarF   rG   rH   r    r   r(   r  r   r   r$  r   rp   r   rC   rC   r   rD   r-        r-  c                       r,  )DepartmentUpdateViewr.  r/  c                    r   )Nchange_departmentr   r   r   rC   rD   r     r   zDepartmentUpdateView.dispatchc                    r   )NzEdit Department - rK   rC   )ro   rp   r  rt   r   r   rC   rD   rp     r!  z%DepartmentUpdateView.get_context_datar1  rC   rC   r   rD   r3    r2  r3  c                       ,   e Zd ZeZdZedZ fddZ  Z	S )DepartmentDeleteViewz!hr/department_confirm_delete.htmlr/  c                    r   )Ndelete_departmentr   r   r   rC   rD   r     r   zDepartmentDeleteView.dispatch)
rF   rG   rH   r    r   r   r   r$  r   r   rC   rC   r   rD   r6    
    r6  c                       r   )
PayslipListViewzhr/payslip_list.htmlr|   r   c                    r   Nview_payslipr   r   r   rC   rD   r     r   zPayslipListView.dispatchc                 C   s   t jdd}| jjd}|r|j|d}| jjd}|r<ztt|	d\}}|j||d}W n	 t
y;   Y nw |dS )Nrf   employee__departmentemployee__employee_id
pay_period-)pay_period_start__yearpay_period_start__monthrk   )r#   ru   rz   r?   r   r   rv   mapintsplit
ValueErrorrx   )rB   r   r   r?  yearmonthrC   rC   rD   r     s    

zPayslipListView.get_querysetc                    .   t  jdi |}tjjddd|d< |S NrP   rQ   r   r   rC   ro   rp   r   ru   rv   rx   r   r   rC   rD   rp   *     z PayslipListView.get_context_data)rF   rG   rH   r#   r   r   r   r   r   r   rp   r   rC   rC   r   rD   r9  	  s    r9  c                       s0   e Zd ZeZdZdZdZdZ fddZ	  Z
S )PayslipDetailViewzhr/payslip_detail.htmlpayslippayslip_numberc                    r   r:  r   r   r   rC   rD   r   6  r   zPayslipDetailView.dispatch)rF   rG   rH   r#   r   r   r   r  r  r   r   rC   rC   r   rD   rM  /  s    rM  c           
      C   s   t t|d}t| jdsttd|ddd}t }d}t||d}t|d	}|j	||gd
}t
|dd}	d|j d|	d< |	S )z$Generate and download payslip as PDF)rO  download_payslipzhr/payslip_pdf.htmlzOptinet Global LinksT)rN  company_nameis_pdfa	  
    @page {
        size: A4;
        margin: 1cm;
    }

    body {
        font-family: Arial, sans-serif;
        font-size: 10pt;
        line-height: 1.4;
        color: #333;
    }

    .payslip-header {
        background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
        color: white;
        padding: 20px;
        margin-bottom: 20px;
        border-radius: 8px;
    }

    .company-logo {
        font-size: 24px;
        font-weight: bold;
        margin-bottom: 5px;
    }

    .payslip-number {
        font-size: 18px;
        margin-bottom: 10px;
    }

    .info-table {
        width: 100%;
        border-collapse: collapse;
        margin-bottom: 15px;
    }

    .info-table td {
        padding: 6px;
        border-bottom: 1px solid #eee;
    }

    .info-table .label {
        font-weight: bold;
        width: 40%;
    }

    .section-header {
        background-color: #f8f9fa;
        padding: 10px;
        margin: 15px 0 5px 0;
        font-weight: bold;
        border-left: 4px solid #667eea;
    }

    .earnings-section {
        border-left-color: #28a745;
    }

    .deductions-section {
        border-left-color: #dc3545;
    }

    .breakdown-table {
        width: 100%;
        border-collapse: collapse;
        margin-bottom: 15px;
    }

    .breakdown-table th,
    .breakdown-table td {
        padding: 6px 10px;
        text-align: left;
        border-bottom: 1px solid #ddd;
    }

    .breakdown-table th {
        background-color: #f8f9fa;
        font-weight: bold;
    }

    .breakdown-table .amount {
        text-align: right;
        font-weight: bold;
    }

    .breakdown-table .sub-item {
        padding-left: 20px;
        font-size: 9pt;
        color: #666;
    }

    .total-row {
        background-color: #f8f9fa;
        font-weight: bold;
        border-top: 2px solid #333;
    }

    .net-salary {
        background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
        color: white;
        padding: 15px;
        text-align: center;
        font-size: 16pt;
        font-weight: bold;
        margin: 20px 0;
        border-radius: 5px;
    }

    .footer-info {
        margin-top: 30px;
        font-size: 8pt;
        color: #666;
        text-align: center;
        border-top: 1px solid #eee;
        padding-top: 10px;
    }
    )r   font_config)r   )rS  stylesheetszapplication/pdf)content_typezattachment; filename="payslip_z.pdf"zContent-Disposition)r   r#   r;   r@   r6   r   r   r   r   	write_pdfr   rO  )
r?   rO  rN  html_stringrS  
css_stringcsshtmlpdf_fileresponserC   rC   rD   payslip_pdf_download;  s    x
r]  c                 C   s  t | jdst| jdkrFz t| jdt j	}t| jdt j
}| jd}W n ttfyC   t| d td Y S w t||d}|d	kr\t|d ddtdd
 }nt||d dtdd
 }|rz
tjj|dg}W n tjy   t| d td Y S w tjjdd}d}|D ]}tjj|||d }	|	s2tjj|d||djtddd ptd}
tjj|d|dtddt|dB jtddd ptd}|j|
 }td}|tdkr|td td }td}|tdkr
ttd|td }ttd|td  }tjj||||td!d
 |j|
||||d| jd"}|d7 }qt | d#| d$|!d%  td&S t }|j	|j
g d't"|j
d( |j
d( tjjdd)gd*#d+d,}t$| d-|S ).z*Generate payslips for all active employeesgenerate_payslipr   rH  rG  r   zInvalid month or year provided.zhr:generate_payslipsr   r   )daysr   zEmployee not found.rP   rQ   r   )rf   pay_period_startpay_period_endT)rf   rU   date_earned__gtedate_earned__lteamount)totalre  z0.00)rf   rU   start_date__lte)end_date__isnull)end_date__gte24000z0.1060001700z0.0251080z0.06r\   )rf   r`  ra  pay_datebasic_salarytotal_bonusestotal_deductionspaye_taxnhif_deductionnssf_deductionrX   generated_byzSuccessfully generated z payslips for z%B %Yzhr:payslip_list))r   January)   February)rl   March)   April)r\   May)   June)   July)rh   August)	   	September)
   October)   November)r   Decemberrv  
terminated)employment_status__inr   )current_monthcurrent_yearmonthsyearsr   zhr/generate_payslips.html)%r;   r@   r6   methodrD  r   r   r2   ry   rH  rG  rF  	TypeErrorr
   r   r   r3   r   ru   DoesNotExistrv   r#   firstr!   	aggregater   r0   r"   r   rn  mincreater   strftimer   rx   r   )r?   rH  rG  r   r`  ra  active_employeesgenerated_countrf   existing_payslipmonthly_bonusesmonthly_deductionsgross_salaryrq  rr  rs  rN  ry   r   rC   rC   rD   generate_payslips  s   
	r  c                 C   r   )Nsend_invitationr   r   rC   rC   rD   r   D  r   c                 C   sp   t t|d}|jrt| |j d td|jdS td|| \}}|r+t	| | nt
| | td|jdS )z!Send invitation email to employeer   z already has an account.r   rf   )r   r   r@   r
   r   r   r   r   r5   r   r   )r?   r   rf   r   r   rC   rC   rD   send_employee_invitationC  s   r  c                       4   e Zd ZeZdZdZdZ fddZdd Z	  Z
S )DeductionListViewzhr/deduction_list.htmlr   r   c                    r   )Nview_deductionr   r   r   rC   rD   r   ^  r   zDeductionListView.dispatchc                 C   R   t jd}| jjd}|r|j|d}| jjd}|r$|j|d}|dS )Nrf   r=  type)deduction_typer[   )r"   ru   rz   r?   r   r   rv   rx   )rB   r   r   r  rC   rC   rD   r   c     
zDeductionListView.get_queryset)rF   rG   rH   r"   r   r   r   r   r   r   r   rC   rC   r   rD   r  X      r  c                       r,  )DeductionCreateViewhr/deduction_form.htmlhr:deduction_listc                    r   )Nadd_deductionr   r   r   rC   rD   r   x  r   zDeductionCreateView.dispatchc                       | j j|j_t |S r   r?   r@   instance
created_byro   
form_validrB   r   r   rC   rD   r  }     zDeductionCreateView.form_valid)rF   rG   rH   r"   r   r*   r  r   r   r$  r   r  r   rC   rC   r   rD   r  r  r2  r  c                       0   e Zd ZeZeZdZedZ	 fddZ
  ZS )DeductionUpdateViewr  r  c                    r   )Nchange_deductionr   r   r   rC   rD   r     r   zDeductionUpdateView.dispatch)rF   rG   rH   r"   r   r*   r  r   r   r$  r   r   rC   rC   r   rD   r        r  c                       r5  )DeductionDeleteViewz hr/deduction_confirm_delete.htmlr  c                    r   )Ndelete_deductionr   r   r   rC   rD   r     r   zDeductionDeleteView.dispatch)
rF   rG   rH   r"   r   r   r   r$  r   r   rC   rC   r   rD   r    r8  r  c                       r  )BonusListViewzhr/bonus_list.htmlr   r   c                    r   )N
view_bonusr   r   r   rC   rD   r     r   zBonusListView.dispatchc                 C   r  )Nrf   r=  r  )
bonus_typer[   )r!   ru   rz   r?   r   r   rv   rx   )rB   r   r   r  rC   rC   rD   r     r  zBonusListView.get_queryset)rF   rG   rH   r!   r   r   r   r   r   r   r   rC   rC   r   rD   r    r  r  c                       r,  )BonusCreateViewhr/bonus_form.htmlhr:bonus_listc                    r   )N	add_bonusr   r   r   rC   rD   r     r   zBonusCreateView.dispatchc                    r  r   r  r  r   rC   rD   r    r  zBonusCreateView.form_valid)rF   rG   rH   r!   r   r)   r  r   r   r$  r   r  r   rC   rC   r   rD   r    r2  r  c                       r  )BonusUpdateViewr  r  c                    r   )Nchange_bonusr   r   r   rC   rD   r     r   zBonusUpdateView.dispatch)rF   rG   rH   r!   r   r)   r  r   r   r$  r   r   rC   rC   r   rD   r    r  r  c                       r5  )BonusDeleteViewzhr/bonus_confirm_delete.htmlr  c                    r   )Ndelete_bonusr   r   r   rC   rD   r     r   zBonusDeleteView.dispatch)
rF   rG   rH   r!   r   r   r   r$  r   r   rC   rC   r   rD   r    r8  r  c                   @   s,   e Zd ZeZdZdZdZdd Zdd Z	dS )EmployeeAccountSetupViewzhr/employee_account_setup.htmltokenc                 C   s.   t t| jd d}|jst| jd d S |S )Nr  )r  z.This invitation link has expired or been used.)r   r$   r~   r   r
   r   r?   )rB   
invitationrC   rC   rD   r     s
   z#EmployeeAccountSetupView.get_objectc           
      O   s   |   }|s
tdS t|jdst|d tdS |j}|jd}|j	}t
jj|d rAt|d | j|g|R i |S d}|jrP|jj dv rPd	}t
jj|||j|j|j|d
}	|	|_|  d|_t |_|  t|d tdS )Nzaccounts:loginsetup_employee_accountz>You do not have permission to set up an account via this link.r   r   z,An account already exists for this employee.r   )r   r   hrr   )r   r   r   r   r   r   Tz1Account created successfully! You can now log in.)r   r   r;   r@   r
   r   rf   r   r   r   r   ru   rv   r   rs   rt   r   r   r   r   r   r   is_usedr   nowused_atr   )
rB   r?   r   r~   r  rf   r   r   r   r@   rC   rC   rD   r     s<   

zEmployeeAccountSetupView.postN)
rF   rG   rH   r$   r   r   r  r  r   r   rC   rC   rC   rD   r    s    r  c                       r   )
EmployeeDocumentListViewzhr/document_list.htmlr{   r   c                    r   )Nview_documentr   r   r   rC   rD   r     r   z!EmployeeDocumentListView.dispatchc                 C   s\   t jddjdd}| jjd}|r|j|d}| jjd}|r)|j|d}|dS )	Nrf   uploaded_byTrT   r=  r  )document_typer   )r%   ru   rz   rv   r?   r   r   rx   )rB   r   r   doc_typerC   rC   rD   r     s   
z%EmployeeDocumentListView.get_querysetc                    s8   t  jdi |}tjjddd|d< tj|d< |S )NrP   rQ   r   r   document_typesrC   )ro   rp   r   ru   rv   rx   r%   DOCUMENT_TYPE_CHOICESr   r   rC   rD   rp   -  s   
z)EmployeeDocumentListView.get_context_data)rF   rG   rH   r%   r   r   r   r   r   r   rp   r   rC   rC   r   rD   r    s    r  c                       sT   e Zd ZeZeZdZ fddZ fddZ	 fddZ
dd	 Z fd
dZ  ZS )EmployeeDocumentCreateViewzhr/document_form.htmlc                    r   )Nadd_documentr   r   r   rC   rD   r   8  r   z#EmployeeDocumentCreateView.dispatchc                    sR   t   }d| jv r'ztjj| jd d}||d< W |S  tjy&   Y |S w |S )Nr   r   rf   )ro   get_form_kwargsr~   r   ru   r   r  )rB   r~   rf   r   rC   rD   r  =  s   


z*EmployeeDocumentCreateView.get_form_kwargsc                    s&   | j j|j_t| j d t |S )NzDocument uploaded successfully.)r?   r@   r  r  r
   r   ro   r  r  r   rC   rD   r  G  s   z%EmployeeDocumentCreateView.form_validc                 C   s(   d| j v rtdd| j d idS tdS )Nr   r   r  hr:document_list)r~   r   rA   rC   rC   rD   r  L  s   
z*EmployeeDocumentCreateView.get_success_urlc                    s^   t  jdi |}d|d< d| jv r-ztjj| jd d|d< W |S  tjy,   Y |S w |S )NzUpload Employee DocumentrK   r   r   rf   rC   )ro   rp   r~   r   ru   r   r  r   r   rC   rD   rp   Q  s   
z+EmployeeDocumentCreateView.get_context_data)rF   rG   rH   r%   r   r,   r  r   r   r  r  r  rp   r   rC   rC   r   rD   r  3  s    
r  c                       s4   e Zd ZeZdZedZ fddZdd Z	  Z
S )EmployeeDocumentDeleteViewzhr/document_confirm_delete.htmlr  c                    r   )Ndelete_documentr   r   r   rC   rD   r   `  r   z#EmployeeDocumentDeleteView.dispatchc                 O   s2   |   | _d| j_| j  t|d t| jS )NFzDocument deleted successfully.)r   r  rU   r   r
   r   r   r$  r   rC   rC   rD   deletee  s
   


z!EmployeeDocumentDeleteView.delete)rF   rG   rH   r%   r   r   r   r$  r   r  r   rC   rC   r   rD   r  [  s    r  c                 C   s   t t|dd}t| jdstddlm} ddlm} ddl	}|j
r7||j
dd||j|j
jd	}|S t| d
 tdS )zDownload employee documentT)pkrU   download_documentr   )FileResponse)	smart_strNrb)as_attachmentfilenamezDocument file not found.r  )r   r%   r;   r@   r6   django.httpr  django.utils.encodingr  osdocument_fileopenpathbasenamert   r
   r   r   )r?   r  documentr  r  r  r\  rC   rC   rD   download_employee_documentm  s   
r  c                       r   )
AttendanceListViewzhr/attendance_list.htmlr}      c                    r   )Nview_attendancer   r   r   rC   rD   r     r   zAttendanceListView.dispatchc                 C   sr   t jddd}| jjd}|r|j|d}| jjd}| jjd}|r/|j|d}|r7|j|d}|S )	Nrf   rg   employee__first_namer=  
start_dateend_date)	date__gte)	date__lte)r&   ru   rz   rx   r?   r   r   rv   )rB   r   r   r  r  rC   rC   rD   r     s   zAttendanceListView.get_querysetc                    rI  rJ  rK  r   r   rC   rD   rp     rL  z#AttendanceListView.get_context_data)rF   rG   rH   r&   r   r   r   r   r   r   rp   r   rC   rC   r   rD   r    s    r  c                 C   s   t | jdst| jdkr4t| j}| r3|jdd}| j|_|  t	
| d|jj  tdS nt }t| d|dd	S )
zCreate attendance recordadd_attendancer   F)commitzAttendance record created for hr:attendance_listzhr/attendance_form.htmlzRecord Attendancer   rK   )r;   r@   r6   r  r.   r   r   r   recorded_byr
   r   rf   r   r   r   )r?   r   
attendancerC   rC   rD   attendance_create  s   

r  c           
      C   s   t | jdst| jdkr[t| j}| rZ|jd }|jd }|jd }|s.tj	j
dd}d}|D ]}tj	j|||| jd	d
\}}|rI|d7 }q2t| d| d|  tdS nt }|dd}	t| d|	S )zCreate bulk attendance recordsadd_attendance_bulkr   r2   r   r`   rP   rQ   r   )r`   r  )rf   r2   defaultsr   zCreated z attendance records for r  zBulk Attendance Recordingr  zhr/bulk_attendance_form.html)r;   r@   r6   r  r/   r   r   r   r   ru   rv   r&   get_or_creater
   r   r   r   )
r?   r   r2   r   r`   created_countrf   r  createdr   rC   rC   rD   bulk_attendance_create  s<   





r  )udjango.shortcutsr   r   r   r   django.contrib.auth.decoratorsr   r   django.contrib.auth.mixinsr   r	   django.contribr
   django.views.genericr   r   r   r   r   r   django.urlsr   django.utilsr   django.db.modelsr   r   r   r  r   r   django.contrib.authr   django.core.paginatorr   django.template.loaderr   
weasyprintr   r   weasyprint.text.fontsr   tempfiler  modelsr   r    r!   r"   r#   r$   r%   r&   formsr'   r(   r)   r*   r+   r,   r-   r.   r/   decimalr0   rq   r2   r3   dateutil.relativedeltar4   uuidsettings.utilsr5   django.core.exceptionsr6   accounts.permissionsr7   r8   r9   r:   r;   r<   r   r=   rI   r   r   r   r  r  r"  r%  r+  r-  r3  r6  r9  rM  r]  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  rC   rC   rC   rD   <module>   s     (, 	-
, l&
 
p
= (
"
