o
    'hc                     @   s  d dl mZmZmZ d dlmZmZ d dlmZ d dl	m
Z
mZ d dlmZ 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Zd dlZd dlZd dl	mZ ddl m!Z!m"Z"m#Z#m$Z$m%Z% ddl&m'Z'm(Z(m)Z)m*Z*m+Z+ ddl,m-Z-m.Z. d dl/m0Z0 d dl1m2Z2m3Z3m4Z4 d dl/m5Z5 dd Z6dd Z7edd Z8edd Z9edd Z:edd  Z;eee6d!d" Z<eee7d#d$ Z=eee7d%d& Z>d'd( Z?d)d* Z@eee7d+d, ZAed-d. ZBeee7d/d0 ZCeee7d1d2 ZDeee7d3d4 ZEeee7d5d6 ZFeee7d7d8 ZGeee7d9d: ZHeee7d;d< ZIeee7d=d> ZJeee2d?d. ZBdS )@    )renderget_object_or_404redirect)login_requireduser_passes_test)messages)JsonResponseHttpResponse)timezone)SumQCount)	Paginator)ListView)LoginRequiredMixin)datetimedate)DecimalN)Http404   )ExpenseExpenseCategoryBudgetAllocationExpenseAttachmentExpenseApprovalLog)ExpenseFormExpenseAttachmentFormSetBudgetAllocationFormExpenseApprovalFormExpenseFilterForm)generate_expense_report_pdf$generate_monthly_expense_summary_pdf)Employee)has_financial_accesshas_permissionget_user_permissions)Payslipc                 C   s<   | j sdS | jr
dS t| }d|v pd|v pd|v pd|v S )z2Check if user can manage expenses (approve/reject)FTmanage_expensesapprove_expenseschange_expensedelete_expenseis_authenticatedis_superuserr%   useruser_permissions r1   1/var/www/html/optinet_system/expenditure/views.pycan_manage_expenses   s   r3   c                 C   sL   | j sdS | jr
dS t| }d|v p%d|v p%d|v p%d|v p%d|v p%d|v S )	z)Check if user can access expense featuresFTview_expensescreate_expensesr'   view_expenseadd_expenser)   r+   r.   r1   r1   r2   can_access_expenses)   s    r8   c                 C   sR  t | jst| d tdS t| jdd}t| jt| jd}|ru|t	j
j|d t	j
j|dd t	j
j|d	d t	j
j|d	d
gdjtddd pTtdtj
j|dt t ddt	j
j|dddd d t| jrt	j
jdd}|| |jtddd ptd|ddd t t d t| d|S )z)Main dashboard for expenditure managementz7You don't have permission to access expense management.customers:dashboardemployee_profileN)
can_manager#   employeepending)r=   statusapprovedpaid)r=   
status__inamounttotalrE   0.00T)r=   	is_activestart_date__lteend_date__gtecategory-submitted_at   )my_expenses_countmy_pending_expensesmy_approved_expensesmy_total_spentmy_allocationsrecent_expensesr?   
   )total_pending_expensespending_amountpending_expensesmonthly_statscategory_statszexpenditure/dashboard.html)r8   r/   r   errorr   getattrr3   r#   updater   objectsfiltercount	aggregater   r   r   r   todayselect_relatedorder_byget_monthly_expense_statsget_category_statsr   )requestr=   contextrW   r1   r1   r2   expense_dashboard:   sP   

	rh   c                 C   s<  t | jst| d tdS t| jdd}|s"t| d tdS | jdkrt| j|d}t	| j| j
}| r| r|jd	d
}||_|  |D ]}|jrk|jdd	sk|jdrk|jd	d
}||_|  qLtjj|d| jdd t| d|j d td|jdS nt|d}t	 }|||d}t| d|S )zCreate a new expensez-You don't have permission to create expenses.r9   r:   Nz0You need an employee profile to create expenses.zexpenditure:dashboardPOSTr<   FcommitDELETEfile	submittedzExpense submitted for approvalexpenseactionperformed_bycommentsExpense z created successfully!expenditure:expense_detailpk)formattachment_formsetr=   zexpenditure/expense_form.html)r8   r/   r   rZ   r   r[   methodr   ri   r   FILESis_validsaver=   cleaned_datagetrp   r   r]   createsuccessexpense_numberrw   r   )rf   r=   rx   ry   rp   attachment_form
attachmentrg   r1   r1   r2   create_expenseo   sJ   


