Merge branch 'master' into nanterre-recette
This commit is contained in:
commit
42f324b8a2
|
@ -956,6 +956,34 @@ def test_cles_de_federations(app, rsu_schema):
|
|||
assert Entity.objects.filter(content__cles_de_federation__technocarte='idtechno').count() == 1
|
||||
assert Entity.objects.filter(content__cles_de_federation__technocarte='idtechno').get().id == first_id
|
||||
|
||||
# suppression d'un individu
|
||||
suppression_url = reverse('rsu-api-suppression-individu', kwargs={
|
||||
'identifier': first_id})
|
||||
response = app.post(suppression_url)
|
||||
# impossible il y a toujours une clé
|
||||
assert response.json['err'] == 1
|
||||
assert len(response.json['errors']) == 1
|
||||
# on supprimer la clé technocarte
|
||||
response = app.post_json(update_url, params={
|
||||
'cles_de_federation': {
|
||||
'technocarte': ''
|
||||
},
|
||||
})
|
||||
entities = Entity.objects.all()
|
||||
relations = Relation.objects.all()
|
||||
# on a initialement 2 individus avec 2 adresses
|
||||
assert entities.count() == 4
|
||||
# on retente
|
||||
response = app.post(suppression_url)
|
||||
# c'est ok
|
||||
assert response.json['err'] == 0
|
||||
# on vérifie qu'il n'y a plus qu'une fiche et qu'une adresse et qu'ils sont liés
|
||||
assert entities.filter(schema__slug='individu').count() == 1
|
||||
assert entities.filter(id=second_id).count() == 1
|
||||
assert entities.filter(schema__slug='adresse').count() == 1
|
||||
assert relations.count() == 1
|
||||
assert relations.filter(left__id=second_id, schema__slug='habite').count() == 1
|
||||
|
||||
|
||||
def test_separation(db, app, rsu_schema):
|
||||
# création du premier adulte
|
||||
|
@ -1039,6 +1067,23 @@ def test_separation(db, app, rsu_schema):
|
|||
assert get_individu_adresse(second_adult) == second_adult_address
|
||||
assert Entity.objects.filter(id=first_adult_address.id).count() == 0
|
||||
|
||||
# on ne peut supprimer aucun des deux
|
||||
suppression_url = reverse('rsu-api-suppression-individu', kwargs={
|
||||
'identifier': first_adult_id})
|
||||
response = app.post(suppression_url)
|
||||
# impossible il y a une union
|
||||
assert response.json['err'] == 1
|
||||
assert len(response.json['errors']) == 1
|
||||
assert 'conjoint' in response.json['errors'][0]
|
||||
suppression_url = reverse('rsu-api-suppression-individu', kwargs={
|
||||
'identifier': second_adult_id})
|
||||
response = app.post(suppression_url)
|
||||
# impossible il y a une union
|
||||
assert response.json['err'] == 1
|
||||
assert response.json['err'] == 1
|
||||
assert len(response.json['errors']) == 1
|
||||
assert 'conjoint' in response.json['errors'][0]
|
||||
|
||||
# rattachement du premier enfant au premier adulte
|
||||
enfant_url = reverse('rsu-api-declaration-responsabilite-legale',
|
||||
kwargs={'identifier': first_adult_id})
|
||||
|
@ -1062,6 +1107,24 @@ def test_separation(db, app, rsu_schema):
|
|||
first_child = Entity.objects.get(id=first_child_id)
|
||||
assert get_individu_adresse(first_child) == second_adult_address
|
||||
|
||||
# on ne peut supprimer le parent, il a un enfant et un conjoint
|
||||
suppression_url = reverse('rsu-api-suppression-individu', kwargs={
|
||||
'identifier': first_adult_id})
|
||||
response = app.post(suppression_url)
|
||||
# impossible il y a une union
|
||||
assert response.json['err'] == 1
|
||||
assert len(response.json['errors']) == 2
|
||||
assert 'enfant' in response.json['errors'][0]
|
||||
assert 'conjoint' in response.json['errors'][1]
|
||||
# on ne peut supprimer l'enfant, il a un parent
|
||||
suppression_url = reverse('rsu-api-suppression-individu', kwargs={
|
||||
'identifier': first_child_id})
|
||||
response = app.post(suppression_url)
|
||||
# impossible il y a une union
|
||||
assert response.json['err'] == 1
|
||||
assert len(response.json['errors']) == 1
|
||||
assert 'avec un parent' in response.json['errors'][0]
|
||||
|
||||
# rattachement du premier enfant au deuxième adulte
|
||||
enfant_url = reverse('rsu-api-declaration-responsabilite-legale',
|
||||
kwargs={'identifier': second_adult_id})
|
||||
|
|
|
@ -52,6 +52,17 @@ def test_list_doublons(nanterre_classic_family, app):
|
|||
first_data = response.json['data'][0]
|
||||
second_data = response.json['data'][1]
|
||||
|
||||
url = reverse('rsu-api-doublons') + '?score_min=90&limit=100'
|
||||
response = app.get(url)
|
||||
assert response.json['err'] == 0
|
||||
assert 'more' not in response.json
|
||||
assert 'cookie' not in response.json
|
||||
assert len(response.json['data']) == 23 # Duplicate.objects.filter(score__gte=Decimal('0.9')).count()
|
||||
for doublon in response.json['data']:
|
||||
assert int(doublon['score']) >= 90
|
||||
assert response.json['score_min'] == '90'
|
||||
assert 'score_max' not in response.json
|
||||
|
||||
doublon_url = reverse('rsu-api-doublon', kwargs={'doublon_id': '%s %s' % (d.first_id,
|
||||
d.second_id)})
|
||||
response = app.get(doublon_url)
|
||||
|
|
|
@ -24,6 +24,7 @@ import time
|
|||
import traceback
|
||||
from dateutil.relativedelta import relativedelta
|
||||
import datetime
|
||||
from decimal import Decimal, InvalidOperation
|
||||
|
||||
from django.conf import settings
|
||||
from django.shortcuts import get_object_or_404
|
||||
|
@ -1393,6 +1394,51 @@ class Synchronisation(TransactionalView):
|
|||
synchronization = Synchronisation.as_view()
|
||||
|
||||
|
||||
class SuppressionIndividu(IndividuViewMixin, TransactionalView):
|
||||
def post(self, request, identifier, format=None):
|
||||
individu = self.get_individu(identifier)
|
||||
|
||||
# vérifie l'absence de relation et de fédérations
|
||||
errors = []
|
||||
parent_count = len(list(utils.parents(individu)))
|
||||
if parent_count:
|
||||
errors.append(u'cet individu a encore %d lien(s) avec un parent' % parent_count)
|
||||
enfant_count = len(list(utils.enfants(individu)))
|
||||
if enfant_count:
|
||||
errors.append(u'cet individu a encore %d lien(s) avec un enfant' % enfant_count)
|
||||
conjoint, rel = utils.conjoint(individu)
|
||||
if conjoint:
|
||||
errors.append(u'cet individu a un conjoint')
|
||||
uuid_authentic = None
|
||||
for application in individu.content['cles_de_federation']:
|
||||
if application == 'authentic':
|
||||
uuid_authentic = individu.content['cles_de_federation']['authentic']
|
||||
else:
|
||||
errors.append(u'cet individu a encore une clé de fédération avec %s' % application)
|
||||
|
||||
if errors:
|
||||
return Response({
|
||||
'err': 1,
|
||||
'errors': errors,
|
||||
})
|
||||
|
||||
adresses = utils.adresses(individu)
|
||||
individu.delete()
|
||||
# supprimer les adresses orphelines
|
||||
for adresse, rel in adresses:
|
||||
# left_relations ne devrait pas exister, mais dans le doute...
|
||||
if not adresse.right_relations.exists() and not adresse.left_relations.exists():
|
||||
adresse.delete()
|
||||
response = {'err': 0}
|
||||
if uuid_authentic:
|
||||
response['cles_de_federation'] = {'authentic': uuid_authentic}
|
||||
response['messages'] = [u'cette fiche avait une clé de fédération sur le portail '
|
||||
u'internet: %s' % uuid_authentic]
|
||||
return Response(response)
|
||||
|
||||
suppression_individu = SuppressionIndividu.as_view()
|
||||
|
||||
|
||||
class SagaTiers(APIView):
|
||||
def get(self, request, application, identifier, format=None):
|
||||
app_dfn = utils.get_application(application)
|
||||
|
@ -1845,6 +1891,21 @@ class DoublonsView(DoublonMixin, APIView):
|
|||
elif dedup:
|
||||
qs = qs.filter(state=models.Duplicate.STATE_DEDUP)
|
||||
|
||||
if 'score_min' in request.GET:
|
||||
try:
|
||||
score_min = Decimal(request.GET['score_min'])
|
||||
except InvalidOperation:
|
||||
pass
|
||||
else:
|
||||
qs = qs.filter(score__gte=score_min/100)
|
||||
if 'score_max' in request.GET:
|
||||
try:
|
||||
score_max = Decimal(request.GET['score_max'])
|
||||
except InvalidOperation:
|
||||
pass
|
||||
else:
|
||||
qs = qs.filter(score__lte=score_max/100)
|
||||
|
||||
# recherche ciblée
|
||||
if 'id' in request.GET:
|
||||
try:
|
||||
|
@ -1871,14 +1932,25 @@ class DoublonsView(DoublonMixin, APIView):
|
|||
'err': 0,
|
||||
'data': data[:limit],
|
||||
}
|
||||
|
||||
params = {'limit': limit}
|
||||
if 'score_min' in request.GET:
|
||||
params['score_min'] = request.GET['score_min']
|
||||
if 'score_max' in request.GET:
|
||||
params['score_max'] = request.GET['score_max']
|
||||
if false_positive:
|
||||
params['false_positive'] = false_positive
|
||||
if dedup:
|
||||
params['dedup'] = dedup
|
||||
content.update(params)
|
||||
|
||||
if len(data) > limit:
|
||||
since = qs[limit - 1].created.isoformat()
|
||||
max_id = qs[limit - 1].id
|
||||
more_url = request.build_absolute_uri(reverse('rsu-api-doublons'))
|
||||
cookie = '%s_%s' % (since, max_id)
|
||||
more_url += '?' + urlencode({'limit': limit, 'cookie': cookie})
|
||||
content['more'] = more_url
|
||||
content['cookie'] = cookie
|
||||
content['cookie'] = params['cookie'] = cookie
|
||||
content['more'] = request.build_absolute_uri(reverse('rsu-api-doublons')) + '?' + urlencode(params)
|
||||
|
||||
return Response(content)
|
||||
|
||||
doublons = DoublonsView.as_view()
|
||||
|
|
|
@ -25,6 +25,8 @@ urlpatterns = [
|
|||
url(r'^import_control/$', import_control, name='demo'),
|
||||
url(r'^search/$', api_views.search, name='rsu-api-search'),
|
||||
url(r'^individu/(?P<identifier>[-\w]+)/$', api_views.reseau, name='rsu-api-reseau'),
|
||||
url(r'^individu/(?P<identifier>[-\w]+)/suppression/$', api_views.suppression_individu,
|
||||
name='rsu-api-suppression-individu'),
|
||||
url(r'^individu/(?P<identifier>[-\w]+)/liste/$', api_views.reseau_liste,
|
||||
name='rsu-api-reseau-liste'),
|
||||
url(r'^individu/(?P<identifier>[-\w]+)/journal/$', api_views.journal, name='rsu-api-journal'),
|
||||
|
|
Loading…
Reference in New Issue