Created
September 6, 2019 18:55
-
-
Save hexvolt/7dfd51381650c50126ddbd3dfcfa6ea9 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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), | |
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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