Example #1
0
    def setUp(self):
        self.user = User(username="******")
        self.user.save()

        self.group = Group(name="Group 1", slug="group1")
        self.group.save()

        self.accounts = [
            Account(name="Account 1", slug="account1", group=self.group),
            Account(name="Account 2", slug="account2", group=self.group),
            Account(name="Account 3", slug="account3", group=self.group),
        ]
        for account in self.accounts:
            account.save()

        self.before = datetime.datetime.now()

        self.transaction = Transaction(group=self.group)
        self.transaction.save()
        self.transaction.entry_set.create(account=self.accounts[0], debit=100)
        self.transaction.entry_set.create(account=self.accounts[1], credit=100)

        self.transaction.set_pending(user=self.user)

        self.after = datetime.datetime.now()
Example #2
0
    def setUp(self):
        self.user = User(username='******')
        self.user.save()

        self.group = Group(name='Group 1', slug='group1')
        self.group.save()

        self.accounts = [
            Account(name='Account 1', slug='account1', group=self.group),
            Account(name='Account 2', slug='account2', group=self.group),
            Account(name='Account 3', slug='account3', group=self.group),
        ]
        for account in self.accounts:
            account.save()

        self.before = datetime.datetime.now()

        self.transaction = Transaction(group=self.group)
        self.transaction.save()
        self.transaction.entry_set.add(
            TransactionEntry(account=self.accounts[0], debit=100))
        self.transaction.entry_set.add(
            TransactionEntry(account=self.accounts[1], credit=100))

        self.transaction.set_pending(user=self.user)

        self.after = datetime.datetime.now()
Example #3
0
    def setUp(self):
        self.user = User(username='******')
        self.user.save()

        self.group = Group(name='Group 1', slug='group1')
        self.group.save()

        self.transaction = Transaction(group=self.group)
        self.transaction.set_pending(user=self.user)
Example #4
0
    def setUp(self):
        self.user = User(username="******")
        self.user.save()

        self.group = Group(name="Group 1", slug="group1")
        self.group.save()

        self.transaction = Transaction(group=self.group)
        self.transaction.set_pending(user=self.user)
Example #5
0
class EntryTestCase(unittest.TestCase):
    def setUp(self):
        self.user = User(username='******')
        self.user.save()

        self.group = Group(name='group1', slug='group1')
        self.group.save()

        self.account = Account(name='account1',
                               slug='account1',
                               group=self.group)
        self.account.save()

        self.transaction = Transaction(group=self.group)
        self.transaction.save()

        self.entry = TransactionEntry(account=self.account,
                                      debit=100,
                                      credit=100,
                                      transaction=self.transaction)

    def tearDown(self):
        self.transaction.delete()
        self.account.delete()
        self.group.delete()
        self.user.delete()

    def testDebitAndCreditInSameEntry(self):
        """Checks that setting both debit and credit does not fail"""

        self.entry.debit = 100
        self.entry.credit = 100
        self.entry.save()

    def testNegativeCredit(self):
        """Checks that inputing av negative credit raises an error"""

        self.entry.credit = -100
        with self.assertRaises(InvalidTransactionEntry):
            self.entry.save()

    def testNegativeDebit(self):
        """Checks that inputing av negative debit  raises an error"""

        self.entry.debit = -100
        with self.assertRaises(InvalidTransactionEntry):
            self.entry.save()

    def testDebitAndCreditSetToZero(self):
        """Checks that setting both debit and credit to zero raises error"""

        self.entry.debit = 0
        self.entry.credit = 0
        with self.assertRaises(InvalidTransactionEntry):
            self.entry.save()
Example #6
0
    def testAccountOnlyOnceInTransaction(self):
        """Checks that multiple credit accounts are allowed in a transaction"""

        transaction = Transaction(group=self.group)
        transaction.save()

        transaction.entry_set.add(TransactionEntry(account=self.accounts[0], debit=200))
        transaction.entry_set.add(TransactionEntry(account=self.accounts[1], credit=100))
        transaction.entry_set.add(TransactionEntry(account=self.accounts[2], credit=100))

        transaction.delete()
Example #7
0
def bill_create_transaction(request, group, bill, is_admin=False):
    if not bill.is_editable():
        messages.info(
            request, _('This bill is already linked to a transaction.'))
        return HttpResponseRedirect(reverse(
            'transaction-details', args=[group.slug, bill.transaction.id]))

    if request.method != 'POST':
        form = CreateTransactionForm(bill)
    else:
        form = CreateTransactionForm(bill, request.POST)

        if form.is_valid():
            pay_to = Account.objects.get(
                group=group, roleaccount__role=form.cleaned_data['pay_to'])

            charge_to = form.cleaned_data['charge_to']

            settlement = form.cleaned_data.get('settlement', None)

            sum = 0
            for line in bill.billingline_set.all():
                sum += line.amount

            transaction = Transaction(group=group, settlement=settlement)
            transaction.save()

            transaction.entry_set.add(
                TransactionEntry(account=charge_to, credit=sum))
            transaction.entry_set.add(
                TransactionEntry(account=pay_to, debit=sum))

            transaction.set_pending(
                user=request.user,
                message=_('Bill #%(id)s: %(description)s') % {
                    'id': bill.pk, 'description': bill.description})

            bill.transaction = transaction
            bill.save()

            return HttpResponseRedirect(reverse(
                'transaction-details', args=[group.slug, transaction.id]))

    return render_to_response(
        'billing/bill_create_transaction.html',
        {
            'is_admin': is_admin,
            'group': group,
            'bill': bill,
            'form': form,
        },
        context_instance=RequestContext(request))
