123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172 |
- #!/usr/bin/python3
- import datetime
- from decimal import *
- from settings import DATA
- from prettytable import PrettyTable
- TWOPLACES = Decimal(10) ** -2
- def daterange(start_date, end_date):
- for n in range(int ((end_date - start_date).days)):
- yield start_date + datetime.timedelta(n)
- class PayPeriod:
- def __init__(self, calculate=False):
- self.bills = []
- self.expenses = DATA.get('expenses')
- self.delta = None
- self.beginning = None
- self.end = None
- self.total_bills = None
- self.money_left = None
- self.total_expenses = None
- if calculate:
- self.calculate_budget()
- def lookup_bills(self):
- if not self.beginning or not self.end:
- self.current_pay_period()
- bill_data = DATA.get('bills')
- for day in daterange(self.beginning, self.end):
- x = bill_data.get(day.day)
- if x:
- for bill in x:
- self.bills.append(bill)
- def pay_period_delta(self):
- period = DATA.get('pay_period')
- if not period:
- raise Error
- unit = period.get('unit')
- value = period.get('value')
- if unit == 'week':
- self.delta = datetime.timedelta(weeks=value)
- elif unit == 'day':
- self.delta = datetime.timedelta(days=value)
- elif unit == 'month':
- self.delta = value
- else:
- raise Error
- def current_pay_period(self):
- self.find_pay_period(datetime.date.today())
- def next_pay_period(self):
- if self.delta == None:
- self.pay_period_delta()
- next_period = PayPeriod()
- next_period.find_pay_period(datetime.date.today() + self.delta)
- next_period.calculate_budget()
- return next_period
- def find_pay_period(self, date):
- if self.delta == None:
- self.pay_period_delta()
- pay_date_str = DATA.get('pay_date')
- if not pay_date_str:
- raise Error
- pay_period = DATA.get('pay_period')
- if not pay_period:
- raise Error
- pay_date_list = pay_date_str.split('/')
- pay_date = datetime.date(int(pay_date_list[0]), int(pay_date_list[1]), int(pay_date_list[2]))
- beginning = pay_date
- end = pay_date
- while date > end:
- beginning = end
- end += self.delta
- self.beginning = beginning
- self.end = end
- def calculate_budget(self):
- if not self.bills:
- self.lookup_bills()
- self.total_bills = Decimal(0)
- for bill in self.bills:
- self.total_bills += bill.get('amt')
- self.total_expenses = Decimal(0)
- for expense in self.expenses:
- self.total_expenses += expense.get('amt')
- self.money_left = DATA.get("pay_amount") - self.total_bills - self.total_expenses
- def print_budget(self):
- if not self.total_bills:
- self.calculate_budget()
- print("\nBills")
- print("***************************")
- bills_table = PrettyTable(["Description", "Amount"])
- bills_table.align["Amount"] = "r"
- for bill in self.bills:
- bills_table.add_row([bill.get('desc'), bill.get('amt').quantize(TWOPLACES)])
- bills_table.add_row(["----------", "-----"])
- bills_table.add_row(["Total", self.total_bills.quantize(TWOPLACES)])
- print(bills_table)
- print("\nExpenses")
- print("***************************")
- expenses_table = PrettyTable(["Description", "Amount"])
- expenses_table.align["Amount"] = "r"
- for expense in self.expenses:
- expenses_table.add_row([expense.get('desc'), expense.get('amt').quantize(TWOPLACES)])
- expenses_table.add_row(["----------", "-----"])
- expenses_table.add_row(["Total", self.total_expenses.quantize(TWOPLACES)])
- print(expenses_table)
- print("\nTotals")
- print("***************************")
- print("Expenses Total: " + str(self.total_expenses.quantize(TWOPLACES)))
- print("Money After Bills + Expenses: " + str(self.money_left.quantize(TWOPLACES)))
- next_period = self.next_pay_period()
- money_left_next = next_period.money_left
- print("Money After Bills + Expenses Next: " + str(money_left_next.quantize(TWOPLACES)))
- if money_left_next <= 0:
- print("Not enough money left next paycheck!! Expenses being rolled together!")
- self.expenses += next_period.expenses
- self.calculate_budget()
- self.money_left = self.money_left + money_left_next + next_period.total_expenses
- print("Money left after combining: " + str(self.money_left.quantize(TWOPLACES)))
- print("\nPercent Expenses")
- print("***************************")
- total_perc_expenses = Decimal(0)
- perc_expenses = PrettyTable(["Description", "Amount"])
- perc_expenses.align["Amount"] = "r"
- for perc_expense in DATA.get("perc_expenses", []):
- amt = perc_expense.get('perc') * self.money_left
- total_perc_expenses += amt
- perc_expenses.add_row([perc_expense.get('desc'), amt.quantize(TWOPLACES)])
- perc_expenses.add_row(["----------", "-----"])
- perc_expenses.add_row(["Total", total_perc_expenses.quantize(TWOPLACES)])
- print(perc_expenses)
- money_left_perc = self.money_left - total_perc_expenses
- print("\nAllowances")
- print("***************************")
- allowance_table = PrettyTable(["Description", "Amount"])
- allowance_table.align["Amount"] = "r"
- for allowance in DATA.get("allowances", []):
- amt = allowance.get('perc') * money_left_perc
- allowance_table.add_row([allowance.get('desc'), amt.quantize(TWOPLACES)])
- print(allowance_table)
- pay_period = PayPeriod()
- pay_period.print_budget()
|