Пример #1
0
 def test_add_first_transaction(self):
     transaction = self.create_transaction()
     interval = 10
     margin = 3
     sequence = TransactionSequence(interval)
     sequence.add_transaction(transaction, margin)
     assert transaction.sequence is None
     assert transaction.id in sequence.transactions
Пример #2
0
 def test_add_transaction_set_ownership(self):
     transaction = self.create_transaction()
     interval = 10
     margin = 3
     sequence = TransactionSequence(interval)
     sequence.add_transaction(transaction, margin, set_ownership=True)
     assert transaction.sequence == sequence
     assert transaction.id in sequence.transactions
Пример #3
0
 def test_add_transactions(self, add_transaction):
     transaction1 = self.create_transaction()
     transaction2 = self.create_transaction()
     transaction3 = self.create_transaction()
     transactions = [transaction1, transaction2, transaction3]
     interval = 10
     margin = 3
     ownership = True
     sequence = TransactionSequence(interval)
     sequence.add_transactions(transactions, margin, ownership)
     add_transaction.assert_has_calls([
         call(transaction1, margin, ownership),
         call(transaction2, margin, ownership),
         call(transaction3, margin, ownership)
     ])
Пример #4
0
 def create_sequence(self):
     transaction1 = Transaction(date='01/02/2020',
                                description='TEST INVOICE 1234',
                                amount='435.23')
     transaction2 = Transaction(date='01/12/2020',
                                description='TEST INVOICE 1234',
                                amount='435.23')
     transaction3 = Transaction(date='01/22/2020',
                                description='TEST INVOICE 1234',
                                amount='435.23')
     transactions = [transaction1, transaction2, transaction3]
     interval = 10
     margin = 3
     ownership = True
     sequence = TransactionSequence(interval)
     sequence.add_transactions(transactions, margin, ownership)
     return sequence
Пример #5
0
 def test_contains(self):
     transaction1 = Transaction(date='01/02/2020',
                                description='TEST INVOICE 1234',
                                amount='435.23')
     transaction2 = Transaction(date='01/12/2020',
                                description='TEST INVOICE 1234',
                                amount='435.23')
     transaction3 = Transaction(date='01/22/2020',
                                description='TEST INVOICE 1234',
                                amount='435.23')
     transactions = [transaction1, transaction2]
     interval = 10
     margin = 3
     ownership = True
     sequence = TransactionSequence(interval)
     sequence.add_transactions(transactions, margin, ownership)
     assert transaction1 in sequence
     assert transaction3 not in sequence
Пример #6
0
 def test_get_last_transaction(self):
     transaction1 = Transaction(date='01/02/2020',
                                description='TEST INVOICE 1234',
                                amount='435.23')
     transaction2 = Transaction(date='01/12/2020',
                                description='TEST INVOICE 1234',
                                amount='435.23')
     transaction3 = Transaction(date='01/22/2020',
                                description='TEST INVOICE 1234',
                                amount='435.23')
     transactions = [transaction1, transaction2, transaction3]
     interval = 10
     margin = 3
     ownership = True
     sequence = TransactionSequence(interval)
     sequence.add_transactions(transactions, margin, ownership)
     first = sequence.get_last_transaction()
     assert first == transaction3
Пример #7
0
 def test_len(self):
     transaction1 = Transaction(date='01/02/2020',
                                description='TEST INVOICE 1234',
                                amount='435.23')
     transaction2 = Transaction(date='01/12/2020',
                                description='TEST INVOICE 1234',
                                amount='435.23')
     transaction3 = Transaction(date='01/22/2020',
                                description='TEST INVOICE 1234',
                                amount='435.23')
     transactions = [transaction1, transaction2, transaction3]
     interval = 10
     margin = 3
     ownership = True
     expected_length = 3
     sequence = TransactionSequence(interval)
     sequence.add_transactions(transactions, margin, ownership)
     length = len(sequence)
     assert length == expected_length
Пример #8
0
    def test_add_sequence(self):
        transaction1 = Transaction(date='01/02/2020',
                                   description='TEST INVOICE 1234',
                                   amount='435.23')
        transaction2 = Transaction(date='01/12/2020',
                                   description='TEST INVOICE 1234',
                                   amount='435.23')
        transaction3 = Transaction(date='01/22/2020',
                                   description='TEST INVOICE 1234',
                                   amount='435.23')
        transactions = [transaction1, transaction2, transaction3]
        interval = 10
        margin = 3
        ownership = True
        sequence = TransactionSequence(interval)
        sequence.add_transactions(transactions, margin, ownership)

        storage = SequenceStorage()
        storage.add_sequence(sequence)
        assert transaction1.id in storage.sequences
        assert transaction2.id in storage.sequences
        assert transaction3.id in storage.sequences
