o
    h                     @   s  d dl mZmZmZ d dlmZ d dlmZ d dlm	Z	 d dl
mZmZ d dlmZ d dlmZ d dlmZ d d	lmZmZ d d
lmZ d dlmZ d dlmZ d dlmZ ddlmZm Z  d dl!m"Z" d dl#Z#d dl$Z$d dl%Z%d dl&Z&edd Z'edd Z(edd Z)edd Z*edd Z+edd Z,edd Z-ed d! Z.ed"d# Z/ed$d% Z0ed&d' Z1ed(d) Z2ed*d+ Z3ed,d- Z4ed.d/ Z5ed0d1 Z6ed2d3 Z7ed4d5 Z8ed6d7 Z9ed8d9 Z:ed:d; Z;ed<d= Z<ed>d? Z=dDd@dAZ>edBdC Z?dS )E    )renderredirectget_object_or_404)staff_member_required)login_required)messages)CountQ)timezone)User)	Paginator)JsonResponseHttpResponse)transaction)	send_mail)render_to_string)settings   )Tenant
TenantUserShopNc                 C   s  t  }tj tjjdd tjjdd tjjdd tjjdd tjjd|t jdd d tj tj tjjd	d
 tjjdd
 tjjdd
 d}tj	ddd }tjjd|t jdd d	ddd }g }t
dD ]8}|jddt jd| d }|t jdd jddt jdd }tjj||gd }	||d|	d q|  ||||d}
t| d|
S )z*System health dashboard for administratorsactivestatustrialexpired	suspended   days)r   trial_ends_at__ltebasicplanstandardpremium)total_tenantsactive_tenantstrial_tenantsexpired_tenantssuspended_tenantsexpiring_soontotal_userstotal_shops
basic_planstandard_planpremium_plan-created_atN
      trial_ends_at   r   )day       )created_at__rangez%b %Y)monthcount)statsrecent_signupsexpiring_trialsmonthly_signupszadmin/system_dashboard.html)r
   nowr   objectsr<   filter	timedeltar   r   order_byrangereplaceappendstrftimereverser   )requestrA   r=   r>   r?   r@   imonth_start	month_endr<   context rP   "/var/www/html/pos/tenants/views.pysystem_dashboard   sP   $
rR   c              
   C   s  t jdd}| }|jdd }|jdd }|jdd }| jd}|rI|t|dt|d	B t|d
B t|dB t|dB }| jd}|rW|j|d}| jd}|re|j|d}t	|d}	| jd}
|	
|
}||||t j||||d	}t| d|S )z*List all tenants with search and filteringownerr2   r   r   r   r   search)name__icontains)tenant_code__icontains)owner__username__icontains)owner__email__icontains)contact_email__icontainsr   r$   r#      page)	page_objrT   r   r$   status_choicesr'   r(   r)   r*   zadmin/tenant_list.html)r   rB   select_relatedrE   r<   rC   GETgetr	   r   get_pageSTATUS_CHOICESr   )rK   tenantsr'   r(   r)   r*   rT   r   r$   	paginatorpage_numberr\   rO   rP   rP   rQ   tenant_listI   sL   	

