U
    i„jãú ã                   @   s®  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mZmZ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 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) d dl*Z*d dl+m,Z,m-Z- d dl$m%Z% d dl.m/Z/ d dl0Z0d dl1m2Z2m3Z3 d dl+m4Z4 d dl5m6Z6m7Z7 ddl8m9Z9 d dl:m;Z; d dl'm'Z'm<Z< d dl=Z=d dl>m?Z? d dl@mAZA d dlBZBd dlmZ d dlCZCd dl mZ d dlDZDd dl>mEZE d dlFmGZG 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m	Z	 d dlmZ d dlmZ d dlmZ d dlCZCG dd„ deƒZHd d!„ ZId"d#„ ZJd d$lmKZK eKƒ Z#G d%d&„ d&eƒZLG d'd(„ d(eƒZMd d)l'm)Z) d dl$m%Z% G d*d+„ d+eƒZNG d,d-„ d-eƒZOG d.d/„ d/eƒZPG d0d1„ d1eƒZQG d2d3„ d3eƒZRG d4d5„ d5eƒZSG d6d7„ d7eƒZTG d8d9„ d9eƒZUd dl$m%Z% d dl'm'Z'm<ZV d dlWZWG d:d;„ d;eƒZXG d<d=„ d=eƒZYd dl=Z=d dl0Z0d dl<Z<d d>lZm[Z[ d dlmZ d dlmZ d dlm	Z	 dd?l
mZ G d@dA„ dAeƒZ\G dBdC„ dCeƒZ]G dDdE„ dEeƒZ^d dl_Z_d dl`Z`dFdG„ Zad dHl'm'Z' d dl+m,Zb d dlmZ d dlmZ ddIl
mZmZmZ G dJdK„ dKeƒZcG dLdM„ dMeƒZdG dNdO„ dOeƒZeG dPdQ„ dQeƒZfd dlgZgd dHl'm'Z' G dRdS„ dSeƒZhG dTdU„ dUeƒZiG dVdW„ dWeƒZjG dXdY„ dYeƒZkd 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dZl
mZmZ G d[d\„ d\eƒZlG d]d^„ d^eƒZmG d_d`„ d`eƒZnG dadb„ dbeƒZoG dcdd„ ddeƒZpG dedf„ dfeƒZqG dgdh„ dheƒZrdS )ié    )Úsettings)Úrender)ÚAPIView)ÚResponse©Ústatusé   )ÚProfilesÚOtpÚProductÚNotificationÚBookingÚClientÚLoanÚ
CollectionÚStudentÚ
AttendanceÚFeesÚFeesHistory)ÚObjectDoesNotExist)ÚNotFound)ÚauthenticateÚlogin)ÚRefreshToken)Úmake_password)ÚUser©Útimezone)ÚdateÚdatetimeÚ	timedeltaN)ÚSumÚCount)ÚHttpResponse)ÚMultiPartParserÚ
FormParser©ÚQ)ÚRetrieveAPIViewÚListAPIView)ÚUserSerializer)ÚIsAuthenticated)r   Útime)ÚEmailMessage)ÚBASE_DIR)Ú	send_mail)Úget_random_string©r!   c                   @   s   e Zd Zdd„ ZdS )ÚLoginAPIViewc                 C   sB  |j }| d¡}|d }|d }t d|¡r\ztjj|d�}W qj tjk
rX   d }Y qjX nt|||d�}|d k	�r| |¡�rt	||ƒ t
 |¡}tjj|jd�}||_| ¡  |jrÆ| |jj¡nd }	d}
|j}ttjd	d
œd d|j|j|j|j|jt|ƒt|jƒ|	|
|j|jdœdœƒS ttjdd
œddd dœtjd�S d S )NÚusernameÚpasswordZ	fcm_tokenz[^@]+@[^@]+\.[^@]+©Úemail)r3   r4   ©Úuser_idÚloopÚsuccess©ÚcodeÚresponsezLogin success)ÚnameÚidr3   r6   ZisSuperZrefreshÚtokenÚprofileÚcompanynameÚphoneÚrole©r   ÚerrorÚmessageÚdatarF   zAuthentication failedzInvalid username or passwordr   )rH   ÚgetÚreÚmatchr   ÚobjectsÚDoesNotExistr   Úcheck_passwordr   r   Zfor_userr	   r?   ÚpincodeÚsaveÚprofilesÚbuild_absolute_uriÚurlrC   r   r   ÚHTTP_200_OKr3   r6   Úis_superuserÚstrZaccess_tokenrD   ZHTTP_401_UNAUTHORIZED)ÚselfÚrequestrH   Zusername_or_emailr4   ÚfcÚuserr@   rA   Úprofile_photorB   rC   © r\   ú*/var/www/html/mysite/school/myapp/views.pyÚpost7   sX    



ôü
üûzLoginAPIView.postN©Ú__name__Ú
__module__Ú__qualname__r^   r\   r\   r\   r]   r2   5   s   r2   c              
   C   s`   d}d|› d�}zt ||tj| gdd� W n0 tk
rZ } ztd|› �ƒ W 5 d }~X Y nX d S )Nú%Your One-Time  (OTP) for Verificationú?Dear User,

    Your One-Time  (OTP) for verification is:

    zâ

    Please enter this code to proceed. This OTP is valid for the next 1 minutes.

    If you did not request this code, please ignore this email.

    Thank you,  
    Pearlcon Technologies LLP
    https://pearlcons.com
    F©Úfail_silentlyúError sending email: ©r/   r   ÚDEFAULT_FROM_EMAILÚ	ExceptionÚprint©r6   ÚotpÚsubjectrG   Úer\   r\   r]   Úsend_otp_emailš   s    üû
rp   c              
   C   s`   d}d|› d�}zt ||tj| gdd� W n0 tk
rZ } ztd|› �ƒ W 5 d }~X Y nX d S )Nrc   rd   zæ

    Please enter this code to proceed. This OTP is valid for the next 1 minutes.

    If you did not request this code, please ignore this email.

    Thank you,  
    Pearlcon Technologies LLP
    https://pearlcons.com
        Fre   rg   rh   rl   r\   r\   r]   Úsend_otp_emails´   s    üû
rq   )Úget_user_modelc                   @   s   e Zd Zdd„ ZdS )ÚSendotpAPIViewc              
   C   s
  |j }z°| di ¡ dd ¡}td|ƒ tjj|d� ¡ sRttj	ddœddd	œƒW S t
jj|d�}td
dd�}||_t ¡ |_| ¡  tjt||fd� ¡  ttjddœd d|idœƒW S  tk
�r } z.td|ƒ ttjddœdt|ƒd	œƒ W Y ¢S d }~X Y nX d S )NÚparamsr6   úReceived email:r5   zEmail not foundr;   TzEmail not registered©r   rF   rG   é   Ú
1234567890©ÚlengthÚallowed_chars©ÚtargetÚargsÚSuccess©r   rF   rH   zError:úInternal Server Error)rH   rI   rk   r   rL   ÚfilterÚexistsr   r   ÚHTTP_404_NOT_FOUNDr
   Úcreater0   rm   r   ÚnowÚotp_created_atrP   Ú	threadingÚThreadrp   ÚstartrT   rj   ÚHTTP_500_INTERNAL_SERVER_ERRORrV   )rW   rX   rH   r6   rZ   rm   ro   r\   r\   r]   r^   Õ   s8    

ý


ý


ýzSendotpAPIView.postNr_   r\   r\   r\   r]   rs   Ô   s   rs   c                   @   s   e Zd Zdd„ ZdS )ÚSendotpsAPIViewc              
   C   sæ   |j }z˜| dd ¡}td|ƒ tjj|d� ¡ rJttj	ddœdddœƒW S t
d	d
d�}tjj||t ¡ d�}tjt||fd� ¡  ttjddœd d|idœƒW S  tk
rà } z$ttjddœdt|ƒdœƒ W Y ¢S d }~X Y nX d S )Nr6   ru   r5   zEmail already registeredr;   Tz;This email is already registered. Please use another email.rv   rw   rx   ry   )r6   rm   r‡   r|   r   r€   r�   )rH   rI   rk   r   rL   r‚   rƒ   r   r   ÚHTTP_409_CONFLICTr0   r
   r…   r   r†   rˆ   r‰   rq   rŠ   rT   rj   r‹   rV   )rW   rX   rH   r6   rm   rZ   ro   r\   r\   r]   r^   û   s0    

ý

ý

ýzSendotpsAPIView.postNr_   r\   r\   r\   r]   rŒ   ú   s   rŒ   ©r    c                   @   s   e Zd Zdd„ Zdd„ ZdS )ÚVerifyotpAPIViewc                 C   sÐ   |j  d¡}|j  d¡}z†tjj|d� d¡}|jtdd� }t 	¡ |krbt
ddd	d
œtjd�W S ||jkr„t
dddd
œtjd�W S t
ddd	d
œtjd�W S W n, tjk
rÊ   t
ddd	d
œtjd� Y S X d S )Nr6   rm   r5   r‡   é<   )Úsecondsi‘  z&OTP expired. Please request a new one.T)r   rG   rF   r   éÈ   zOTP VerifiedFé�  zInvalid OTPé”  zOTP not found)Úquery_paramsrI   r
   rL   r‚   Úlatestr‡   r    r   r†   r   r   rT   rm   rM   )rW   rX   r6   Zotp_enteredZuser_otpZexpiration_timer\   r\   r]   rI     sH    ýü