Example #8
0
class LogTestCase(unittest.TestCase):
    def setUp(self):
        self.user = User(username='******')
        self.user.save()

        self.group = Group(name='Group 1', slug='group1')
        self.group.save()

        self.transaction = Transaction(group=self.group)
        self.transaction.set_pending(user=self.user)

    def tearDown(self):
        self.transaction.delete()
        self.group.delete()
        self.user.delete()

    def testLogEntryUniqePerType(self):
        """Checks that only one log entry of each type is allowed (except for
        pending)
        """

        for key, value in Transaction.TRANSACTION_STATE:
            log1 = TransactionLog(type=key,
                                  transaction=self.transaction,
                                  user=self.user)
            log2 = TransactionLog(type=key,
                                  transaction=self.transaction,
                                  user=self.user)
            if key != Transaction.PENDING_STATE:
                log1.save()
                with self.assertRaises(InvalidTransactionLog):
                    log2.save()

    def testLogEntryModify(self):
        """Checks that modifying log entry raises error"""

        log_entry = self.transaction.log_set.filter(
            type=Transaction.PENDING_STATE)[0]

        with self.assertRaises(InvalidTransactionLog):
            log_entry.save()

        for key, value in Transaction.TRANSACTION_STATE:
            log1 = TransactionLog(type=key,
                                  transaction=self.transaction,
                                  user=self.user)

            if key != Transaction.PENDING_STATE:
                log1.save()
                with self.assertRaises(InvalidTransactionLog):
                    log1.save()
Example #9
0
class EntryTestCase(unittest.TestCase):
    def setUp(self):
        self.user = User(username="******")
        self.user.save()

        self.group = Group(name="group1", slug="group1")
        self.group.save()

        self.account = Account(name="account1", slug="account1", group=self.group)
        self.account.save()

        self.transaction = Transaction(group=self.group)
        self.transaction.save()

        self.entry = TransactionEntry(account=self.account, debit=100, credit=100, transaction=self.transaction)

    def tearDown(self):
        self.transaction.delete()
        self.account.delete()
        self.group.delete()
        self.user.delete()

    def testDebitAndCreditInSameEntry(self):
        """Checks that setting both debit and credit does not fail"""

        self.entry.debit = 100
        self.entry.credit = 100
        self.entry.save()

    def testNegativeCredit(self):
        """Checks that inputing av negative credit raises an error"""

        self.entry.credit = -100
        with self.assertRaises(InvalidTransactionEntry):
            self.entry.save()

    def testNegativeDebit(self):
        """Checks that inputing av negative debit  raises an error"""

        self.entry.debit = -100
        with self.assertRaises(InvalidTransactionEntry):
            self.entry.save()

    def testDebitAndCreditSetToZero(self):
        """Checks that setting both debit and credit to zero raises error"""

        self.entry.debit = 0
        self.entry.credit = 0
        with self.assertRaises(InvalidTransactionEntry):
            self.entry.save()
Example #10
0
def transaction_from_list(request, group, list, is_admin=False):
    """Enter list"""

    form = ListTransactionForm(list, request.POST or None)

    if form.is_valid():
        transaction = Transaction(group=list.group)
        transaction.save()

        for entry in form.transaction_entries():
            entry.transaction = transaction
            entry.save()

        transaction.save()
        transaction.set_pending(
            user=request.user, message=_('Created from list: %s') % list.slug)

        return HttpResponseRedirect(reverse(
            'edit-transaction',
            kwargs={
                'group': group.slug,
                'transaction': transaction.id,
            }))

    return render_to_response(
        'reports/list_transaction_form.html',
        {
            'is_admin': is_admin,
            'group': group,
            'list': list,
            'form': form,
        },
        context_instance=RequestContext(request))
Example #11
0
    def setUp(self):
        self.user = User(username="******")
        self.user.save()

        self.group = Group(name="Group 1", slug="group1")
        self.group.save()

        self.accounts = [
            Account(name="Account 1", slug="account1", group=self.group),
            Account(name="Account 2", slug="account2", group=self.group),
            Account(name="Account 3", slug="account3", group=self.group),
        ]
        for account in self.accounts:
            account.save()

        self.before = datetime.datetime.now()

        self.transaction = Transaction(group=self.group)
        self.transaction.save()
        self.transaction.entry_set.add(TransactionEntry(account=self.accounts[0], debit=100))
        self.transaction.entry_set.add(TransactionEntry(account=self.accounts[1], credit=100))

        self.transaction.set_pending(user=self.user)

        self.after = datetime.datetime.now()
Example #12
0
    def setUp(self):
        self.user = User(username="******")
        self.user.save()

        self.group = Group(name="Group 1", slug="group1")
        self.group.save()

        self.transaction = Transaction(group=self.group)
        self.transaction.set_pending(user=self.user)
Example #13
0
    def setUp(self):
        self.user = User(username="******")
        self.user.save()

        self.group = Group(name="group1", slug="group1")
        self.group.save()

        self.account = Account(name="account1",
                               slug="account1",
                               group=self.group)
        self.account.save()

        self.transaction = Transaction(group=self.group)
        self.transaction.save()

        self.entry = self.transaction.entry_set.create(account=self.account,
                                                       debit=100,
                                                       credit=100)
Example #14
0
class LogTestCase(unittest.TestCase):
    def setUp(self):
        self.user = User(username="******")
        self.user.save()

        self.group = Group(name="Group 1", slug="group1")
        self.group.save()

        self.transaction = Transaction(group=self.group)
        self.transaction.set_pending(user=self.user)

    def tearDown(self):
        self.transaction.delete()
        self.group.delete()
        self.user.delete()

    def testLogEntryUniqePerType(self):
        """Checks that only one log entry of each type is allowed (except for
        pending)
        """

        for key, value in Transaction.TRANSACTION_STATE:
            log1 = TransactionLog(type=key, transaction=self.transaction, user=self.user)
            log2 = TransactionLog(type=key, transaction=self.transaction, user=self.user)
            if key != Transaction.PENDING_STATE:
                log1.save()
                with self.assertRaises(InvalidTransactionLog):
                    log2.save()

    def testLogEntryModify(self):
        """Checks that modifying log entry raises error"""

        log_entry = self.transaction.log_set.filter(type=Transaction.PENDING_STATE)[0]

        with self.assertRaises(InvalidTransactionLog):
            log_entry.save()

        for key, value in Transaction.TRANSACTION_STATE:
            log1 = TransactionLog(type=key, transaction=self.transaction, user=self.user)

            if key != Transaction.PENDING_STATE:
                log1.save()
                with self.assertRaises(InvalidTransactionLog):
                    log1.save()
