Example #1
0
        def wrapper(self, data):
            try:
                trigger = Trigger(**data['trigger'])
                workflow = Workflow(trigger=trigger).save()

                for data_step in data['steps']:
                    step = Step(**data_step)
                    workflow.steps.append(step)
                    workflow.save()
            except Exception:
                abort(500, description='Error procesando el archivo, por favor intente de nuevo.')

            self.workflow = workflow
            self.bank = BankService(workflow=self.workflow)

            return function(self)
Example #2
0
    def test_withdraw_no_funds(self):
        """Prueba que valída el método de retirar dinero de la cuenta de un usuario sin fondos suficientes."""
        mock_workflow = Mock(pk=12345)
        user = User.objects().first()
        money = 200000
        withdraw = 300000

        bank = BankService(workflow=mock_workflow)
        bank.deposit_money(user_id=user.user_id, money=money)
        bank.withdraw(user_id=user.user_id, money=withdraw)
        bank.get_account_balance(user_id=user.user_id)

        execution = Execution.objects(workflow=str(mock_workflow.pk)).first()
        self.assertEqual(execution.result['balance'], money)
Example #3
0
    def test_withdraw_in_dollars_negative(self):
        """Prueba que valída el método de retirar dinero en dólares de la cuenta de un usuario con valores negativos.
        """
        mock_workflow = Mock(pk=12345)
        user = User.objects().first()
        money = 100000
        withdraw = -5

        bank = BankService(workflow=mock_workflow)
        bank.deposit_money(user_id=user.user_id, money=money)
        bank.withdraw_in_dollars(user_id=user.user_id, money=withdraw)
        bank.get_account_balance(user_id=user.user_id)

        execution = Execution.objects(workflow=str(mock_workflow.pk)).first()
        self.assertEqual(execution.result['balance'], money)
Example #4
0
    def test_deposit_money_negative(self):
        """Prueba que valída el método de depositar dinero en la cuenta de un usuario con valores negativos."""
        mock_workflow = Mock(pk=12345)
        user = User.objects().first()
        money = -100000

        bank = BankService(workflow=mock_workflow)
        bank.deposit_money(user_id=user.user_id, money=money)
        bank.get_account_balance(user_id=user.user_id)

        execution = Execution.objects(workflow=str(mock_workflow.pk)).first()
        self.assertEqual(execution.result['balance'], 0)
Example #5
0
    def test_withdraw_in_dollars(self):
        """Prueba que valída el método de retirar dinero en dólares de la cuenta de un usuario exitosamente."""
        rate_params = {'vigenciadesde': datetime.date.today().isoformat()}
        rate = requests.get('https://www.datos.gov.co/resource/32sa-8pi3.json',
                            params=rate_params)
        usd_rate = float(rate.json()[0]['valor'])

        mock_workflow = Mock(pk=12345)
        user = User.objects().first()
        money = 100000
        withdraw = 3

        bank = BankService(workflow=mock_workflow)
        bank.deposit_money(user_id=user.user_id, money=money)
        bank.withdraw_in_dollars(user_id=user.user_id, money=withdraw)
        bank.get_account_balance(user_id=user.user_id)

        execution = Execution.objects(workflow=str(mock_workflow.pk)).first()
        self.assertEqual(execution.result['balance'],
                         money - (withdraw * usd_rate))
Example #6
0
class WorkflowService:
    def __init__(self, data):
        """Inicializa la instancia del servicio Workflow."""
        self.execute_trigger(data=data)

    def _workflow(function):
        """Inicia el workflow almacenando la información de su ejecución."""
        @wraps(function)
        def wrapper(self, data):
            try:
                trigger = Trigger(**data['trigger'])
                workflow = Workflow(trigger=trigger).save()

                for data_step in data['steps']:
                    step = Step(**data_step)
                    workflow.steps.append(step)
                    workflow.save()
            except Exception:
                abort(500, description='Error procesando el archivo, por favor intente de nuevo.')

            self.workflow = workflow
            self.bank = BankService(workflow=self.workflow)

            return function(self)
        return wrapper

    @_workflow
    def execute_trigger(self):
        """Realiza la ejecución del trigger del workflow."""
        print('Inicia ejecución del Trigger...')

        try:
            trigger = self.workflow.trigger
            Execution(
                workflow=str(self.workflow.pk),
                name=trigger.id,
                type=Execution.TYPE_TRIGGER,
                result=trigger.params
            ).save()
        except Exception:
            abort(500, description='Error ejecutando Trigger.')

        if trigger.transitions:
            self.execute_transitions(transitions=trigger.transitions)

    def execute_transitions(self, transitions):
        """Ejecuta cada transicion hacia un paso verificando que las condiciones de la transicion se cumplan."""
        target = None
        for transition in transitions:
            print(f'Inicia ejecución de la transicion hacia el paso {transition["target"]}')

            if transition['condition']:
                for condition in transition['condition']:
                    print('Validando condicion de la transicion:')

                    try:
                        _filter = f'result__{condition["field_id"]}'
                        _filter += f'__{condition["operator"]}' if not condition['operator'] == 'eq' else ''

                        filters = {'workflow': str(self.workflow.pk), 'name': condition['from_id']}
                        filters[_filter] = condition['value']
                    except Exception:
                        abort(
                            500,
                            description=(
                                f'Error calculando filtros de una condicion hacia el paso {transition["target"]}'
                            )
                        )

                    if Execution.objects(**filters):
                        target = transition['target']
                        break
                if target:
                    break
            else:
                target = transition['target']
                break

        if target:
            self.execute_step(target=transition['target'])

    def execute_step(self, target):
        """Ejecuta la accion dentro de un paso y posteriormente continúa hacia otra transición si existe."""
        step = self.workflow.steps.get(id=target)
        print(f'Inicia ejecución del paso {step["id"]}')

        print('Inicia obtención de los parámetros del paso')
        params = {'step': step}
        for param_name, param_value in step['params'].items():
            try:
                params[param_name] = self.get_param(param=param_value)
            except Exception:
                abort(500, description='Error obteniendo parámetro para la ejecución del paso.')

        self.bank.call_action(action=step['action'], params=params)

        if step.transitions:
            self.execute_transitions(transitions=step.transitions)

    def get_param(self, param):
        """Obtiene el parámetro solicitado para la ejecución de un paso."""
        return_param = None

        try:
            if param['from_id']:
                execution = (
                    Execution
                    .objects(workflow=str(self.workflow.pk), name=param['from_id'])
                    .order_by('-id')
                    .first()
                )

                return_param = execution.result[param['param_id']]
            elif param['value']:
                return_param = param['value']
        except Exception:
            abort(500, description=f'Error obtiendo el parámetro {param["param_id"]}.')

        return return_param