ýüýüýüzVerifyotpAPIView.getc                 C   s˜   |d k	r€zJt jj|d�}|jr:|jjdd� d |_| ¡  ttjddœd ddœƒW S  t	k
r~   ttj
ddœd d	dœƒ Y S X ttjddœd
ddœƒS )Nr7   F)rP   r:   r;   z"Profile image deleted successfullyrv   ÚfailedzProfile not foundzID not providedzUser ID is required)r	   rL   rI   rQ   ÚdeleterP   r   r   rT   r   r„   ÚHTTP_400_BAD_REQUEST)rW   rX   r?   rA   r\   r\   r]   r˜   E  s.    
ý

ý
ýzVerifyotpAPIView.deleteN)r`   ra   rb   rI   r˜   r\   r\   r\   r]   r�     s   'r�   c                   @   s*   e Zd ZefZdd„ Zdd„ Zdd„ ZdS )ÚProfileupdateAPIViewc                 K   s¼   |  d¡}|d k	r¸zxtjj |d�}tjj |jd�}|jrN|jjdkrN|jj}nd}|j|j|j	|j
|j||jdœ}ttjddœd |dœƒW S  tk
r¶   ttjd	dœd
ddœƒ Y S X d S )Nr?   ©r?   r7   z../static/dummy.png)r>   r6   rC   Úf_nameZl_namerA   r?   r   r;   r€   ZFailedTzCompany not foundrv   )rI   r   rL   r	   r?   rQ   rS   r>   r6   rC   Ú
first_nameÚ	last_namer   r   rT   r   r„   )rW   rX   Úkwargsr?   rZ   ÚcompanyÚprrH   r\   r\   r]   rI   j  s6    

ø
ý

ýzProfileupdateAPIView.getc              
   C   sÞ   |j }zD| d¡}tjj|jjd�}||_| ¡  tt	j
ddœd ddœƒW S  tk
r’ } z*tt	jddœdd	t|ƒ› �dœƒ W Y ¢S d }~X Y nH tk
rØ } z*tt	jddœdd
t|ƒ› �dœƒ W Y ¢S d }~X Y nX d S )NÚ
prof_photor7   r:   r;   zProfile updated successfullyrv   r—   TúMissing required field: zAn error occurred: )rH   rI   r	   rL   rZ   r?   rQ   rP   r   r   ÚHTTP_201_CREATEDÚKeyErrorr™   rV   rj   r‹   )rW   rX   rH   ZphoÚtakero   r\   r\   r]   r^   ’  s.    

ý

ý
ýzProfileupdateAPIView.postc                 C   s  |j }|j d¡}zÀtjj|d�}tjj|d�}| d|j¡|_| d|j¡|_| d|j¡|_| d|j	¡|_	| 
¡  | d|j	¡|_	| d|j¡|_| d|j¡|_|r²||_| 
¡  ttjd	d
œd ddœƒW S  tk
�r    ttjdd
œdddœƒ Y S X d S )Nr¢   r7   r›   r�   Zfirst_namesrž   Zemail_idZphone_nor:   r;   úUser updated successfullyrv   r—   TzUser not found)rH   ÚFILESrI   r	   rL   r   r3   r�   rž   r6   rP   rC   r>   rQ   r   r   rT   r   r„   )rW   rX   r?   rH   ÚphotoÚmmÚsdr\   r\   r]   Úput¸  s6    
ý

ýzProfileupdateAPIView.putN)r`   ra   rb   r+   Úpermission_classesrI   r^   r¬   r\   r\   r\   r]   rš   f  s   (&rš   c                   @   s,   e Zd Zdd„ Zdd„ Zdd„ Zdd„ Zd	S )
ÚRegisterAPIViewc           
      K   sx  |  d¡}|d k	r¤z`tjj |d�}|j|j|j|j|j|j|j	|j
rR| |j
j¡nd dœ}tt	jddœd |dœƒW S  tjk
r    tt	jddœdd	d
œƒ Y S X nÐzŠtjjdddgd� d¡}g }t|dƒD ]F\}}| ||j|j|j|j|j	|j|j
�r
| |j
j¡nd dœ¡ qÎtt	jddœd |dœƒW S  tk
�rr }	 z$tt	jddœdt|	ƒd
œƒ W Y ¢S d }	~	X Y nX d S )Nr?   r7   )r?   r3   rC   r4   r6   rD   r   r[   r:   r;   r€   r—   TúNo student foundrv   é   é   r   )Zrole__inú-created_atr   )Úrowr?   ZemployeeNamer6   rC   r   rD   r©   )rI   r	   rL   r8   r>   rC   r4   r6   rD   r   rQ   rR   rS   r   rT   r   rM   r„   r‚   Úorder_byÚ	enumerateÚappendrj   r™   rV   )
rW   rX   rŸ   r?   ÚstudentrH   Z	employeesZemployee_listÚindexro   r\   r\   r]   rI   ä  sb    
ö
ý

ý÷

ý

ýzRegisterAPIView.getc              
   C   sö   |j }|j d¡}z’| d¡}| d¡}| d¡}| d¡}| d¡}t|ƒ}	tjj|||	d�}
|j d¡}tjj|||||
j||d�}t	d	d
dœd ddœt
jd�W S  tk
rð } z.t	dddœddt|ƒ› �dœt
jd� W Y ¢S d }~X Y nX d S )Nr[   r3   r6   rC   r4   rD   )r3   r6   r4   )r>   r6   rC   rD   r8   r4   rQ   éÉ   r:   r;   zEmployee created successfullyrv   r   r“   r—   TúError: )rH   r¨   rI   r   r   rL   r…   r	   r?   r   r   r¤   rj   rV   r™   )rW   rX   rH   r©   r3   r6   rC   r4   rD   Úhashed_passwordÚvanrA   ro   r\   r\   r]   r^      sN    




ýù
ýüýüzRegisterAPIView.postc                 C   s  |j }|j d¡}zÆ|j d¡}| d¡}| d¡}| d¡}| d¡}| d¡}	tjj|d�}
tjj|d�}||
_||
_||
_|	|
_	||
_
|r–||
_|
 ¡  t|ƒ}||_||_||_
| ¡  ttjd	d
œd ddœƒW S  tk
�r   ttjdd
œdddœƒ Y S X d S )Nr[   r3   r6   rC   r4   rD   r7   r›   r:   r;   r§   rv   r—   TúSomething went wrong)rH   r¨   rI   r	   rL   r   r>   r6   rC   rD   r4   rQ   rP   r   r3   r   r   r¤   r   r™   )rW   rX   r?   rH   r©   r3   r6   rC   r4   rD   rª   r«   Zpassesr\   r\   r]   r¬   R  sF    





ý

ýzRegisterAPIView.putc                 O   s‚   |  d¡}zFtjj |d�}| ¡  tjj |d�}| ¡  ttjddœd ddœƒW S  tk
r|   ttj	ddœd	d
dœƒ Y S X d S )Nr?   r7   r›   r:   r;   zCompany deleted successfullyrv   r—   TúNo data found)
rI   r	   rL   r˜   r   r   r   rT   r   r„   )rW   r~   rŸ   Z
company_idr¡   r    r\   r\   r]   r˜   ~  s"    

ý

ýzRegisterAPIView.deleteN)r`   ra   rb   rI   r^   r¬   r˜   r\   r\   r\   r]   r®   ã  s   <2,r®   c                   @   s   e Zd Zdd„ ZdS )ÚCompanydashboardAPIViewc                 C   sè   z¶ddl m} |jj}tjj|d� ¡ }ddl m} ddlm	} |jj}|ƒ }d}d}d}	d}
d}d}d	}d}d}d
}d}d}|||	|
|||||||||dœ}t
tjddœd |dœƒW S  tk
râ   t
tjddœdddœƒ Y S X d S )Nr   ©r†   ©Úcreated_by_idrŽ   rw   é   é   é   é	   é   r°   )ÚtotalenquiryÚtotalvendorÚtotalenquirytodaydateÚactivevendorÚinactivevendorÚ	monthdataÚtotalvendorlastmonthÚcurrent_month_enquiryÚlast_month_enquiryÚcurrent_month_auctionÚlast_month_auctionÚcurrent_month_productÚlast_month_productr:   r;   r€   r—   Tr¾   rv   )Údjango.utils.timezoner†   rZ   r?   r   rL   r‚   Úcountr   r    r   r   rT   r   r„   )rW   rX   r†   ÚoprÈ   r    Úcurrent_daterÎ   rÉ   rÊ   rË   rÍ   rÌ   rÐ   rÏ   rÑ   rÒ   rÓ   rÔ   rH   r\   r\   r]   rI   ™  sZ    ó
ý

