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    ú=C:\Users\psant\Downloads\Sarath Backend\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   Ú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__rR   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)rL   rM   r   rY   rZ   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_termsrX   Úrow)r9   rd   re   rf   r:   rg   rh   ri   rj   rX   Úbuild_absolute_uriÚurl)rL   rM   Úcompanyrk   Ú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 )	Nrd   zCompany name is required.r:   z^[^@\s]+@[^@\s]+\.[^@\s]+$zEnter a valid email address.rf   ú^[0-9+\-\s]{7,15}$úEnter a valid mobile number.©r@   r*   rA   rC   rD   )rL   r   ÚpartialÚerrorsrd   r:   rf   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 ©)rk   ©rp   ©Ú.0ÚiÚc©rM   rL   r    r!   Ú
<listcomp>Ú   s     z&CompanyAPIView.get.<locals>.<listcomp>r   )r   rE   r@   rF   r&   r	   ÚHTTP_404_NOT_FOUNDr"   rp   Úquery_paramsrA   ÚallÚorder_byÚfilterr   Ú	enumerate)rL   rM   r9   rn   ry   Ú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 )Nrd   re   rf   r:   rg   rh   ri   rj   )	rd   re   rf   r:   rg   rh   ri   rj   rX   zCompany added successfullyr%   )r   rv   r&   r	   rB   rc   r   rE   Úcreater@   r"   rp   ÚHTTP_201_CREATEDrb   r*   )rL   rM   r   ru   rX   rn   Úer    r    r!   rR   Ý   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 )Nrw   rx   T©rt   rd   re   rf   r:   rg   rh   ri   rj   zCompany updated successfullyr?   )r   r   rE   r@   rF   r&   r	   r…   rv   rB   rc   rd   re   rf   r:   rg   rh   ri   rj   rX   Úsaver"   rp   rb   r*   )rL   rM   r9   r   rn   ru   rX   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 )Nrw   rx   úCompany deleted successfullyr?   )	r   rE   r@   rF   r&   r	   r…   Údeleter"   )rL   rM   r9   rn   r    r    r!   r”     s    zCompanyAPIView.delete)N)F)N)rS   rT   rU   r   Úpermission_classesrc   rp   rv   r@   rR   r’   r”   r    r    r    r!   rW   “   s   


