@@ -68,10 +68,12 @@ class RunningTotal(models.Model):
68
68
This is used to speed up the calculation of account balances.
69
69
70
70
This field should be considered an estimated value calculated for performance reasons.
71
- It is not guaranteed to be accurate.
71
+ It is not guaranteed to be accurate:
72
+ * Running totals are calculated through post_delete and pre_save signals on the Transaction model.
73
+ This means that they are not updated when a transaction is mass updated.
74
+ * They don't take into account children accounts - the total value of a parent
75
+ account needs to be calculated from its children manually now
72
76
73
- Running totals are calculated through post_delete and pre_save signals on the Transaction model.
74
- This means that they are not updated when a transaction is mass updated.
75
77
"""
76
78
77
79
account = models .ForeignKey (
@@ -386,30 +388,46 @@ def transfer_to(self, to_account, amount, **transaction_kwargs):
386
388
return transaction
387
389
388
390
def update_running_totals (self , check_only = False ):
389
- """Update the running totals for this account"""
390
- all_values_are_correct = True
391
+ """
392
+ Update the running totals for this account by counting all transactions
391
393
394
+ Args:
395
+ check_only (bool): If true, don't actually update the running totals,
396
+ just check that they are correct.
397
+ Returns:
398
+ list: A list of currencies that have been updated or didn't pass the check
399
+ """
392
400
total = self .balance ()
401
+ faulty_values = []
402
+
393
403
for money in total .monies ():
394
404
currency = money .currency .code
405
+ if total [currency ].amount == 0 :
406
+ continue
395
407
try :
396
408
running_total = self .running_totals .get (currency = currency )
397
409
if running_total .balance != total [currency ]:
398
410
print (
399
411
f"Running total for { self } ({ currency } ) is "
400
412
f"{ running_total .balance } but should be { total [currency ]} "
401
413
)
402
- all_values_are_correct = False
414
+ faulty_values .append (
415
+ (currency , running_total .balance , total [currency ])
416
+ )
417
+ if not check_only :
418
+ self .running_totals .filter (currency = currency ).update (
419
+ balance = total [currency ]
420
+ )
403
421
except RunningTotal .DoesNotExist :
404
422
print (f"No running total for { self } ({ currency } )" )
405
- all_values_are_correct = False
406
- if not check_only :
407
- RunningTotal .objects .update_or_create (
408
- account = self ,
409
- currency = currency ,
410
- defaults = { "balance" : total [currency ]} ,
411
- )
412
- return all_values_are_correct
423
+ faulty_values . append (( currency , None , total [ currency ]))
424
+ if not check_only :
425
+ RunningTotal .objects .create (
426
+ account = self ,
427
+ currency = currency ,
428
+ balance = total [currency ],
429
+ )
430
+ return faulty_values
413
431
414
432
415
433
class TransactionManager (models .Manager ):
0 commit comments