ýzCompanydashboardAPIView.getN©r`   ra   rb   rI   r\   r\   r\   r]   r¿   –  s   r¿   c                   @   s   e Zd Zdd„ ZdS )ÚAdmindashboardAPIViewc              	   C   s`  �z*ddl m} |jj}|ƒ }tjjddd� ¡ }tjjddd� ¡ }dd l}ddl	m	} g }	| ¡ j
}
| ¡ j}|d }ddlm} td|ƒD ]"}|j| }d}|	 ||dœ¡ q�tjjdd	� ¡ }d}d}tjjdd	�}|D ] }zW qà tjk
rþ   Y qàX qà||||||	d
œ}ttjddœd |dœƒW S  tk
�rZ   ttjddœdddœƒ Y S X d S )Nr   rÀ   r   )r   rD   r°   ©r   r1   )Ú	monthnameÚcounts)rD   )ÚpaidcompanyÚunpaidcompanyÚtotalcompanyÚactivecompanyÚinactivecompanyrÍ   r:   r;   r€   r—   Tr¾   rv   )rÕ   r†   rZ   r?   r	   rL   r‚   rÖ   Úcalendarr   ÚyearÚmonthÚdjango.db.modelsr!   ÚrangeÚ
month_abbrr¶   ZPaymentrM   r   r   rT   r   r„   )rW   rX   r†   r×   rØ   rá   râ   rã   r   rÍ   Úcurrent_yearÚcurrent_monthZbakr!   rå   Ú
month_nameÚpaymentrà   rÞ   rß   ZqpÚbrH   r\   r\   r]   rI   Ý  s^    


þ

	ø

ý

ýzAdmindashboardAPIView.getNrÙ   r\   r\   r\   r]   rÚ   Ú  s   rÚ   c                   @   s   e Zd Zddd„ZdS )ÚCheckcompanyAPIViewNc           	      C   sî   |j  d¡}|j  d¡}|j  d¡}|j  d¡p:|j  d¡}td|||ƒ |sZ|sZ|sZ|rÐtƒ }|rr|t|d�O }|r„|t|d�O }|r–|t|d	�O }|r¨|t|d
�O }tj |¡ ¡ }tt	j
ddœd |dœƒS tt	jddœdddœt	jd�S )NrC   r6   r3   Ú	gstnumberÚgstzCheck Params:©r>   )rC   r5   )rï   r:   r;   )r   rF   rƒ   r—   Tz!No phone, email, or GST provided.rv   r   )r•   rI   rk   r'   r	   rL   r‚   rƒ   r   r   rT   r™   )	rW   rX   r?   rC   r6   r>   rï   Úqueryrƒ   r\   r\   r]   rI   1  s8    
ý
ýüzCheckcompanyAPIView.get)NrÙ   r\   r\   r\   r]   rî   0  s   rî   c                   @   s4   e Zd ZefZd
dd„Zdd„ Zdd„ Zdd	„ ZdS )ÚProductAPIViewNc              L   C   s:  |d k	�r˜�zZt jj|d�}|j|j|j|j|j|j|j	|j
|j|j|j|j|j|j|j|j|j|j|j|j|j|j|j|j|j|j|j|j|j|j |j!|j"|j#|j$|j%|j&|j'|j(|j)|j*|j+|j,|j-|j.|j/|j0|j1|j2|j3|j4|j5|j6|j7|j8|j9|j:|j;|j<|j=|j>|j?|j@|jA|jB|jC|jD|jE|jF|jG|jH|jI|jJ|jK|jL|jMdœK}tNtOjPddœd |dœƒW S  tQk
�r”   tNtOjRddœddd	œƒ Y S X nžznd
}g }t jjS|jTjd�}|D ]4}|d7 }| U||j|j|j|j|j|jOdœ¡ �q¸tNtOjPddœd |dœƒW S  tQk
�r4   tNtOjRddœddd	œƒ Y S X d S )Nr›   )Kr?   Úcompany_nameÚapplicationÚproject_nameÚcountryÚbidclosedateÚdeliverydateÚs2dailyflowÚs2monthflowÚ
s2weekflowÚs2maxdailyflowÚ
s2hourflowÚs2bodÚs2bodoutÚ	s2bodrateÚs2codÚs2codoutÚ	s2codrateÚs2tssÚs2tssoutÚ	s2tssrateÚs2tnÚs2tnoutÚs2tnrateÚs2tpÚs2tpoutÚs2tprateÚs2oilÚs2oiloutÚ	s2oilrateÚs2avgwatertempÚs2avgwatertempoutÚs2avgwatertemprateÚs2maxwatertempÚs2maxwatertempoutÚs2maxwatertemprateÚs2minwatertempÚs2minwatertempoutÚs2minwatertemprateÚ	Davgflux1Ú	Davgflux2Ú	DpeakfluxÚMsurfacearea1ÚMsurfacearea2ÚproductcodeÚ
NoofmoduleÚ
NoofmtrainÚNoofmptrainÚTNMÚTMsurfaceareaÚ	Aavgflux1Ú	Aavgflux2Ú
Apeakflux1Ú
Apeakflux2Ús4AT1Ús4AT2Ús4AT3Ús4AT4Ús4AT5Ús4AT6Ús4AT7Ús4TT1Ús4TT2Ús4TT3Ús4TT4Ús4TT5Ús4TT6Ús4TT7Ús4MT1Ús4MT2Ús4MT3Ús4MT4Ús4MT5Ús4MT6Ús4MT7r:   r;   r€   r—   Tr¾   rv   r   rÁ   r   )r³   r?   rô   rõ   rö   r÷   r   )Vr   rL   rI   r?   rô   rõ   rö   r÷   rø   rù   rú   rû   rü   rý   rþ   rÿ   r   r  r  r  r  r  r  r  r  r	  r
  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r   r!  r"  r#  r$  r%  r&  r'  r(  r)  r*  r+  r,  r-  r.  r/  r0  r1  r2  r3  r4  r5  r6  r7  r8  r9  r:  r;  r<  r=  r   r   rT   r   r„   r‚   rZ   r¶   )rW   rX   r?   r    rH   r¸   Ú	companiesZproductsr\   r\   r]   rI   Z  sè    
žo
ý

ý÷
ý

ýzProductAPIView.getc              M   C   sB  |j }�zîtjj|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/ |d0 |d1 |d2 |d3 |d4 |d5 |d6 |d7 |d8 |d9 |d: |d; |d< |d= |d> |d? |d@ |dA |dB |dC |dD |dE |dF |dG |dH |dI |dJ |jdK�K}| ¡  ttjdLdMœd dNdOœƒW S  t	k
�r< } z&ttj
dPdMœdQdR|› �dOœƒ W Y ¢S d }~X Y nX d S )SNrô   rö   rõ   r÷   rù   rø   rú   rû   rü   rý   rþ   rÿ   r   r  r  r  r  r  r  r  r  r	  r
  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r   r!  r"  r#  r$  r%  r&  r'  r(  r)  r*  r+  r,  r-  r.  r/  r0  r1  r2  r3  r4  r5  r6  r7  r8  r9  r:  r;  r<  r=  )Krô   rö   rõ   r÷   rù   rø   rú   rû   rü   rý   rþ   rÿ   r   r  r  r  r  r  r  r  r  r	  r
  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r   r!  r"  r#  r$  r%  r&  r'  r(  r)  r*  r+  r,  r-  r.  r/  r0  r1  r2  r3  r4  r5  r6  r7  r8  r9  r:  r;  r<  r=  Ú
created_byr:   r;   zProduct created successfullyrv   r—   Tr£   )rH   r   rL   r…   rZ   rP   r   r   r¤   r¥   r™   ©rW   rX   rH   r    ro   r\   r\   r]   r^     s¶    ¤^
ý

ýzProductAPIView.postc              
   C   sR  |j }�zÐtjj|d�}| d|j¡|_| d|j¡|_| d|j¡|_| d|j¡|_| d|j¡|_| d|j	¡|_	| d|j
¡|_
| d	|j¡|_| d
|j¡|_| d|j¡|_| d|j¡|_| d|j¡|_| d|j¡|_| d|j¡|_| d|j¡|_| d|j¡|_| d|j¡|_| d|j¡|_| d|j¡|_| d|j¡|_| d|j¡|_| d|j¡|_| d|j¡|_| d|j¡|_| d|j¡|_| d|j¡|_| d|j¡|_| d|j¡|_| d|j ¡|_ | d|j!¡|_!| d |j"¡|_"| d!|j#¡|_#| d"|j$¡|_$| d#|j%¡|_%| d$|j&¡|_&| d%|j'¡|_'| d&|j(¡|_(| d'|j)¡|_)| d(|j*¡|_*| d)|j+¡|_+| d*|j,¡|_,| d+|j-¡|_-| d,|j.¡|_.| d-|j/¡|_/| d.|j0¡|_0| d/|j1¡|_1| d0|j2¡|_2| d1|j3¡|_3| d2|j4¡|_4| d3|j5¡|_5| d4|j6¡|_6| d5|j7¡|_7| d6|j8¡|_8| d7|j9¡|_9| d8|j:¡|_:| d9|j;¡|_;| d:|j<¡|_<| d;|j=¡|_=| d<|j>¡|_>| d=|j?¡|_?| d>|j@¡|_@| d?|jA¡|_A| d@|jB¡|_B| dA|jC¡|_C| dB|jD¡|_D| dC|jE¡|_E| dD|jF¡|_F| dE|jG¡|_G| dF|jH¡|_H| dG|jI¡|_I| dH|jJ¡|_J| dI|jK¡|_K| dJ|jL¡|_L| dK|jM¡|_M| N¡  tOtPjQdLdMœd dNdOœƒW S  tRk
�r   tOtPjSdPdMœdQdRdOœƒ Y S  tTk
�rL } z(tU|ƒ tOtPjVdPdMœdQdSdOœƒ W Y ¢S d }~X Y nX d S )TNr›   rô   rö   rõ   r÷   rù   rø   rú   rû   rü   rý   rþ   rÿ   r   r  r  r  r  r  r  r  r  r	  r
  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r   r!  r"  r#  r$  r%  r&  r'  r(  r)  r*  r+  r,  r-  r.  r/  r0  r1  r2  r3  r4  r5  r6  r7  r8  r9  r:  r;  r<  r=  r:   r;   zProduct updated successfullyrv   r—   Tr¾   r½   )WrH   r   rL   rI   rô   rö   rõ   r÷   rù   rø   rú   rû   rü   rý   rþ   rÿ   r   r  r  r  r  r  r  r  r  r	  r
  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r   r!  r"  r#  r$  r%  r&  r'  r(  r)  r*  r+  r,  r-  r.  r/  r0  r1  r2  r3  r4  r5  r6  r7  r8  r9  r:  r;  r<  r=  rP   r   r   rT   r   r„   rj   rk   r™   )rW   rX   r?   rH   r    ro   r\   r\   r]   r¬   y  sÀ    