rW   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   re   rg   rf   rk   r—   )rL   rM   Úcustomerrk   ro   r    r    r!   rp     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.rf   rq   rr   rs   )rL   r   rt   ru   r8   rf   r    r    r!   rv   *  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 )Nrw   úNo customer foundry   r'   rz   ©Zname__icontainsr{   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"   rp   r†   rA   r‡   rˆ   r‰   r   rŠ   )rL   rM   r9   r˜   ry   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   re   rg   rf   )r8   re   rg   rf   zCustomer added successfullyr%   )r   rv   r&   r	   rB   r   rE   r�   r@   r"   rp   rŽ   rb   r*   )rL   rM   r   ru   r˜   r�   r    r    r!   rR   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 )Nrw   r™   Tr�   r8   re   rg   rf   zCustomer updated successfullyr?   )r   r   rE   r@   rF   r&   r	   r…   rv   rB   r8   re   rg   rf   r‘   r"   rp   rb   r*   )rL   rM   r9   r   r˜   ru   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 )Nrw   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"   )rL   rM   r9   r˜   r    r    r!   r”   m  s    
ÿzCustomerAPIView.delete)N)F)N©rS   rT   rU   r   r•   rp   rv   r@   rR   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Úunitrk   )r9   r8   rŸ   r*   r    r¡   )rL   rM   Úproductrk   ro   r    r    r!   rp   }  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)   )rL   r   rt   ru   r8   Úrater    r    r!   rv   ‰  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 )Nrw   úNo product foundry   r'   rz   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"   rp   r†   rA   r‡   rˆ   r‰   r   rŠ   )rL   rM   r9   r¢   ry   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   rv   r&   r	   rB   r   rE   r�   r@   r"   rp   rŽ   rb   r*   )rL   rM   r   ru   r¢   r�   r    r    r!   rR   ¦  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 )Nrw   r¥   Tr�   r8   rŸ   r    r¡   zProduct updated successfullyr?   )r   r   rE   r@   rF   r&   r	   r…   rv   rB   r8   rŸ   r    r¡   r‘   r"   rp   rb   r*   )rL   rM   r9   r   r¢   ru   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 )Nrw   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"   )rL   rM   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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   s>   g | ]6}|j |j|jj|jjt|jƒt|jƒt|jƒd œ‘qS ))r9   r¢   Zproduct_namerŸ   Úquantityr¤   Úamount)	r9   Ú
product_idr¢   r8   rŸ   r*   rª   r¤   r«   )r€   Úitemr    r    r!   r„   Ý  s   
øùz-InvoiceAPIView._serialize.<locals>.<listcomp>)r9   Úinvoice_numberÚinvoice_dater˜   Zcustomer_nameZcustomer_gst_numberZcustomer_addressÚeway_bill_noÚeway_bill_dateÚ
vehicle_noÚsubtotalÚcgstÚsgstÚigstÚ	round_offÚgrand_totalÚitemsrk   )r¹   r‡   r9   r®   r¯   Úcustomer_idr˜   r8   rg   re   r°   r±   r²   r*   r³   r´   rµ   r¶   r·   r¸   )rL   rM   Úinvoicerk   r¹   ro   r    r    r!   rp   Ü  s0    
öïzInvoiceAPIView._serializec           
      C   s^  |sdS g }t ƒ }t|dƒD �]6\}}| 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ƒ}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 �rBdd|› d�f  S | |||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.rw   z: product not found.rª   r   r¤   z: z": quantity must be greater than 0.z: rate cannot be negative.)r¬   rª   r¤   )ÚsetrŠ   r@   r*   Úaddr   rE   r‰   rœ   r.   r)   Úappend)
rL   Ú
items_dataÚcleanedZseen_productsÚidxÚitr¬   Zqtyr¤   r�   r    r    r!   Ú_validate_items   s0    
.

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 )Nrw   úNo invoice foundry   r'   rz   )Zinvoice_number__icontains)Zcustomer__name__icontainsc                    s    g | ]\}}ˆj ˆ ||d �‘qS r}   r~   )r€   Úrr�   rƒ   r    r!   r„   /  s     z&InvoiceAPIView.get.<locals>.<listcomp>r   )r   rE   r@   rF   r&   r	   r…   r"   rp   r†   rA   r‡   rˆ   r‰   r   rŠ   )rL   rM   r9   r»   ry   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)rL   r´   rµ   r¶   r·   r    r    r!   Ú_validate_tax_fields2  s    z#InvoiceAPIView._validate_tax_fieldsc                    sv  |j }| d¡pd ¡ }| d¡}| dg ¡}|s:tdƒS tjj|d� ¡ r\td|› d�ƒS |rrtjj|d	� ¡ sztd
ƒS | d¡sŒtdƒS |  	|¡\}}|r¦t|ƒS zTt
| d¡p¶ddƒ}t
| d¡pÊddƒ}	t
| d¡pÞddƒ}
t
| d¡pòddƒ}W n4 tk
�r. } ztt|ƒƒ W Y ¢S d }~X Y nX |  ||	|
|¡}|�rNt|ƒ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¡|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
�rp } ztt|ƒƒ W Y ¢S d }~X Y nX d S )Nr®   r'   r˜   r¹   zInvoice number is required.©r®   úInvoice number 'ú' is already in use.rw   ú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¸   c                    s:   g | ]2}t ˆ |d  |d |d t|d |d  ƒd�‘qS ©r¬   rª   r¤   )r»   r¬   rª   r¤   r«   ©r   r2   rÍ   ©r»   r    r!   r„   t  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   Úatomicr2   Úsumr   r�   r   Úbulk_creater"   rp   r	   rŽ   rb   )rL   rM   r   r®   rº   r¿   Úcleaned_itemsÚerrr´   rµ   r¶   r·   r�   Útax_errr³   r¸   r    rÓ   r!   rR   ?  sj    

