U
    ¤\»jûÃ  ã                   @   sV  d dl Z d dlZd dl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 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 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 Z d dl m!Z!m"Z"m#Z# ddlmZmZmZmZmZ e!dƒZ$ddej%fdd„Z&ej'fdd„Z(dd„ Z)dd„ Z*G dd„ deƒZ+G dd„ deƒZ,G dd„ deƒZ-G dd „ d eƒZ.G d!d"„ d"eƒZ/d#d$„ Z0d%d&„ Z1d d'lm2Z2 e2ƒ ZG d(d)„ d)eƒZ3G d*d+„ d+eƒZ4d d,l5m6Z6 d d-l7m8Z8 G d.d/„ d/eƒZ9G d0d1„ d1eƒZ:G d2d3„ d3eƒZ;dS )4é    N)ÚauthenticateÚlogin)ÚUser)ÚContentFile)Útransaction)ÚQ©Ústatus)ÚAPIView©ÚResponse)ÚIsAuthenticated)ÚRefreshTokené   )ÚCompanyÚCustomerÚProductÚInvoiceÚInvoiceItem)ÚObjectDoesNotExist)ÚDecimalÚInvalidOperationÚROUND_HALF_UPz0.01c                 C   s.   t |ddœd dœ|rd|ini d| i–|d�S )NÚsuccess©ÚcodeÚresponse)r	   ÚerrorÚmessageÚdatar   r   )r   r   r   © r    ú*/var/www/html/SARATH/school/myapp/views.pyÚok&   s    þ üûr"   c                 C   s   t |ddœd| dœ|d�S )NÚfailedr   T©r	   r   r   r   r   ©r   r   r    r    r!   Úfail/   s    ýür&   c              
   C   s^   | dks| dkr t d|› d�ƒ‚ztt| ƒƒW S  tt tfk
rX   t d|› d�ƒ‚Y nX dS )zÓ
    Validate + coerce a value into a Decimal, raising a clear message on bad
    input. Goes through str() first so binary floating-point artifacts
    (e.g. 0.1 + 0.2 != 0.3) never leak into money fields.
    NÚ ú'z' is required.z' must be a valid number.)Ú
ValueErrorr   Ústrr   Ú	TypeError)ÚvalueÚ
field_namer    r    r!   Ú
to_decimal7   s    r.   c                 C   s   t | ƒjttd�S )zKRound a Decimal to exactly 2 places using standard rounding (not banker's).)Úrounding)r   ÚquantizeÚ
TWO_PLACESr   )r,   r    r    r!   Úq2E   s    r2   c                   @   s   e Zd ZdZdd„ ZdS )ÚLoginAPIViewu<  
    Accepts either a username or an email in `username`, plus `password`.
    `fcm_token` (optional) is stored against the profile for push notifications â€”
    it is intentionally NOT written into `pincode`; that was a bug in the
    previous version. Adjust the field name below to match your Profile model.
    c                 C   s  |j }| d¡pd ¡ }| d¡}| d¡}|r4|s@tdtjƒS t d|¡}|rŽztj	j|d�}|j
}W q’ tjk
rŠ   tdtjƒ Y S X n|}t|||d	�}	|	d kr´tdtjƒS |	jsÆtd
tjƒS t||	ƒ t |	¡}
d }d }d }t|	j
|	j|	j
|	j|	jt|
ƒt|
jƒ|d||dœdd�S )NÚusernamer'   ÚpasswordÚ	fcm_tokenz)Username/email and password are required.z[^@]+@[^@]+\.[^@]+)Zemail__iexactzInvalid username or password.)r4   r5   zThis account has been disabled.Úloop)ÚnameÚidr4   ÚemailZisSuperZrefreshÚtokenÚprofileZcompanynameÚphoneÚrolezLogin success©r   )r   ÚgetÚstripr&   r	   ÚHTTP_400_BAD_REQUESTÚreÚmatchr   Úobjectsr4   ÚDoesNotExistÚHTTP_401_UNAUTHORIZEDr   Ú	is_activeÚHTTP_403_FORBIDDENr   r   Zfor_userr"   r9   r:   Úis_superuserr*   Zaccess_token)ÚselfÚrequestr   Zusername_or_emailr5   r6   Úis_emailÚmatchedZusername_to_authÚuserr;   Úprofile_photor=   r>   r    r    r!   ÚpostS   sN    