ý

ý
ýzProductAPIView.putc                 C   sl   |d k	rhz0t jj|d�}| ¡  ttjddœd ddœƒW S  t jk
rf   ttjddœd ddœƒ Y S X d S )Nr›   r:   r;   zProduct deleted successfullyrv   r—   zNo product found)	r   rL   rI   r˜   r   r   rT   rM   r„   )rW   rX   r?   Úproductr\   r\   r]   r˜   ÿ  s    
ý

ýzProductAPIView.delete)N)	r`   ra   rb   r+   r­   rI   r^   r¬   r˜   r\   r\   r\   r]   ró   W  s   
 ,t ró   c                   @   s   e Zd Zddd„Zdd„ ZdS )ÚClientAPIViewNc           	      C   sH  |d k	r°zxt jj|d�}z|jr(|jjnd }W n tk
rF   d }Y nX |j|j|j|j	|j
||jdœ}ttjddœd |dœƒW S  tk
r¬   ttjddœddd	œƒ Y S X n”zdd
}g }tj ¡ }|D ]2}|d7 }| ||j|j|j|j|j|jdœ¡ qÈttjddœd |dœƒW S  tk
�rB   ttjddœddd	œƒ Y S X d S )Nr›   ©r?   r>   r<   ÚdescriptionÚspecificationÚsfiler   r:   r;   r€   r—   Tr¾   rv   r   r   )r³   r?   Úclient_namerC   r6   ÚaddressÚdoj)r   rL   rI   rF  rS   Ú
ValueErrorr?   r>   r<   rD  rE  r   r   rT   r   r„   r   Úallr¶   rG  rC   r6   rH  rI  )	rW   rX   r?   r    ÚflrH   r¸   r>  Úclientr\   r\   r]   rI   #  sh    
ø
ý

ý
ø

ý

ýzClientAPIView.getc              
   C   sœ   |j }zLtjj|d |d |d d�}| ¡  ttjddœd d|j|j	dœd	œƒW S  t
k
r– } z&ttjd
dœdd|› �dœƒ W Y ¢S d }~X Y nX d S )NZ
clientNameÚmobilenumberrH  )rG  rC   rH  r:   r;   zClient created successfully)r?   rM  rE   r—   Tr£   rv   )rH   r   rL   r…   rP   r   r   r¤   r?   rG  r¥   r™   r@  r\   r\   r]   r^   t  s,    ü
þü
	
ýzClientAPIView.post)N©r`   ra   rb   rI   r^   r\   r\   r\   r]   rB     s   
QrB  c                   @   s   e Zd Zdd„ ZdS )ÚDashboardStatsAPIViewc              	   C   s†  |j  dd ¡}|j  dd ¡}|j  dd ¡}t d¡}|rHt |d¡ ¡ nt ¡  |¡ ¡ }t	j
jdd�}tj
j|ddd	�}tj
j|d
dd	�}	|�r,|�r,z|t |d¡ ¡ }
t |d¡ ¡ }| t ||
¡¡}| t ||¡¡}| tj¡}| tj¡}|j||d�}|	j||d�}	W n tk
�r*   Y nX t|jddd�ƒ}t|	jddd�ƒ}|jddgd� ¡ }|jd
dgd� ¡ }t|ƒ}t|ƒ}|dk�r¢t|| d ƒnd}|dk�rÀt|| d ƒnd}g }|D ]„}|jdk}|jdk}|j|k�rôdn|�rþdnd}|j|k�rdn|�rdnd}| |j|||j�rB| |jj¡nd |dœ¡ �qÌtdddœ|||dœ|||dœ|| d¡dœdœƒS ) Nr   Ú	from_timeÚto_timezAsia/Muscatú%Y-%m-%dr   r   ÚPresent)r   Úsession_typer   r°   z%H:%M)Zcreated_at__gteZcreated_at__lteÚ
student_idT)Úflatr±   )ZclassType__inr   éd   )r   r±   )r°   r±   ÚPÚAz--)r>   Ún_statusÚs_statusr©   Z
is_specialr’   r:   r;   )ZpresentÚtotalÚpercent)Zn_dataZs_dataÚstudent_listZselected_date©r   rH   ) r•   rI   Úpytzr   r   Ústrptimer   r†   Ú
astimezoner   rL   r‚   r   r,   ÚlocalizeÚcombineÚutcrJ  ÚsetÚvalues_listrÖ   ÚlenÚintÚ	classTyper?   r¶   ÚstudentNamer©   rR   rS   r   Ústrftime)rW   rX   Zdate_strrQ  rR  Zoman_tzÚtarget_dateZall_studentsZn_qsZs_qsZft_naiveZtt_naiveZfrom_dt_omanZ
to_dt_omanZfrom_dt_utcZ	to_dt_utcZn_present_idsZs_present_idsZn_totalZs_totalZ	n_presentZ	s_presentZ	n_percentZ	s_percentZstudent_daily_listr·   Zis_n_elgZis_s_elgr[  r\  r\   r\   r]   rI   é  s”    
ÿýýý
ÿ
ÿþþ


þþû

üþzDashboardStatsAPIView.getNrÙ   r\   r\   r\   r]   rP  è  s   rP  c                   @   s   e Zd Zdd„ ZdS )ÚStudentClassCountAPIViewc              
   C   s’   zPt jj|dd� ¡ }t jj|dd� ¡ }t||dƒ tdddœ||dœd	œƒW S  tk