Example #15
0
    def setUp(self):
        self.user = User(username='******')
        self.user.save()

        self.group = Group(name='group1', slug='group1')
        self.group.save()

        self.account = Account(name='account1',
                               slug='account1',
                               group=self.group)
        self.account.save()

        self.transaction = Transaction(group=self.group)
        self.transaction.save()

        self.entry = TransactionEntry(account=self.account,
                                      debit=100,
                                      credit=100,
                                      transaction=self.transaction)
Example #16
0
    def testEqualDebitAndCreditAmount(self):
        """Checks that transaction only accept sum(debit)==sum(credit)"""

        transaction = Transaction(group=self.group)
        transaction.save()

        transaction.entry_set.create(account=self.accounts[1], debit=200)
        transaction.entry_set.create(account=self.accounts[0], credit=100)

        with pytest.raises(InvalidTransaction):
            transaction.set_pending(user=self.user)

        transaction.delete()
Example #17
0
    def testEqualDebitAndCreditAmount(self):
        """Checks that transaction only accept sum(debit)==sum(credit)"""

        transaction = Transaction(group=self.group)
        transaction.save()

        transaction.entry_set.add(TransactionEntry(account=self.accounts[1], debit=200))
        transaction.entry_set.add(TransactionEntry(account=self.accounts[0], credit=100))
        with self.assertRaises(InvalidTransaction):
            transaction.set_pending(user=self.user)

        transaction.delete()
Example #18
0
    def setUp(self):
        self.user = User(username="******")
        self.user.save()

        self.group = Group(name="group1", slug="group1")
        self.group.save()

        self.account = Account(name="account1", slug="account1", group=self.group)
        self.account.save()

        self.transaction = Transaction(group=self.group)
        self.transaction.save()

        self.entry = TransactionEntry(account=self.account, debit=100, credit=100, transaction=self.transaction)
Example #19
0
def bill_create_transaction(request, group, bill, is_admin=False):
    if not bill.is_editable():
        messages.info(
            request, _("This bill is already linked to a transaction.")
        )
        return HttpResponseRedirect(
            reverse(
                "transaction-details", args=[group.slug, bill.transaction.id]
            )
        )

    if request.method != "POST":
        form = CreateTransactionForm(bill)
    else:
        form = CreateTransactionForm(bill, request.POST)

        if form.is_valid():
            pay_to = Account.objects.get(
                group=group, roleaccount__role=form.cleaned_data["pay_to"]
            )

            charge_to = form.cleaned_data["charge_to"]

            settlement = form.cleaned_data.get("settlement", None)

            sum = 0
            for line in bill.billingline_set.all():
                sum += line.amount

            transaction = Transaction(group=group, settlement=settlement)
            transaction.save()

            transaction.entry_set.create(account=charge_to, credit=sum)
            transaction.entry_set.create(account=pay_to, debit=sum)
            transaction.set_pending(
                user=request.user,
                message=_("Bill #%(id)s: %(description)s")
                % {"id": bill.pk, "description": bill.description},
            )

            bill.transaction = transaction
            bill.save()

            return HttpResponseRedirect(
                reverse(
                    "transaction-details", args=[group.slug, transaction.id]
                )
            )

    return render(
        request,
        "billing/bill_create_transaction.html",
        {"is_admin": is_admin, "group": group, "bill": bill, "form": form},
    )
Example #20
0
def bill_create_transaction(request, group, bill, is_admin=False):
    if not bill.is_editable():
        messages.info(request,
                      _('This bill is already linked to a transaction.'))
        return HttpResponseRedirect(
            reverse('transaction-details',
                    args=[group.slug, bill.transaction.id]))

    if request.method != 'POST':
        form = CreateTransactionForm(bill)
    else:
        form = CreateTransactionForm(bill, request.POST)

        if form.is_valid():
            pay_to = Account.objects.get(
                group=group, roleaccount__role=form.cleaned_data['pay_to'])

            charge_to = form.cleaned_data['charge_to']

            settlement = form.cleaned_data.get('settlement', None)

            sum = 0
            for line in bill.billingline_set.all():
                sum += line.amount

            transaction = Transaction(group=group, settlement=settlement)
            transaction.save()

            transaction.entry_set.add(
                TransactionEntry(account=charge_to, credit=sum))
            transaction.entry_set.add(
                TransactionEntry(account=pay_to, debit=sum))

            transaction.set_pending(
                user=request.user,
                message=_('Bill #%(id)s: %(description)s') % {
                    'id': bill.pk,
                    'description': bill.description
                })

            bill.transaction = transaction
            bill.save()

            return HttpResponseRedirect(
                reverse('transaction-details',
                        args=[group.slug, transaction.id]))

    return render_to_response('billing/bill_create_transaction.html', {
        'is_admin': is_admin,
        'group': group,
        'bill': bill,
        'form': form,
    },
                              context_instance=RequestContext(request))
Example #21
0
    def testAccountOnlyOnceInTransaction(self):
        """Checks that multiple credit accounts are allowed in a transaction"""

        transaction = Transaction(group=self.group)
        transaction.save()

        transaction.entry_set.add(
            TransactionEntry(account=self.accounts[0], debit=200))
        transaction.entry_set.add(
            TransactionEntry(account=self.accounts[1], credit=100))
        transaction.entry_set.add(
            TransactionEntry(account=self.accounts[2], credit=100))

        transaction.delete()