r   c                 C   sZ  t | jst| d tdS t| j}t| jrtj	
 }nt| jdd}|r0tj	j|d}ntj	 }|dddd	}| r|jdrR|j|jd d}|jdra|j|jd d
}|jdrp|j|jd d}|jdr|j|jd d}|jdr|j|jd d}t|d}| jd}||}||t| jd}t| d|S )zList expenses with filters-You don't have permission to access expenses.r9   r:   Nr<   r=   rJ   budget_allocationrK   rJ   r?   rS   monthexpense_date__monthyearexpense_date__year   page)rx   page_objr;   zexpenditure/expense_list.html)r8   r/   r   rZ   r   r   GETr3   r   r]   allr[   r^   nonerb   rc   r|   r~   r   r   get_pager   )rf   rx   expensesr=   	paginatorpage_numberr   rg   r1   r1   r2   expense_list   s<   





r   c                 C   s   t | jst| d tdS tt|d}t| js2t| jdd}|r(|j	|kr2t| d tdS |t| j|j
 |j d}t| d	|S )
zView expense detailsr   r9   rv   r:   Nz/You don't have permission to view this expense.expenditure:expense_list)rp   r;   attachmentsapproval_logszexpenditure/expense_detail.html)r8   r/   r   rZ   r   r   r   r3   r[   r=   r   r   r   r   )rf   rw   rp   r=   rg   r1   r1   r2   expense_detail   s   

r   c                 C   sB  t t|d}| jdkrt| j}| r|jd }|jd }|dkrEd|_| j|_	t
 |_tjj|d| j|d t| d|j d	 nB|d
kr|jd }|s_t| d t| d||dS d|_| j|_t
 |_||_tjj|d| jd| d t| d|j d |  td|jdS nt }||d}t| d|S )zApprove or reject an expenserv   ri   rq   rs   approver@   ro   rt   z approved successfully!rejectrejection_reasonz&Please provide a reason for rejection.z expenditure/approve_expense.html)rp   rx   rejectedz
Rejected: z
 rejected.ru   )r   r   rz   r   ri   r|   r~   r?   r/   approved_byr
   nowapproved_atr   r]   r   r   r   r   rZ   r   rejected_byrejected_atr   r}   r   rw   )rf   rw   rp   rx   rq   rs   r   rg   r1   r1   r2   approve_expense   sR   






+r   c                 C   s   t jddd}| jd}| jd}|r|j|d}|r&|j|d}t|d}| jd}||}|t	jjdd	t
jjd
d||d}t| d|S )zList budget allocationsr=   rJ   z-created_at)employee__id)category__idr   r   active)employment_statusT)rG   )r   	employees
categoriesemployee_filtercategory_filterz'expenditure/budget_allocation_list.html)r   r]   rb   rc   r   r   r^   r   r   r"   r   r   )rf   allocationsr   r   r   r   r   rg   r1   r1   r2   budget_allocation_list%  s"   

r   c                 C   st   | j dkr-t| j}| r,|jdd}| j|_|  t| d|j	j
 d tdS nt }d|i}t| d|S )	zCreate a new budget allocationri   Frj   zBudget allocation created for !z"expenditure:budget_allocation_listrx   z'expenditure/budget_allocation_form.html)rz   r   ri   r|   r}   r/   
created_byr   r   r=   	full_namer   r   )rf   rx   
allocationrg   r1   r1   r2   create_budget_allocationB  s   

