Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1# (c) 2018-2020
2# MPIB <https://www.mpib-berlin.mpg.de/>,
3# MPI-CBS <https://www.cbs.mpg.de/>,
4# MPIP <http://www.psych.mpg.de/>
5#
6# This file is part of Castellum.
7#
8# Castellum is free software; you can redistribute it and/or modify it
9# under the terms of the GNU Affero General Public License as published
10# by the Free Software Foundation; either version 3 of the License, or
11# (at your option) any later version.
12#
13# Castellum is distributed in the hope that it will be useful, but
14# WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16# Affero General Public License for more details.
17#
18# You should have received a copy of the GNU Affero General Public
19# License along with Castellum. If not, see
20# <http://www.gnu.org/licenses/>.
22from django.conf import settings
23from django.db import models
25from castellum.contacts.models import Contact
26from castellum.recruitment import filter_queries
27from castellum.recruitment.models import ParticipationRequest
28from castellum.subjects.models import Subject
31def get_export_requested(limit_by):
32 subjects = Subject.objects.filter(export_requested__isnull=False).annotate(
33 due=models.ExpressionWrapper(
34 models.F('export_requested') + settings.CASTELLUM_SUBJECT_DELETION_PERIOD,
35 output_field=models.DateField(),
36 )
37 )
39 return subjects[:limit_by], max(subjects.count() - limit_by, 0)
42def get_to_be_deleted(limit_by):
43 subjects = Subject.objects.filter(to_be_deleted__isnull=False).annotate(
44 due=models.ExpressionWrapper(
45 models.F('to_be_deleted') + settings.CASTELLUM_SUBJECT_DELETION_PERIOD,
46 output_field=models.DateField(),
47 )
48 )
50 return subjects[:limit_by], max(subjects.count() - limit_by, 0)
53def get_no_legal_basis(limit_by):
54 # this query has the biggest potential to shrink down
55 # the number of matches, so it is done first
56 subjects = Subject.objects\
57 .annotate(pr_count=models.Count('participationrequest', filter=~models.Q(
58 participationrequest__status=ParticipationRequest.UNSUITABLE
59 )))\
60 .filter(~filter_queries.has_consent(include_waiting=True), pr_count=0)
61 subject_pks = subjects.values_list('pk', flat=True)
63 contacts = Contact.objects\
64 .annotate(guardian_of_count=models.Count('guardian_of'))\
65 .filter(guardian_of_count=0, subject_id__in=list(subject_pks))
67 subjects = Subject.objects.filter(filter_queries.pk_filter(contacts))
69 return subjects[:limit_by], max(subjects.count() - limit_by, 0)
72def get_unreachable(limit_by):
73 contacts = Contact.objects\
74 .annotate(guardian_count=models.Count('guardians'))\
75 .filter(
76 guardian_count=0,
77 address=None,
78 email='',
79 phone_number='',
80 )\
81 .order_by()
83 subjects = Subject.objects.filter(filter_queries.pk_filter(contacts))
85 return subjects[:limit_by], max(subjects.count() - limit_by, 0)
88def get_all_subjects(limit_by):
89 subjects = set()
90 missing = 0
91 for fn in [get_to_be_deleted, get_no_legal_basis, get_unreachable]:
92 s, m = fn(limit_by)
93 subjects.update(s)
94 missing += m
95 return subjects, missing