rŒ } ztd
t|ƒitj	d� W Y ¢S d }~X Y nX d S )Nr   )rV  rU  r°   Zjsabdbsdsmdbasmdbsandr’   r:   r;   )Únormal_countÚspecial_countr`  rF   r   )
r   rL   r‚   rÖ   rk   r   rj   rV   r   r™   )rW   rX   r?   rp  rq  ro   r\   r\   r]   rI   ¢  s    þþ
zStudentClassCountAPIView.getNrÙ   r\   r\   r\   r]   ro  ¡  s   ro  )ÚContentFile)r   c                   @   s6   e Zd Zdd„ Zddd„Zdd„ Zdd	„ Zd
d„ ZdS )ÚStudentAPIViewc              
   C   s°   d|j kr|j d S | d¡}| ddtt ¡ ƒ› d�¡}|r¬z6d|krV| d¡d }| ¡ }t |¡}t||d�W S  t	k
rª } zt
d	|› �ƒ W Y ¢d
S d
}~X Y nX d
S )ab  
        ????? device / country-????? photo handle ???????:
 
        Method 1 ? request.FILES['photo']
                    Android native multipart
                    Web direct blob (India Netlify)
 
        Method 2 ? data['photo_base64']
                    iOS Safari (Oman, ???? country-?????)
                    FileReader base64 string
        r©   Úphoto_base64Úphoto_filenameZphoto_z.jpgú,r   rñ   z[Photo] Base64 decode error: N)r¨   rI   rj  r,   ÚsplitÚstripÚbase64Ú	b64decoderr  rj   rk   )rW   rX   rH   rt  ru  Z
image_dataro   r\   r\   r]   Ú_handle_photoÄ  s    



zStudentAPIView._handle_photoNc           	      C   s|  |d k	r®ztt jj|d�}|j|j|j|j|j|j|j	|j
|j|j|j|j|jr\| |jj¡nd dœ}ttjddœd |dœƒW S  t jk
rª   ttjddœddd	œƒ Y S X nÊz„t j ¡  d
¡}g }t|dƒD ]J\}}| ||j|j|j|j|j	|j|j|j�r| |jj¡nd dœ	¡ qÎttjddœd |dœƒW S  tk
�rv } z$ttjddœdt|ƒd	œƒ W Y ¢S d }~X Y nX d S )Nr›   )r?   rl  Ú
parentNamerN  ÚagerH  rk  Úmonthly_feesÚnormal_feesÚspecial_feesÚdateOfJoiningr   r©   r:   r;   r€   r—   Tr¯   rv   r²   r   )	r³   r?   rl  r|  rN  rk  r   r}  r©   )r   rL   rI   r?   rl  r|  rN  r}  rH  rk  r~  r  r€  r�  r   r©   rR   rS   r   rT   rM   r„   rK  r´   rµ   r¶   rj   r™   rV   )	rW   rX   r?   r·   rH   Ústudentsr_  r¸   ro   r\   r\   r]   rI   ë  sl    ó
ý

ý÷

ý

ýzStudentAPIView.getc                 C   sN  |j }|  ||¡}zôt| dd¡p$dƒ}t| dd¡p8dƒ}|| }| dd¡}t|tƒr‚zt |¡}W n tk
r€   g }Y nX d}d|krœd|krœd	}nd|kr¨d
}t	j
j| d¡| d¡| d¡| d¡| d¡||||| d¡|dd�}	ttjddœddœƒW S  tk
�rH }
 z"ttjddœt|
ƒdœƒ W Y ¢S d }
~
X Y nX d S )Nr  r   r€  rk  z[]r   ÚNormalÚSpecialr±   r°   rl  r|  rN  r}  rH  r�  )rl  r|  rN  r}  rH  r~  r  r€  rk  r�  r©   r   r:   r;   zStudent created successfully©r   rG   r—   )rH   r{  ÚfloatrI   Ú
isinstancerV   ÚjsonÚloadsrj   r   rL   r…   r   r   r¤   r™   )rW   rX   rH   r©   Ún_feesÚs_feesZ
total_feesZfrontend_classZfinal_class_idr·   ro   r\   r\   r]   r^   &  sP    

ô
þ

þzStudentAPIView.postc           
   
   C   sâ  |j }|  ||¡}�z^tjj|d�}| d¡}|d k	r^zt|ƒ|_W n ttfk
r\   Y nX d|krr| d¡|_	d|kr†| d¡|_
z>t| d¡pœ|j	pœdƒ}t| d¡p´|j
p´dƒ}|| |_W n tk
rØ   Y nX | d|j¡|_| d|j¡|_| d|j¡|_| d	|j¡|_| d
|j¡|_d|k�r@| d¡|_|�rL||_| ¡  tdddœd|j› d�dœƒW S  tjk
�rž   tdddœddœƒ Y S  tk
�rÜ }	 z tdddœt|	ƒdœƒ W Y ¢S d }	~	X Y nX d S )Nr›   rk  r  r€  r   rl  r|  rN  r}  rH  r   r’   r:   r;   zStudent z updated successfully.r…  r”   r—   úStudent not foundr“   )rH   r{  r   rL   rI   rj  rk  rJ  Ú	TypeErrorr  r€  r†  r~  rj   rl  r|  rN  r}  rH  r   r©   rP   r   rM   rV   )
rW   rX   r?   rH   r©   r·   Z
class_dataÚnÚsro   r\   r\   r]   r¬   V  sX    

þ
þþzStudentAPIView.putc                 C   s¢   |d k	ržzft jj|d�}tjj|d� ¡  tjj|d� ¡  tjj|d� ¡  | ¡  tt	j
ddœd ddœƒW S  tjk
rœ   tt	jddœd ddœƒ Y S X d S )	Nr›   ©rV  r:   r;   z4Student and all related records deleted successfullyrv   r—   r¯   )r   rL   rI   r   r‚   r˜   r   r   r   r   rT   r   rM   r„   ©rW   rX   r?   r·   r\   r\   r]   r˜   ”  s$    
ý

ýzStudentAPIView.delete)N)r`   ra   rb   r{  rI   r^   r¬   r˜   r\   r\   r\   r]   rs  Á  s
   '
;0>rs  c                   @   s   e Zd Zdd„ ZdS )ÚBookingReportAPIViewc                 C   s¤   |j  d¡}|j  d¡}|r |s2tdditjd�S tjj||gd� d¡j	t
dƒtd	ƒd
� d¡}tjj||gd�jt
dƒtd	ƒd�}td||dœ||dœtjd�S )NÚ	from_dateÚto_daterG   z)Please provide both from_date and to_dater   ©Zbooking_date__rangeÚnet_selectionr?   Úamount)Ztotal_bookingsZtotal_revenuez-total_revenue)Zgrand_total_bookingsZgrand_total_revenuer:   )ÚfromÚto)r   Z
date_rangeZdetailed_reportZoverall)r•   rI   r   r   r™   r   rL   r‚   ÚvaluesÚannotater"   r!   r´   Ú	aggregaterT   )rW   rX   r“  r”  Úreport_dataZoverall_statsr\   r\   r]   rI   µ  s8    ÿþüûÿüüûzBookingReportAPIView.getNrÙ   r\   r\   r\   r]   r’  ´  s   r’  c                   @   s:   e Zd Zddd„ZddlmZ dd„ Zdd	„ Zd
d„ ZdS )ÚBookingAPIViewNc                 C   s¾  |d k	r®zrt jj|d�}|j|j|j|j|j|j|j	 
d¡|jrL|j 
d¡nd |j|j|j|jdœ}ttjddœ|dœƒW S  t jk
r¨   tddid	d
œtjd� Y S X �nzÌ|j d¡}|rÒt |d¡ ¡ }nt ¡  ¡ }t jj|d� dd¡}g }t|dƒD ]`\}	}
| |	|
j|
j|
j|
j|
j|
j|
j	 
d¡|
j�rF|
j 
d¡nd |
j|
j|
j|
jdœ¡ �qttjddœ|dœƒW S  tk
�r¸ } ztdt |ƒitj!d� W Y ¢S d }~X Y nX d S )Nr›   rS  )r?   Úcustomer_namerC   r6   r–  Úbooking_typeÚbooking_dateÚend_dateÚ
start_timeÚend_timer—  Úpayment_statusr:   r;   r`  r<   r”   úBooking not foundr…  r   r   )Zbooking_date__gter¡  r£  r   )r³   r?   rŸ  rC   r6   r–  r   r¡  r¢  r£  r¤  r—  r¥  rF   )"r   rL   rI   r?   rŸ  rC   r6   r–  r   r¡  rm  r¢  r£  r¤  r—  r¥  r   r   rT   rM   r„   r•   r   rb  r   r   r†   r‚   r´   rµ   r¶   rj   rV   r™   )rW   rX   r?   ÚbookingrH   Ztarget_date_strrn  ÚbookingsZbooking_listr¸   rí   ro   r\   r\   r]   rI   Ø  sf    
ô
þ
"
ó
þ
zBookingAPIView.getr   r&   c                 C   sp  |j }�z$| dd¡}t | d¡d¡ ¡ }| d¡}| d¡}| d¡}d }|dkrnt | d	¡d¡ ¡ }n|}tjj|||d
� t||fd�t||fd�B t||d�B ¡ 	¡ }	|	rÊt
dditjd�W S tjj| d¡| d¡| d¡||||dkrú|nd ||| d¡| d¡d�}
t
d|
jdœtjd�W S  tk
�rj } zt
dt|ƒitjd� W Y ¢S d }~X Y nX d S )Nr   ÚDayr¡  rS  r£  r¤  r–  ÚMonthr¢  ©r–  Zstart_time__ltZend_time__gtr•  ©Zend_date__range©Zbooking_date__lteZend_date__gterG   zOSlot already booked! Selected dates or times conflict with an existing booking.r   rŸ  rC   r6   r—  r¥  )rŸ  rC   r6   r–  r   r¡  r¢  r£  r¤  r—  r¥  zBooking confirmed successfully!)rG   r?   )rH   rI   r   rb  r   r   rL   r‚   r'   rƒ   r   r   r�   r…   r?   r¤   rj   rV   r™   )rW   rX   rH   Úb_typeÚ
start_dateÚ	raw_startÚraw_endÚnetr¢  Úoverlapr§  ro   r\   r\   r]   r^     sd    


ýÿ
þú ÿþõþýzBookingAPIView.postc              
   C   s  |j }�zªtjj|d�}| d|j¡}| d¡}|rDt |d¡ ¡ n|j}| d|j	¡}| d|j
¡}	| d|j¡}
|dkrž| d	¡ržt | d	¡d¡ ¡ }n|d
kr¬|}n|j}tjj|
|	|d� t||fd�t||fd�B t||d�B ¡j|d� ¡ }|�rtdditjd�W S | d|j¡|_| d|j¡|_| d|j¡|_|
|_||_||_|dk�rd|nd |_||_	|	|_
| d|j¡|_| d|j¡|_| ¡  tdddœtjd�W S  tjk
�rÜ   tdditjd� Y S  tk
�r } ztdt|ƒitjd� W Y ¢S d }~X Y nX d S )Nr›   r   r¡  rS  r£  r¤  r–  rª  r¢  r©  r«  r•  r¬  r­  rG   z3Update failed! Slot conflicts with another booking.r   rŸ  rC   r6   r—  r¥  r:   zBooking updated successfully!r…  r¦  ) rH   r   rL   rI   r   r   rb  r   r¡  r£  r¤  r–  r¢  r‚   r'   Úexcluderƒ   r   r   r�   rŸ  rC   r6   r—  r¥  rP   rT   rM   r„   rj   rV   r™   )rW   rX   r?   rH   r§  r®  Zstart_date_strr¯  r°  r±  r²  r¢  r³  ro   r\   r\   r]   r¬   V  sp    
ýÿ
þûø

 ÿþþýzBookingAPIView.putc                 C   sh   |d k	rdz.t jj|d�}| ¡  ttjddœddœƒW S  t jk
rb   ttjddœddœƒ Y S X d S )Nr›   r:   r;   z!Booking slot deleted successfullyr…  r—   zNo booking found)	r   rL   rI   r˜   r   r   rT   rM   r„   )rW   rX   r?   r§  r\   r\   r]   r˜   ”  s    
þ

