nanterre: améliore le passage à la majorité
- Les trames sont envoyés de manière différée pour ne pas ralentir le processus. - Le cas des enfants sans adresses ou avec deux adresses est pris en compte. - Un message particulier est envoyé dans le journal pour le processus de base et pour chaque trame, le message de base a été modifié pour comporter deux parties une fixe en fonction de l'action et un deuxième variable en fonction du statut.
This commit is contained in:
parent
ac5a8d103d
commit
c023fdc182
|
@ -1216,7 +1216,7 @@ def test_rsu_cron(db, settings, nanterre_classic_family):
|
|||
|
||||
assert Log.objects.count() == 20
|
||||
call_command('rsu-cron', verbosity=0)
|
||||
assert Log.objects.count() == 10
|
||||
assert Log.objects.count() == 11
|
||||
|
||||
|
||||
def test_passage_a_la_majorite(db, settings, nanterre_classic_family, freezer):
|
||||
|
@ -1241,6 +1241,21 @@ def test_passage_a_la_majorite(db, settings, nanterre_classic_family, freezer):
|
|||
# passage à la majorité de lilou
|
||||
requests = []
|
||||
|
||||
result = passage_a_la_majorite()
|
||||
|
||||
assert result['updated_entities'] == 1
|
||||
assert result['deleted_relations'] == 2
|
||||
assert Entity.objects.filter(schema__slug='individu').count() == 4
|
||||
assert Entity.objects.filter(schema__slug='adresse').count() == 2
|
||||
assert Relation.objects.filter(schema__slug='habite').count() == 4
|
||||
assert Relation.objects.filter(schema__slug='responsabilite-legale').count() == 2
|
||||
assert Entity.objects.filter(content__statut_legal='majeur').count() == 3
|
||||
assert Entity.objects.filter(content__prenoms='LILOU', content__statut_legal='majeur').count() == 1
|
||||
|
||||
assert Job.objects.count() == 1
|
||||
assert Job.objects.todo().count() == 1
|
||||
assert len(requests) == 0
|
||||
|
||||
@httmock.urlmatch()
|
||||
def technocarte_ok(url, request):
|
||||
requests.append(request)
|
||||
|
@ -1250,19 +1265,9 @@ def test_passage_a_la_majorite(db, settings, nanterre_classic_family, freezer):
|
|||
'Content-Type': 'application/json',
|
||||
})
|
||||
with httmock.HTTMock(technocarte_ok):
|
||||
result = passage_a_la_majorite()
|
||||
|
||||
assert result['updated_entities'] == 1
|
||||
assert result['deleted_relations'] == 2
|
||||
assert not result['errors']
|
||||
assert Entity.objects.filter(schema__slug='individu').count() == 4
|
||||
assert Entity.objects.filter(schema__slug='adresse').count() == 2
|
||||
assert Relation.objects.filter(schema__slug='habite').count() == 4
|
||||
assert Relation.objects.filter(schema__slug='responsabilite-legale').count() == 2
|
||||
assert Entity.objects.filter(content__statut_legal='majeur').count() == 3
|
||||
assert Entity.objects.filter(content__prenoms='LILOU', content__statut_legal='majeur').count() == 1
|
||||
|
||||
Job.redo(timestamp=now() + datetime.timedelta(seconds=20))
|
||||
assert len(requests) == 1
|
||||
|
||||
req_content = json.loads(requests[0].body)
|
||||
assert req_content['metadonnees']['service'] == 'passage-majorite'
|
||||
assert len(req_content['fragments']) == 3
|
||||
|
@ -1282,7 +1287,6 @@ def test_passage_a_la_majorite(db, settings, nanterre_classic_family, freezer):
|
|||
result = passage_a_la_majorite()
|
||||
assert result['updated_entities'] == 0
|
||||
assert result['deleted_relations'] == 0
|
||||
assert not result['errors']
|
||||
assert Entity.objects.filter(content__statut_legal='majeur').count() == 3
|
||||
assert Entity.objects.filter(content__prenoms='LILOU', content__statut_legal='majeur').count() == 1
|
||||
|
||||
|
|
|
@ -210,15 +210,16 @@ class FragmentBuilder(object):
|
|||
state = self.handle_response(response, job=job)
|
||||
app_name = self.application['name']
|
||||
kwargs = {}
|
||||
message = self.journal_message
|
||||
if state == job.STATE_SUCCESS:
|
||||
message = u'Synchronisation réussie avec %s' % app_name
|
||||
# reset errors
|
||||
self.error = {}
|
||||
message += u': ok'
|
||||
elif state == Job.STATE_ERROR:
|
||||
message = u'Erreur temporaire de synchronisation avec %s' % app_name
|
||||
message += u': erreur temporaire'
|
||||
kwargs['error'] = self.error
|
||||
elif state == Job.STATE_UNRECOVERABLE_ERROR:
|
||||
message = u'Erreur irrécupérable de synchronisation avec %s' % app_name
|
||||
message += u': erreur irrécupérable'
|
||||
kwargs['error'] = self.error
|
||||
else:
|
||||
raise NotImplementedError
|
||||
|
@ -247,6 +248,11 @@ class FragmentBuilder(object):
|
|||
**kwargs)
|
||||
return state
|
||||
|
||||
@property
|
||||
def journal_message(self):
|
||||
app_name = self.application['name']
|
||||
return u'Synchronisation avec %s' % app_name
|
||||
|
||||
def to_json(self):
|
||||
s = {
|
||||
'application_id': self.application_id,
|
||||
|
@ -817,6 +823,7 @@ class SuppressionResponsabiliteEnfant(RelationSynchro):
|
|||
|
||||
|
||||
class PassageALaMajorite(RelationSynchro):
|
||||
# PassageALaMajorite does not send fragments immediatelly, it's special
|
||||
service = 'passage-majorite'
|
||||
|
||||
@classmethod
|
||||
|
@ -842,12 +849,8 @@ class PassageALaMajorite(RelationSynchro):
|
|||
def par_application(cls, application, individu, relations, meta=None, transaction=None):
|
||||
relations = [relation for relation in relations if cls.condition(application, relation)]
|
||||
action = cls.create(application, individu, relations, meta=meta)
|
||||
job = Job.create(action, transaction=transaction)
|
||||
if job.state != Job.STATE_SUCCESS:
|
||||
if action.human_result:
|
||||
yield action.human_result
|
||||
else:
|
||||
yield 'Erreur interne'
|
||||
# PassageALaMajorite does not send fragments immediatelly, it's special
|
||||
Job.create(action, do_later=True, transaction=transaction)
|
||||
|
||||
@classmethod
|
||||
def pour_chaque_application(cls, individu, relations, meta=None, transaction=None):
|
||||
|
@ -855,7 +858,11 @@ class PassageALaMajorite(RelationSynchro):
|
|||
for application in utils.get_applications(rsu_ws_url=True):
|
||||
if application not in individu.content['cles_de_federation']:
|
||||
continue
|
||||
for message in cls.par_application(application, individu, relations, meta=meta,
|
||||
transaction=transaction):
|
||||
yield message
|
||||
return list(helper())
|
||||
cls.par_application(application, individu, relations,
|
||||
meta=meta, transaction=transaction)
|
||||
helper()
|
||||
|
||||
@property
|
||||
def journal_message(self):
|
||||
app_name = self.application['name']
|
||||
return u'Passage à la majorité sur %s' % app_name
|
||||
|
|
|
@ -45,11 +45,11 @@ class Command(BaseCommand):
|
|||
print('Suppression de %d entrées du journal.' % count)
|
||||
|
||||
def passage_a_la_majorite(self):
|
||||
with transaction.atomic():
|
||||
result = passage_a_la_majorite()
|
||||
result = passage_a_la_majorite()
|
||||
if result['errors'] and self.options['verbosity'] > 0:
|
||||
print('Mise à jour de %d enfants.' % result['updated_entities'])
|
||||
for individu in result['errors']:
|
||||
print('Erreur:', individu, result['errors'][individu])
|
||||
for error in result['errors'][individu]:
|
||||
print('Erreur:', 'individu %s' % individu.pk, error)
|
||||
elif result['updated_entities'] and self.options['verbosity'] > 1:
|
||||
print('Mise à jour de %d enfants.' % result['updated_entities'])
|
||||
|
|
|
@ -1284,14 +1284,21 @@ def csv_export_response(rows, filename):
|
|||
return r
|
||||
|
||||
|
||||
@transaction.atomic
|
||||
def passage_a_la_majorite():
|
||||
from . import fragments
|
||||
|
||||
transaction = Transaction.get_transaction()
|
||||
transaction.content = {
|
||||
'action': 'passage-a-la-majorite',
|
||||
}
|
||||
|
||||
entity_schema = EntitySchema.objects.get(slug=INDIVIDU_ENT)
|
||||
responsabilite_legale_schema = RelationSchema.objects.get(slug=RESPONSABILITE_LEGALE_REL)
|
||||
|
||||
non_majeurs = Entity.objects.filter(schema=entity_schema).exclude(content__statut_legal='majeur')
|
||||
birthdate_threshold = now().date() - relativedelta(years=18)
|
||||
transaction.content['birthdate_threshold'] = str(birthdate_threshold)
|
||||
non_majeurs_to_update = non_majeurs.filter(content__date_de_naissance__timestamp__lte=birthdate_threshold)
|
||||
updated_entities = non_majeurs_to_update.count()
|
||||
|
||||
|
@ -1300,6 +1307,8 @@ def passage_a_la_majorite():
|
|||
schema=responsabilite_legale_schema,
|
||||
right__in=non_majeurs_to_update))
|
||||
deleted_relations = len(relations_to_delete)
|
||||
schema_adresse = EntitySchema.objects.get(slug=ADRESSE_ENT)
|
||||
habite_schema = RelationSchema.objects.get(slug=HABITE_REL)
|
||||
|
||||
errors = {}
|
||||
# updating
|
||||
|
@ -1307,24 +1316,60 @@ def passage_a_la_majorite():
|
|||
individu.content['statut_legal'] = 'majeur'
|
||||
individu.save()
|
||||
# computing new adress, reusing first adresse
|
||||
new_adresse, new_adresse_rel = adresses(individu)[0]
|
||||
# delete link to old address
|
||||
new_adresse_rel.delete()
|
||||
# create new address
|
||||
new_adresse.pk = None
|
||||
new_adresse.save()
|
||||
assert new_adresse.pk
|
||||
# link new address to old mineur
|
||||
new_adresse_rel.pk = None
|
||||
new_adresse_rel.content['principale'] = False
|
||||
new_adresse_rel.right = new_adresse
|
||||
new_adresse_rel.save()
|
||||
adrs = adresses(individu)
|
||||
_parents = parents(individu)
|
||||
relations_parentales = [rel for parent, rel in _parents]
|
||||
journalize(
|
||||
individu,
|
||||
old_adresses=[adr[0].pk for adr in adrs],
|
||||
old_parents=[parent.pk for parent, rel in _parents],
|
||||
transaction=transaction,
|
||||
text=u'Passage à la majorité')
|
||||
if adrs:
|
||||
new_adresse, new_adresse_rel = adrs[0]
|
||||
# delete link to old addresses
|
||||
for _0, rel in adrs:
|
||||
rel.delete()
|
||||
# create new address
|
||||
new_adresse.pk = None
|
||||
new_adresse.created = transaction
|
||||
new_adresse.save()
|
||||
assert new_adresse.pk
|
||||
# link new address to old mineur
|
||||
new_adresse_rel.pk = None
|
||||
new_adresse_rel.created = transaction
|
||||
new_adresse_rel.content['principale'] = False
|
||||
new_adresse_rel.right = new_adresse
|
||||
new_adresse_rel.save()
|
||||
else:
|
||||
# set unknown address
|
||||
new_adresse = Entity.objects.create(
|
||||
schema=schema_adresse,
|
||||
created=transaction,
|
||||
content={
|
||||
"at": "",
|
||||
"city": "NANTERRE",
|
||||
"ext1": "",
|
||||
"ext2": "",
|
||||
"country": "FR",
|
||||
"zipcode": "92000",
|
||||
"inseecode": "92050",
|
||||
"streetname": "VOIE INCONNUE",
|
||||
"streetnumber": "0",
|
||||
"streetnumberext": "",
|
||||
"streetmatriculation": ""
|
||||
})
|
||||
new_adresse_rel = Relation(
|
||||
created=transaction,
|
||||
left=individu,
|
||||
right=new_adresse,
|
||||
schema=habite_schema,
|
||||
content={
|
||||
'principale': False,
|
||||
})
|
||||
assert len(adresses(individu)) == 1
|
||||
relations_parentales = [rel for parent, rel in parents(individu)]
|
||||
# launch messages to applications
|
||||
messages = fragments.PassageALaMajorite.pour_chaque_application(individu, relations_parentales)
|
||||
if messages:
|
||||
errors[individu] = messages
|
||||
fragments.PassageALaMajorite.pour_chaque_application(individu, relations_parentales)
|
||||
|
||||
# delete relations
|
||||
for relation in relations_to_delete:
|
||||
|
@ -1333,8 +1378,12 @@ def passage_a_la_majorite():
|
|||
# we cannot delete relation if no entity is updated
|
||||
assert updated_entities or (not deleted_relations)
|
||||
|
||||
return {
|
||||
result = transaction.content['result'] = {
|
||||
'updated_entities': updated_entities,
|
||||
'deleted_relations': deleted_relations,
|
||||
'errors': errors,
|
||||
}
|
||||
|
||||
transaction.save()
|
||||
|
||||
return result
|
||||
|
|
Loading…
Reference in New Issue