Example #22
0
    def testAccountOnlyOnceInTransaction(self):
        """Checks that multiple credit accounts are allowed in a transaction"""

        transaction = Transaction(group=self.group)
        transaction.save()

        TransactionEntry.objects.create(account=self.accounts[0],
                                        debit=200,
                                        transaction=transaction)
        TransactionEntry.objects.create(account=self.accounts[1],
                                        credit=100,
                                        transaction=transaction)
        TransactionEntry.objects.create(account=self.accounts[2],
                                        credit=100,
                                        transaction=transaction)

        transaction.delete()
Example #23
0
def transaction_from_list(request, group, list, is_admin=False):
    """Enter list"""

    form = ListTransactionForm(list, request.POST or None)

    if form.is_valid():
        transaction = Transaction(group=list.group)
        transaction.save()

        for entry in form.transaction_entries():
            entry.transaction = transaction
            entry.save()

        transaction.save()
        transaction.set_pending(user=request.user,
                                message=_("Created from list: %s") % list.slug)

        return HttpResponseRedirect(
            reverse(
                "edit-transaction",
                kwargs={
                    "group": group.slug,
                    "transaction": transaction.id
                },
            ))

    return render(
        request,
        "reports/list_transaction_form.html",
        {
            "is_admin": is_admin,
            "group": group,
            "list": list,
            "form": form
        },
    )
Example #24
0
    def testEmptyTransaction(self):
        """Checks that empty transactions are accepted"""

        transaction = Transaction(group=self.group)
        transaction.save()
        transaction.delete()
Example #25
0
class TransactionTestCase(unittest.TestCase):
    def setUp(self):
        self.user = User(username="******")
        self.user.save()

        self.group = Group(name="Group 1", slug="group1")
        self.group.save()

        self.accounts = [
            Account(name="Account 1", slug="account1", group=self.group),
            Account(name="Account 2", slug="account2", group=self.group),
            Account(name="Account 3", slug="account3", group=self.group),
        ]
        for account in self.accounts:
            account.save()

        self.before = datetime.datetime.now()

        self.transaction = Transaction(group=self.group)
        self.transaction.save()
        self.transaction.entry_set.add(TransactionEntry(account=self.accounts[0], debit=100))
        self.transaction.entry_set.add(TransactionEntry(account=self.accounts[1], credit=100))

        self.transaction.set_pending(user=self.user)

        self.after = datetime.datetime.now()

    def tearDown(self):
        self.transaction.delete()
        for account in self.accounts:
            account.delete()
        self.group.delete()
        self.user.delete()

    def testEmptyTransaction(self):
        """Checks that empty transactions are accepted"""

        transaction = Transaction(group=self.group)
        transaction.save()
        transaction.delete()

    def testEqualDebitAndCreditAmount(self):
        """Checks that transaction only accept sum(debit)==sum(credit)"""

        transaction = Transaction(group=self.group)
        transaction.save()

        transaction.entry_set.add(TransactionEntry(account=self.accounts[1], debit=200))
        transaction.entry_set.add(TransactionEntry(account=self.accounts[0], credit=100))
        with self.assertRaises(InvalidTransaction):
            transaction.set_pending(user=self.user)

        transaction.delete()

    def testAccountOnlyOnceInTransaction(self):
        """Checks that multiple credit accounts are allowed in a transaction"""

        transaction = Transaction(group=self.group)
        transaction.save()

        transaction.entry_set.add(TransactionEntry(account=self.accounts[0], debit=200))
        transaction.entry_set.add(TransactionEntry(account=self.accounts[1], credit=100))
        transaction.entry_set.add(TransactionEntry(account=self.accounts[2], credit=100))

        transaction.delete()

    def testPendingLogEntry(self):
        """Checks that a pending log entry is created"""

        transaction = self.transaction

        self.assertEqual(transaction.is_pending(), True)
        self.assertEqual(transaction.log_set.count(), 1)
        self.assertEqual(transaction.log_set.filter(type=Transaction.PENDING_STATE).count(), 1)

        pending = transaction.log_set.filter(type=Transaction.PENDING_STATE)[0].timestamp

        self.assert_(pending > self.before)
        self.assert_(pending < self.after)

    def testCommittedLogEntry(self):
        """Checks that a committed log entry is created"""

        transaction = self.transaction

        before = datetime.datetime.now()
        transaction.set_committed(user=self.user)
        after = datetime.datetime.now()

        self.assertEqual(transaction.is_committed(), True)
        self.assertEqual(transaction.log_set.count(), 2)
        self.assertEqual(transaction.log_set.filter(type=Transaction.COMMITTED_STATE).count(), 1)

        committed = transaction.log_set.filter(type=Transaction.COMMITTED_STATE)[0].timestamp

        self.assert_(committed > before)
        self.assert_(committed < after)

    def testRejectLogEntry(self):
        """Checks that pending transaction can be rejected"""

        transaction = self.transaction
        self.assertEqual(transaction.is_pending(), True)

        before = datetime.datetime.now()
        transaction.set_rejected(message="Reason for rejecting", user=self.user)
        after = datetime.datetime.now()

        self.assertEqual(transaction.is_rejected(), True)
        self.assertEqual(transaction.log_set.count(), 2)
        self.assertEqual(transaction.log_set.filter(type=Transaction.REJECTED_STATE).count(), 1)

        rejected = transaction.log_set.filter(type=Transaction.REJECTED_STATE)[0].timestamp
        self.assert_(rejected > before)
        self.assert_(rejected < after)

    def testRejectCommitedTransaction(self):
        """Tests that rejecting committed transaction fails"""

        transaction = self.transaction
        transaction.set_committed(user=self.user)

        with self.assertRaises(InvalidTransaction):
            transaction.set_rejected(message="Reason for rejecting", user=self.user)