þzBookingAPIView.delete)N)	r`   ra   rb   rI   ræ   r'   r^   r¬   r˜   r\   r\   r\   r]   rž  Ô  s
   
@:>rž  c                   C   s   dd  tjtjdd�¡ S )NZRECÚ rw   )Úk)ÚjoinÚrandomÚchoicesÚstringÚdigitsr\   r\   r\   r]   Úgenerate_receipt_no¨  s    r¼  rÛ   )r   r   r   c                   @   s   e Zd Zddd„Zdd„ ZdS )ÚFeesAPIViewNc                 C   s  t  ¡ j}t  ¡ j}|�rˆ�z<tjj|d�}tjj|d� 	¡ }t
tjj|d||d�jtdƒd�d pfdƒ}t
tjj|d	||d�jtdƒd�d p’dƒ}t
|jp dƒ}	|rÚ|dkrÎt
|jƒ|	k rÎt
|jƒ|	 }
qÞt
|jƒ}
n|	}
t
|jpèdƒ}|�r(|dk�rt
|jƒ|k �rt
|jƒ| }n
t
|jƒ}n|}|j|j|	||
|||d
œ}tddi|dœƒW S  tjk
�r‚   tddiddœƒ Y S X �n|tjjdd�}g }|D �]P}tjj|d� 	¡ }t
tjj|d||d�jtdƒd�d �pàdƒ}t
tjj|d	||d�jtdƒd�d �pdƒ}t
|j�pdƒ}	|�r^|dk�rRt
|jƒ|	k �rRt
|jƒ|	 }
n
t
|jƒ}
n|	}
t
|j�pndƒ}|�r®|dk�r¢t
|jƒ|k �r¢t
|jƒ| }n
t
|jƒ}n|}| |j|j�rÐ| |jj¡nd |j|j|	||
|||dœ
¡ �qžtddi|dœƒS d S )Nr›   ©r·   ÚNORMAL)r·   Úfee_typeÚpayment_date__monthÚpayment_date__yearÚamount_paid©r]  r]  r   ÚSPECIAL)rl  rk  r  Únormal_paidÚnormal_balancer€  Úspecial_paidÚspecial_balancer<   r’   r`  r”   rŒ  r…  r   r   )
r?   r©   rl  rk  r  rÆ  rÇ  r€  rÈ  rÉ  )r   r†   rå   rä   r   rL   rI   r   r‚   Úfirstr†  r   rœ  ÚDSumr  rÇ  r€  rÉ  rl  rk  r   rM   r¶   r?   r©   rR   rS   )rW   rX   r?   rê   ré   r·   Z
fee_recordZn_paid_this_monthZs_paid_this_monthrŠ  Z	n_balancer‹  Z	s_balancerH   r‚  Ú	data_listr\   r\   r]   rI   ²  sÖ    

  þýýý  þýýýø

  þýýý  þýýýõzFeesAPIView.getc              
   C   sF  �z t jj|d�}|j}t| dd¡ƒ}t| dd¡ƒ}| d¡}tjj|d�\}}	|	r†t|jpbdƒ|_t|jprdƒ|_t	 
¡  ¡ |_|dkrªt|jp˜dƒ| |_||_n"|dkrÌt|jp¼dƒ| |_||_| ¡  tjj|||t	 
¡  ¡ d	� td
diddœƒW S  tk
�r@ }
 ztd
dit|
ƒdœƒ W Y ¢S d }
~
X Y nX d S )Nr›   Zpaid_amountr   Zbalance_amountrÀ  r¾  r¿  rÅ  )r·   rÃ  rÀ  Úpayment_dater<   r’   zPayment Recorded Successfullyr…  r“   )r   rL   rI   rH   r†  r   Úget_or_creater  r€  r   r†   r   rÍ  rÆ  rÇ  rÈ  rÉ  rP   r   r…   r   rj   rV   )rW   rX   r?   Zstudent_objÚdZpaid_nowZnew_balancerÀ  ZfeeÚcreatedro   r\   r\   r]   r¬   #	  s6    

üzFeesAPIView.put)N)r`   ra   rb   rI   r¬   r\   r\   r\   r]   r½  ±  s   
qr½  c                   @   s   e Zd Zdd„ ZdS )ÚFeesHistoryAPIViewc              
   C   sœ  ddl m} �zJtjj|d�}|j ¡ }t ¡  ¡ }t	jj
|d�}tƒ }|D ]&}	|	j d¡› d|	j› �}
| |
¡ qLg }|jdd�}||k�r>| d¡}d	D ]�}|› d|› �}||krü|j|j|j|d
�}| |j| d¡t|jƒ|j d¡|jddœ¡ qœ| d| d¡› d|› �| d¡dd |ddœ¡ qœ||dd�7 }q„| ¡  tddi|dœƒW S  tk
�r– } ztddit|ƒdœƒ W Y ¢S d }~X Y nX d S )Nr   )Úrelativedeltar›   r�  z%m-%YÚ-r   )Úday)r¿  rÅ  )rÁ  rÂ  rÀ  z%B %Yz%d-%m-%YZPAID)r?   rë   rÃ  rÍ  rÀ  r   zunpaid-ZNOT_PAID)Úmonthsr<   r’   r`  r“   r…  )Zdateutil.relativedeltarÒ  r   rL   rI   Ú
created_atr   r   r†   r   r‚   rg  rÍ  rm  rÀ  ÚaddÚreplacerå   rä   r¶   r?   r†  rÃ  Úreverser   rj   rV   )rW   rX   rV  rÒ  r·   Z	join_daterØ   Zhistory_recordsZpaid_monthsÚhÚkeyZ
final_dataZ	temp_dateZ
month_yearZf_typeZ	check_keyÚrecordro   r\   r\   r]   rI   L	  sV    


ý
ú
ú

zFeesHistoryAPIView.getNrÙ   r\   r\   r\   r]   rÑ  K	  s   rÑ  c                   @   s   e Zd Zdd„ ZdS )ÚStudentStatusAPIViewc                 C   st   zHt jj|d�}|jdkr"d|_nd|_| ¡  tdddœ|jddœƒW S  t jk
rn   td	d
idd� Y S X d S )Nr›   r   r°   r’   r:   r;   úStatus updated successfully©r   Z
new_statusrG   rF   rŒ  r”   r   )r   rL   rI   r   rP   r   rM   r‘  r\   r\   r]   Úpatch 	  s    
ý
zStudentStatusAPIView.patchN©r`   ra   rb   rà  r\   r\   r\   r]   rÝ  Ÿ	  s   rÝ  c                   @   s   e Zd Zdd„ ZdS )ÚEmployeeStatusAPIViewc                 C   st   zHt jj|d�}|jdkr"d|_nd|_| ¡  tdddœ|jddœƒW S  tjk
rn   td	d
idd� Y S X d S )Nr7   r   r°   r’   r:   r;   rÞ  rß  rF   rŒ  r”   r   )r	   rL   rI   r   rP   r   r   rM   r‘  r\   r\   r]   rà  ³	  s    
ý
zEmployeeStatusAPIView.patchNrá  r\   r\   r\   r]   râ  ²	  s   râ  c                   @   s   e Zd ZegZdd„ ZdS )ÚMonthlyAttendanceAPIViewc                 C   s(  t |j dt ¡ j¡ƒ}t |j dt ¡ j¡ƒ}|j d¡}t ||¡d }tj	| d d… }g }t
d|d ƒD ] }| ||› d|d›�dœ¡ qp|r®|d	kr®tjj|d
�}	n
tj ¡ }	tjj||d�}
g }|	D �]>}i }d}d}d}d}|D ]ê}|d }|
j|j|dd� ¡ }|
j|j|dd� ¡ }|�r<|jdk�r<dn|�rFdnd}|�r`|jdk�r`dn|�rjdnd}||d|› d�< ||d|› d�< |dk�r¢|d7 }n|dk�r´|d7 }|dk�rÈ|d7 }qî|dkrî|d7 }qî| |j|j�rø| |jj¡nd |j|||||dœ¡ qÐt|ƒ t||dœƒS )Nrå   rä   rV  r   r±   Ú Z02d)Úday_numÚdisplayrK  r›   )Zdate__monthZ
date__yearr   rå  )rV  Z	date__dayrU  r°   rT  rY  rZ  rÓ  Zday_Ú_nZ_s)r>   r©   rk  Ú
attendanceÚ	total_n_pÚ	total_n_aÚ	total_s_pÚ	total_s_a)ÚdaysÚreport)rj  r•   rI   r   r†   rå   rä   rã   Ú
monthrangerë   rç   r¶   r   rL   r‚   rK  r   r?   rÊ  r   rl  r©   rR   rS   rk  rk   r   )rW   rX   rå   rä   Zstudent_id_paramZnum_daysrë   Z	days_listrÏ  r‚  Zattendance_recordsr�  r·   Zstudent_attré  rê  rë  rì  Zday_objZn_recZs_recr[  r\  r\   r\   r]   rI   Ê	  sj    þ


$$
 

 
 
 
ø
þzMonthlyAttendanceAPIView.getN)r`   ra   rb   r+   r­   rI   r\   r\   r\   r]   rã  Ç	  s   rã  c                   @   s$   e Zd Zdd„ Zdd„ Zdd„ ZdS )ÚAttendanceAPIViewc           	      C   sê   z¢|j  dt ¡  ¡ ¡}|j  d¡}tjj|d� d¡}|rH|j|d�}g }t	|dƒD ]2\}}| 
||j|jj|jj|j|j|jdœ¡ qVttjdd	œd |d
œƒW S  tk
rä } z$ttjdd	œdt|ƒdœƒ W Y ¢S d }~X Y nX d S )Nr   rU  )r   r²   )rU  r   )r³   r?   Ú	studentIdrl  r   rU  r   r:   r;   r€   r—   Trv   )r•   rI   r   ÚtodayÚ	isoformatr   rL   r‚   r´   rµ   r¶   r?   r·   rl  r   rU  r   rT   rj   r™   rV   )	rW   rX   Z
query_daterU  ÚattendancesZattendance_listr¸   Zattro   r\   r\   r]   rI   
  s8    ù


