def list_for_prescriber(request, template_name="apply/list_for_prescriber.html"): """ List of applications for a prescriber. """ prescriber_organization = None pk = request.session.get(settings.ITOU_SESSION_CURRENT_PRESCRIBER_ORG_KEY) if pk: queryset = PrescriberOrganization.objects.member_required(request.user) prescriber_organization = get_object_or_404(queryset, pk=pk) if prescriber_organization: # Show all applications organization-wide. job_applications = prescriber_organization.jobapplication_set.all() else: job_applications = request.user.job_applications_sent.all() job_applications = job_applications.select_related( "job_seeker", "sender", "sender_siae", "sender_prescriber_organization", "to_siae", ).prefetch_related("selected_jobs__appellation") job_applications_page = pager(job_applications, request.GET.get("page"), items_per_page=10) context = {"job_applications_page": job_applications_page} return render(request, template_name, context)
def list_for_prescriber(request, template_name="apply/list_for_prescriber.html"): """ List of applications for a prescriber. """ job_applications = get_all_available_job_applications_as_prescriber( request) filters_form = PrescriberFilterJobApplicationsForm(job_applications, request.GET or None) filters = None job_applications = job_applications.with_list_related_data() if filters_form.is_valid(): job_applications = job_applications.filter( *filters_form.get_qs_filters()) filters = filters_form.humanize_filters() job_applications_page = pager(job_applications, request.GET.get("page"), items_per_page=10) context = { "job_applications_page": job_applications_page, "filters_form": filters_form, "filters": filters } return render(request, template_name, context)
def list_for_job_seeker(request, template_name="apply/list_for_job_seeker.html"): """ List of applications for a job seeker. """ filters_form = FilterJobApplicationsForm(request.GET or None) filters = None job_applications = request.user.job_applications if filters_form.is_valid(): job_applications = job_applications.filter( *filters_form.get_qs_filters()) filters = filters_form.humanize_filters() job_applications = job_applications.select_related( "job_seeker", "sender", "sender_siae", "sender_prescriber_organization", "to_siae", ).prefetch_related("selected_jobs__appellation") job_applications_page = pager(job_applications, request.GET.get("page"), items_per_page=10) context = { "job_applications_page": job_applications_page, "filters_form": filters_form, "filters": filters, } return render(request, template_name, context)
def list_for_siae(request, template_name="apply/list_for_siae.html"): """ List of applications for an SIAE. """ siae = get_current_siae_or_404(request) job_applications = siae.job_applications_received filters_form = SiaeFilterJobApplicationsForm(job_applications, request.GET or None) filters = None job_applications = job_applications.not_archived().with_list_related_data() if filters_form.is_valid(): job_applications = job_applications.filter( *filters_form.get_qs_filters()) filters = filters_form.humanize_filters() job_applications_page = pager(job_applications, request.GET.get("page"), items_per_page=10) context = { "siae": siae, "job_applications_page": job_applications_page, "filters_form": filters_form, "filters": filters, } return render(request, template_name, context)
def search_prescribers_results( request, template_name="search/prescribers_search_results.html"): city = None distance = None form = PrescriberSearchForm( data=request.GET or None, initial={"distance": PrescriberSearchForm.DISTANCE_DEFAULT}) prescriber_orgs_page = None if form.is_valid(): city = form.cleaned_data["city"] distance = form.cleaned_data["distance"] prescriber_orgs = (PrescriberOrganization.objects.filter( is_authorized=True).within(city.coords, distance).annotate( distance=Distance("coords", city.coords)).order_by("distance")) prescriber_orgs_page = pager(prescriber_orgs, request.GET.get("page"), items_per_page=10) context = { "city": city, "distance": distance, "form": form, "prescriber_orgs_page": prescriber_orgs_page } return render(request, template_name, context)
def list_for_prescriber(request, template_name="apply/list_for_prescriber.html"): """ List of applications for a prescriber. """ prescriber_organization = None pk = request.session.get(settings.ITOU_SESSION_CURRENT_PRESCRIBER_ORG_KEY) if pk: queryset = PrescriberOrganization.objects.member_required(request.user) prescriber_organization = get_object_or_404(queryset, pk=pk) if prescriber_organization: # Show all applications organization-wide. job_applications = prescriber_organization.jobapplication_set else: job_applications = request.user.job_applications_sent filters_form = PrescriberFilterJobApplicationsForm(job_applications, request.GET or None) filters = None if filters_form.is_valid(): job_applications = job_applications.filter( *filters_form.get_qs_filters()) filters = filters_form.humanize_filters() job_applications = job_applications.select_related( "job_seeker", "sender", "sender_siae", "sender_prescriber_organization", "to_siae", ).prefetch_related("selected_jobs__appellation") job_applications_page = pager(job_applications, request.GET.get("page"), items_per_page=10) context = { "job_applications_page": job_applications_page, "filters_form": filters_form, "filters": filters, } return render(request, template_name, context)
def list_for_job_seeker(request, template_name="apply/list_for_job_seeker.html"): """ List of applications for a job seeker. """ job_applications = request.user.job_applications.select_related( "job_seeker", "sender", "sender_siae", "sender_prescriber_organization", "to_siae", ).prefetch_related("selected_jobs__appellation") job_applications_page = pager(job_applications, request.GET.get("page"), items_per_page=10) context = {"job_applications_page": job_applications_page} return render(request, template_name, context)
def search_prescribers_results( request, template_name="search/prescribers_search_results.html"): form = PrescriberSearchForm(data=request.GET or None) prescriber_orgs_page = None if form.is_valid(): city = form.cleaned_data["city"] distance_km = form.cleaned_data["distance"] prescriber_orgs = PrescriberOrganization.objects.filter( is_authorized=True).within(city.coords, distance_km) prescriber_orgs_page = pager(prescriber_orgs, request.GET.get("page"), items_per_page=10) context = {"form": form, "prescriber_orgs_page": prescriber_orgs_page} return render(request, template_name, context)
def list_for_siae(request, template_name="apply/list_for_siae.html"): """ List of applications for an SIAE. """ pk = request.session[settings.ITOU_SESSION_CURRENT_SIAE_KEY] queryset = Siae.active_objects.member_required(request.user) siae = get_object_or_404(queryset, pk=pk) job_applications = siae.job_applications_received.select_related( "job_seeker", "sender", "sender_siae", "sender_prescriber_organization", "to_siae", ).prefetch_related("selected_jobs__appellation") job_applications_page = pager(job_applications, request.GET.get("page"), items_per_page=10) context = {"siae": siae, "job_applications_page": job_applications_page} return render(request, template_name, context)
def search_siaes(request, template_name="search/siaes_search_results.html"): form = SiaeSearchForm(data=request.GET) siaes_page = None if form.is_valid(): city = form.cleaned_data["city"] distance_km = form.cleaned_data["distance"] kind = form.cleaned_data["kind"] siaes = ( Siae.active_objects.within(city.coords, distance_km) .prefetch_job_description_through(is_active=True) .prefetch_related("members") ) if kind: siaes = siaes.filter(kind=kind) siaes_page = pager(siaes, request.GET.get("page"), items_per_page=10) context = {"form": form, "siaes_page": siaes_page} return render(request, template_name, context)
def list_for_siae(request, template_name="apply/list_for_siae.html"): """ List of applications for an SIAE. """ pk = request.session[settings.ITOU_SESSION_CURRENT_SIAE_KEY] queryset = Siae.active_objects.member_required(request.user) siae = get_object_or_404(queryset, pk=pk) job_applications = siae.job_applications_received filters_form = SiaeFilterJobApplicationsForm(job_applications, request.GET or None) filters = None if filters_form.is_valid(): job_applications = job_applications.filter( *filters_form.get_qs_filters()) filters = filters_form.humanize_filters() job_applications = job_applications.select_related( "job_seeker", "sender", "sender_siae", "sender_prescriber_organization", "to_siae", ).prefetch_related("selected_jobs__appellation") job_applications_page = pager(job_applications, request.GET.get("page"), items_per_page=10) context = { "siae": siae, "job_applications_page": job_applications_page, "filters_form": filters_form, "filters": filters, } return render(request, template_name, context)
def search_siaes_results(request, template_name="search/siaes_search_results.html"): city = None distance = None siaes_page = None siaes_step_1 = None form = SiaeSearchForm( request.GET or None, initial={"distance": SiaeSearchForm.DISTANCE_DEFAULT}) if form.is_valid(): # The filtering is made in 3 steps: # 1. query with city and distance # 2. extract departments and districts filters from first query # 3. final query with all the others criteria city = form.cleaned_data["city"] distance = form.cleaned_data["distance"] # Step 1 - Initial query siaes_step_1 = Siae.objects.active().within(city.coords, distance) # Step 2 # Extract departments from results to inject them as filters # The DB contains around 4k SIAE (always fast in Python and no need of iterator()) departments = set() departments_districts = defaultdict(set) for siae in siaes_step_1: # Extract the department of SIAE if siae.department: departments.add(siae.department) # Extract the post_code if it's a district to use it as criteria if siae.department in DEPARTMENTS_WITH_DISTRICTS: if int(siae.post_code) <= DEPARTMENTS_WITH_DISTRICTS[ siae.department]["max"]: departments_districts[siae.department].add( siae.post_code) if departments: departments = sorted(departments) form.add_field_departements(departments) if departments_districts: for department, districts in departments_districts.items(): districts = sorted(districts) form.add_field_districts(department, districts) # Step 3 - Final filtering kinds = form.cleaned_data["kinds"] departments = request.GET.getlist("departments") districts = [] for department_with_district in DEPARTMENTS_WITH_DISTRICTS: districts += request.GET.getlist( f"districts_{department_with_district}") siaes = ( siaes_step_1 # Convert km to m (injected in SQL query) .annotate(distance=Distance("coords", city.coords) / 1000) .prefetch_job_description_through() # For sorting let's put siaes in only 2 buckets (boolean has_active_members). # If we sort naively by `-_total_active_members` we would show # siaes with 10 members (where 10 is the max), then siaes # with 9 members, then siaes with 8 members etc... # This is clearly not what we want. We want to show siaes with members # (whatever the number of members is) then siaes without members. .with_has_active_members() .with_job_app_score() # Sort in 4 subgroups in the following order, each subgroup being sorted by job_app_score. # 1) has_active_members and not block_job_applications # These are the siaes which can currently hire, and should be on top. # 2) has_active_members and block_job_applications # These are the siaes currently blocking job applications, they should # be rather high in the list since they are likely to hire again. # 3) not has_active_members and not block_job_applications # These are the siaes with no member, they should show last. # 4) not has_active_members and block_job_applications # This group is supposed to be empty. But itou staff may have # detached members from their siae so it could still happen. .order_by("-has_active_members", "block_job_applications", "job_app_score") ) if kinds: siaes = siaes.filter(kind__in=kinds) if departments: siaes = siaes.filter(department__in=departments) if districts: siaes = siaes.filter(post_code__in=districts) siaes_page = pager(siaes, request.GET.get("page"), items_per_page=10) context = { "city": city, "distance": distance, "ea_eatt_kinds": [Siae.KIND_EA, Siae.KIND_EATT], "form": form, "siaes_page": siaes_page, "siaes_step_1": siaes_step_1, # Used to display a specific badge } return render(request, template_name, context)
def list(request, template_name="employee_record/list.html"): """ Displays a list of employee records for the SIAE """ siae = get_current_siae_or_404(request) if not siae.can_use_employee_record: raise PermissionDenied form = SelectEmployeeRecordStatusForm(data=request.GET or None) status = EmployeeRecord.Status.NEW # Employee records are created with a job application object # At this stage, new job applications / hirings do not have # an associated employee record object # Objects in this list can be either: # - employee records: iterate on their job application object # - basic job applications: iterate as-is employee_records_list = True navigation_pages = None data = None # Construct badges # Badges for "real" employee records employee_record_statuses = (EmployeeRecord.objects.filter( job_application__to_siae=siae).values("status").annotate( cnt=Count("status")).order_by("-status")) employee_record_badges = { row["status"]: row["cnt"] for row in employee_record_statuses } # Set count of each status for badge display status_badges = [ ( JobApplication.objects.eligible_as_employee_record(siae).count(), "info", ), (employee_record_badges.get(EmployeeRecord.Status.READY, 0), "secondary"), (employee_record_badges.get(EmployeeRecord.Status.SENT, 0), "warning"), (employee_record_badges.get(EmployeeRecord.Status.REJECTED, 0), "danger"), (employee_record_badges.get(EmployeeRecord.Status.PROCESSED, 0), "success"), ] # Override defaut value (NEW status) # See comment above on `employee_records_list` var if form.is_valid(): status = form.cleaned_data["status"] # Not needed every time (not pulled-up), and DRY here base_query = EmployeeRecord.objects.full_fetch() if status == EmployeeRecord.Status.NEW: data = JobApplication.objects.eligible_as_employee_record(siae) employee_records_list = False elif status == EmployeeRecord.Status.READY: data = base_query.ready_for_siae(siae) elif status == EmployeeRecord.Status.SENT: data = base_query.sent_for_siae(siae) elif status == EmployeeRecord.Status.REJECTED: data = EmployeeRecord.objects.rejected_for_siae(siae) elif status == EmployeeRecord.Status.PROCESSED: data = base_query.processed_for_siae(siae) if data: navigation_pages = pager(data, request.GET.get("page", 1), items_per_page=10) context = { "form": form, "employee_records_list": employee_records_list, "badges": status_badges, "navigation_pages": navigation_pages, "feature_availability_date": settings.EMPLOYEE_RECORD_FEATURE_AVAILABILITY_DATE, } return render(request, template_name, context)