õôzLoginAPIView.postN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__rQ   r    r    r    r!   r3   K   s   r3   c                   @   sP   e Zd ZefZdd„ Zddd„Zddd„Zdd	d
„Zdd„ Z	dd„ Z
dd„ ZdS )ÚCompanyAPIViewc                 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Š   Y d S X d S )	NÚlogoÚlogo_base64Úlogo_filenameZlogo_z.jpgú,r   )r8   )
ÚFILESr@   ÚintÚtimeÚsplitrA   Úbase64Ú	b64decoder   Ú	Exception)rK   rL   r   rX   rY   Z
image_datar    r    r!   Ú_handle_logo–   s    



zCompanyAPIView._handle_logoNc                 C   sT   |j |j|j|j|j|j|j|j|j|j	r8| 
|j	j¡nd dœ
}|d k	rP||d< |S )N)
r9   Úcompany_nameÚaddressÚmobiler:   Ú
gst_numberÚbank_detailsÚ
dealers_inÚinvoice_termsrW   Úrow)r9   rc   rd   re   r:   rf   rg   rh   ri   rW   Úbuild_absolute_uriÚurl)rK   rL   Úcompanyrj   Úpayloadr    r    r!   Ú
_serialize¨   s    özCompanyAPIView._serializeFc                 C   sz   i }|  d¡}|s*|r"t|ƒ ¡ s*d|d< |  d¡}|rPt dt|ƒ¡sPd|d< |  d¡}|rvt dt|ƒ¡svd|d< |S )	Nrc   zCompany name is required.r:   z^[^@\s]+@[^@\s]+\.[^@\s]+$zEnter a valid email address.re   ú^[0-9+\-\s]{7,15}$úEnter a valid mobile number.©r@   r*   rA   rC   rD   )rK   r   ÚpartialÚerrorsrc   r:   re   r    r    r!   Ú	_validate¹   s    


zCompanyAPIView._validatec                    sÄ   |d k	rNzt jj|d�}W n" t jk
r<   tdtjƒ Y S X tˆ ˆ |¡ƒS ˆ j	 dd¡ 
¡ }t j ¡  d¡}|r¢| t|d�t|d�B t|d�B t|d	�B ¡}‡ ‡fd
d„t|dƒD ƒ}t|ƒS )N©r9   úNo company foundÚsearchr'   ú-created_at)Zcompany_name__icontains©Zgst_number__icontains©Zmobile__icontains)Zemail__icontainsc                    s    g | ]\}}ˆj ˆ ||d �‘qS ©)rj   ©ro   ©Ú.0ÚiÚc©rL   rK   r    r!   Ú
<listcomp>Ú   s     z&CompanyAPIView.get.<locals>.<listcomp>r   )r   rE   r@   rF   r&   r	   ÚHTTP_404_NOT_FOUNDr"   ro   Úquery_paramsrA   ÚallÚorder_byÚfilterr   Ú	enumerate)rK   rL   r9   rm   rx   ÚqsÚ	data_listr    r‚   r!   r@   É   s(    ÿþýÿzCompanyAPIView.getc                 C   sÐ   |j }|  |¡}|r t|tjƒS |  ||¡}zltjj| 	d¡| 	d¡| 	d¡| 	d¡| 	d¡| 	d¡| 	d¡| 	d¡pxd |d	�	}t
|  ||¡d
tjd�W S  tk
rÊ } ztt|ƒƒ W Y ¢S d }~X Y nX d S )Nrc   rd   re   r:   rf   rg   rh   ri   )	rc   rd   re   r:   rf   rg   rh   ri   rW   zCompany added successfullyr%   )r   ru   r&   r	   rB   rb   r   rE   Úcreater@   r"   ro   ÚHTTP_201_CREATEDra   r*   )rK   rL   r   rt   rW   rm   Úer    r    r!   rQ   Ý   s,    
÷ÿzCompanyAPIView.postc              
   C   sH  |j }ztjj|d�}W n" tjk