Example #26
0
class TransactionTestCase(unittest.TestCase):
    def setUp(self):
        self.user = User(username='******')
        self.user.save()

        self.group = Group(name='Group 1', slug='group1')
        self.group.save()

        self.accounts = [
            Account(name='Account 1', slug='account1', group=self.group),
            Account(name='Account 2', slug='account2', group=self.group),
            Account(name='Account 3', slug='account3', group=self.group),
        ]
        for account in self.accounts:
            account.save()

        self.before = datetime.datetime.now()

        self.transaction = Transaction(group=self.group)
        self.transaction.save()
        self.transaction.entry_set.add(
            TransactionEntry(account=self.accounts[0], debit=100))
        self.transaction.entry_set.add(
            TransactionEntry(account=self.accounts[1], credit=100))

        self.transaction.set_pending(user=self.user)

        self.after = datetime.datetime.now()

    def tearDown(self):
        self.transaction.delete()
        for account in self.accounts:
            account.delete()
        self.group.delete()
        self.user.delete()

    def testEmptyTransaction(self):
        """Checks that empty transactions are accepted"""

        transaction = Transaction(group=self.group)
        transaction.save()
        transaction.delete()

    def testEqualDebitAndCreditAmount(self):
        """Checks that transaction only accept sum(debit)==sum(credit)"""

        transaction = Transaction(group=self.group)
        transaction.save()

        transaction.entry_set.add(
            TransactionEntry(account=self.accounts[1], debit=200))
        transaction.entry_set.add(
            TransactionEntry(account=self.accounts[0], credit=100))
        with self.assertRaises(InvalidTransaction):
            transaction.set_pending(user=self.user)

        transaction.delete()

    def testAccountOnlyOnceInTransaction(self):
        """Checks that multiple credit accounts are allowed in a transaction"""

        transaction = Transaction(group=self.group)
        transaction.save()

        transaction.entry_set.add(
            TransactionEntry(account=self.accounts[0], debit=200))
        transaction.entry_set.add(
            TransactionEntry(account=self.accounts[1], credit=100))
        transaction.entry_set.add(
            TransactionEntry(account=self.accounts[2], credit=100))

        transaction.delete()

    def testPendingLogEntry(self):
        """Checks that a pending log entry is created"""

        transaction = self.transaction

        self.assertEqual(transaction.is_pending(), True)
        self.assertEqual(transaction.log_set.count(), 1)
        self.assertEqual(
            transaction.log_set.filter(type=Transaction.PENDING_STATE).count(),
            1)

        pending = transaction.log_set.filter(
            type=Transaction.PENDING_STATE)[0].timestamp

        self.assert_(pending > self.before)
        self.assert_(pending < self.after)

    def testCommittedLogEntry(self):
        """Checks that a committed log entry is created"""

        transaction = self.transaction

        before = datetime.datetime.now()
        transaction.set_committed(user=self.user)
        after = datetime.datetime.now()

        self.assertEqual(transaction.is_committed(), True)
        self.assertEqual(transaction.log_set.count(), 2)
        self.assertEqual(
            transaction.log_set.filter(
                type=Transaction.COMMITTED_STATE).count(), 1)

        committed = transaction.log_set.filter(
            type=Transaction.COMMITTED_STATE)[0].timestamp

        self.assert_(committed > before)
        self.assert_(committed < after)

    def testRejectLogEntry(self):
        """Checks that pending transaction can be rejected"""

        transaction = self.transaction
        self.assertEqual(transaction.is_pending(), True)

        before = datetime.datetime.now()
        transaction.set_rejected(message='Reason for rejecting',
                                 user=self.user)
        after = datetime.datetime.now()

        self.assertEqual(transaction.is_rejected(), True)
        self.assertEqual(transaction.log_set.count(), 2)
        self.assertEqual(
            transaction.log_set.filter(
                type=Transaction.REJECTED_STATE).count(), 1)

        rejected = transaction.log_set.filter(
            type=Transaction.REJECTED_STATE)[0].timestamp
        self.assert_(rejected > before)
        self.assert_(rejected < after)

    def testRejectCommitedTransaction(self):
        """Tests that rejecting committed transaction fails"""

        transaction = self.transaction
        transaction.set_committed(user=self.user)

        with self.assertRaises(InvalidTransaction):
            transaction.set_rejected(message='Reason for rejecting',
                                     user=self.user)
Example #27
0
    def setUp(self):
        self.users = [
            User(username='******'),
            User(username='******'),
            User(username='******'),
        ]
        for user in self.users:
            user.save()

        self.group = Group(name='Group 1', slug='group1')
        self.group.save()

        self.accounts = [
            # Normal user account
            Account(name='Account 1',
                    slug='account1',
                    group=self.group,
                    owner=self.users[0]),
            # Normal user account
            Account(name='Account 2',
                    slug='account2',
                    group=self.group,
                    owner=self.users[1]),
            # Inactive user account
            Account(name='Account 3',
                    slug='account3',
                    group=self.group,
                    owner=self.users[2],
                    active=False),
            # Group account
            Account(name='Account 4',
                    slug='account4',
                    group=self.group,
                    type=Account.ASSET_ACCOUNT),
            # Inactive group account
            Account(name='Account 5',
                    slug='account5',
                    group=self.group,
                    type=Account.ASSET_ACCOUNT,
                    active=False),
            # Bank account
            self.group.roleaccount_set.get(role=RoleAccount.BANK_ACCOUNT
                                           ).account,
            # Cash account
            self.group.roleaccount_set.get(role=RoleAccount.CASH_ACCOUNT
                                           ).account,
        ]
        for account in self.accounts:
            account.save()
        self.account = self.accounts[0]

        self.transactions = {
            'Pen': Transaction(group=self.group),
            'Com': Transaction(group=self.group),
            'Rej': Transaction(group=self.group),
        }
        values = {
            'Pen': 150,
            'Com': 200,
            'Rej': 100,
        }
        for state, transaction in self.transactions.items():
            transaction.save()
            transaction.entry_set.add(
                TransactionEntry(account=self.accounts[0],
                                 credit=values[state]))
            transaction.entry_set.add(
                TransactionEntry(account=self.accounts[1],
                                 debit=values[state]))
            transaction.set_pending(user=self.users[0])

        self.transactions['Undef'] = Transaction(group=self.group)
        self.transactions['Undef'].save()

        self.transactions['Com'].set_committed(user=self.users[2])
        self.transactions['Rej'].set_rejected(user=self.users[2])