ý

ýzAttendanceAPIView.getc           
   
   C   sø   |j }z¤| d¡}| dt ¡  ¡ ¡}| d¡}| d¡}tjj|||d� ¡ }|rh||_	| 
¡  d}ntjj||||d�}d}tt	jd	d
œd ||j|jj|j	dœdœƒW S  tk
rò }	 z*tt	jdd
œddt|	ƒ› �dœƒ W Y ¢S d }	~	X Y nX d S )Nrñ  r   rU  r   ©rV  r   rU  zAttendance updated successfully)rV  r   rU  r   zAttendance marked successfullyr:   r;   )r?   rl  r   rE   r—   Trº   rv   )rH   rI   r   rò  ró  r   rL   r‚   rÊ  r   rP   r…   r   r¤   r?   r·   rl  rj   r™   rV   )
rW   rX   rH   rV  Zatt_dateÚsessionZ
att_statusZattendance_objrG   ro   r\   r\   r]   r^   5
  sJ    


ý
ü
ýü

ýzAttendanceAPIView.postc              
   C   sÖ   z”|j  d¡}|j  d¡}|j  d¡}|r2|r2|sFtddiddœƒW S tjj|||d� ¡ \}}|d	kr~td
ddœddœƒW S tddiddœƒW S W n< tk
rÐ } ztddit|ƒdœƒ W Y ¢S d }~X Y nX d S )Nrñ  r   rU  r<   r“   z&studentId, date, session_type requiredr…  rõ  r   r’   r:   r;   zAttendance deleted successfullyr”   zAttendance record not found)	r•   rI   r   r   rL   r‚   r˜   rj   rV   )rW   rX   rV  r   rU  Zdeleted_countÚ_ro   r\   r\   r]   r˜   g
  s8    þ
ýþ
þþzAttendanceAPIView.deleteN)r`   ra   rb   rI   r^   r˜   r\   r\   r\   r]   rð  
  s   #2rð  c                   @   s   e Zd Zddd„Zdd„ ZdS )ÚLoanAPIViewNc                 C   sÞ  |d k	r²zxt jj|d�}z|jr(|jjnd }W n tk
rF   d }Y nX |j|j|j|j	|j
||jdœ}ttjddœd |dœƒW S  tk
r¬   ttjddœddd	œƒ Y S X �n(zøg }tjjd
d�}|D ],}tjj|jd�}	| |j|	j|	jdœ¡ qÊd}
g }tj ¡ }|D ]€}|
d7 }
tjj|jd�}tjj|jd�jtdƒd�d �pNd}| |
|jdt|jƒ ||j|j|j|j|j|j|j dœ¡ �qttjddœd ||dœƒW S  tk
�rØ   ttjddœddd	œƒ Y S X d S )Nr›   rC  r:   r;   r€   r—   Tr¾   rv   ÚActive©Úloan_status)Úloan_idr>   rC   r   r   ©rü  ÚcollectedamonutrÄ  r]  ÚL00)r³   r?   rü  ÚpaidrG  Zclient_phoneÚloan_amountÚloan_tenure_monthsÚcollection_typeÚcollection_dayrû  )r   rF   rH   Ú
activeloan)!r   rL   rI   rF  rS   rJ  r?   r>   r<   rD  rE  r   r   rT   r   r„   r   r‚   r   Ú	client_idr¶   rG  rC   rK  r   rœ  r!   rV   r  r  r  r  rû  )rW   rX   r?   r    rL  rH   r  ÚloaÚiÚclientsr¸   r>  ÚloanrM  Úcollectedamountr\   r\   r]   rI   Ž
  s”    
ø
ý

ýý

ÿþþô
ü

ýzLoanAPIView.getc                 C   sÂ   |j }zrd}tjj|d |d |d ||d |d | dd¡|d	 |d
 | dd¡d�
}| ¡  ttjddœd ddœƒW S  t	k
r¼ } z&ttj
ddœdd|› �dœƒ W Y ¢S d }~X Y nX d S )Nr   ZclientIdZ
loanAmountZloanDateZ
loanTenureZemiStartDateZcollectionTypeZDailyZavgRateZ
loanStatusÚremarksrµ  )
r  r  Ú	loan_dateÚinterest_rater  Úemi_start_dater  r  rû  r  r:   r;   úLoan created successfullyrv   r—   Tr£   )rH   r   rL   r…   rI   rP   r   r   r¤   r¥   r™   )rW   rX   rH   Úrater    ro   r\   r\   r]   r^   ù
  s6    

î
ý

ýzLoanAPIView.post)NrO  r\   r\   r\   r]   rø  ‹
  s   
krø  c                   @   s   e Zd Zddd„ZdS )ÚDashboardAPIViewNc              	   C   s(  |d k	rîz´g }t jj|d�}|D ]$}| |j|j|j|j|jdœ¡ q t jj|d�j	t
dƒd�d pfd}tjj|d�}tjj|jd�}|j|j|j|j|j|dœ}	ttjd	d
œd ||	dœƒW S  tk
rè   ttjdd
œdddœƒ Y S X �n6�zd}
g }ddlm} tjjdd� ¡ }tjjdd� ¡ }tj 	t
dƒ¡d �pBd}t j 	t
dƒ¡d �p\d}t|ƒt|ƒ }tjjdd� 	t
dƒ¡d �pŽd}| ¡  ¡ }t jj|d� 	t
dƒ¡d �p¼d}|||||||dœ}t|dƒ ttjd	d
œd |dœƒW S  tk
�r"   ttjdd
œdddœƒ Y S X d S )Nrý  ©r?   rþ  Úmethodrü  r   rþ  rÄ  r]  r   r›   ©rG  rC   r  Útenurerû  r   r:   r;   ©r   rF   rH   Údatasr—   Tr¾   rv   r   rù  rú  ÚClosedr  Úloan_amount__sumÚcollectedamonut__sumr  Zcollection_day__sum)Zcreated_at__date)ÚactiveÚinactiveÚtotal_disbursedÚtotal_collectedÚtotal_outstandingÚexpected_dailyÚactual_dailyZfdddgdgfdgdfgdfgfdgfdgfdr€   ) r   rL   r‚   r¶   r?   rþ  r  rü  rÖ  rœ  r!   r   rI   r   r  rG  rC   r  r  rû  r   r   rT   r   r„   Údjango.utilsr   rÖ   r†  r†   r   rk   )rW   rX   r?   ÚdogoÚ
collectionÚmr  r  ÚclirH   r¸   r>  r   r  r  r  r  r   r!  rò  r"  r  r\   r\   r]   rI   …  s�    û

ÿþþú

ü

ý""ù

ý

ýzDashboardAPIView.get)NrÙ   r\   r\   r\   r]   r  ‚  s   r  )r   r   c                   @   s   e Zd Zdd„ ZdS )ÚMonthlyReportAPIViewc           	   
   C   s  |j  d¡}|j  d¡}|r |s4t ¡  ¡ }|}|}z–tjj||gd� t	dƒ¡d pXd}t
jj||gd� t	dƒ¡d p|d}tjj||gd� ¡ }td	||t|ƒt|ƒ ||› d
|› �dœdœtjd�W S  tk
�r
 } z tdt|ƒdœtjd� W Y ¢S d }~X Y nX d S )Nr¯  r¢  )Zcreated_at__date__ranger  r  r   rþ  r  r:   z to )r  r  Znet_flowÚnew_loans_countÚperiodr`  r   rF   r…  )r•   rI   r   r†   r   r   rL   r‚   rœ  r!   r   rÖ   r   r†  r   rT   rj   rV   r™   )	rW   rX   r¯  r¢  rò  Z	disbursedÚ	collectedr)  ro   r\   r\   r]   rI   ò  sR    ÿþþþÿþþþÿ
ûþ	÷zMonthlyReportAPIView.getNrÙ   r\   r\   r\   r]   r(  ñ  s   r(  c                   @   s   e Zd Zddd„Zdd„ ZdS )ÚCollectionAPIViewNc                 C   s¦  |d k	rìz´g }t jj|d�}|D ]$}| |j|j|j|j|jdœ¡ q t jj|d�j	t
dƒd�d pfd}tjj|d�}tjj|jd�}|j|j|j|j|j|dœ}	ttjd	d
œd ||	dœƒW S  tk
rè   ttjdd
œdddœƒ Y S X n¶z†d}
g }tj ¡ }|D ]T}|
d7 }
tjj|jd�}| |
|jdt|jƒ |j|j|j|j|j|jdœ	¡ �qttjd	d
œd |dœƒW S  tk
�r    ttjdd
œdddœƒ Y S X d S )Nrý  r  rþ  rÄ  r]  r   r›   r  r:   r;   r  r—   Tr¾   rv   r   rÿ  ©	r³   r?   rü  rG  r  r  r  r  rû  r€   )r   rL   r‚   r¶   r?   rþ  r  rü  rÖ  rœ  r!   r   rI   r   r  rG  rC   r  r  rû  r   r   rT   r   r„   rK  rV   r  r  )rW   rX   r?   r$  r%  r&  r  r  r'  rH   r¸   r>  r
  r    rM  r\   r\   r]   rI     sŠ    û