r:   tdtjƒ Y S X | j|dd�}|rZt|tj	ƒS z´|  
||¡}| d|j¡|_| d|j¡|_| d|j¡|_| d|j¡|_| d	|j¡|_| d
|j¡|_| d|j¡|_| d|j¡|_|rò||_| ¡  t|  ||¡dd�W S  tk
�rB } ztt|ƒƒ W Y ¢S d }~X Y nX d S )Nrv   rw   T©rs   rc   rd   re   r:   rf   rg   rh   ri   zCompany updated successfullyr?   )r   r   rE   r@   rF   r&   r	   r„   ru   rB   rb   rc   rd   re   r:   rf   rg   rh   ri   rW   Úsaver"   ro   ra   r*   )rK   rL   r9   r   rm   rt   rW   rŽ   r    r    r!   Úputõ   s0    zCompanyAPIView.putc                 C   sH   zt jj|d�}W n" t jk
r4   tdtjƒ Y S X | ¡  tdd�S )Nrv   rw   úCompany deleted successfullyr?   )	r   rE   r@   rF   r&   r	   r„   Údeleter"   )rK   rL   r9   rm   r    r    r!   r“     s    zCompanyAPIView.delete)N)F)N)rR   rS   rT   r   Úpermission_classesrb   ro   ru   r@   rQ   r‘   r“   r    r    r    r!   rV   “   s   


rV   c                   @   sH   e Zd ZefZddd„Zddd„Zddd„Zd	d
„ Zdd„ Z	dd„ Z
dS )ÚCustomerAPIViewNc                 C   s.   |j |j|j|j|jdœ}|d k	r*||d< |S )N©r9   r8   rd   rf   re   rj   r–   )rK   rL   Úcustomerrj   rn   r    r    r!   ro     s    ûzCustomerAPIView._serializeFc                 C   sT   i }|  d¡}|s*|r"t|ƒ ¡ s*d|d< |  d¡}|rPt dt|ƒ¡sPd|d< |S )Nr8   zCustomer name is required.re   rp   rq   rr   )rK   r   rs   rt   r8   re   r    r    r!   ru   *  s    

zCustomerAPIView._validatec                    sº   |d k	rNzt jj|d�}W n" t jk
r<   tdtjƒ Y S X tˆ ˆ |¡ƒS ˆ j	 dd¡ 
¡ }t j ¡  d¡}|r˜| t|d�t|d�B t|d�B ¡}‡ ‡fd	d
„t|dƒD ƒ}t|ƒS )Nrv   úNo customer foundrx   r'   ry   ©Zname__icontainsrz   r{   c                    s    g | ]\}}ˆj ˆ ||d �‘qS r|   r}   r~   r‚   r    r!   rƒ   D  s     z'CustomerAPIView.get.<locals>.<listcomp>r   )r   rE   r@   rF   r&   r	   r„   r"   ro   r…   rA   r†   r‡   rˆ   r   r‰   )rK   rL   r9   r—   rx   rŠ   r‹   r    r‚   r!   r@   4  s$    ÿþÿzCustomerAPIView.getc              
   C   sž   |j }|  |¡}|r t|tjƒS zFtjj| d¡| d¡| d¡| d¡d�}t	|  
||¡dtjd�W S  tk
r˜ } ztt|ƒƒ W Y ¢S d }~X Y nX d S )Nr8   rd   rf   re   )r8   rd   rf   re   zCustomer added successfullyr%   )r   ru   r&   r	   rB   r   rE   rŒ   r@   r"   ro   r�   ra   r*   )rK   rL   r   rt   r—   rŽ   r    r    r!   rQ   G  s     
üÿzCustomerAPIView.postc              
   C   sð   |j }ztjj|d�}W n" tjk
r:   tdtjƒ Y S X | j|dd�}|rZt|tj	ƒS z^| d|j
¡|_
| d|j¡|_| d|j¡|_| d|j¡|_| ¡  t|  ||¡d	d
�W S  tk
rê } ztt|ƒƒ W Y ¢S d }~X Y nX d S )Nrv   r˜   Tr�   r8   rd   rf   re   zCustomer updated successfullyr?   )r   r   rE   r@   rF   r&   r	   r„   ru   rB   r8   rd   rf   re   r�   r"   ro   ra   r*   )rK   rL   r9   r   r—   rt   rŽ   r    r    r!   r‘   X  s"    zCustomerAPIView.putc                 C   s^   zt jj|d�}W n" t jk
r4   tdtjƒ Y S X |j ¡ rLtdtj	ƒS | 
¡  tdd�S )Nrv   r˜   z9This customer has invoices attached and can't be deleted.zCustomer deleted successfullyr?   )r   rE   r@   rF   r&   r	   r„   ÚinvoicesÚexistsrB   r“   r"   )rK   rL   r9   r—   r    r    r!   r“   m  s    
ÿzCustomerAPIView.delete)N)F)N©rR   rS   rT   r   r”   ro   ru   r@   rQ   r‘   r“   r    r    r    r!   r•     s   