rf   c                 C   sF   t t|d}tjj|dd}tjj|d}|||d}t| d|S )z View detailed tenant informationid)tenantuser)ri   tenant_usersshopszadmin/tenant_detail.html)r   r   r   rB   rC   r^   r   r   )rK   	tenant_idri   rk   rl   rO   rP   rP   rQ   tenant_detail|   s   rn   c                 C   s   | j dkr9tt|d}| jd}|ttjv r2||_|  t	
| d|j d|  tddiS tdd	d
S tddd
S )zUpdate tenant status via AJAXPOSTrg   r   Tenant z status updated to successTFInvalid statusrq   errorzInvalid request)methodr   r   ro   r`   dictrb   r   saver   rq   namer   )rK   rm   ri   
new_statusrP   rP   rQ   tenant_status_update   s   
rz   c           $         s  | j dkr| jd}| jd}| jd}| jd}| jd}| jd}| jd}| jd	d
}| jd}	| jdd}
t| jdd}t| jdd}| jddk}| jddk}zt  ddl}|d|st	| d t
| ddtjiW  d   W S tjj|d rt	| d| d t
| ddtjiW  d   W S |dd }| d| }|}d}tjj|d  r| d| }|d7 }tjj|d  stjj||||d!d"\}}d}|rtjtj tj d#  d fd$d%td&D }|| |  tjj|||||||	|
||d'
}dd(lm}m} ddl}| t!}z6||j"}|rZ||j" |#d)|j"  t$| d*| d+ n|	d,|j"  t%| d*| d- W n- t&y } z |	d.|j" d/|  t%| d*| d0t'|  W Y d}~nd}~ww t(jj||d1d2 |rzdd3l)m*} |jj|| d4|
pd5|	|d6 W n   Y |r1|r1zFd7}d8| +  d9} |||j"|| d:d;d<}!t,d=|!}"d>|j- d?|j" d@|j. dA| dB|  dC}#t/||#t0j1|g|"dDdE t$| dF|  W n t&y0 } zt%| dGt'|  W Y d}~nd}~ww t$| dH| dI |rKt#| dJ|j. d/|  t2dK|j3dLW  d   W S 1 s^w   Y  W n t&y } zt	| dMt'|  W Y d}~nd}~ww dtji}!t
| d|!S )NzCreate a new tenantro   rx   tenant_codecontact_emailowner_emailowner_first_nameowner_last_namer$   r   r   contact_phoneaddress 	max_shopsr   	max_users   send_welcome_emailon
auto_setupr   N^[a-zA-Z0-9]+$STenant code can only contain letters and numbers (no spaces or special characters).zadmin/tenant_create.htmlplan_choicesr{   Tenant code "z" is already taken.@_usernamer   
first_name	last_nameemaildefaults!@#$%&*c                 3       | ]}t  V  qd S Nsecretschoice.0r   charsrP   rQ   	<genexpr>       z tenant_create.<locals>.<genexpr>   )
rx   r{   rS   r$   r   r|   r   r   r   r   )create_tenant_schemamigrate_tenant_schemau?   ✅ Successfully created schema and migrated tables for tenant rp   z5 created successfully with dedicated database schema.u'   ❌ Failed to create schema for tenant z9 created but schema setup failed. Please contact support.u'   ❌ Error setting up schema for tenant z: z" created but schema setup failed: rS   ri   rj   roler   z Main BranchzMain Location)ri   rx   r   phoner   z/Welcome to Sales Shark - Your Account is Ready!zhttps:///auth/login/support@salesshark.com+254 796374224)rj   ri   r{   password	login_urlsupport_emailr   z!landing/emails/welcome_email.htmlz,Welcome to Sales Shark!

Your organization: 
Tenant Code: z
Username: 
Password: 

Login at: z

Need help? Contact our support team:
Email: support@salesshark.com
Phone: +254 796374224

Thank you for choosing Sales Shark!Fsubjectmessage
from_emailrecipient_listhtml_messagefail_silentlyzWelcome email sent to z)Tenant created but welcome email failed: Tenant "z" created successfully!zGenerated password for tenants_admin:tenant_detailrm   zError creating tenant: )4ru   ro   r`   intr   atomicrematchr   rt   r   r   PLAN_CHOICESrB   rC   existssplitr   get_or_createstringascii_lowercaseascii_uppercasedigitsjoinrF   set_passwordrw   createschema_utilsr   r   logging	getLogger__name__r{   inforq   warning	Exceptionstrr   settings.modelsr   get_hostr   rx   r   r   r   DEFAULT_FROM_EMAILr   rh   )$rK   rx   r{   r|   r}   r~   r   r$   r   r   r   r   r   r   r   r   email_prefixbase_usernamer   counterrj   createdr   ri   r   r   r   loggerschema_createder   r   r   rO   r   plain_messagerP   r   rQ   tenant_create   s(  

	



(


" ( "r   c              
   C   s  t t|d}| jdkr| jd|j}||jkrWddl}|d|s6t	| d |tj
tjd}t| d	|S tjj|d
 rWt	| d| d |tj
tjd}t| d	|S | jd|j|_||_| jd|j|_| jd|j|_| jd|j|_| jd|j|_| jd|j|_t| jd|j|_t| jd|j|_z|  t| d td|jdW S  ty } zt	| dt|  W Y d}~nd}~ww |tj
tjd}t| d	|S )zEdit tenant detailsrg   ro   r{   r   Nr   r   )ri   r   r]   zadmin/tenant_edit.htmlr   r   z" is already in use.rx   r$   r   r|   r   r   r   r   zTenant updated successfully!r   r   zError updating tenant: )r   r   ru   ro   r`   r{   r   r   r   rt   r   rb   r   rB   rC   r   rx   r$   r   r|   r   r   r   r   r   rw   rq   r   rh   r   r   )rK   rm   ri   new_tenant_coder   rO   r   rP   rP   rQ   tenant_editQ  sR   

