37680-vm/core/views.py
2026-01-21 23:05:26 +00:00

350 lines
12 KiB
Python

import os
import platform
from django.shortcuts import render, redirect, get_object_or_404
from django.contrib.auth import login, logout, authenticate
from django.contrib.auth.forms import UserCreationForm, AuthenticationForm
from django.contrib.auth.decorators import login_required
from django.contrib import messages
from django.db import transaction
from .models import Company, Profile, JobStatus, RequiredFolder, Job, JobFolderCompletion
from .forms import CompanyForm, JobStatusForm, RequiredFolderForm, JobForm
def home(request):
if request.user.is_authenticated:
return redirect('dashboard')
context = {
"project_name": "RepairsHub",
}
return render(request, "core/index.html", context)
def register_view(request):
if request.method == 'POST':
form = UserCreationForm(request.POST)
if form.is_valid():
user = form.save()
login(request, user)
return redirect('company_setup')
else:
form = UserCreationForm()
return render(request, 'core/register.html', {'form': form})
def login_view(request):
if request.method == 'POST':
form = AuthenticationForm(data=request.POST)
if form.is_valid():
user = form.get_user()
login(request, user)
return redirect('dashboard')
else:
form = AuthenticationForm()
return render(request, 'core/login.html', {'form': form})
def logout_view(request):
logout(request)
return redirect('home')
@login_required
def company_setup(request):
# Check if user already has a company
if request.user.profile.company:
return redirect('dashboard')
if request.method == 'POST':
company_form = CompanyForm(request.POST)
status_names = request.POST.getlist('statuses')
default_status_idx = request.POST.get('default_status')
folder_names = request.POST.getlist('folders')
if company_form.is_valid() and status_names and default_status_idx is not None:
with transaction.atomic():
company = company_form.save()
# Link user to company as ADMIN
profile = request.user.profile
profile.company = company
profile.role = 'ADMIN'
profile.save()
# Create statuses
for i, name in enumerate(status_names):
if name.strip():
JobStatus.objects.create(
company=company,
name=name.strip(),
is_starting_status=(str(i) == default_status_idx),
order=i
)
# Create folders
for name in folder_names:
if name.strip():
RequiredFolder.objects.create(
company=company,
name=name.strip()
)
messages.success(request, f"Company {company.name} created successfully!")
return redirect('dashboard')
else:
if not status_names:
messages.error(request, "At least one status is required.")
if default_status_idx is None:
messages.error(request, "You must select a starting status.")
else:
company_form = CompanyForm()
return render(request, 'core/company_setup.html', {
'company_form': company_form,
})
@login_required
def dashboard(request):
profile = request.user.profile
if not profile.company:
return redirect('company_setup')
company = profile.company
jobs = Job.objects.filter(company=company)
context = {
'company': company,
'total_jobs': jobs.count(),
'jobs': jobs.order_by('-created_at')[:5], # Recent jobs
}
return render(request, 'core/dashboard.html', context)
@login_required
def job_list(request):
profile = request.user.profile
if not profile.company:
return redirect('company_setup')
company = profile.company
jobs = Job.objects.filter(company=company).order_by('-created_at')
return render(request, 'core/job_list.html', {
'jobs': jobs,
'company': company
})
@login_required
def job_create(request):
profile = request.user.profile
if not profile.company:
return redirect('company_setup')
company = profile.company
if request.method == 'POST':
form = JobForm(request.POST, company=company)
if form.is_valid():
job = form.save(commit=False)
job.company = company
job.save()
# Initialize folder completions
for folder in company.required_folders.all():
JobFolderCompletion.objects.get_or_create(job=job, folder=folder)
messages.success(request, f"Job {job.job_ref} created successfully!")
return redirect('job_detail', pk=job.pk)
else:
form = JobForm(company=company)
return render(request, 'core/job_form.html', {
'form': form,
'title': 'Create New Job',
'company': company
})
@login_required
def job_detail(request, pk):
profile = request.user.profile
if not profile.company:
return redirect('company_setup')
company = profile.company
job = get_object_or_404(Job, pk=pk, company=company)
# Ensure all required folders have completion records (in case new ones were added later)
for folder in company.required_folders.all():
JobFolderCompletion.objects.get_or_create(job=job, folder=folder)
folder_completions = job.folder_completions.all().select_related('folder')
return render(request, 'core/job_detail.html', {
'job': job,
'folder_completions': folder_completions,
'company': company
})
@login_required
def job_update(request, pk):
profile = request.user.profile
if not profile.company:
return redirect('company_setup')
company = profile.company
job = get_object_or_404(Job, pk=pk, company=company)
if request.method == 'POST':
form = JobForm(request.POST, instance=job, company=company)
if form.is_valid():
form.save()
messages.success(request, f"Job {job.job_ref} updated successfully!")
return redirect('job_detail', pk=job.pk)
else:
form = JobForm(instance=job, company=company)
return render(request, 'core/job_form.html', {
'form': form,
'title': f'Edit Job: {job.job_ref}',
'company': company
})
@login_required
def job_delete(request, pk):
profile = request.user.profile
if not profile.company:
return redirect('company_setup')
company = profile.company
job = get_object_or_404(Job, pk=pk, company=company)
if request.method == 'POST':
job_ref = job.job_ref
job.delete()
messages.success(request, f"Job {job_ref} deleted.")
return redirect('job_list')
return render(request, 'core/job_confirm_delete.html', {
'job': job,
'company': company
})
@login_required
def toggle_folder_completion(request, pk, folder_id):
profile = request.user.profile
if not profile.company:
return redirect('company_setup')
company = profile.company
job = get_object_or_404(Job, pk=pk, company=company)
completion = get_object_or_404(JobFolderCompletion, job=job, folder_id=folder_id)
completion.is_completed = not completion.is_completed
completion.save()
messages.success(request, f"Folder '{completion.folder.name}' status updated.")
return redirect('job_detail', pk=job.pk)
@login_required
def settings_view(request):
profile = request.user.profile
if not profile.company:
return redirect('company_setup')
if profile.role != 'ADMIN':
messages.error(request, "Only admins can access company settings.")
return redirect('dashboard')
company = profile.company
statuses = company.statuses.all()
folders = company.required_folders.all()
return render(request, 'core/settings.html', {
'company': company,
'statuses': statuses,
'folders': folders
})
@login_required
def status_create(request):
profile = request.user.profile
if profile.role != 'ADMIN': return redirect('dashboard')
if request.method == 'POST':
form = JobStatusForm(request.POST)
if form.is_valid():
status = form.save(commit=False)
status.company = profile.company
if status.is_starting_status:
# Unset other starting statuses
JobStatus.objects.filter(company=profile.company).update(is_starting_status=False)
status.save()
messages.success(request, "New status created.")
return redirect('settings')
else:
form = JobStatusForm()
return render(request, 'core/status_form.html', {'form': form, 'title': 'Create Status'})
@login_required
def status_update(request, pk):
profile = request.user.profile
if profile.role != 'ADMIN': return redirect('dashboard')
status = get_object_or_404(JobStatus, pk=pk, company=profile.company)
if request.method == 'POST':
form = JobStatusForm(request.POST, instance=status)
if form.is_valid():
if form.cleaned_data['is_starting_status']:
JobStatus.objects.filter(company=profile.company).update(is_starting_status=False)
form.save()
messages.success(request, "Status updated.")
return redirect('settings')
else:
form = JobStatusForm(instance=status)
return render(request, 'core/status_form.html', {'form': form, 'title': 'Edit Status'})
@login_required
def status_delete(request, pk):
profile = request.user.profile
if profile.role != 'ADMIN': return redirect('dashboard')
status = get_object_or_404(JobStatus, pk=pk, company=profile.company)
if status.is_starting_status:
messages.error(request, "Cannot delete the starting status. Please set another status as starting first.")
return redirect('settings')
if request.method == 'POST':
starting_status = profile.company.statuses.filter(is_starting_status=True).first()
Job.objects.filter(status=status).update(status=starting_status)
status.delete()
messages.success(request, f"Status deleted. Jobs reassigned to {starting_status.name}.")
return redirect('settings')
return render(request, 'core/status_confirm_delete.html', {'status': status})
@login_required
def folder_create(request):
profile = request.user.profile
if profile.role != 'ADMIN': return redirect('dashboard')
if request.method == 'POST':
form = RequiredFolderForm(request.POST)
if form.is_valid():
folder = form.save(commit=False)
folder.company = profile.company
folder.save()
# Note: The jobs will automatically see this new folder in job_detail view
messages.success(request, f"Folder '{folder.name}' added company-wide.")
return redirect('settings')
else:
form = RequiredFolderForm()
return render(request, 'core/folder_form.html', {'form': form})
@login_required
def folder_delete(request, pk):
profile = request.user.profile
if profile.role != 'ADMIN': return redirect('dashboard')
folder = get_object_or_404(RequiredFolder, pk=pk, company=profile.company)
if request.method == 'POST':
folder.delete()
messages.success(request, "Folder removed from company settings.")
return redirect('settings')
return render(request, 'core/folder_confirm_delete.html', {'folder': folder})