r•   c                   @   sH   e Zd ZefZddd„Zddd„Zddd„Zd	d
„ Zdd„ Z	dd„ Z
dS )ÚProductAPIViewNc                 C   s2   |j |j|jt|jƒ|jdœ}|d k	r.||d< |S )N)r9   r8   Úhsn_codeÚdefault_rateÚunitrj   )r9   r8   rž   r*   rŸ   r    )rK   rL   Úproductrj   rn   r    r    r!   ro   }  s    ûzProductAPIView._serializeFc              	   C   sz   i }|  d¡}|s*|r"t|ƒ ¡ s*d|d< |  d¡}|dkrvzt|ƒdk rRd|d< W n  ttfk
rt   d|d< Y nX |S )Nr8   zProduct name is required.rŸ   )Nr'   r   z Default rate cannot be negative.z$Default rate must be a valid number.)r@   r*   rA   Úfloatr+   r)   )rK   r   rs   rt   r8   Úrater    r    r!   ru   ‰  s    

zProductAPIView._validatec                    s°   |d k	rNzt jj|d�}W n" t jk
r<   tdtjƒ Y S X tˆ ˆ |¡ƒS ˆ j	 dd¡ 
¡ }t j ¡  d¡}|rŽ| t|d�t|d�B ¡}‡ ‡fdd	„t|d
ƒD ƒ}t|ƒS )Nrv   úNo product foundrx   r'   ry   r™   )Zhsn_code__icontainsc                    s    g | ]\}}ˆj ˆ ||d �‘qS r|   r}   )r   r€   Úpr‚   r    r!   rƒ   £  s     z&ProductAPIView.get.<locals>.<listcomp>r   )r   rE   r@   rF   r&   r	   r„   r"   ro   r…   rA   r†   r‡   rˆ   r   r‰   )rK   rL   r9   r¡   rx   rŠ   r‹   r    r‚   r!   r@   —  s    zProductAPIView.getc              
   C   s¤   |j }|  |¡}|r t|tjƒS zLtjj| d¡| d¡| d¡pDd| dd¡d�}t	|  
||¡dtjd	�W S  tk
rž } ztt|ƒƒ W Y ¢S d }~X Y nX d S )
Nr8   rž   rŸ   r   r    ÚKg)r8   rž   rŸ   r    zProduct added successfullyr%   )r   ru   r&   r	   rB   r   rE   rŒ   r@   r"   ro   r�   ra   r*   )rK   rL   r   rt   r¡   rŽ   r    r    r!   rQ   ¦  s     

üÿzProductAPIView.postc              
   C   sð   |j }ztjj|d�}W n" tjk
r:   tdtjƒ Y S X | j|dd�}|rZt|tj	ƒS z^| d|j
¡|_
| d|j¡|_| d|j¡|_| d|j¡|_| ¡  t|  ||¡d	d
�W S  tk
rê } ztt|ƒƒ W Y ¢S d }~X Y nX d S )Nrv   r¤   Tr�   r8   rž   rŸ   r    zProduct updated successfullyr?   )r   r   rE   r@   rF   r&   r	   r„   ru   rB   r8   rž   rŸ   r    r�   r"   ro   ra   r*   )rK   rL   r9   r   r¡   rt   rŽ   r    r    r!   r‘   ·  s"    zProductAPIView.putc                 C   s^   zt jj|d�}W n" t jk
r4   tdtjƒ Y S X |j ¡ rLtdtj	ƒS | 
¡  tdd�S )Nrv   r¤   z6This product is used in invoices and can't be deleted.zProduct deleted successfullyr?   )r   rE   r@   rF   r&   r	   r„   Úinvoice_itemsr›   rB   r“   r"   )rK   rL   r9   r¡   r    r    r!   r“   Ì  s    
ÿzProductAPIView.delete)N)F)Nrœ   r    r    r    r!   r�   z  s   


r�   c                   @   sN   e Zd ZefZddd„Zdd„ Zddd„Zdd	„ Zd
d„ Z	dd„ Z
dd„ ZdS )ÚInvoiceAPIViewNc                 C   s
  dd„ |j  ¡ D ƒ}|j|j|j|j|jr2|jjnd |jr�|jj|jj|jj|jj	|jj
