feat: add automation activity and employer intelligence
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
|
||||
from django.db.models import Avg, Count, Max, Q, QuerySet
|
||||
|
||||
from apps.profiles.models import SearchProfile
|
||||
from apps.sources.models import Source
|
||||
|
||||
from ..models import Application, Employer, JobPosting, ScoreRun
|
||||
from .cockpit import annotate_latest_profile_score
|
||||
from .relevance import it_relevance_query
|
||||
|
||||
|
||||
def employer_index_queryset(*, user, profile: SearchProfile | None) -> QuerySet[Employer]:
|
||||
score_filter = Q(jobs__scores__profile=profile) if profile else Q(pk__isnull=True)
|
||||
return Employer.objects.annotate(
|
||||
active_vacancies=Count(
|
||||
"jobs", filter=Q(jobs__status=JobPosting.Status.ACTIVE), distinct=True
|
||||
),
|
||||
relevant_vacancies=Count(
|
||||
"jobs",
|
||||
filter=Q(jobs__status=JobPosting.Status.ACTIVE) & it_relevance_query("jobs__"),
|
||||
distinct=True,
|
||||
),
|
||||
previous_applications=Count(
|
||||
"jobs__applications",
|
||||
filter=Q(jobs__applications__user=user),
|
||||
distinct=True,
|
||||
),
|
||||
source_count=Count("jobs__source_aliases__source", distinct=True),
|
||||
latest_job_at=Max("jobs__first_seen"),
|
||||
average_match=Avg("jobs__scores__score", filter=score_filter),
|
||||
)
|
||||
|
||||
|
||||
def filter_employers(
|
||||
queryset: QuerySet[Employer], *, query: str = "", channel: str = "", active_only: bool = False
|
||||
) -> QuerySet[Employer]:
|
||||
if query.strip():
|
||||
queryset = queryset.filter(
|
||||
Q(name__icontains=query.strip())
|
||||
| Q(domain__icontains=query.strip())
|
||||
| Q(jobs__raw_location__icontains=query.strip())
|
||||
)
|
||||
if channel == "direct":
|
||||
queryset = queryset.filter(is_direct_employer=True, is_recruiter=False)
|
||||
elif channel == "recruiter":
|
||||
queryset = queryset.filter(is_recruiter=True)
|
||||
if active_only:
|
||||
queryset = queryset.filter(active_vacancies__gt=0)
|
||||
return queryset.order_by("-relevant_vacancies", "-active_vacancies", "name").distinct()
|
||||
|
||||
|
||||
def build_employer_detail(
|
||||
*, employer: Employer, user, profile: SearchProfile | None
|
||||
) -> dict[str, Any]:
|
||||
jobs = annotate_latest_profile_score(
|
||||
employer.jobs.select_related("employer").all(), profile
|
||||
).order_by("-first_seen")
|
||||
sources = Source.objects.filter(job_aliases__job__employer=employer).distinct().order_by("name")
|
||||
locations = list(
|
||||
employer.jobs.exclude(raw_location="")
|
||||
.order_by("raw_location")
|
||||
.values_list("raw_location", flat=True)
|
||||
.distinct()[:8]
|
||||
)
|
||||
return {
|
||||
"employer": employer,
|
||||
"recent_jobs": list(jobs[:12]),
|
||||
"active_jobs": list(jobs.filter(status=JobPosting.Status.ACTIVE)[:8]),
|
||||
"applications": list(
|
||||
Application.objects.filter(user=user, job__employer=employer)
|
||||
.select_related("job")
|
||||
.order_by("-updated_at")[:8]
|
||||
),
|
||||
"sources": list(sources[:10]),
|
||||
"locations": locations,
|
||||
"match_history": list(
|
||||
ScoreRun.objects.filter(profile=profile, job__employer=employer)
|
||||
.select_related("job")
|
||||
.order_by("-created_at")[:20]
|
||||
)
|
||||
if profile
|
||||
else [],
|
||||
}
|
||||
Reference in New Issue
Block a user