"r   c           	      C   s   t jddd}| jd}|r$|t|dt|dB t|dB }| jd}|r2|j|d}| jd	}|r@|j|d
}t|d}| jd}|	|}||||t
j t jd}t| d|S )z$List all tenant users with filteringri   rj   z
-joined_atrT   )user__username__icontains)user__email__icontains)tenant__name__icontains)
tenant__idr   )r   rZ   r[   )r\   rT   tenant_filterrole_filterrc   role_choiceszadmin/tenant_user_list.html)r   rB   r^   rE   r_   r`   rC   r	   r   ra   r   allROLE_CHOICESr   )	rK   rk   rT   r   r   rd   re   r\   rO   rP   rP   rQ   tenant_user_list  s6   

	r   c                 C   s   | j dkrRz1tt|d}t|j|jj|jj|jj|j	 |jj
|jj|j|j|jdd
}td|dW S  tyQ } ztdt|dW  Y d	}~S d	}~ww tdd
dS )z)Get tenant user details for modal displayr_   pkz	%B %d, %Y)
rh   r   r   r   	full_namer   tenant_namer   	is_active	joined_atT)rq   rj   Frs   NInvalid request method)ru   r   r   r   rh   rj   r   r   r   get_full_namer   ri   rx   r   r   r   rI   r   r   )rK   tenant_user_idtenant_user	user_datar   rP   rP   rQ   tenant_user_detail  s(   

r   c              
   C   s  | j dkrz^tt|d}|j}| jdd|_| jdd|_| jd|j|_| jd|j	|_	| jd}|rB|
 rB|| |  | jd	|j|_| jd
dk|_|  tdddW S  ty~ } ztdt|dW  Y d}~S d}~ww tdddS )zEdit tenant user detailsro   r   r   r   r   r   r   new_passwordr   r   trueTzUser updated successfullyrq   r   Frs   Nr   )ru   r   r   rj   ro   r`   r   r   r   r   stripr   rw   r   r   r   r   r   )rK   r   r   rj   r   r   rP   rP   rQ   tenant_user_edit  s0   


r   c                    s  | j dkrztt|d}|j}tjtj tj d  d fddt	dD }|
| |  z]d|jj }d	|   d
}||j|jj||ddd}td|}d|jj d| p_|j d|j d| d|jj d| d}	t||	tj|jg|dd tdd|j d| dW W S  ty }
 ztdd| dt|
 dW  Y d}
~
W S d}
~
ww  ty }
 ztdt|
dW  Y d}
~
S d}
~
ww tdddS ) zReset tenant user passwordro   r   r   r   c                 3   r   r   r   r   r   rP   rQ   r     r   z-tenant_user_reset_password.<locals>.<genexpr>r   zPassword Reset - http://r   zsupport@posapp.co.ker   )rj   ri   r{   r   r   r   r   z"tenants/emails/password_reset.htmlz

Hello z\,

Your password has been reset by an administrator.

Your new login credentials:
Username: z
New Password: r   r   z

IMPORTANT: For security reasons, please change this password after your first login.

Support: support@posapp.co.ke
Phone: +254 796374224

Best regards,
The POS 254 TeamFr   TzPassword reset and sent to z. New password: r   z+Password reset successfully. New password: z. Email failed: Nrs   r   )ru   r   r   rj   r   r   r   r   r   rF   r   rw   ri   rx   r   r{   r   r   r   r   r   r   r   r   r   r   )rK   r   r   rj   r   r   r   rO   r   r   r   rP   r   rQ   tenant_user_reset_password  sn   



		r   c              
   C   s   | j dkraz@tt|d}|j p|jj}|jj}|jdkr5tj	j