ÿþþú

ü

ý
ó
ý

ýzCollectionAPIView.getc              
   C   sê   |j }zš|d }|d }|d }| dd¡}tjj||||d�}tjj|d�jtdƒd	�d
 p`d}tjj|d�}	|	j	|krˆd|	_
|	 ¡  ttjddœd ddœƒW S  tk
rä }
 z&ttjddœdd|
› �dœƒ W Y ¢S d }
~
X Y nX d S )NZloanIdZamountCollectedZpaymentModer  rµ  )rü  rþ  r  r  rý  rþ  rÄ  r]  r   r›   r  r:   r;   r  rv   r—   Tr£   )rH   rI   r   rL   r…   r‚   rœ  r!   r   r  rû  rP   r   r   r¤   r¥   r™   )rW   rX   rH   rü  Zamount_collectedÚpayment_moder  r%  Zcollected_totalr
  ro   r\   r\   r]   r^     sD    ü	ÿþþ

ý

ýzCollectionAPIView.post)NrO  r\   r\   r\   r]   r,    s   
ar,  c                   @   s   e Zd Zddd„ZdS )ÚGetclientAPIViewNc                 C   s  |d k	rzzBt jj|d�}|j|j|j|j|jdœ}tt	j
ddœd |dœƒW S  tk
rv   tt	jddœddd	œƒ Y S X n„zTd
}g }t j ¡ D ]&}|d7 }| ||j|j|jdœ¡ qŽtt	j
ddœd |dœƒW S  tk
� rü   tt	jddœddd	œƒ Y S X d S )Nr›   )r?   Ú
vendornamerC   r6   rH  r:   r;   r€   r—   Tr¾   rv   r   r   )r³   r?   rM  rC   )r   rL   r‚   r?   r0  rC   r6   rH  r   r   rT   r   r„   rK  r¶   rG  )rW   rX   r?   r    rH   r¸   r>  r\   r\   r]   rI   ³  sT    û
ý

ýü

ý

ýzGetclientAPIView.get)NrÙ   r\   r\   r\   r]   r/  °  s   r/  c                   @   s   e Zd Zddd„ZdS )ÚOldloanAPIViewNc                 C   sJ  |d k	r’zZg }t jj|d�}|D ](}| |j|j|j|j|j|j	dœ¡ q t
tjddœd |dœƒW S  tk
rŽ   t
tjddœddd	œƒ Y S X n´z„d
}g }t j ¡ }|D ]R}	|d7 }tjj|	jd�}
| ||	jdt|	jƒ |
j|	j|	j|	j|	j|	j	dœ	¡ qªt
tjddœd |dœƒW S  tk
�rD   t
tjddœddd	œƒ Y S X d S )N)r  )r  r  rü  ZemisdateZemildaterû  r:   r;   r€   r—   Tr¾   rv   r   r   r›   rÿ  r-  )r   rL   r‚   r¶   r  r  r?   r  r  rû  r   r   rT   r   r„   rK  r   rI   r  rV   rG  r  r  )rW   rX   r?   r$  r%  r&  r¸   r>  r
  r    rM  r\   r\   r]   rI   ï  sj    ú

ý

ý
ó

ý

ýzOldloanAPIView.get)NrÙ   r\   r\   r\   r]   r1  ì  s   r1  c                   @   s   e Zd Zdd„ ZdS )Ú	FpAPIViewc           	   
   C   s®   |j }z^| di ¡}| d¡}| d¡}t|ƒ}tjj|d�}||_| ¡  ttj	ddœd ddœƒW S  t
k
r¨ } z&ttjd	dœd
d|› �dœƒ W Y ¢S d }~X Y nX d S )Nrt   r6   r4   r5   r:   r;   zPassword reset successfullyrv   r—   Tr£   )rH   rI   r   r   rL   r4   rP   r   r   rT   r¥   r™   )	rW   rX   rH   rt   r6   r4   r»   Zmanro   r\   r\   r]   r^   G  s(    


ý

ýzFpAPIView.postNr_   r\   r\   r\   r]   r2  C  s   r2  c                   @   s&   e Zd ZefZddd„Zddd„ZdS )ÚNotificationAPIViewNc                 C   s   |d k	rtz:t jj|d�}|j|j|jdœ}ttjddœd |dœƒW S  t	k
rn   ttj
ddœddd	œƒ Y S X �nˆd
dlm} d
dlm} �z(d
}g }|jj}	tjj|	d�}
|
jdk�r˜tjjddgd� d¡}|D ] }|d7 }z|jrò|jjnd}W n tjk
�r   d}Y nX |jdk�r.d|› �}n|jdk�rF|› d�}nd}| ||j|j||j||j|ƒ ƒd dœ¡ qÖttjddœd |t|ƒdœƒW S ttjddœddg dœƒW S W nD tk
�rú } z$ttjddœdt|ƒd	œƒ W Y ¢S d }~X Y nX d S )Nr›   )r?   r0  rC   r:   r;   r€   r—   Tr¾   rv   r   )Ú	timesincerÀ   r7   r   ZnewuserZpaymentuser)Ztype__inr²   ÚUnknownzNew Company Registered: z made a paymentzUnknown notification typez ago)r³   r?   ÚtyperG   rÖ  Ztime_ago)r   rF   rH   rÖ   Ú	forbiddenz1You do not have permission to view notifications.rE   ) ZVendorrL   rI   r?   r0  rC   r   r   rT   r   r„   Údjango.utils.timesincer4  rÕ   r†   rZ   r	   rD   r   r‚   r´   r3   r   rM   r6  r¶   rÖ  ri  ZHTTP_403_FORBIDDENrj   r‹   rV   )rW   rX   r?   r    rH   r4  r†   r¸   Únoter×   rA   ZnotificationsrŽ  r3   rG   ro   r\   r\   r]   rI   o  sˆ    ý
ý

ý	ÿþ
ú


ü
	
ü
ýzNotificationAPIView.getc              
   C   sâ   zp|d k	r:t jj|d�}| ¡  ttjddœd ddœƒW S |jj}t jj	|d� ¡  ttjddœd ddœƒW S W nl t
k
rœ   ttjddœd	d
dœƒ Y S  tk
rÜ } z$ttjddœd	t|ƒdœƒ W Y ¢S d }~X Y nX d S )Nr›   r:   r;   z!Notification deleted successfullyrv   r7   z&All notifications deleted successfullyr—   TzNotification not found)r   rL   rI   r˜   r   r   rT   rZ   r?   r‚   r   r„   rj   r‹   rV   )rW   rX   r?   Únotificationr×   ro   r\   r\   r]   r˜   È  s8    
ý

ý
ý
ýzNotificationAPIView.delete)N)N)r`   ra   rb   r+   r­   rI   r˜   r\   r\   r\   r]   r3  l  s   
Yr3  c                   @   s   e Zd Zdd„ ZdS )Ú ProductactivestatusupdateAPIViewc              
   C   sš   zPt jj|d�}|jdkr*d|_| ¡  nd|_| ¡  ttjddœd ddœƒW S  tk
r” } z&ttjddœd	d
|› �dœƒ W Y ¢S d }~X Y nX d S )Nr›   r   r°   r:   r;   zQuote accepted successfullyrv   r—   Tr£   )	r   rL   rI   r   rP   r   r¤   r¥   r™   )rW   rX   r?   Zvenro   r\   r\   r]   r¬   ï  s$    


ý

ýz$ProductactivestatusupdateAPIView.putN)r`   ra   rb   r¬   r\   r\   r\   r]   r;  í  s   r;  )sÚdjango.confr   Zdjango.shortcutsr   Zrest_framework.viewsr   Zrest_framework.responser   Úrest_frameworkr   Úmodelsr	   r
   r   r   r   r   r   r   r   r   r   r   Údjango.core.exceptionsr   Zrest_framework.exceptionsr   Údjango.contrib.authr   r   Zrest_framework_simplejwt.tokensr   Údjango.contrib.auth.hashersr   Údjango.contrib.auth.modelsr   r#  r   Zdjtzr   r   r    Úrequestsræ   r!   r"   Údjango.httpr#   ry  Zrest_framework.parsersr$   r%   r'   Zrest_framework.genericsr(   r)   Úserializersr*   Zrest_framework.permissionsr+   r,   rˆ  Údjango.core.mailr-   Zschool.settingsr.   ZpdfkitrJ   rˆ   r/   Údjango.utils.cryptor0   r2   rp   rq   rr   rs   rŒ   r�   rš   r®   r¿   rÚ   rî   ró   rB  Zdt_timera  rP  ro  Údjango.core.files.baserr  rs  r’  rž  r¸  rº  r¼  rË  r½  rÑ  rÝ  râ  rã   rã  rð  rø  r  r(  r,  r/  r1  r2  r3  r;  r\   r\   r\   r]   Ú<module>   sð   8e& I} 4DV'   L E : t  S TH| xh* <W) 