Files
company_site/company_site/financial/views.py

210 lines
7.8 KiB
Python

from django.shortcuts import render, redirect
from django.contrib.auth.decorators import user_passes_test
from .forms import EmployeeForm, ContractForm, ChargeNumberForm, TimeLogForm, NewEmployeeForm
from .models import Contract, TimeCard, TimeCardCell, Employee
from django.utils import timezone
from django.db.models import Sum
from datetime import timedelta
import json
def is_admin(user):
return user.is_active and user.is_superuser
@user_passes_test(is_admin)
def index(request):
contracts = Contract.objects.all()
for c in contracts:
total = TimeCardCell.objects.filter(contract=c).aggregate(Sum('hour'))['hour__sum']
c.total_logged = total if total else 0.0
employees = Employee.objects.all()
employee_data = []
for e in employees:
contract_hours = []
for c in contracts:
total_e_c = TimeCardCell.objects.filter(contract=c, timeCard__employee=e).aggregate(Sum('hour'))['hour__sum']
contract_hours.append({'contract': c, 'hours': total_e_c if total_e_c else 0.0})
employee_data.append({'employee': e, 'contract_hours': contract_hours})
return render(request, "financial/index.html", {
'contracts': contracts,
'employee_data': employee_data
})
@user_passes_test(is_admin)
def new_employee(request):
if request.method == "POST":
form = NewEmployeeForm(request.POST)
if form.is_valid():
form.save()
return redirect('financial_index')
else:
form = NewEmployeeForm()
return render(request, 'financial/new_employee.html', {"form": form})
@user_passes_test(is_admin)
def contracts(request):
contracts_list = Contract.objects.all()
today = timezone.now().date()
chart_data_list = []
for c in contracts_list:
cells = TimeCardCell.objects.filter(contract=c).select_related('timeCard__employee').order_by('date')
total_hours = sum((cell.hour or 0.0) for cell in cells)
total_money = sum((cell.hour or 0.0) * cell.timeCard.employee.hourly_salary for cell in cells)
c.total_hours_spent = total_hours
c.total_money_spent = total_money
c.remaining_hours = max(0, c.budget_hours - total_hours)
budget_amt = c.funded_amount if c.funded_amount > 0 else c.proposed_amount
c.remaining_money = max(0, budget_amt - total_money)
proj_end = None
if cells.exists():
first_date = cells.first().date or c.baseline_start or today
last_date = cells.last().date or today
days_elapsed = (last_date - first_date).days
if days_elapsed <= 0:
days_elapsed = 1
daily_hour_burn = total_hours / days_elapsed
daily_money_burn = total_money / days_elapsed
days_out_hours = (c.remaining_hours / daily_hour_burn) if daily_hour_burn > 0 else 9999
days_out_money = (c.remaining_money / daily_money_burn) if daily_money_burn > 0 else 9999
days_out = max(days_out_hours, days_out_money)
if days_out < 9999:
proj_end = last_date + timedelta(days=int(days_out))
c.projected_end_date = proj_end if proj_end else "N/A"
start_dt = str(c.baseline_start or today)
end_dt = str(proj_end or (today + timedelta(days=30)))
chart_data_list.append({
'name': c.name,
'start_date': start_dt,
'today': str(today),
'projected_end': end_dt,
'budget': float(budget_amt),
'spent': float(total_money),
'remaining': float(c.remaining_money)
})
return render(request, 'financial/contracts.html', {
'contracts': contracts_list,
'chart_data_json': json.dumps(chart_data_list)
})
@user_passes_test(is_admin)
def contract_detail(request, contract_slug):
contract = Contract.objects.filter(slug=contract_slug).first()
if request.method == 'POST':
form = ContractForm(request.POST, instance=contract)
if form.is_valid():
form.save()
return redirect('contracts')
else:
form = ContractForm(instance=contract)
charge_number_form = ChargeNumberForm()
return render(request, 'financial/contract_detail.html', {'is_new': False, 'form': form, 'charge_number_form':charge_number_form, 'contract': contract})
@user_passes_test(is_admin)
def new_contract(request):
if request.method == "POST":
form = ContractForm(request.POST)
if form.is_valid():
form.save()
return redirect('contracts')
else:
form = ContractForm()
return render(request, 'financial/contract_detail.html', {"form": form, 'is_new': True})
@user_passes_test(is_admin)
def timekeeping(request):
if request.method == "POST":
form = TimeLogForm(request.POST)
if form.is_valid():
employee = Employee.objects.filter(user=request.user).first()
if not employee:
employee = Employee.objects.first()
if not employee:
return render(request, 'financial/timekeeping.html', {"form": form, "error": "No Employee exists. Cannot auto-create TimeCard. Please create an Employee first."})
time_card, _ = TimeCard.objects.get_or_create(employee=employee, startDate=timezone.now().date(), endDate=timezone.now().date())
cell = form.save(commit=False)
cell.timeCard = time_card
cell.save()
return redirect('financial_index')
else:
form = TimeLogForm()
return render(request, 'financial/timekeeping.html', {'form': form})
@user_passes_test(is_admin)
def time_logs(request):
logs = TimeCardCell.objects.all().order_by('-date', '-created')
return render(request, 'financial/time_logs.html', {'logs': logs})
@user_passes_test(is_admin)
def edit_time_log(request, log_id):
log_entry = TimeCardCell.objects.filter(id=log_id).first()
if not log_entry:
return redirect('time_logs')
if request.method == "POST":
form = TimeLogForm(request.POST, instance=log_entry)
if form.is_valid():
form.save()
return redirect('time_logs')
else:
form = TimeLogForm(instance=log_entry)
return render(request, 'financial/edit_time_log.html', {'form': form, 'log': log_entry})
@user_passes_test(is_admin)
def delete_time_log(request, log_id):
if request.method == "POST":
log_entry = TimeCardCell.objects.filter(id=log_id).first()
if log_entry:
log_entry.delete()
return redirect('time_logs')
@user_passes_test(is_admin)
def client_reports(request):
contracts = Contract.objects.all()
for c in contracts:
total = TimeCardCell.objects.filter(contract=c).aggregate(Sum('hour'))['hour__sum']
c.total_logged = total if total else 0.0
c.remaining_budget = c.budget_hours - c.total_logged
return render(request, 'financial/reports.html', {'contracts': contracts})
@user_passes_test(is_admin)
def update_charge_number(request, charge_number_slug):
return render(request, 'financial/not_created.html', {})
@user_passes_test(is_admin)
def new_charge_number(request, charge_number_slug):
return render(request, 'financial/not_created.html', {})
@user_passes_test(is_admin)
def timeapproval(request):
return render(request, 'financial/not_created.html', {})
@user_passes_test(is_admin)
def chargenumber(request):
return render(request, 'financial/not_created.html', {})
@user_passes_test(is_admin)
def procurement(request):
return render(request, 'financial/procurement.html', {})
@user_passes_test(is_admin)
def profile(request):
form = EmployeeForm()
return render(request, 'financial/profile.html', {'form': form})