|jdd }|dkr5tdddW S |  td	| d
| dW S  ty` } ztdt|dW  Y d}~S d}~ww tdddS )zRemove user from tenantro   r   rS   )ri   r   r   Fz*Cannot remove the last owner of the tenantrs   Tz removed from r   Nr   )ru   r   r   rj   r   r   ri   rx   r   rB   rC   r<   r   deleter   r   )rK   r   r   	user_namer   owners_countr   rP   rP   rQ   tenant_user_remove;  s6   



r  c                    s  | j dkrg| jd}| jd}| jd}z/tt|d}|dd }|j d| }|}d	}tjj	|d

 rP| d| }|d	7 }tjj	|d

 s<tjj||| jdd| jdddd\}	}
d}|
r| jd}|r{| r{|}nddl}tjtj tj d  d fddtdD }|	| |	  tjj||	d|id\}}|r>zcd|j d}d|   d}|	||j|||ddd}td|}d|j d|	 p|	j d |j d!| d"|	j d#|r|nd$ d%|j d&| d'}t||tj|g|d(d) t | d*|j d+|  W n/ t!y= } zt | d*|j d, t"| d-t#|  W Y d}~nd}~ww t"| d. t$d/W S  t!yf } zt%| d0t#|  W Y d}~nd}~ww tj& tj'd1}t(| d2|S )3zCreate a new tenant userro   ri   
user_emailr   rg   r   r   r   r   r   r   r   r   r   r   Nr   r   c                 3   r   r   r   r   r   rP   rQ   r     r   z%tenant_user_create.<locals>.<genexpr>r   )ri   rj   r   zWelcome to z - Your Account is Ready!r   r   r   r   )rj   ri   r{   r   r   r   r   r   z'tenants/emails/tenant_user_welcome.htmlz	!

Hello z,

You have been added to z as a z%.

Your login credentials:
Username: r   zUse your existing passwordr   r   z|

Need help? Contact our support team:
Email: support@salesshark.com
Phone: +254 796374224

Thank you for using Sales Shark!Fr   zUser added to z% successfully! Welcome email sent to z successfully!zWelcome email failed to send: z#User already exists in this tenant.ztenants_admin:tenant_user_listzError creating tenant user: )rc   r   zadmin/tenant_user_create.html))ru   ro   r`   r   r   r   r{   r   rB   rC   r   r   r   randomr   r   r   r   r   rF   r   rw   r   rx   r   r   r   r   r   r   r   r   rq   r   r   r   r   rt   r   r   r   )rK   rm   r  r   ri   r   r   r   r   rj   r   r   custom_passwordr  r   created_tenant_userr   r   rO   r   r   r   rP   r   rQ   tenant_user_create]  s   
	




		"
"r  c                 C   st   ddl m} |jdd}| jd}|r|j|d}t|d}| jd}|	|}|||j
d	}t| d
|S )zList all subscriptionsr   Subscriptionri   r2   r   payment_statusrZ   r[   )r\   r   r]   zadmin/subscription_list.html)modelsr	  rB   r^   rE   r_   r`   rC   r   ra   PAYMENT_STATUS_CHOICESr   )rK   r	  subscriptionsr   rd   re   r\   rO   rP   rP   rQ   subscription_list  s   

r  c                 C   s   ddl m} ddlm} t }|jjddj|ddd	 p d|jjd|j	|j
d
j|ddd	 p4d|jjdd |jjdd d}d|i}t| d|S )zBilling overview and analyticsr   r  r   )Sumpaidr
  amount)totalr  )r  start_date__monthstart_date__yearpendingfailed)total_revenuemonthly_revenuepending_paymentsfailed_paymentsbilling_statszadmin/billing_overview.html)r  r	  django.db.modelsr  r
   rA   rB   rC   	aggregater;   yearr<   r   )rK   r	  r  rA   r  rO   rP   rP   rQ   billing_overview  s2   r   c                 C   s    | j dkrt| d t| dS )zSystem-wide settingsro   z%System settings updated successfully!zadmin/system_settings.html)ru   r   rq   r   )rK   rP   rP   rQ   system_settings
  s   

r!  c                 C   s   t dd}d|d< t|}|g d tjd }|D ]5}||j|j	|j
 p/|j
j|j
j|j|j| | |j|j|j|jd|jrP|jdndg q|S )	zExport tenant data as CSVztext/csv)content_typez)attachment; filename="tenants_export.csv"zContent-Disposition)NameSlugz
Owner NamezOwner EmailzContact EmailzContact PhonePlanStatuszDays Remainingz	Max Shopsz	Max Usersz
Created AtzTrial Ends AtrS   z%Y-%m-%d %H:%M:%Sr   )r   csvwriterwriterowr   rB   r^   r   rx   slugrS   r   r   r   r|   r   get_plan_displayget_status_displaydays_remainingr   r   
created_atrI   r5   )rK   responser(  rc   ri   rP   rP   rQ   tenant_export  s,   


r0  c              
   C   s   | j dkrgzFt| j}|dg }|d}|r|s#tdddW S |ttjvr2tdddW S tj	j
|dj|d	}td
|d| d| dW S  tyf } ztdt|dW  Y d}~S d}~ww tdddS )zBulk update tenant statusro   
tenant_idsr   FzInvalid datars   rr   id__inr   TzUpdated z tenants to )rq   updated_countr   Nr   )ru   jsonloadsbodyr`   r   rv   r   rb   rB   rC   updater   r   )rK   datar1  ry   r4  r   rP   rP   rQ   bulk_status_update4  s(   


r:  c           	      C   s2  | j dkrzqt| j}|dg }|stdddW S tjj|d}d}|D ]B}z;d|j	 }d	|j
 p9|j
