diff --git a/speid/helpers/callback_helper.py b/speid/helpers/callback_helper.py index 1dba6545..465fde0c 100644 --- a/speid/helpers/callback_helper.py +++ b/speid/helpers/callback_helper.py @@ -1,6 +1,5 @@ import base64 import os -from typing import Optional from celery import Celery @@ -20,18 +19,12 @@ def auth_header(username: str, password: str) -> dict: def set_status_transaction( speid_id: str, state: str, - curp: Optional[str] = None, - rfc: Optional[str] = None, - nombre_beneficiario: Optional[str] = None, ) -> None: queue.send_task( SEND_STATUS_TRANSACTION_TASK, kwargs=dict( speid_id=speid_id, state=state, - rfc=rfc, - curp=curp, - nombre_beneficiario=nombre_beneficiario, ), ) diff --git a/speid/models/transaction.py b/speid/models/transaction.py index ee51af79..4d3c3ae1 100644 --- a/speid/models/transaction.py +++ b/speid/models/transaction.py @@ -26,6 +26,7 @@ from speid.processors import stpmex_client from speid.types import Estado, EventType, TipoTransaccion +from ..helpers.callback_helper import set_status_transaction from .account import Account from .base import BaseModel from .events import Event @@ -131,12 +132,9 @@ class Transaction(Document, BaseModel): } def set_state(self, state: Estado): - from ..tasks.transactions import send_transaction_status - - send_transaction_status.apply_async((str(self.id), state)) self.estado = state - self.events.append(Event(type=EventType.completed)) + set_status_transaction(self.speid_id, state) def confirm_callback_transaction(self): response = '' diff --git a/speid/tasks/transactions.py b/speid/tasks/transactions.py index b60f0909..39e353a3 100644 --- a/speid/tasks/transactions.py +++ b/speid/tasks/transactions.py @@ -1,22 +1,11 @@ from typing import List -import cep -import pytz -from cep.exc import CepError, MaxRequestError from mongoengine import DoesNotExist -from stpmex.business_days import current_cdmx_time_zone -from speid.helpers import callback_helper -from speid.models import Account, Event, Transaction +from speid.models import Event, Transaction from speid.tasks import celery from speid.types import Estado, EventType -CURP_LENGTH = 18 -RFC_LENGTH = 13 -STP_BANK_CODE = 90646 -GET_RFC_TASK_MAX_RETRIES = 7 # reintentos -GET_RFC_TASK_DELAY = 4 # Segundos - @celery.task def retry_incoming_transactions(speid_ids: List[str]) -> None: @@ -56,68 +45,3 @@ def process_outgoing_transactions(self, transactions: list): Event(type=event_type, metadata=str('Reversed by recon task')) ) transaction.save() - - -@celery.task(bind=True, max_retries=GET_RFC_TASK_MAX_RETRIES) -def send_transaction_status(self, transaction_id: str, state: str) -> None: - try: - transaction = Transaction.objects.get(id=transaction_id) - except DoesNotExist: - return - - account = Account.objects.get(cuenta=transaction.cuenta_ordenante) - rfc = None - curp = None - nombre_beneficiario = None - - if account.is_restricted: - cdmx_tz = current_cdmx_time_zone(transaction.created_at) - - created_at_utc = transaction.created_at.replace(tzinfo=pytz.utc) - transaction_local_time = created_at_utc.astimezone( - pytz.timezone(cdmx_tz) - ) - - rfc_curp = None - - try: - transferencia = cep.Transferencia.validar( - fecha=transaction_local_time.date(), - clave_rastreo=transaction.clave_rastreo, - emisor=str(STP_BANK_CODE), - receptor=transaction.institucion_beneficiaria, - cuenta=transaction.cuenta_beneficiario, - monto=transaction.monto / 100, - ) - assert transferencia is not None - except MaxRequestError: - rfc_curp = 'max retries' - except CepError: - self.retry(countdown=GET_RFC_TASK_DELAY) - except AssertionError: - rfc_curp = None - else: - rfc_curp = str(transferencia.beneficiario.rfc) - nombre_beneficiario = transferencia.beneficiario.nombre - - if len(rfc_curp) == CURP_LENGTH: - curp = rfc_curp - transaction.rfc_curp_beneficiario = rfc_curp - transaction.save() - elif len(rfc_curp) == RFC_LENGTH: - rfc = rfc_curp - transaction.rfc_curp_beneficiario = rfc_curp - transaction.save() - else: - rfc_curp = None - curp = None - rfc = None - - # Si no se pudo obtener el RFC o CURP de ninguna fuente se reintenta - # en 5 segundos - if not rfc_curp and self.request.retries < GET_RFC_TASK_MAX_RETRIES: - self.retry(countdown=GET_RFC_TASK_DELAY) - - callback_helper.set_status_transaction( - transaction.speid_id, state, curp, rfc, nombre_beneficiario - ) diff --git a/tests/tasks/test_transactions.py b/tests/tasks/test_transactions.py index 9ad8caf8..38429566 100644 --- a/tests/tasks/test_transactions.py +++ b/tests/tasks/test_transactions.py @@ -2,19 +2,14 @@ from unittest.mock import patch import pytest -from celery.exceptions import Retry -from cep.exc import CepError, MaxRequestError from speid.models import Transaction from speid.tasks.transactions import ( - GET_RFC_TASK_MAX_RETRIES, process_outgoing_transactions, retry_incoming_transactions, - send_transaction_status, ) from speid.types import Estado, EventType from speid.validations import SpeidTransaction -from tests.conftest import SEND_STATUS_TRANSACTION_TASK @pytest.fixture @@ -160,223 +155,3 @@ def test_outgoing_transaction_retry_core( ) as method_mock: retry_incoming_transactions(speid_ids=[speid_id]) method_mock.assert_called_once() - - -@patch('celery.Celery.send_task') -@pytest.mark.vcr -def test_send_transaction_restricted_accounts_retry_task( - mock_send_task, outcome_transaction, moral_account, orden_pago -): - - outcome_transaction.institucion_beneficiaria = '40012' - outcome_transaction.clave_rastreo = 'CUENCA954881386502' - outcome_transaction.cuenta_ordenante = '646180157016683211' - outcome_transaction.cuenta_beneficiario = '012180015839965374' - outcome_transaction.created_at = dt.datetime(2022, 4, 12, 20, 31) - outcome_transaction.save() - - moral_account.cuenta = '646180157016683211' - moral_account.is_restricted = True - moral_account.save() - - with pytest.raises(Retry): - send_transaction_status(outcome_transaction.id, Estado.rejected) - - mock_send_task.assert_not_called() - - -@patch('celery.Celery.send_task') -@pytest.mark.vcr -def test_send_transaction_restricted_accounts_info_from_cep( - mock_send_task, outcome_transaction, moral_account, orden_pago -): - - outcome_transaction.institucion_beneficiaria = '40012' - outcome_transaction.clave_rastreo = orden_pago['ordenPago']['claveRastreo'] - outcome_transaction.cuenta_beneficiario = '012180015025335996' - outcome_transaction.created_at = dt.datetime(2022, 4, 6, 23, 19) - outcome_transaction.save() - - moral_account.is_restricted = True - moral_account.save() - - send_transaction_status(outcome_transaction.id, Estado.succeeded) - - mock_send_task.assert_called_with( - SEND_STATUS_TRANSACTION_TASK, - kwargs=dict( - speid_id=outcome_transaction.speid_id, - state=Estado.succeeded.value, - rfc='MAVM901122UK9', - curp=None, - nombre_beneficiario='MANUEL ALEJANDRO MARTINEZ VIQUEZ', - ), - ) - - -@patch('celery.Celery.send_task') -@pytest.mark.vcr -def test_send_transaction_restricted_accounts_curp_from_cep( - mock_send_task, outcome_transaction, moral_account, orden_pago -): - - outcome_transaction.institucion_beneficiaria = '40012' - outcome_transaction.clave_rastreo = 'CUENCA22026847429' - outcome_transaction.cuenta_beneficiario = '012180015328558878' - outcome_transaction.created_at = dt.datetime(2022, 4, 20, 2, 33) - outcome_transaction.monto = 1 - outcome_transaction.save() - - moral_account.is_restricted = True - moral_account.save() - - send_transaction_status(outcome_transaction.id, Estado.succeeded) - - mock_send_task.assert_called_with( - SEND_STATUS_TRANSACTION_TASK, - kwargs=dict( - speid_id=outcome_transaction.speid_id, - state=Estado.succeeded.value, - rfc=None, - curp='AOVM910106HCSPRL05', - nombre_beneficiario='MIGUEL ACOSTA VENTURA', - ), - ) - - -@patch('celery.Celery.send_task') -def test_send_transaction_restricted_accounts_retry_task_on_cep_error( - mock_send_task, outcome_transaction, moral_account -): - moral_account.is_restricted = True - moral_account.save() - - with patch('cep.Transferencia.validar', side_effect=CepError): - with pytest.raises(Retry): - send_transaction_status(outcome_transaction.id, Estado.rejected) - - mock_send_task.assert_not_called() - - -@patch('celery.Celery.send_task') -def test_send_transaction_status_does_not_retry_task_on_max_retries( - mock_send_task, outcome_transaction, moral_account -): - moral_account.is_restricted = True - moral_account.save() - - with patch('cep.Transferencia.validar', side_effect=MaxRequestError): - send_transaction_status(outcome_transaction.id, Estado.succeeded) - - mock_send_task.assert_called_with( - SEND_STATUS_TRANSACTION_TASK, - kwargs=dict( - speid_id=outcome_transaction.speid_id, - state=Estado.succeeded.value, - rfc=None, - curp=None, - nombre_beneficiario=None, - ), - ) - - -@patch( - 'speid.tasks.transactions.send_transaction_status.request.retries', - GET_RFC_TASK_MAX_RETRIES, -) -@patch('celery.Celery.send_task') -@pytest.mark.vcr -def test_send_transaction_restricted_accounts_send_status_on_last_retry_task( - mock_send_task, outcome_transaction, moral_account -): - - outcome_transaction.institucion_beneficiaria = '40012' - outcome_transaction.clave_rastreo = 'CUENCA954881386502' - outcome_transaction.cuenta_ordenante = '646180157016683211' - outcome_transaction.cuenta_beneficiario = '012180015839965374' - outcome_transaction.created_at = dt.datetime(2022, 4, 12, 20, 31) - outcome_transaction.save() - - moral_account.cuenta = '646180157016683211' - moral_account.is_restricted = True - moral_account.save() - - send_transaction_status(outcome_transaction.id, Estado.succeeded) - - mock_send_task.assert_called_with( - SEND_STATUS_TRANSACTION_TASK, - kwargs=dict( - speid_id=outcome_transaction.speid_id, - state=Estado.succeeded.value, - rfc=None, - curp=None, - nombre_beneficiario='MANUEL AVALOS TOVAR', - ), - ) - - -@patch('celery.Celery.send_task') -@pytest.mark.vcr -def test_send_transaction_restricted_accounts_cep_not_found( - mock_send_task, outcome_transaction, moral_account -): - - outcome_transaction.institucion_beneficiaria = '40012' - outcome_transaction.clave_rastreo = 'CUENCA954881386503' - outcome_transaction.cuenta_ordenante = '646180157016683211' - outcome_transaction.cuenta_beneficiario = '012180015839965344' - outcome_transaction.created_at = dt.datetime(2022, 4, 12, 20, 31) - outcome_transaction.save() - - moral_account.cuenta = '646180157016683211' - moral_account.is_restricted = True - moral_account.save() - - with pytest.raises(Retry): - send_transaction_status(outcome_transaction.id, Estado.succeeded) - - mock_send_task.assert_not_called() - - -@patch('celery.Celery.send_task') -def test_send_transaction_restricted_transaction_does_not_exist( - mock_send_task, -): - send_transaction_status('624f53b45809fa4d49258a57', Estado.failed) - mock_send_task.assert_not_called() - - -@patch('celery.Celery.send_task') -def test_send_transaction_not_restricted_accounts( - mock_send_task, outcome_transaction, moral_account -): - send_transaction_status(outcome_transaction.id, Estado.succeeded) - - outcome_transaction.reload() - mock_send_task.assert_called_with( - SEND_STATUS_TRANSACTION_TASK, - kwargs=dict( - speid_id=outcome_transaction.speid_id, - state=Estado.succeeded.value, - rfc=None, - curp=None, - nombre_beneficiario=None, - ), - ) - - -@patch('celery.Celery.send_task') -def test_send_transaction_not_restricted_accounts_persona_fisica( - mock_send_task, outcome_transaction, physical_account -): - send_transaction_status(outcome_transaction.id, Estado.succeeded) - mock_send_task.assert_called_with( - SEND_STATUS_TRANSACTION_TASK, - kwargs=dict( - speid_id=outcome_transaction.speid_id, - state=Estado.succeeded.value, - rfc=None, - curp=None, - nombre_beneficiario=None, - ), - )