r   c                  C   st   t  j} g }tddD ]+}tjj| |ddgd}|jtddd p&t	d	}|
 }|tj| ||d
 q|S )zGet monthly expense statisticsr      r@   rA   )r   r   rB   rC   rD   rE   rF   )r   total_amountr_   )r   ra   r   ranger   r]   r^   r`   r   r   r_   appendcalendar
month_name)current_yearmonthly_datar   month_expensesr   r_   r1   r1   r2   rd   W  s    

rd   c                   C   s4   t jjtdtdtddgdddjdd	d
S )z"Get expense statistics by categoryr   expenses__amountr@   rA   )expenses__status__in)r^   )total_expensesr   r   )total_expenses__gtz-total_amount)r   r]   annotater   r   r   r^   rc   r1   r1   r1   r2   re   n  s   re   c                 C   s*  | j d}| j dt j}| j d}| j d}tjjddgd}|r-|j|d}|r5|j|d	}|r=|j|d
}|rE|j|d}|jt	ddd pRt
d}| }|djt	dtddd}|ddjt	dtddd}	|d||||	t| j ||||dd}
t| d|
S )zGenerate expense reportsr   r   rJ   r=   r@   rA   rB   r   r   )category_id)employee_idrC   rD   rE   rF   category__nameid)rE   r_   z-totalemployee__first_nameemployee__last_name-expense_date)r   r   rJ   r=   )r   r   total_countcategory_breakdownemployee_breakdownfilter_formcurrent_filterszexpenditure/reports.html)r   r   r   ra   r   r   r]   r^   r`   r   r   r_   valuesr   r   rc   r   r   )rf   r   r   r   r   r   r   r   r   r   rg   r1   r1   r2   expense_reportsu  sP   
r   c           	      C   s   t t|d}|j}t| js&t| jdd}|r|j|kr&t| d t	dS ddl
m} ddlm} ddl}|jrN||jd	d
||j|jjd}|S t| d t	d|jdS )zDownload expense attachmentrv   r:   Nz6You don't have permission to download this attachment.r   r   )FileResponse)	smart_strrbT)as_attachmentfilenamezAttachment file not found.ru   )r   r   rp   r3   r/   r[   r=   r   rZ   r   django.httpr   django.utils.encodingr   osrm   openpathbasenamenamerw   )	rf   rw   r   rp   r=   r   r   r   responser1   r1   r2   download_expense_attachment  s&   

r   c                 C   sl  t | j}tjjddgdddd}i }| r|j	dr2|j|jd d}|jd j
|d< |j	drI|j|jd d}|jd j|d< |j	d	r_|j|jd	 d
}|jd	 |d	< |j	drz|j|jd d}tjt|jd  |d< |j	dr|j|jd d}|jd |d< t||}tdd}dt d d}d| d|d< ||  |S )zDownload expenses as PDF reportr@   rA   r   r=   rJ   r   r<   r   r?   rS   r   r   r   r   application/pdfcontent_typeexpense_report_z%Y%m%d.pdfattachment; filename=""Content-Disposition)r   r   r   r]   r^   rb   rc   r|   r~   r   r   r   r   r   intr    r	   r
   r   strftimewritegetvalue)rf   rx   r   filters
pdf_bufferr   r   r1   r1   r2   download_expense_report_pdf  s:   


r   c                 C   s   t t|d}|jdkrt| d td|jdS | jdkrf| j	dd}| j	dd}d	|_t
 |_||_||_|  tjj|d	| jd
| |rOd| nd d t| d|j d td|jdS td|jdS )zMark an expense as paidrv   r@   z-Only approved expenses can be marked as paid.ru   ri   payment_method payment_referencerA   zMarked as paid via z - Ref: ro   rt   z marked as paid successfully!)r   r   r?   r   rZ   r   rw   rz   ri   r   r
   r   paid_atr   r   r}   r   r]   r   r/   r   r   )rf   rw   rp   r   r   r1   r1   r2   mark_expense_paid  s*   


