Dashboard changes to list Incomplete folders

This commit is contained in:
Flatlogic Bot 2026-01-22 00:00:28 +00:00
parent 10bb02df57
commit a1804debdb
3 changed files with 60 additions and 3 deletions

View File

@ -39,7 +39,7 @@
padding: 1.5rem; padding: 1.5rem;
border-radius: 12px; border-radius: 12px;
border: none; border: none;
box-shadow: 0 1px 3px rgba(0,0,0,0.1); box-shadow: 0 1px 3px rgba(0,0=0,0.1);
} }
.stat-value { .stat-value {
font-size: 2rem; font-size: 2rem;
@ -127,6 +127,28 @@
</div> </div>
</div> </div>
<div class="row g-4 mb-5">
<div class="col-md-12">
<div class="stat-card">
<h6 class="mb-3">Incomplete Folder Breakdown</h6>
{% if incomplete_folder_breakdown %}
<ul class="list-group list-group-flush">
{% for item in incomplete_folder_breakdown %}
<li class="list-group-item d-flex justify-content-between align-items-center px-0 py-1">
<a href="{% url 'job_list' %}?missing_folder_id={{ item.folder.id }}" class="text-decoration-none text-dark">
{{ item.folder.name }}
</a>
<span class="badge bg-danger rounded-pill">{{ item.missing_count }}</span>
</li>
{% endfor %}
</ul>
{% else %}
<p class="text-muted">All required folders are complete for all jobs, or no required folders are defined.</p>
{% endif %}
</div>
</div>
</div>
<div class="card border-0 shadow-sm"> <div class="card border-0 shadow-sm">
<div class="card-header bg-white py-3 border-0 d-flex justify-content-between align-items-center"> <div class="card-header bg-white py-3 border-0 d-flex justify-content-between align-items-center">
<h5 class="mb-0">Recent Repair Jobs</h5> <h5 class="mb-0">Recent Repair Jobs</h5>

View File

@ -16,6 +16,9 @@ from django.core.mail import send_mail
from django.conf import settings from django.conf import settings
from django.urls import reverse from django.urls import reverse
from django.utils import timezone from django.utils import timezone
from django.contrib.auth import get_user_model
User = get_user_model()
from .models import Company, Profile, JobStatus, RequiredFolder, Job, JobFolderCompletion, JobFile, Invitation from .models import Company, Profile, JobStatus, RequiredFolder, Job, JobFolderCompletion, JobFile, Invitation
from .forms import CompanyForm, JobStatusForm, RequiredFolderForm, JobForm, JobFileForm, ImportJobsForm, InviteUserForm from .forms import CompanyForm, JobStatusForm, RequiredFolderForm, JobForm, JobFileForm, ImportJobsForm, InviteUserForm
@ -117,15 +120,34 @@ def dashboard(request):
jobs_by_status = jobs.values('status__name').annotate(count=Count('id')).order_by('status__name') jobs_by_status = jobs.values('status__name').annotate(count=Count('id')).order_by('status__name')
# Jobs with incomplete folders # Jobs with incomplete folders (overall count, existing logic)
jobs_with_incomplete_folders = jobs.filter(folder_completions__is_completed=False).distinct().count() jobs_with_incomplete_folders = jobs.filter(folder_completions__is_completed=False).distinct().count()
# NEW LOGIC: Breakdown of incomplete folders per RequiredFolder
incomplete_folder_breakdown = []
required_folders = company.required_folders.all()
for folder in required_folders:
# Count jobs where this specific folder is NOT completed
missing_count = Job.objects.filter(
company=company,
folder_completions__folder=folder,
folder_completions__is_completed=False
).distinct().count()
if missing_count > 0: # Only include if there are missing jobs for this folder
incomplete_folder_breakdown.append({
'folder': folder,
'missing_count': missing_count
})
context = { context = {
'company': company, 'company': company,
'total_jobs': total_jobs, 'total_jobs': total_jobs,
'jobs_by_status': jobs_by_status, 'jobs_by_status': jobs_by_status,
'jobs_with_incomplete_folders': jobs_with_incomplete_folders, 'jobs_with_incomplete_folders': jobs_with_incomplete_folders, # Keep existing for now
'jobs': jobs.order_by('-created_at')[:5], 'jobs': jobs.order_by('-created_at')[:5],
'incomplete_folder_breakdown': incomplete_folder_breakdown, # NEW CONTEXT VARIABLE
} }
return render(request, 'core/dashboard.html', context) return render(request, 'core/dashboard.html', context)
@ -138,6 +160,19 @@ def job_list(request):
company = profile.company company = profile.company
jobs = Job.objects.filter(company=company).order_by('-created_at') jobs = Job.objects.filter(company=company).order_by('-created_at')
# NEW LOGIC: Filter by missing_folder_id
missing_folder_id = request.GET.get('missing_folder_id')
if missing_folder_id:
# Find all jobs that have this folder as required but it's not completed
jobs = jobs.filter(
folder_completions__folder__id=missing_folder_id,
folder_completions__is_completed=False
).distinct()
# Optional: Get the folder name to display in the template
missing_folder = get_object_or_404(RequiredFolder, pk=missing_folder_id, company=company)
messages.info(request, f"Showing jobs missing '{missing_folder.name}' folder completion.")
return render(request, 'core/job_list.html', { return render(request, 'core/job_list.html', {
'jobs': jobs, 'jobs': jobs,
'company': company 'company': company