|jjt|jdd ƒr|| |jjj¡nd |jj|jjdœ	nd |j|jj|jj|jj|j|j|j|j|jt|jƒt|jƒt|jƒt|jƒt|jƒt|j ƒ|dœ}|d k	�r||d< |S )Nc                 S   sL   g | ]D}|j |j|jj|jj|jjt|jƒt|jƒt|j	ƒt|j
ƒd œ	‘qS ))	r9   r¡   Zproduct_namerž   r    Úquantityr£   ÚamountÚpackagecount)r9   Ú
product_idr¡   r8   rž   r    r*   r©   r£   rª   r«   )r   Úitemr    r    r!   rƒ   Û  s   ö÷z-InvoiceAPIView._serialize.<locals>.<listcomp>Ú	signature)	r9   rc   rd   re   r:   rf   r®   rg   ri   )r9   Úinvoice_numberÚinvoice_daterm   rc   Zcompany_detailsr—   Zcustomer_nameZcustomer_gst_numberZcustomer_addressÚeway_bill_noÚeway_bill_dateÚ
vehicle_noÚpurchase_order_numberÚpurchase_order_dateÚsubtotalÚcgstÚsgstÚigstÚ	round_offÚgrand_totalÚitemsrj   )!r¼   r†   r9   r¯   r°   Ú
company_idrm   rc   rd   re   r:   rf   Úgetattrrk   r®   rl   rg   ri   Úcustomer_idr—   r8   r±   r²   r³   r´   rµ   r*   r¶   r·   r¸   r¹   rº   r»   )rK   rL   Úinvoicerj   r¼   rn   r    r    r!   ro   Ú  sV    ôóÿôÝ%
zInvoiceAPIView._serializec                 C   s˜  |sdS g }t ƒ }t|dƒD �]p\}}| d¡}|sHdd|› d�f  S t|ƒ|krhdd|› d�f  S | t|ƒ¡ tjj|d� ¡ sœdd|› d	�f  S z>t	| d
d¡d
ƒ}t	| dd¡dƒ}t	| dd¡pÒddƒ}	W n@ t
k
�r }
 z dd|› d|
› �f W Y ¢  S d}
~
X Y nX |dk�r:dd|› d�f  S |dk �rXdd|› d�f  S |	dk �rvdd|› d�f  S | |||t|	ƒdœ¡ q|dfS )zPReturns (cleaned_items, error_message_or_None). Also rejects duplicate products.)NzAdd at least one line item.r   r¡   NzLine z: select a product.z/: this product is already added to the invoice.rv   z: product not found.r©   r   r£   r«   z: z": quantity must be greater than 0.z: rate cannot be negative.z(: number of packages cannot be negative.)r¬   r©   r£   r«   )Úsetr‰   r@   r*   Úaddr   rE   rˆ   r›   r.   r)   Úappendr\   )rK   Ú
items_dataÚcleanedZseen_productsÚidxÚitr¬   Zqtyr£   r«   rŽ   r    r    r!   Ú_validate_items  s@    
.


ü
zInvoiceAPIView._validate_itemsc                    s°   |d k	rNzt jj|d�}W n" t jk
r<   tdtjƒ Y S X tˆ ˆ |¡ƒS ˆ j	 dd¡ 
¡ }t j ¡  d¡}|rŽ| t|d�t|d�B ¡}‡ ‡fdd	„t|d
ƒD ƒ}t|ƒS )Nrv   úNo invoice foundrx   r'   ry   )Zinvoice_number__icontains)Zcustomer__name__icontainsc                    s    g | ]\}}ˆj ˆ ||d �‘qS r|   r}   )r   Úrr€   r‚   r    r!   rƒ   I  s     z&InvoiceAPIView.get.<locals>.<listcomp>r   )r   rE   r@   rF   r&   r	   r„   r"   ro   r…   rA   r†   r‡   rˆ   r   r‰   )rK   rL   r9   rÀ   rx   rŠ   r‹   r    r‚   r!   r@   ;  s    ÿzInvoiceAPIView.getc                 C   s8   |dk rdS |dk rdS |dk r$dS t |ƒdkr4dS d S )Nr   zCGST cannot be negative.zSGST cannot be negative.zIGST cannot be negative.r   u6   Round off must be a small adjustment (less than â‚¹1).)Úabs)rK   r·   r¸   r¹   rº   r    r    r!   Ú_validate_tax_fieldsL  s    z#InvoiceAPIView._validate_tax_fieldsc                    sÂ  |j }| d¡pd ¡ }| d¡}| d¡}| dg ¡}|sDtdƒS tjj|d� ¡ rftd|› d	�ƒS |r|tjj|d
� ¡ s„tdƒS |ršt	jj|d
� ¡ s¢tdƒS | d¡s´tdƒS |  
|¡\}}|rÎt|ƒS zXt| d¡pÞddƒ}	t| d¡pòddƒ}
t| d¡�pddƒ}t| d¡�pddƒ}W n4 tk
�rZ } ztt|ƒƒ W Y ¢S d }~X Y nX |  |	|
||¡}|�rzt|ƒS �zt ¡ �ä ttdd„ |D ƒtdƒƒƒ}t||	 |
 | | ƒ}|dk �rÜtdƒW  5 Q R £ W S tjj|| d¡||| d¡| d¡�pd | d¡| d¡�pd | d¡�p*d |t|	ƒt|
