add whole new app for balance prediction, replace uwsgi, update everything
This commit is contained in:
0
core/management/commands/__init__.py
Normal file
0
core/management/commands/__init__.py
Normal file
74
core/management/commands/predict_balance.py
Normal file
74
core/management/commands/predict_balance.py
Normal file
@@ -0,0 +1,74 @@
|
||||
from datetime import datetime
|
||||
from decimal import Decimal
|
||||
|
||||
from dateutil.relativedelta import relativedelta
|
||||
from django.core.management import BaseCommand
|
||||
|
||||
from core.models import Subject
|
||||
from core.prediction import predict_transactions
|
||||
|
||||
past_lookup_delta = relativedelta(weeks=2)
|
||||
future_lookup_delta = relativedelta(months=2)
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument(
|
||||
"--start", default="0", help="the current balance to use as a starting point for prediction",
|
||||
)
|
||||
|
||||
def handle(self, *args, **options):
|
||||
start_balance = Decimal(options["start"])
|
||||
|
||||
today = datetime.now().date()
|
||||
past_lookup_bound = today - past_lookup_delta
|
||||
future_lookup_bound = today + future_lookup_delta
|
||||
|
||||
transaction_dict = {}
|
||||
for subject in Subject.objects.all():
|
||||
transactions = []
|
||||
for tr in subject.transactions.order_by("booking_date"):
|
||||
if past_lookup_bound <= tr.booking_date <= future_lookup_bound:
|
||||
transactions.append(tr)
|
||||
predicted_transaction, prediction_info = predict_transactions(subject)
|
||||
if predicted_transaction:
|
||||
first_predicted_date = predicted_transaction[0].booking_date
|
||||
if first_predicted_date >= past_lookup_bound:
|
||||
# if two weeks after the first predicted transaction have passed, the subject is considered done
|
||||
for tr in predicted_transaction:
|
||||
if past_lookup_bound <= tr.booking_date <= future_lookup_bound:
|
||||
transactions.append(tr)
|
||||
transaction_dict[subject] = (transactions, prediction_info)
|
||||
|
||||
future_transactions = []
|
||||
for subject, prediction in transaction_dict.items():
|
||||
transactions, info = prediction[0], prediction[1]
|
||||
print(f">>> {subject}")
|
||||
if info:
|
||||
rec_days, rec_months, day_of_month = \
|
||||
info["recurring_days"], info["recurring_months"], info["day_of_month"]
|
||||
if rec_months and day_of_month:
|
||||
print(f"~~~ predicted transaction on day-of-month {day_of_month} every {rec_months} month(s)")
|
||||
elif rec_months:
|
||||
print(f"~~~ predicted transaction every {rec_months} month(s)")
|
||||
elif rec_days:
|
||||
print(f"~~~ predicted transaction every {rec_days} day(s)")
|
||||
else:
|
||||
print("~~~ no prediction possible")
|
||||
for tr in transactions:
|
||||
print(f" {tr.booking_date:%d.%m.%Y} | {tr.amount} € | {'stored' if tr.pk else 'predicted'}")
|
||||
if tr.booking_date > today:
|
||||
future_transactions.append(tr)
|
||||
print()
|
||||
|
||||
current_balance = start_balance
|
||||
print(f"starting calculation with amount {current_balance} €")
|
||||
for tr in sorted(future_transactions, key=lambda t: t.booking_date):
|
||||
current_balance += tr.amount
|
||||
print(
|
||||
f"{tr.booking_date:%d.%m.%Y} | "
|
||||
f"{tr.subject.name:<18} | "
|
||||
f"{tr.amount:>8} € ==> "
|
||||
f"{current_balance:>8} €"
|
||||
)
|
||||
Reference in New Issue
Block a user