Пример #9
0
    def test_get_sequence(self):
        transaction1 = Transaction(date='01/02/2020',
                                   description='TEST INVOICE 1234',
                                   amount='435.23')
        transaction2 = Transaction(date='01/12/2020',
                                   description='TEST INVOICE 1234',
                                   amount='435.23')
        transaction3 = Transaction(date='01/22/2020',
                                   description='TEST INVOICE 1234',
                                   amount='435.23')
        transactions = [transaction1, transaction2]
        interval = 10
        margin = 3
        ownership = True
        sequence = TransactionSequence(interval)
        sequence.add_transactions(transactions, margin, ownership)

        storage = SequenceStorage()
        storage.add_sequence(sequence)
        sequence1 = storage.get_sequence(transaction1)
        sequence2 = storage.get_sequence(transaction2)
        sequence3 = storage.get_sequence(transaction3)
        assert sequence1 == sequence2 == sequence
        assert sequence3 is None
Пример #10
0
    def test_iter(self):
        called = Mock()
        transaction1 = Transaction(date='01/02/2020',
                                   description='TEST INVOICE 1234',
                                   amount='435.23')
        transaction2 = Transaction(date='01/12/2020',
                                   description='TEST INVOICE 1234',
                                   amount='435.23')
        transaction3 = Transaction(date='01/22/2020',
                                   description='TEST INVOICE 1234',
                                   amount='435.23')
        transactions = [transaction1, transaction2, transaction3]
        interval = 10
        margin = 3
        ownership = True
        sequence = TransactionSequence(interval)
        sequence.add_transactions(transactions, margin, ownership)
        for transaction in sequence:
            called(transaction)

        called.assert_has_calls(
            [call(transaction1),
             call(transaction2),
             call(transaction3)])
Пример #11
0
def parse_sequences(transaction_list, margin=DEFAULT_MARGIN):
    """
    Given a list of transactions with similar descriptions, find sequences that respect
    the interval rule.

    :param transaction_list: List of transactions with similar descriptions.
    :param margin: Acceptable margin for the interval rule.
    :return: List of valid sequences.
    """
    def get_margin(days):
        return [str(i) for i in range(days - margin, days + margin + 1)]

    # First, we should evaluate sequence candidates from transaction combinations.
    # By using itertools.combinations, we avoid the issue of singleton transactions breaking
    # a possible sequence.
    delta_hash = OrderedDict()
    for a, b in itertools.combinations(transaction_list, 2):
        xdiff = b.date - a.date
        if xdiff.days >= MINIMUM_INTERVAL:  # '4 day rule' evaluation
            keys = list(
                set(delta_hash.keys()).intersection(get_margin(
                    xdiff.days)))  # margin evaluation
            if len(keys) > 0:
                delta_hash[keys[0]].add_transactions([a, b], margin=margin)
            else:
                sequence = TransactionSequence(interval=xdiff.days)
                sequence.add_transactions([a, b], margin=margin)
                delta_hash[str(xdiff.days)] = sequence

    sequences = []
    # Now that we have the candidates, we should make sure that we are adhering to the minimum transactions and
    # the single-sequence rules, iterating through our candidates to get rid of extra sequences.
    for key, sequence in delta_hash.items():
        transactions = [
            transaction for transaction in sequence if not transaction.sequence
        ]  # Single-sequence evaluation

        if len(transactions
               ) >= MINIMUM_TRANSACTIONS:  # Minimum transactions evaluation
            clean_sequence = TransactionSequence(interval=int(key))
            clean_sequence.add_transactions(transactions,
                                            margin=margin,
                                            set_ownership=True)
            sequences.append(clean_sequence)

    return sequences
Пример #12
0
    def test_add_second_transaction_outside_margin(self):
        transaction = self.create_transaction()
        second_transaction = Transaction(date='01/02/2021',
                                         description='TEST INVOICE 1234',
                                         amount='435.23')
        interval = 10
        margin = 3
        sequence = TransactionSequence(interval)
        sequence.add_transaction(transaction, margin)
        sequence.add_transaction(second_transaction, margin)

        assert transaction.sequence is None
        assert second_transaction.sequence is None
        assert transaction.id in sequence.transactions
        assert second_transaction.id not in sequence.transactions
Пример #13
0
 def test_creation(self):
     interval = 10
     sequence = TransactionSequence(interval)
     assert sequence.interval == interval
     assert sequence.transactions == {}