Example #28
0
class TransactionTestCase(unittest.TestCase):
    def setUp(self):
        self.user = User(username="******")
        self.user.save()

        self.group = Group(name="Group 1", slug="group1")
        self.group.save()

        self.accounts = [
            Account(name="Account 1", slug="account1", group=self.group),
            Account(name="Account 2", slug="account2", group=self.group),
            Account(name="Account 3", slug="account3", group=self.group),
        ]
        for account in self.accounts:
            account.save()

        self.before = datetime.datetime.now()

        self.transaction = Transaction(group=self.group)
        self.transaction.save()
        self.transaction.entry_set.create(account=self.accounts[0], debit=100)
        self.transaction.entry_set.create(account=self.accounts[1], credit=100)

        self.transaction.set_pending(user=self.user)

        self.after = datetime.datetime.now()

    def tearDown(self):
        self.transaction.delete()
        for account in self.accounts:
            account.delete()
        self.group.delete()
        self.user.delete()

    def testEmptyTransaction(self):
        """Checks that empty transactions are accepted"""

        transaction = Transaction(group=self.group)
        transaction.save()
        transaction.delete()

    def testEqualDebitAndCreditAmount(self):
        """Checks that transaction only accept sum(debit)==sum(credit)"""

        transaction = Transaction(group=self.group)
        transaction.save()

        transaction.entry_set.create(account=self.accounts[1], debit=200)
        transaction.entry_set.create(account=self.accounts[0], credit=100)

        with pytest.raises(InvalidTransaction):
            transaction.set_pending(user=self.user)

        transaction.delete()

    def testAccountOnlyOnceInTransaction(self):
        """Checks that multiple credit accounts are allowed in a transaction"""

        transaction = Transaction(group=self.group)
        transaction.save()

        TransactionEntry.objects.create(account=self.accounts[0],
                                        debit=200,
                                        transaction=transaction)
        TransactionEntry.objects.create(account=self.accounts[1],
                                        credit=100,
                                        transaction=transaction)
        TransactionEntry.objects.create(account=self.accounts[2],
                                        credit=100,
                                        transaction=transaction)

        transaction.delete()

    def testPendingLogEntry(self):
        """Checks that a pending log entry is created"""

        transaction = self.transaction

        assert transaction.is_pending() is True
        assert transaction.log_set.count() == 1
        assert (transaction.log_set.filter(
            type=Transaction.PENDING_STATE).count() == 1)

        pending = transaction.log_set.filter(
            type=Transaction.PENDING_STATE)[0].timestamp

        assert pending > self.before
        assert pending < self.after

    def testCommittedLogEntry(self):
        """Checks that a committed log entry is created"""

        transaction = self.transaction

        before = datetime.datetime.now()
        transaction.set_committed(user=self.user)
        after = datetime.datetime.now()

        assert transaction.is_committed() is True
        assert transaction.log_set.count() == 2
        assert (transaction.log_set.filter(
            type=Transaction.COMMITTED_STATE).count() == 1)

        committed = transaction.log_set.filter(
            type=Transaction.COMMITTED_STATE)[0].timestamp

        assert committed > before
        assert committed < after

    def testRejectLogEntry(self):
        """Checks that pending transaction can be rejected"""

        transaction = self.transaction
        assert transaction.is_pending() is True

        before = datetime.datetime.now()
        transaction.set_rejected(message="Reason for rejecting",
                                 user=self.user)
        after = datetime.datetime.now()

        assert transaction.is_rejected() is True
        assert transaction.log_set.count() == 2
        assert (transaction.log_set.filter(
            type=Transaction.REJECTED_STATE).count() == 1)

        rejected = transaction.log_set.filter(
            type=Transaction.REJECTED_STATE)[0].timestamp
        assert rejected > before
        assert rejected < after

    def testRejectCommitedTransaction(self):
        """Tests that rejecting committed transaction fails"""

        transaction = self.transaction
        transaction.set_committed(user=self.user)

        with pytest.raises(InvalidTransaction):
            transaction.set_rejected(message="Reason for rejecting",
                                     user=self.user)
Example #29
0
    def testEmptyTransaction(self):
        """Checks that empty transactions are accepted"""

        transaction = Transaction(group=self.group)
        transaction.save()
        transaction.delete()
Example #30
0
def transfer(
    request,
    group,
    account=None,
    transfer_type=None,
    is_admin=False,
    is_owner=False,
):
    """Deposit, withdraw or transfer money"""

    if request.method == "POST":
        data = request.POST
    else:
        data = None

    if transfer_type == "transfer":
        title = _("Transfer from account")
        form = TransferForm(data, account=account)
    elif transfer_type == "deposit":
        title = _("Deposit to account")
        form = DepositWithdrawForm(data)
    elif transfer_type == "withdraw":
        title = _("Withdrawal from account")
        form = DepositWithdrawForm(data)
    else:
        return HttpResponseForbidden(_("Forbidden if not group admin."))

    if request.method == "POST" and form.is_valid():
        amount = form.cleaned_data["amount"]
        details = form.cleaned_data["details"].strip()

        if details == "":
            details = None

        bank_account = group.roleaccount_set.get(
            role=RoleAccount.BANK_ACCOUNT).account

        transaction = Transaction(group=group)
        # FIXME: save() shouldn't be need if we figure out a reasonable hack
        transaction.save()

        if transfer_type == "deposit":
            # Deposit to user account
            transaction.entry_set.create(account=account, credit=amount)
            transaction.entry_set.create(account=bank_account, debit=amount)
            transaction.set_pending(user=request.user, message=details)

        elif transfer_type == "withdraw":
            # Withdraw from user account
            transaction.entry_set.create(account=account, debit=amount)
            transaction.entry_set.create(account=bank_account, credit=amount)
            transaction.set_pending(user=request.user, message=details)

        elif transfer_type == "transfer":
            # Transfer from user account to other user account
            credit_account = Account.objects.get(
                id=form.cleaned_data["credit_account"])
            transaction.entry_set.create(account=account, debit=amount)
            transaction.entry_set.create(account=credit_account, credit=amount)
            transaction.set_pending(user=request.user, message=details)

            if amount <= account.normal_balance() - (group.block_limit or 0):
                transaction.set_committed(user=request.user)
            else:
                messages.info(
                    request,
                    _("Your transaction has been added, "
                      "but your group admin has to commit it."),
                )

        else:
            return HttpResponseForbidden(_("Forbidden if not group admin."))

        messages.success(request, _("Added transaction: %s") % transaction)

        return HttpResponseRedirect(
            reverse("account-summary", args=[account.group.slug,
                                             account.slug]))

    return render(
        request,
        "accounting/transfer.html",
        {
            "is_admin": is_admin,
            "is_owner": is_owner,
            "account": account,
            "type": transfer_type,
            "title": title,
            "form": form,
            "group": group,
        },
    )