"

ôø
ÿ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 �zDt ¡ �� |�pÄˆ jˆ _| dˆ j¡ˆ _| dˆ j¡ˆ _| dˆ j¡�púd ˆ _| dˆ j¡ˆ _| d¡�rFt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
�rV } ztt|ƒƒ W Y ¢S d }~X Y nX d S )Nrw   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Ë   c                    s:   g | ]2}t ˆ |d  |d |d t|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"   rp   rb   )rL   rM   r9   r   Z
new_numberr×   rØ   r´   rµ   r¶   r·   r�   rÙ   Zprospective_subtotalZprospective_grand_totalr    rÓ   r!   r’   ƒ  sz    
"ÿ þ

ø




ÿ 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 )Nrw   rÄ   zInvoice deleted successfullyr?   )	r   rE   r@   rF   r&   r	   r…   r”   r"   )rL   rM   r9   r»   r    r    r!   r”   Ö  s    zInvoiceAPIView.delete)N)N)rS   rT   rU   r   r•   rp   rÃ   r@   rÇ   rR   r’   r”   r    r    r    r!   r©   Ù  s   
$!
DSr©   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_EMAILrb   Ú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_OKrb   ÚHTTP_500_INTERNAL_SERVER_ERRORr*   )rL   rM   r   r:   rP   ræ   r�   r    r    r!   rR     s8    

ý


ý


ýzSendotpAPIView.postN©rS   rT   rU   rR   r    r    r    r!   rë     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  rb   r  r*   )rL   rM   r   r:   ræ   rP   r�   r    r    r!   rR   B  s0    

ý

ý

ýzSendotpsAPIView.postNr  r    r    r    r!   r  A  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   )rL   rM   r:   Zotp_enteredZuser_otpZexpiration_timer    r    r!   r@   e  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   )rL   rM   r9   r<   r    r    r!   r”   Œ  s.    
ý

ý
ýzVerifyotpAPIView.deleteN)rS   rT   rU   r@   r”   r    r    r    r!   r  d  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   rw   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  rm   r8   r:   r=   Ú
first_nameÚ	last_namer   r	   r  r   r…   )rL   rM   Úkwargsr9   rP   rn   Ú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   rP   r9   r  r‘   r   r	   rŽ   ÚKeyErrorrB   r*   rb   r  )rL   rM   r   ZphoZtaker�   r    r    r!   rR   Ù  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  rw   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…   )rL   rM   r9   r   ÚphotoÚmmÚsdr    r    r!   r’   ÿ  s6    
ý

ýzProfileupdateAPIView.putN)rS   rT   rU   r   r•   r@   rR   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	   rQ   r   r   rø   r#   TzNo student foundr$   é   é   r   )Zrole__inrz   r   )rk   r9   ZemployeeNamer:   r=   r	   r>   r  )r@   r  rE   r  r8   r=   r5   r:   r>   r	   r  rl   rm   r   r  ZStudentrF   r…   r‰   rˆ   rŠ   r¾   rb   rB   r*   )
rL   rM   r  r9   Zstudentr   Z	employeesZemployee_listÚindexr�   r    r    r!   r@   +  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 )NrQ   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Ž   rb   r*   rB   )rL   rM   r   r  r4   r:   r=   r5   r>   Zhashed_passwordZvanr<   r�   r    r    r!   rR   g  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 )NrQ   r4   r:   r=   r5   r>   r  rw   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   )rL   rM   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  rw   r   r   r“   r$   r#   TzNo data found)
r@   r  rE   r”   r   r   r	   r  r   r…   )rL   rö   r  Z
company_idr  rn   r    r    r!   r”   Å  s"    

ý

ýzRegisterAPIView.deleteN)rS   rT   rU   r@   rR   r’   r”   r    r    r    r!   r  *  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	   Ú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   rW   r–   rž   r©   rè   ré   rê   rë   r  Údatetimer  Údjango.utilsrü   r  r  r  r    r    r    r!   Ú<module>   s^   	H 	__  
& I}