r   c                 C   s   t | jdt j}| jd}|rt |nd}t||}tdd}|s)| n	tj	|  d| }d| d}d	| d
|d< |
|  |S )z'Download monthly expense summary as PDFr   r   Nr   r   _monthly_expense_summary_r   r   r   r   )r   r   r   r   ra   r   r!   r	   r   r   r   r   )rf   r   r   r   r   
period_strr   r1   r1   r2   download_monthly_summary_pdf  s   

r   c                 C   s$   t j d}d|i}t| d|S )zList all expense categoriesr   r   zexpenditure/category_list.html)r   r]   r   rc   r   )rf   r   rg   r1   r1   r2   expense_category_list*  s   r   c                 C   sl   ddl m} | jdkr(|| j}| r'| }t| d|j d t	dS n| }|dd}t
| d	|S )
zCreate a new expense categoryr   ExpenseCategoryFormri   Expense category "z" created successfully!expenditure:category_listzCreate Expense Category)rx   titleexpenditure/category_form.html)formsr   rz   ri   r|   r}   r   r   r   r   r   )rf   r   rx   rJ   rg   r1   r1   r2   create_expense_category5  s   

r  c                 C   s   ddl m} tt|d}| jdkr0|| j|d}| r/| }t	| d|j
 d tdS n||d}||d	d
}t| d|S )zEdit an expense categoryr   r   rv   ri   )instancer   z" updated successfully!r   zEdit Expense Category)rx   rJ   r   r   )r  r   r   r   rz   ri   r|   r}   r   r   r   r   r   )rf   rw   r   rJ   rx   rg   r1   r1   r2   edit_expense_categoryJ  s   

r  c                 C   s   t t|d}|j }| jdkr;|dkr&t| d|j d| d t
d	S |j}|  t	| d| d t
d	S ||d
}t| d|S )zDelete an expense categoryrv   ri   r   zCannot delete category "z" because it has z associated expenses.r   z" deleted successfully!r   )rJ   expense_countz(expenditure/category_confirm_delete.html)r   r   r   r_   rz   r   rZ   r   deleter   r   r   )rf   rw   rJ   r  category_namerg   r1   r1   r2   delete_expense_categorya  s   

r  c              
   C   s   | j dkr;zddlm} |d t| d W tdS  ty: } zt| dt|  W Y d}~tdS d}~ww t	j
jd	d
dd}d|i}t| d|S )z'Generate expenses for approved payslipsri   r   )call_commandgenerate_payroll_expensesz(Payroll expenses generated successfully!z#Error generating payroll expenses: Nz%expenditure:generate_payroll_expensesr@   T)r?   related_expense__isnullr=   unprocessed_payslipsz*expenditure/generate_payroll_expenses.html)rz   django.core.managementr	  r   r   	ExceptionrZ   strr   r&   r]   r^   rb   r   )rf   r	  er  rg   r1   r1   r2   r
  y  s(   
 r
  c           	      C   s   t t|d}|j}t| jdstd|jj}tj	|s!tdt
|\}}|du r.d}z2t|d"}t| |d}d	|jjd
d  d|d< |W  d   W S 1 sYw   Y  W dS  tyk   tdw )z#Download an expense attachment filerv   r4   zFile not foundzFile not found on serverNzapplication/octet-streamr   r   r   /r   r   zError reading file)r   r   rp   has_department_permissionr/   r   rm   r   r   exists	mimetypes
guess_typer   r	   readr   splitIOError)	rf   attachment_idr   rp   	file_pathr   r   fr   r1   r1   r2   r     s&   ()Kdjango.shortcutsr   r   r   django.contrib.auth.decoratorsr   r   django.contribr   r   r   r	   django.utilsr
   django.db.modelsr   r   r   django.core.paginatorr   django.views.genericr   django.contrib.auth.mixinsr   r   r   decimalr   r   r   r  r   modelsr   r   r   r   r   r  r   r   r   r   r   utilsr    r!   	hr.modelsr"   accounts.permissionsr#   r$   r%   r&   r3   r8   rh   r   r   r   r   r   r   rd   re   r   r   r   r   r   r   r  r  r  r
  r1   r1   r1   r2   <module>   s    
4
2
.
96
) 	