Dashboard changes to list Incomplete folders
This commit is contained in:
parent
10bb02df57
commit
a1804debdb
Binary file not shown.
@ -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>
|
||||||
|
|||||||
@ -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)
|
||||||
|
|
||||||
@ -137,6 +159,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,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user