Example #31
0
def new_edit_transaction(request, group, transaction=None, is_admin=False):
    """Admin view for creating transactions"""

    if transaction is None:
        transaction = Transaction(group=group)
    elif not transaction.is_editable():
        messages.error(
            request, _('Transaction %d can\'t be changed.' % transaction.id))

        db_transaction.commit()

        url = reverse('group-summary', args=(group.slug,))
        return HttpResponseRedirect(url)

    if request.method == 'POST':
        data = request.POST
    elif transaction.id:
        data = {}
        # Load "fake" post data if we are editing a transaction
        for e in transaction.entry_set.all():
            if e.debit > 0:
                data['%d-debit' % e.account.id] = e.debit
            if e.credit > 0:
                data['%d-credit' % e.account.id] = e.credit

        data['settlement-settlement'] = transaction.settlement_id
    else:
        data = None

    # Init forms
    settlement_form = TransactionSettlementForm(
        data, prefix='settlement', instance=transaction)

    user_forms = []
    group_forms = []

    for account in ufs_sorted(group.user_account_set.filter(active=True)):
        user_forms.append((account, EntryForm(data, prefix=account.id)))

    for account in ufs_sorted(group.group_account_set.filter(active=True)):
        group_forms.append((account, EntryForm(data, prefix=account.id)))

    errors = []

    if request.method == 'POST' and settlement_form.is_valid():
        entries = {}

        if transaction.id is None:
            transaction.save()
        else:
            for e in transaction.entry_set.all():
                entries[e.account.id] = e

        transaction.settlement = settlement_form.cleaned_data['settlement']

        try:
            for forms in [group_forms, user_forms]:
                for account, form in forms:
                    if not form.is_valid():
                        raise InvalidTransaction(
                            'Form was not valid, id: %d' % account.id)
                    else:
                        credit = form.cleaned_data['credit']
                        debit = form.cleaned_data['debit']

                        if account.id in entries:
                            entry = entries[account.id]
                        else:
                            entry = TransactionEntry(
                                account=account, transaction=transaction)

                        if credit > 0 or debit > 0:
                            entry.credit = credit or 0
                            entry.debit = debit or 0
                            entry.save()
                        elif entry.id:
                            entry.delete()

            details = settlement_form.cleaned_data['details']

            transaction.save()

            transaction.set_pending(user=request.user, message=details)

            messages.success(request, _('Your transaction has been added.'))

        except InvalidTransaction, e:
            errors.append(e)
            db_transaction.rollback()
        else:
            db_transaction.commit()
            url = reverse('group-summary', args=(group.slug,))
            return HttpResponseRedirect(url)
Example #32
0
def transfer(
        request, group, account=None, transfer_type=None, is_admin=False,
        is_owner=False):
    """Deposit, withdraw or transfer money"""

    if request.method == 'POST':
        data = request.POST
    else:
        data = None

    if transfer_type == 'transfer':
        title = _('Transfer from account')
        form = TransferForm(data, account=account)
    elif transfer_type == 'deposit':
        title = _('Deposit to account')
        form = DepositWithdrawForm(data)
    elif transfer_type == 'withdraw':
        title = _('Withdrawal from account')
        form = DepositWithdrawForm(data)
    else:
        return HttpResponseForbidden(_('Forbidden if not group admin.'))

    if request.method == 'POST' and form.is_valid():
        amount = form.cleaned_data['amount']
        details = form.cleaned_data['details'].strip()

        if details == '':
            details = None

        bank_account = group.roleaccount_set.get(
            role=RoleAccount.BANK_ACCOUNT).account

        transaction = Transaction(group=group)
        # FIXME: save() shouldn't be need if we figure out a reasonable hack
        transaction.save()

        if transfer_type == 'deposit':
            # Deposit to user account

            transaction.entry_set.add(
                TransactionEntry(account=account, credit=amount))
            transaction.entry_set.add(
                TransactionEntry(account=bank_account, debit=amount))

            transaction.set_pending(user=request.user, message=details)

        elif transfer_type == 'withdraw':
            # Withdraw from user account

            transaction.entry_set.add(
                TransactionEntry(account=account, debit=amount))
            transaction.entry_set.add(
                TransactionEntry(account=bank_account, credit=amount))

            transaction.set_pending(user=request.user, message=details)

        elif transfer_type == 'transfer':
            # Transfer from user account to other user account

            credit_account = Account.objects.get(
                id=form.cleaned_data['credit_account'])

            transaction.entry_set.add(
                TransactionEntry(account=account, debit=amount))
            transaction.entry_set.add(
                TransactionEntry(account=credit_account, credit=amount))

            transaction.set_pending(user=request.user, message=details)

            if amount <= account.normal_balance() - (group.block_limit or 0):
                transaction.set_committed(user=request.user)
            else:
                messages.info(request, _(
                    'Your transaction has been added, '
                    'but your group admin has to commit it.'))

        else:
            return HttpResponseForbidden(_('Forbidden if not group admin.'))

        messages.success(request, _('Added transaction: %s') % transaction)

        return HttpResponseRedirect(reverse(
            'account-summary', args=[account.group.slug, account.slug]))

    return render_to_response('accounting/transfer.html', {
        'is_admin': is_admin,
        'is_owner': is_owner,
        'account': account,
        'type': transfer_type,
        'title': title,
        'form': form,
        'group': group,
    }, context_instance=RequestContext(request))
