Example #1
0
    def handle_CreateAccount(self, command):
        ''' Handles CreateAccount command

            Keyword Arguments:
            command -- Command entity with necessary account creation data

            Returns:
            An array containing violations ocurred during execution
        '''
        assert isinstance(
            command,
            CreateAccount), '{} must be of type \'CreateAccount\''.format(
                command)

        violations = []
        account = command.accountToCreate

        existingAccounts = self.accountRepository.getByFilter(
            lambda account: True)

        if existingAccounts:
            violations += ['account-already-initialized']
            return Account.getAccountAndViolationsDict(existingAccounts[0],
                                                       violations)

        self.accountRepository.add(account)

        returnDict = Account.getAccountAndViolationsDict(account, violations)

        return returnDict
Example #2
0
    def test_getAccountAndViolationsDict_empty(self):
        account = Account(True, 100)
        violations = []

        expectedDict = { "account": { "activeCard": True, "availableLimit": 100 }, "violations": [] }
        result = Account.getAccountAndViolationsDict(account, violations)

        self.assertDictEqual(expectedDict, result)
Example #3
0
    def test_getAccountAndViolationsDict_Valid(self):
        account = Account(True, 99)
        violations = ['insufficient-limit']

        expectedDict = { "account": { "activeCard": True, "availableLimit": 99 }, "violations": ['insufficient-limit'] }
        result = Account.getAccountAndViolationsDict(account, violations)

        self.assertDictEqual(expectedDict, result)
Example #4
0
    def handle_AuthorizeTransaction(self, command):
        ''' Handles AuthorizeTransaction command

            Keyword Arguments:
            command -- Command entity with necessary transaction authorization data

            Returns:
            A dictionary containing the account and a new field containing possible violations
        '''
        assert isinstance(
            command, AuthorizeTransaction
        ), '{} must be of type \'AuthorizeTransaction\''.format(command)

        transaction = command.transactionToCreate
        violations = []

        # Gets the first account
        account = self.accountRepository.getByFilter(lambda account: True)[0]

        # •	No transaction should be accepted when the card is not active: card-not-active
        if not account.activeCard:
            violations += ['card-not-active']
            return Account.getAccountAndViolationsDict(account, violations)

        # •	The transaction amount should not exceed available limit: insufficient-limit
        if account.availableLimit < transaction.amount:
            violations += ['insufficient-limit']
            return Account.getAccountAndViolationsDict(account, violations)

        # •	There should not be more than 3 transactions on a 2 minute interval: high-frequency-small-interval
        transactionTime = datetime.strptime(transaction.time,
                                            '%Y-%m-%dT%H:%M:%S.%fZ')

        minDiffInMinutes = 2
        fromDatetime = transactionTime - timedelta(minutes=minDiffInMinutes)

        recentTransactions = self.transactionRepository.getByFilter(
            lambda transactions: transactions.time >= fromDatetime)

        if len(recentTransactions) >= 3:
            violations += ['high-frequency-small-interval']
            return Account.getAccountAndViolationsDict(account, violations)

        # •	There should not be more than 2 similar transactions (same amount and merchant) in a 2 minutes interval: doubled-transaction
        doubledTransactions = list(filter(lambda transactions: \
            transactions.amount == transaction.amount \
            and transactions.merchant == transaction.merchant \
            , recentTransactions))

        if doubledTransactions and len(doubledTransactions) > 1:
            violations += ['doubled-transaction']
            return Account.getAccountAndViolationsDict(account, violations)

        # Everything should be fine down here
        transaction.time = transactionTime
        self.transactionRepository.add(transaction)

        account.availableLimit -= transaction.amount
        self.accountRepository.update(account)

        return Account.getAccountAndViolationsDict(account, violations)