ƒt|ƒt|ƒ|d�‰ tj ‡ fdd„|D ƒ¡ W 5 Q R X t|  |ˆ ¡d tjd!�W S  tk
�r¼ } ztt|ƒƒ W Y ¢S d }~X Y nX d S )"Nr¯   r'   r—   rm   r¼   zInvoice number is required.©r¯   úInvoice number 'ú' is already in use.rv   ú1Please select which company this invoice is from.úA valid customer is required.r°   zInvoice date is required.r·   r   r¸   r¹   rº   c                 s   s   | ]}|d  |d  V  qdS ©r©   r£   Nr    ©r   r€   r    r    r!   Ú	<genexpr>}  s     z&InvoiceAPIView.post.<locals>.<genexpr>Ú0õ?   Invoice total cannot be negative â€” check the entered amounts.r±   r²   r³   r´   rµ   )r¯   r°   r½   r¿   r±   r²   r³   r´   rµ   r¶   r·   r¸   r¹   rº   r»   c                    s@   g | ]8}t ˆ |d  |d |d t|d |d  ƒ|d d�‘qS ©r¬   r©   r£   r«   )rÀ   r¬   r©   r£   rª   r«   ©r   r2   rÓ   ©rÀ   r    r!   rƒ   •  s   	øúz'InvoiceAPIView.post.<locals>.<listcomp>zInvoice created successfullyr%   )r   r@   rA   r&   r   rE   rˆ   r›   r   r   rÈ   r.   r)   r*   rÌ   r   Úatomicr2   Úsumr   rŒ   r   Úbulk_creater"   ro   r	   r�   ra   )rK   rL   r   r¯   r¿   r½   rÄ   Úcleaned_itemsÚerrr·   r¸   r¹   rº   rŽ   Útax_errr¶   r»   r    rÙ   r!   rQ   Y  sv    


"

ð	÷ÿzInvoiceAPIView.postc              
      sº  |j }ztjj|d�‰ W n" tjk
