Skip to content

Instantly share code, notes, and snippets.

@hexvolt
Created September 6, 2019 18:55
Show Gist options
  • Save hexvolt/7dfd51381650c50126ddbd3dfcfa6ea9 to your computer and use it in GitHub Desktop.
Save hexvolt/7dfd51381650c50126ddbd3dfcfa6ea9 to your computer and use it in GitHub Desktop.
class Account(models.Model):
client = models.ForeignKey(Client, related_name='client')
transactions = models.ManyToManyField('Transaction')
name = models.CharField(max_length=150, unique=True, null=True, blank=True)
currency = models.ForeignKey('Currency', related_name='currency')
is_usd_account = models.BooleanField(default=False)
created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(null=True, blank=True)
class Meta:
ordering = ['-created']
def recalculate(self):
pass
# ...business logic:
# analyzing all the transactions of account, updating
# some application-wide metrics and other stuff
def display_name(self):
return f"Account: {self.name}"
def save(self, **kwargs):
self.modified = datetime.now()
super().save(**kwargs)
class Transaction(models.Model):
account = models.ForeignKey(Account, on_delete=models.CASCADE)
description = models.CharField(max_length=150, null=True, blank=True)
amount = models.DecimalField(max_digits=12, decimal_places=4, null=True, blank=True)
created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(null=True, blank=True)
def save(self, **kwargs):
self.modified = datetime.now()
self.account.transactions.add(self)
self.account.recalculate()
super().save(**kwargs)
def get_client_statistics(client):
"""
Return a total amount of all transactions of a client and the total number of transactions.
:return tuple: (<total_amount>, <number>)
"""
if not client:
return None
x = y = 0
accounts = Account.objects.filter(client=client).all()
for account in accounts:
transactions = Transaction.objects.filter(account=account, amount__gt=0).all()
y += transactions.count()
for transaction in transactions:
x += transaction.amount
return x, y
from models import Account
def forwards(migration_apps, schema_editor):
for account in Account.objects.all():
account.name = account.display_name
account.save()
class Migration(migrations.Migration):
dependencies = [
# ...
]
operations = [
migrations.RunPython(forwards, None),
]
class StatisticsTestCase(TestCase):
def setUp(self):
self.client_a = Client.objects.create(...)
self.account_a = Account.objects.create(client=self.client_a, ...)
Transaction.objects.create(account=self.account_a, amount=2.5, ...)
Transaction.objects.create(account=self.account_a, amount=-2, ...)
Transaction.objects.create(account=self.account_a, amount=0.5, ...)
self.client_b = Client.objects.create(...)
self.account_b = Account.objects.create(client=self.client_b, ...)
Transaction.objects.create(account=self.account_b, amount=-5, ...)
Transaction.objects.create(account=self.account_b, amount=-2, ...)
Transaction.objects.create(account=self.account_b, amount=0, ...)
def test_statistics(self):
self.assertIsNone(get_client_statistics(None))
amount, number = get_client_statistics(self.client_a)
self.assertEqual(amount, 3)
self.assertEqual(number, 2)
amount, number = get_client_statistics(self.client_b)
self.assertEqual(amount, 0)
self.assertEqual(number, 0)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment