toulouse-maelis: trigger wcs when basket subscription is cancelled (#76398)

This commit is contained in:
Nicolas Roche 2023-04-26 21:54:18 +02:00 committed by Nicolas Roche
parent 0276de78c2
commit 347d09db89
2 changed files with 203 additions and 3 deletions

View File

@ -3833,6 +3833,7 @@ class ToulouseMaelis(BaseResource, HTTPResource):
maelis_data_update_date=now(),
)
self.logger.info("Ajout de %s sur la famille '%s'", repr(invoice), family_id)
invoice.match_subscriptions()
return {'data': response}
@endpoint(
@ -4361,6 +4362,30 @@ class Invoice(models.Model):
obj.save()
return True
def match_subscriptions(self):
invoice_subscription_ids = []
for line in self.maelis_data['lineInvoiceList'] or []:
subscription_id = line.get('idIns')
if subscription_id:
invoice_subscription_ids.append(subscription_id)
if not invoice_subscription_ids:
return
for subscription in Subscription.objects.filter(
regie_id=self.regie_id, family_id=self.family_id, invoice__isnull=True
):
for line in subscription.maelis_data['basket']['lignes']:
subscription_id = line.get('idIns')
if subscription_id and subscription_id in invoice_subscription_ids:
subscription.invoice = self
subscription.save()
break
def set_trigger_subscriptions(self):
for subscription in self.subscription_set.filter(wcs_trigger_payload__isnull=True):
if subscription.trigger_status() == 'triggering':
subscription.set_trigger()
@transaction.atomic
def cancel(self):
obj = Invoice.objects.select_for_update().get(pk=self.pk)
@ -4377,6 +4402,9 @@ class Invoice(models.Model):
obj.maelis_cancel_notification_date = now()
obj.save()
obj.resource.logger.info("Annulation de %s sur la famille '%s'", repr(obj), obj.family_id)
# match cancelled invoice with subscriptions and trigger w.c.s.
obj.set_trigger_subscriptions()
return True
class Meta:
@ -4406,7 +4434,12 @@ class Subscription(models.Model):
def status(self):
if self.invoice is not None:
pass
if self.invoice.status() == 'cancelled':
# related invoice is cancelled
return 'cancelled'
else:
# there is a related invoice
return 'pending_invoice'
else:
if self.basket_removal_date is not None:
# no basket validation (no related invoice generated)
@ -4419,7 +4452,7 @@ class Subscription(models.Model):
if self.wcs_trigger_date is not None:
# wcs demand was triggered
return 'triggered'
if self.status() in ['removed']:
if self.status() in ['cancelled', 'removed']:
# wcs demand can be triggered
return 'triggering'
else:
@ -4432,7 +4465,7 @@ class Subscription(models.Model):
if self.wcs_trigger_payload:
return
self.wcs_trigger_payload = {
'err': 1 if self.status() in ['removed'] else 0,
'err': 1 if self.status() in ['cancelled', 'removed'] else 0,
'data': {
'regie_id': self.regie_id,
'regie_text': self.resource.get_referential_value('Regie', self.regie_id),
@ -4446,6 +4479,8 @@ class Subscription(models.Model):
}
if self.status() == 'removed':
self.wcs_trigger_payload['err_desc'] = "Le panier n'a pas été validé"
if self.status() == 'cancelled':
self.wcs_trigger_payload['err_desc'] = "La facture a été annulée"
self.save()
self.resource.add_job(
'trigger_subscription_job',

View File

@ -10149,6 +10149,171 @@ def test_invoice_pdf_error(invoice_service, con, app):
assert resp.json['err_desc'] == 'Fichier PDF non trouvé'
def test_trigger_wcs_on_cancelled_subscriptions_cron(
family_service, activity_service, wcs_service, con, app, freezer, caplog
):
family_service.add_soap_response('readFamily', get_xml_file('R_read_family_for_subscription.xml'))
activity_service.add_soap_response('getPersonUnitInfo', get_xml_file('R_get_person_unit_info.xml'))
activity_service.add_soap_response('addPersonUnitBasket', get_xml_file('R_add_person_unit_basket.xml'))
activity_service.add_soap_response('getFamilyBasket', get_xml_file('R_get_family_basket.xml'))
activity_service.add_soap_response('validateBasket', get_xml_file('R_validate_basket.xml'))
activity_service.add_soap_response(
'cancelInvoiceAndDeleteSubscribeList',
get_xml_file('R_cancel_invoice_and_delete_subscribe_list.xml'),
)
wcs_service.add(
responses.POST,
'https://wcs.example.com/api/forms/exemple-inscription-loisirs-1/12/hooks/update_subscription/',
json={'err': 0},
status=200,
)
Link.objects.create(resource=con, family_id='1312', name_id='local')
# subscribe providing a wcs demand
freezer.move_to('2023-03-03 18:20:00')
resp = app.post_json(
get_endpoint('add-person-basket-subscription') + '?NameID=local',
params={
'person_id': '266145',
'activity_id': 'A10053179798',
'unit_id': 'A10053179809',
'place_id': 'A10053179757',
'start_date': '2023-02-01',
'end_date': '2023-06-30',
'form_api_url': 'https://wcs.example.com/api/forms/exemple-inscription-loisirs-1/12/',
'form_number': '13-12',
},
)
assert resp.json['err'] == 0
subscription = con.subscription_set.get(wcs_form_number='13-12')
assert subscription.status() == 'pending_basket'
assert [x['idIns'] for x in subscription.maelis_data['basket']['lignes']] == ['S10055641658']
# validate basket
freezer.move_to('2023-03-03 18:30:00')
resp = app.post_json(
get_endpoint('validate-basket') + '?NameID=local', params={'basket_id': 'S10055641661'}
)
assert resp.json['err'] == 0
invoice = con.invoice_set.get(regie_id=109, invoice_id=18)
assert invoice.status() == 'created'
assert 'S10055641658' in [x['idIns'] for x in invoice.maelis_data['lineInvoiceList']]
subscription = con.subscription_set.get(wcs_form_number='13-12')
assert subscription.status() == 'pending_invoice'
# send invoice cancellation order to maelis and trigger wcs
freezer.move_to('2023-03-03 19:20:00')
con.hourly()
invoice = con.invoice_set.get(regie_id=109, invoice_id=18)
assert invoice.status() == 'cancelled'
assert (
'https://wcs.example.com/api/forms/exemple-inscription-loisirs-1/12/hooks/update_subscription/'
in wcs_service.calls[-1].request.url
)
trigger_body = json.loads(wcs_service.calls[-1].request.body)
assert trigger_body['err'] == 1
assert trigger_body['err_desc'] == "La facture a été annulée"
assert trigger_body['data']['subscription_status'] == 'cancelled'
assert trigger_body['data']['regie_text'] == 'DSBL'
assert any(['trigger wcs' in x.message for x in caplog.records])
subscription = con.subscription_set.get(wcs_form_number='13-12')
assert subscription.trigger_status() == 'triggered'
def test_trigger_wcs_on_cancelled_subscriptions_job(
family_service, activity_service, wcs_service, con, app, freezer, caplog
):
family_service.add_soap_response('readFamily', get_xml_file('R_read_family_for_subscription.xml'))
activity_service.add_soap_response('getPersonUnitInfo', get_xml_file('R_get_person_unit_info.xml'))
activity_service.add_soap_response('addPersonUnitBasket', get_xml_file('R_add_person_unit_basket.xml'))
activity_service.add_soap_response('getFamilyBasket', get_xml_file('R_get_family_basket.xml'))
activity_service.add_soap_response('validateBasket', get_xml_file('R_validate_basket.xml'))
activity_service.add_soap_response(
'cancelInvoiceAndDeleteSubscribeList',
get_xml_file('R_cancel_invoice_and_delete_subscribe_list.xml'),
)
wcs_service.add(
responses.POST,
'https://wcs.example.com/api/forms/exemple-inscription-loisirs-1/12/hooks/update_subscription/',
json={'err': 0},
status=200,
)
Link.objects.create(resource=con, family_id='1312', name_id='local')
# subscribe providing a wcs demand
freezer.move_to('2023-03-03 18:20:00')
resp = app.post_json(
get_endpoint('add-person-basket-subscription') + '?NameID=local',
params={
'person_id': '266145',
'activity_id': 'A10053179798',
'unit_id': 'A10053179809',
'place_id': 'A10053179757',
'start_date': '2023-02-01',
'end_date': '2023-06-30',
'form_api_url': 'https://wcs.example.com/api/forms/exemple-inscription-loisirs-1/12/',
'form_number': '13-12',
},
)
assert resp.json['err'] == 0
subscription = con.subscription_set.get(wcs_form_number='13-12')
assert subscription.status() == 'pending_basket'
assert [x['idIns'] for x in subscription.maelis_data['basket']['lignes']] == ['S10055641658']
# validate basket
freezer.move_to('2023-03-03 18:30:00')
resp = app.post_json(
get_endpoint('validate-basket') + '?NameID=local', params={'basket_id': 'S10055641661'}
)
assert resp.json['err'] == 0
invoice = con.invoice_set.get(regie_id=109, invoice_id=18)
assert invoice.status() == 'created'
assert 'S10055641658' in [x['idIns'] for x in invoice.maelis_data['lineInvoiceList']]
subscription = con.subscription_set.get(wcs_form_number='13-12')
assert subscription.status() == 'pending_invoice'
# send invoice cancellation order to maelis (side effect of get-basket)
freezer.move_to('2023-03-03 19:20:00')
resp = app.get(get_endpoint('get-baskets') + '?NameID=local')
assert resp.json['err'] == 0
invoice = con.invoice_set.get(regie_id=109, invoice_id=18)
assert invoice.status() == 'cancelled'
subscription = con.subscription_set.get(wcs_form_number='13-12')
assert subscription.trigger_status() == 'triggering'
job = Job.objects.get(method_name='trigger_subscription_job', natural_id='13-12/%s' % subscription.pk)
assert job.status == 'registered'
# send invoice cancellation order to maelis and trigger wcs
con.jobs()
assert (
'https://wcs.example.com/api/forms/exemple-inscription-loisirs-1/12/hooks/update_subscription/'
in wcs_service.calls[-1].request.url
)
trigger_body = json.loads(wcs_service.calls[-1].request.body)
assert trigger_body['err'] == 1
assert trigger_body['err_desc'] == "La facture a été annulée"
assert trigger_body['data']['subscription_status'] == 'cancelled'
assert trigger_body['data']['regie_text'] == 'DSBL'
assert any(['trigger wcs' in x.message for x in caplog.records])
job = Job.objects.get(method_name='trigger_subscription_job', natural_id='13-12/%s' % subscription.pk)
assert job.status == 'completed'
subscription = con.subscription_set.get(wcs_form_number='13-12')
assert subscription.trigger_status() == 'triggered'
def test_trigger_wcs_on_removed_subscriptions_cron(
family_service, activity_service, wcs_service, con, app, freezer, caplog
):