126 lines
4.7 KiB
Python
126 lines
4.7 KiB
Python
import json
|
|
from decimal import *
|
|
from datetime import *
|
|
|
|
##############################################################################
|
|
#
|
|
# This is the BQL query to put into Fava to generate the CSV that can be used
|
|
# to create the JSON file for this. Might consider reading in the CSV directly
|
|
# and prompting for the other information?
|
|
#
|
|
# select date, number where year=2022 And account~".*:CreditLine"
|
|
#
|
|
##############################################################################
|
|
#
|
|
# Consider altering this program to generate the text to go into the beancount
|
|
# files directly so that it can just be a cut and paste job.
|
|
#
|
|
##############################################################################
|
|
|
|
|
|
def main():
|
|
filename = '2023.gtploc.json'
|
|
account = loadAccountInformation(getFullPathofFile(filename))
|
|
|
|
starting_balance = Decimal(account['starting_balance'])
|
|
apr = Decimal(account['interest_rate']) / 100
|
|
daily_interest_rate = apr / 360
|
|
|
|
fiscal_year = account['fiscal_year']
|
|
first_day = datetime(fiscal_year, 1, 1)
|
|
last_day = datetime(fiscal_year, 12, 31)
|
|
days_in_year = (last_day - first_day).days + 2
|
|
print("Line of Credit Report")
|
|
print("Fiscal Year: {1} Input File Name: {0}".format(filename, fiscal_year))
|
|
print("Starting Balance: {0} Interest Rate: {1}".format(starting_balance, account['interest_rate']))
|
|
print("Report Run Date: {0}".format(datetime.now()))
|
|
print("\n=========================================================================================\n")
|
|
|
|
day_nets = {}
|
|
transactions = account['transactions']
|
|
print("Summarizing {0} transactions:".format(len(transactions)))
|
|
for entry in transactions:
|
|
entry_date = entry[0]
|
|
entry_amount = Decimal(entry[1])
|
|
|
|
if entry_date not in day_nets:
|
|
day_nets[entry_date] = entry_amount
|
|
else:
|
|
day_nets[entry_date] = day_nets[entry_date] + entry_amount
|
|
|
|
for key in day_nets.keys():
|
|
print("Date: {0} Net Change: {1}".format(key, day_nets[key]))
|
|
|
|
print("Summary complete.")
|
|
|
|
current_balance = starting_balance
|
|
accummulated_interest = Decimal('0.00')
|
|
daily_interest = calculateDailyInterest(current_balance, daily_interest_rate)
|
|
|
|
print("\n=========================================================================================\n")
|
|
print("Calculating interest charges...")
|
|
# print("Beginning Balance: {1} Daily Interest: {2}".format(first_day,starting_balance, daily_interest))
|
|
for i in range(1, days_in_year):
|
|
current_date = (first_day + timedelta(days=i-1)).date()
|
|
|
|
if current_date.day == 1:
|
|
print("BEGIN MONTH: {0} Starting Balance: {1} Starting Daily Interest: {2}".format(current_date,
|
|
current_balance,
|
|
daily_interest))
|
|
|
|
if current_date.__str__() in day_nets:
|
|
current_balance = current_balance + day_nets[current_date.__str__()]
|
|
daily_interest = calculateDailyInterest(current_balance, daily_interest_rate)
|
|
print("Balance Change: Date: {0} Net: {1} New Balance: {2}".format(
|
|
current_date, day_nets[current_date.__str__()], current_balance))
|
|
|
|
accummulated_interest = accummulated_interest + daily_interest
|
|
|
|
if is_last_day_of_month(current_date):
|
|
current_balance = current_balance + accummulated_interest
|
|
daily_interest = calculateDailyInterest(current_balance, daily_interest_rate)
|
|
print("END MONTH: Date: {0} Post Accumulated Interest: {1} New Balance: {2} New Daily Interest: {3}".format(
|
|
current_date, accummulated_interest, current_balance, daily_interest))
|
|
accummulated_interest = 0
|
|
|
|
|
|
def is_last_day_of_month(some_date):
|
|
if some_date.day < 28:
|
|
return False
|
|
|
|
next_day = some_date + timedelta(days=1)
|
|
if next_day.month == some_date.month:
|
|
return False
|
|
return True
|
|
|
|
|
|
def calculateDailyInterest(principal, rate):
|
|
return (principal*rate).quantize(Decimal('.001'))
|
|
|
|
|
|
def loadAccountInformation(filename):
|
|
return getDatastore(filename)
|
|
|
|
|
|
def getDatastore(filename=None):
|
|
try:
|
|
if filename:
|
|
with open(filename, 'r') as f:
|
|
datastore = json.load(f)
|
|
|
|
except Exception as e:
|
|
print("An error occurred opening your file '%s'. " % filename)
|
|
print("The Exception:")
|
|
print(e.__repr__())
|
|
quit()
|
|
|
|
return datastore
|
|
|
|
|
|
def getFullPathofFile(filename):
|
|
return '/Users/john/PycharmProjects/LoCInterestCalculator/' + filename
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|