r:   tdtjƒ Y S X | d¡}|r~|ˆ jkr~tjj	|d�j
|d� ¡ r~td|› d�ƒS d }d|kr¬|  | dg ¡¡\}}|r¬t|ƒS zTt| dˆ j¡dƒ}t| d	ˆ j¡d	ƒ}t| d
ˆ j¡d
ƒ}	t| dˆ j¡dƒ}
W n4 tk
�r4 } ztt|ƒƒ W Y ¢S d }~X Y nX |  |||	|
¡}|�rTt|ƒS |d k	�rzttdd„ |D ƒtdƒƒƒnˆ j}t|| | |	 |
 ƒ}|dk �rªtdƒS �z¢t ¡ ��| |�pÄˆ jˆ _| dˆ j¡ˆ _| dˆ j¡ˆ _| dˆ j¡�púd ˆ _| dˆ j¡ˆ _| dˆ j¡ˆ _| dˆ j ¡�p0d ˆ _ | d¡�rlt!jj	|d d� ¡ �s`tdƒ‚| d¡ˆ _"| d¡�r¤t#jj	|d d� ¡ �s˜tdƒ‚| d¡ˆ _$|d k	�rÜˆ j% &¡  '¡  t(j )‡ fdd„|D ƒ¡ |ˆ _t|ƒˆ _t|ƒˆ _t|	ƒˆ _t|
ƒˆ _tˆ jˆ j ˆ j ˆ j ˆ j ƒˆ _*ˆ  +¡  W 5 Q R X t,|  -|ˆ ¡dd�W S  tk
�r‚ } ztt|ƒƒ W Y ¢S d }~X Y n4 t.k
�r´ } ztt|ƒƒ W Y ¢S d }~X Y nX d S )Nrv   rÉ   r¯   rÍ   rÎ   rÏ   r¼   r·   r¸   r¹   rº   c                 s   s   | ]}|d  |d  V  qdS rÒ   r    rÓ   r    r    r!   rÔ   È  s     z%InvoiceAPIView.put.<locals>.<genexpr>rÕ   r   rÖ   r°   r±   r²   r³   r´   rµ   r—   rÑ   rm   rÐ   c                    s@   g | ]8}t ˆ |d  |d |d t|d |d  ƒ|d d�‘qS r×   rØ   rÓ   rÙ   r    r!   rƒ   ç  s   	øúz&InvoiceAPIView.put.<locals>.<listcomp>zInvoice updated successfullyr?   )/r   r   rE   r@   rF   r&   r	   r„   r¯   rˆ   Úexcluder›   rÈ   r.   r·   r¸   r¹   rº   r)   r*   rÌ   r2   rÛ   r   r¶   r   rÚ   r°   r±   r²   r³   r´   rµ   r   r¿   r   r½   r¼   r†   r“   r   rÜ   r»   r�   r"   ro   ra   )rK   rL   r9   r   Z
new_numberrÝ   rÞ   r·   r¸   r¹   rº   rŽ   rß   Zprospective_subtotalZprospective_grand_totalr    rÙ   r!   r‘   ¥  s–    
"ÿ þ
 ÿ ÿþ
	÷



ÿ zInvoiceAPIView.putc                 C   sH   zt jj|d�}W n" t jk
r4   tdtjƒ Y S X | ¡  tdd�S )Nrv   rÉ   zInvoice deleted successfullyr?   )	r   rE   r@   rF   r&   r	   r„   r“   r"   )rK   rL   r9   rÀ   r    r    r!   r“     s    zInvoiceAPIView.delete)N)N)rR   rS   rT   r   r”   ro   rÈ   r@   rÌ   rQ   r‘   r“   r    r    r    r!   r¨   ×  s   
8)
L^r¨   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: ©Ú	send_mailÚsettingsÚDEFAULT_FROM_EMAILra   Úprint©r:   ÚotpÚsubjectr   rŽ   r    r    r!   Úsend_otp_email  s    üû
rî   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 )Nrá   râ   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
        Frã   rå   ræ   rë   r    r    r!   Úsend_otp_emails%  s    üû
rï   )Ú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Úparamsr:   úReceived email:©r:   zEmail not foundr   TzEmail not registeredr$   é   Ú
1234567890©ÚlengthÚallowed_chars©ÚtargetÚargsÚSuccess©r	   r   r   zError:úInternal Server Error)r   r@   rê   r   rE   rˆ   r›   r   r	   r„   ÚOtprŒ   Úget_random_stringrì   ÚtimezoneÚnowÚotp_created_atr�   Ú	threadingÚThreadrî   ÚstartÚHTTP_200_OKra   ÚHTTP_500_INTERNAL_SERVER_ERRORr*   )rK   rL   r   r:   rO   rì   rŽ   r    r    r!   rQ   F  s8    

ý


ý


ýzSendotpAPIView.postN©rR   rS   rT   rQ   r    r    r    r!   rñ   E  s   rñ   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 )Nr:   ró   rô   zEmail already registeredr   Tz;This email is already registered. Please use another email.r$   rõ   rö   r÷   )r:   rì   r  rú   rý   rþ   rÿ   )r   r@   rê   r   rE   rˆ   r›   r   r	   ÚHTTP_409_CONFLICTr  r   rŒ   r  r  r  r  rï   r  r  ra   r	  r*   )rK   rL   r   r:   rì   rO   rŽ   r    r    r!   rQ   l  s0    

ý

ý

ýzSendotpsAPIView.postNr
  r    r    r    r!   r  k  s   r  )Ú	timedelta)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 )Nr:   rì   rô   r  é<   )Úsecondsi‘  z&OTP expired. Please request a new one.T)r	   r   r   r   éÈ   zOTP VerifiedFé�  zInvalid OTPi”  zOTP not found)r…   r@   r   rE   rˆ   Úlatestr  r  r  r  r   r	   r  rì   rF   )rK   rL   r:   Zotp_enteredZuser_otpZexpiration_timer    r    r!   r@   �  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 )N©Úuser_idF)r�   r   r   z"Profile image deleted successfullyr$   r#   zProfile not foundzID not providedzUser ID is required)ÚProfilesrE   r@   Úprofilesr“   r�   r   r	   r  r   r„   rB   )rK   rL   r9   r<   r    r    r!   r“   ¶  s.    
ý

ý
ýzVerifyotpAPIView.deleteN)rR   rS   rT   r@   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 )Nr9   rv   r  z../static/dummy.png)r8   r:   r=   Úf_nameZl_namer<   r9   rý   r   rþ   ZFailedTzCompany not foundr$   )r@   r   rE   r  r9   r  rl   r8   r:   r=   Ú
first_nameÚ	last_namer   r	   r  r   r„   )rK   rL   Úkwargsr9   rO   rm   Úprr   r    r    r!   r@   Û  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_photor  r   r   zProfile updated successfullyr$   r#   TzMissing required field: zAn error occurred: )r   r@   r  rE   rO   r9   r  r�   r   r	   r�   ÚKeyErrorrB   r*   ra   r	  )rK   rL   r   ZphoZtakerŽ   r    r    r!   rQ     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  r  rv   r  Zfirst_namesr  Zemail_idZphone_nor   r   úUser updated successfullyr$   r#   TzUser not found)r   r[   r@   r  rE   r   r4   r  r  r:   r�   r=   r8   r  r   r	   r  r   r„   )rK   rL   r9   r   ÚphotoÚmmÚsdr    r    r!   r‘   )  s6    
ý

ýzProfileupdateAPIView.putN)rR   rS   rT   r   r”   r@   rQ   r‘   r    r    r    r!   r  ×  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 )Nr9   r  )r9   r4   r=   r5   r:   r>   r	   rP   r   r   rþ   r#   TzNo student foundr$   é   é   r   )Zrole__inry   r   )rj   r9   ZemployeeNamer:   r=   r	   r>   r!  )r@   r  rE   r  r8   r=   r5   r:   r>   r	   r  rk   rl   r   r  ZStudentrF   r„   rˆ   r‡   r‰   rÃ   ra   rB   r*   )
rK   rL   r  r9   Zstudentr   Z	employeesZemployee_listÚindexrŽ   r    r    r!   r@   U  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 )NrP   r4   r:   r=   r5   r>   )r4   r:   r5   )r8   r:   r=   r>   r  r5   r  éÉ   r   r   zEmployee created successfullyr$   r   r  r#   TzError: )r   r[   r@   Úmake_passwordr   rE   rŒ   r  r9   r   r	   r�   ra   r*   rB   )rK   rL   r   r!  r4   r:   r=   r5   r>   Zhashed_passwordZvanr<   rŽ   r    r    r!   rQ   ‘  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 )NrP   r4   r:   r=   r5   r>   r  rv   r   r   r   r$   r#   TzSomething went wrong)r   r[   r@   r  rE   r   r8   r:   r=   r>   r5   r  r�   r)  r4   r   r	   r�   r   rB   )rK   rL   r9   r   r!  r4   r:   r=   r5   r>   r"  r#  Zpassesr    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 )Nr9   r  rv   r   r   r’   r$   r#   TzNo data found)
r@   r  rE   r“   r   r   r	   r  r   r„   )rK   rü   r  r½   r  rm   r    r    r!   r“   ï  s"    

ý

ýzRegisterAPIView.deleteN)rR   rS   rT   r@   rQ   r‘   r“   r    r    r    r!   r$  T  s   <2,r$  )<rC   r]   r_   Údjango.contrib.authr   r   Údjango.contrib.auth.modelsr   Údjango.core.files.baser   Ú	django.dbr   Údjango.db.modelsr   Úrest_frameworkr	   Zrest_framework.viewsr
   Úrest_framework.responser   Zrest_framework.permissionsr   Zrest_framework_simplejwt.tokensr   Úmodelsr   r   r   r   r   Údjango.core.exceptionsr   Údecimalr   r   r   r1   r  r"   rB   r&   r.   r2   r3   rV   r•   r�   r¨   rî   rï   rð   rñ   r  Údatetimer  Údjango.utilsr  r  r  r$  r    r    r    r!   Ú<module>   s^   	H 	_]  6& I}