j d
|j	 d|j d|  d|   d|j d}t||tj|jgdd |d7 }W q'   Y q'td|d| ddW S  ty } ztdt|dW  Y d}~S d}~ww tdddS )z(Send reminder emails to selected tenantsro   r1  FzNo tenants selectedrs   r2  r   zTrial Reminder - 
Hello z7,

This is a reminder about your Sales Shark trial for z.

Days remaining: 	
Status: z^

To continue using Sales Shark after your trial, please upgrade your plan.

Login at: http:///auth/login/
Tenant Code: z&

Thank you for choosing Sales Shark!
Tr   r   r   r   r   r   zSent reminders to  tenantsrq   
sent_countr   Nr   )ru   r5  r6  r7  r`   r   r   rB   rC   rx   rS   r   r   r-  r,  r   r{   r   r   r   r|   r   r   )	rK   r9  r1  rc   rA  ri   r   r   r   rP   rP   rQ   bulk_send_remindersP  sX   



rB  c                 C   s(  | j dkrzlt }tjjd|tjdd |d}d}|D ]G}z@d|j }d|j	 p/|jj
 d	|j d
|j d|  d|  d|   d|j d}t||tj|jgdd |d7 }W q   Y qtd|d| ddW S  ty } ztdt|dW  Y d}~S d}~ww tdddS )z?Send trial reminder emails to tenants with trials expiring soonro   r   r4   r   )r   r!   trial_ends_at__gter   z&Your Sales Shark Trial Expires Soon - r;  z,

Your Sales Shark trial for z expires in zo days.

To continue using Sales Shark, please upgrade to a paid plan before your trial expires.

Current plan: r<  z

Login to upgrade: http://r=  zL

Need help? Contact our support team.

Thank you for choosing Sales Shark!
Tr>  r   zSent trial reminders to r?  r@  Frs   Nr   )ru   r
   rA   r   rB   rC   rD   rx   rS   r   r   r-  r+  r,  r   r{   r   r   r   r|   r   r   r   )rK   rA   expiring_tenantsrA  ri   r   r   r   rP   rP   rQ   send_trial_reminders  s^   



rE  c                 C   s   | j dkrmzLtt|d}d|j }d|j p|jj d|j d|  d|  d|j	 d	| 
  d
|j d}t||tj|jgdd tdd|j dW S  tyl } ztdt|dW  Y d}~S d}~ww tdddS )z&Send reminder email to specific tenantro   rg   zAccount Reminder - r;  z9,

This is a reminder about your Sales Shark account for z.

Status: z
Plan: z
Days remaining: z

Login at: http://r=  z`

If you need assistance, please contact our support team.

Thank you for choosing Sales Shark!
Fr>  TzReminder sent to r   rs   Nr   )ru   r   r   rx   rS   r   r   r,  r+  r-  r   r{   r   r   r   r|   r   r   r   )rK   rm   ri   r   r   r   rP   rP   rQ   tenant_send_reminder  sF   
	


rF  c              
   C   sL  | j dkrz~tt|d}| jd}| jd}| jd|j}| jddk}|r,|s4tdd	d
W S d|   d}|j|j	|j
 pH|j
