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 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 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 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)
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()
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 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))
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()
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()
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))
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 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)
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()
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 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 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 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 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}, )
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))
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 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 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 }, )
def testEmptyTransaction(self): """Checks that empty transactions are accepted""" transaction = Transaction(group=self.group) transaction.save() transaction.delete()
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)
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)
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])
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)
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, }, )
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)
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))
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, }, )
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])