Example #33
0
def new_edit_transaction(request, group, transaction=None, is_admin=False):
    """Admin view for creating transactions"""

    savepoint_id = db_transaction.savepoint()
    if transaction is None:
        transaction = Transaction(group=group)
    elif not transaction.is_editable():
        messages.error(request,
                       _("Transaction %d can't be changed." % transaction.id))

        db_transaction.savepoint_rollback(savepoint_id)

        url = reverse("group-summary", args=(group.slug, ))
        return HttpResponseRedirect(url)

    if request.method == "POST":
        data = request.POST
    elif transaction.id:
        data = {}
        # Load "fake" post data if we are editing a transaction
        for e in transaction.entry_set.all():
            if e.debit > 0:
                data["%d-debit" % e.account.id] = e.debit
            if e.credit > 0:
                data["%d-credit" % e.account.id] = e.credit

        data["settlement-settlement"] = transaction.settlement_id
    else:
        data = None

    # Init forms
    settlement_form = TransactionSettlementForm(data,
                                                prefix="settlement",
                                                instance=transaction)

    user_forms = []
    group_forms = []

    for account in ufs_sorted(group.user_account_set.filter(active=True)):
        user_forms.append((account, EntryForm(data, prefix=account.id)))

    for account in ufs_sorted(group.group_account_set.filter(active=True)):
        group_forms.append((account, EntryForm(data, prefix=account.id)))

    errors = []

    if request.method == "POST" and settlement_form.is_valid():
        entries = {}

        if transaction.id is None:
            transaction.save()
        else:
            for e in transaction.entry_set.all():
                entries[e.account.id] = e

        transaction.settlement = settlement_form.cleaned_data["settlement"]

        try:
            for forms in [group_forms, user_forms]:
                for account, form in forms:
                    if not form.is_valid():
                        raise InvalidTransaction("Form was not valid, id: %d" %
                                                 account.id)
                    else:
                        credit = form.cleaned_data["credit"] or 0
                        debit = form.cleaned_data["debit"] or 0

                        if account.id in entries:
                            entry = entries[account.id]
                        else:
                            entry = TransactionEntry(account=account,
                                                     transaction=transaction)

                        if credit > 0 or debit > 0:
                            entry.credit = credit or 0
                            entry.debit = debit or 0
                            entry.save()
                        elif entry.id:
                            entry.delete()

            details = settlement_form.cleaned_data["details"]

            transaction.save()

            transaction.set_pending(user=request.user, message=details)

            messages.success(request, _("Your transaction has been added."))

        except InvalidTransaction as e:
            errors.append(e)
            db_transaction.savepoint_rollback(savepoint_id)
        else:
            db_transaction.savepoint_commit(savepoint_id)
            url = reverse("group-summary", args=(group.slug, ))
            return HttpResponseRedirect(url)

    db_transaction.savepoint_rollback(savepoint_id)

    return render(
        request,
        "accounting/transaction_form.html",
        {
            "is_admin": is_admin,
            "group": group,
            "settlement_form": settlement_form,
            "group_forms": group_forms,
            "user_forms": user_forms,
            "errors": errors,
            "transaction": transaction,
        },
    )
Example #34
0
    def setUp(self):
        self.users = [
            User(username="******"),
            User(username="******"),
            User(username="******"),
        ]
        for user in self.users:
            user.save()

        self.group = Group(name="Group 1", slug="group1")
        self.group.save()

        self.accounts = [
            # Normal user account
            Account(
                name="Account 1",
                slug="account1",
                group=self.group,
                owner=self.users[0],
            ),
            # Normal user account
            Account(
                name="Account 2",
                slug="account2",
                group=self.group,
                owner=self.users[1],
            ),
            # Inactive user account
            Account(
                name="Account 3",
                slug="account3",
                group=self.group,
                owner=self.users[2],
                active=False,
            ),
            # Group account
            Account(
                name="Account 4",
                slug="account4",
                group=self.group,
                type=Account.ASSET_ACCOUNT,
            ),
            # Inactive group account
            Account(
                name="Account 5",
                slug="account5",
                group=self.group,
                type=Account.ASSET_ACCOUNT,
                active=False,
            ),
            # Bank account
            self.group.roleaccount_set.get(role=RoleAccount.BANK_ACCOUNT
                                           ).account,
            # Cash account
            self.group.roleaccount_set.get(role=RoleAccount.CASH_ACCOUNT
                                           ).account,
        ]
        for account in self.accounts:
            account.save()
        self.account = self.accounts[0]

        self.transactions = {
            "Pen": Transaction(group=self.group),
            "Com": Transaction(group=self.group),
            "Rej": Transaction(group=self.group),
        }
        values = {"Pen": 150, "Com": 200, "Rej": 100}
        for state, transaction in self.transactions.items():
            transaction.save()
            transaction.entry_set.create(account=self.accounts[0],
                                         credit=values[state])
            transaction.entry_set.create(account=self.accounts[1],
                                         debit=values[state])
            transaction.set_pending(user=self.users[0])

        self.transactions["Undef"] = Transaction(group=self.group)
        self.transactions["Undef"].save()

        self.transactions["Com"].set_committed(user=self.users[2])
        self.transactions["Rej"].set_rejected(user=self.users[2])