j|j|d}| D ]\}	}
||	|
}||	|
}qR|g}|ro|| jj t||tj|dd tdd| dW S  ty } ztdt|d
W  Y d}~S d}~ww tddd
S )z$Send custom email to specific tenantro   rg   r   r   	recipient	send_copyr   Fz Subject and message are requiredrs   r   r   )z{tenant_name}z{tenant_code}z{owner_name}z{contact_email}z{login_url}r>  TzEmail sent to r   Nr   )ru   r   r   ro   r`   r|   r   r   rx   r{   rS   r   r   itemsrG   rH   rj   r   r   r   r   r   r   )rK   rm   ri   r   r   rG  rH  r   replacementsplaceholdervaluer   r   rP   rP   rQ   tenant_send_email  sL   

rM  c                    s  | j dkrKz'tt|d}| jd}| jd}| jdd}| jdd}| jdd}| jd	d
k}|r;|sCtdddW S d}	d}
|rtjj|d	 }|rtt
jj||d	 }|rhtdddW S t
jj|||d |}nV|dd }d}|}tjj|d r| | }|d7 }tjj|d stjtj tj d  d fddtdD }
tjj|||||
d}t
jj|||d d}	d|j d}d|   d }|r|	rd!|pd" d#|j d$| d%|j d&|
 d'|j d(| d)| d*}nd!|pd" d#|j d$| d+|j d,| d)| d-}t||tj|gdd. tdd/| |	d0W S  tyJ } ztdt|dW  Y d}~S d}~ww tdd1dS )2z$Send invitation email to join tenantro   rg   r   r   r   r   r   personal_messagecreate_accountr   FzEmail and role are requiredrs   N)r   )ri   rj   z'User is already a member of this tenantr   r   r   r   r   r   c                 3   r   r   r   r   r   rP   rQ   r   U  r   z)tenant_send_invitation.<locals>.<genexpr>r   )r   r   r   r   r   TzInvitation to join z on Sales Sharkr   r   zHello therez!,

You have been invited to join z on Sales Shark as a zK.

Your account has been created with the following credentials:
Username: r   r   r   z

z9

Welcome to Sales Shark!

Best regards,
Sales Shark Teamz.

Tenant Code: z
Login at: zz

If you don't have an account yet, please contact the administrator for account creation.

Best regards,
Sales Shark Teamr>  zInvitation sent to )rq   r   account_createdr   )ru   r   r   ro   r`   r   r   rB   rC   firstr   r   r   r   r   r   r   r   r   rF   create_userrx   r   r   r{   r   r   r   r   r   )rK   rm   ri   r   r   r   r   rN  rO  rQ  r   existing_userexisting_tenant_userrj   r   r   original_usernamer   r   r   r   rP   r   rQ   tenant_send_invitation  s   
		

rW  c              
   C   s   | j dkr:ztt|d}|j}|  tdd| ddW S  ty9 } ztdt|dW  Y d	}~S d	}~ww tdd
dS )z#Delete tenant (dangerous operation)DELETErg   Tr   z" deleted successfullyr   Frs   Nr   )ru   r   r   rx   r   r   r   r   )rK   rm   ri   r   r   rP   rP   rQ   tenant_delete  s   


rY  c                 C   sf   d}|rt t|dd}n| jd}|r)z
tjj|dd}W n
 tjy(   Y nw d|i}t| d|S )zDisplay suspended tenant pageNr   )r{   r   r{   ri   zadmin/tenant_suspended.html)r   r   sessionr`   rB   DoesNotExistr   )rK   r{   ri   session_tenant_coderO   rP   rP   rQ   tenant_suspended  s   r]  c                 C   s   | j jrtjdd}ntjj| j dddd}| jdkr:| j	d}|r:t
t|d}|j| jd< td	S d
|i}t| d|S )z9Allow users to switch between tenants they have access tori   tenant__nameT)rj   r   ro   rm   rg   r{   	dashboardrk   zadmin/tenant_switch.html)rj   is_superuserr   rB   r^   rE   rC   ru   ro   r`   r   r   r{   rZ  r   r   )rK   rk   rm   ri   rO   rP   rP   rQ   tenant_switch  s"   
ra  r   )@django.shortcutsr   r   r   %django.contrib.admin.views.decoratorsr   django.contrib.auth.decoratorsr   django.contribr   r  r   r	   django.utilsr
   django.contrib.auth.modelsr   django.core.paginatorr   django.httpr   r   	django.dbr   django.core.mailr   django.template.loaderr   django.confr   r  r   r   r   r   r5  r'  r   r   rR   rf   rn   rz   r   r   r   r   r   r   r  r  r  r   r!  r0  r:  rB  rE  rF  rM  rW  rY  r]  ra  rP   rP   rP   rQ   <module>   s   
2
2


 4
4
'

$
L
!
x



 

6
7
*
3
 

