def get_user_expenses(cls, month, year): """ """ first_day = date(year, month, 1) if month == 12: last_day = date(year + 1, 1, 1) else: last_day = date(year, month + 1, 1) logging.info("load user expenses between %s and %s" % (first_day.strftime('%d %b %Y'), last_day.strftime('%d %b %Y'))) q = Expenses.query(ancestor=expenses_key(month, year)) q.filter(ndb.AND(Expenses.date >= first_day, Expenses.date < last_day)) #query for old data that had no ancestor (before migration to High Replication Datastore) q_old = Expenses.query(ndb.AND(Expenses.date >= first_day, Expenses.date < last_day)) users_expenses = dict() keys = set() if users_helper.is_autorized(): # always start with the current user currentUser = users.get_current_user().nickname() users_expenses[currentUser] = UserExpenses(currentUser) x = 0 #TODO Hem refactor this ugly code for exp in q.fetch(500): exp.update_urlsafe() keys.add(exp.urlsafe) user_nickname = exp.user.nickname() if user_nickname not in users_expenses.keys(): users_expenses[user_nickname] = UserExpenses(user_nickname) users_expenses[user_nickname].add(exp) x += 1 logging.info('%d expenses with ancestor', x) x = 0 for exp in q_old.fetch(500): exp.update_urlsafe() if exp.urlsafe not in keys: user_nickname = exp.user.nickname() if user_nickname not in users_expenses.keys(): users_expenses[user_nickname] = UserExpenses(user_nickname) users_expenses[user_nickname].add(exp) x += 1 logging.info('%d expenses with no ancestor', x) for usr in users_expenses.keys(): users_expenses[usr].taxratio = cls.get_tax_ratio(usr, year) users_expenses[usr].expenses = sorted(users_expenses[usr].expenses, key=lambda e: e.date) return users_expenses.values()
def __edit_shared_expense_into_simple(current_user_id, our_expenses, expense, our_accounts, our_users, date, description, account_id, amount, error, category_id, categories, accounts, users, expense_id, key=None, dict=None): '''Edit a shared expense entry into a simple expense entry''' our_loans = Loans(current_user_id) # percentage split loaned_then_amount = round((float(expense[0].amount) * (100-float(expense[3])))/100, 2) # credit our loan account our_accounts.modify_loan_balance(amount=-float(loaned_then_amount), with_user_id=expense[2]) their_expenses = Expenses(expense[2]) their_accounts = Accounts(expense[2]) their_loans = Loans(expense[2]) # fetch their expense their_expense = their_expenses.get_expense(loan_id=expense[1]) # delete the shared user's expense their_expenses.delete_expense(expense_id=their_expense[0].id) # delete their loan status towards us their_accounts.modify_loan_balance(amount=expense[4], with_user_id=current_user_id) # unlink expenses to loan entries our_expenses.unlink_loan(loan_id=expense[1]) # get slug as a unique identifier slug = our_loans.get_loan_slug(loan_id=expense[1]) # delete the original loans our_loans.delete_loan(loan_id=expense[1]) their_loans.delete_loan(slug=slug) flash('Loan reverted') # credit our account back with the full amount (expense amount + loaned amount) our_accounts.modify_user_balance(amount=float(expense[0].amount), account_id=expense[0].deduct_from) # debit from account our_accounts.modify_user_balance(amount=-float(amount), account_id=account_id) # edit expense our_expenses.edit_expense(date=date, category_id=category_id, account_id=account_id, amount=amount, description=description, expense_id=expense_id) flash('Expense edited') # do a GET otherwise category will fail return redirect(url_for('expenses.edit_expense', expense_id=expense_id))
def dashboard(): '''Test budget dashboard''' u = UsersTable(u"Admin", False, u"admin", u"admin") db_session.add(u) db_session.commit() current_user_id = u.id # get uncategorized expenses exp = Expenses(current_user_id) uncategorized_expenses = exp.get_entries(category_name="Uncategorized") # get latest expenses exp = Expenses(current_user_id) latest_expenses = exp.get_entries(limit=5) # get accounts acc = Accounts(current_user_id) accounts = acc.get_accounts_and_loans() # split, get totals assets, liabilities, loans, assets_total, liabilities_total = [], [], [], 0, 0 for a in accounts: if a[0].type == 'asset': assets.append(a) assets_total += float(a[0].balance) elif a[0].type == 'liability': liabilities.append(a) liabilities_total += float(a[0].balance) elif a[0].type == 'loan': # if we owe someone, it is our liability if float(a[0].balance) < 0: liabilities.append(a) liabilities_total += float(a[0].balance) else: assets.append(a) # get the monthly totals t = Totals(current_user_id) totals = t.get_totals() return render_template('admin_dashboard.html', **locals()) #class SQLiteSequenceTable(Base): # """SQLite sequence table""" # # __tablename__ = 'sqlite_master' # rowid = Column(Integer, primary_key=True) # name = Column(String(200)) # seq = Column(Integer)
def post(self): try: bank_statement = self.get_uploads()[0] from ofxparse import OfxParser ofx = OfxParser.parse(bank_statement.open()) user = users.get_current_user() logging.info(ofx.account.number) # The account number logging.info(ofx.account.routing_number) # The transit id (sometimes called branch number) #logging.info(ofx.account.statement # Account information for a period of time logging.info(ofx.account.statement.start_date) # The start date of the transactions logging.info(ofx.account.statement.end_date) # The end date of the transactions #ofx.account.statement.transactions # A list of account activities logging.info(ofx.account.statement.balance) # The money in the account as of the statement for tx in ofx.account.statement.transactions: logging.info(vars(tx)) if tx.type == 'debit': # new expense: new_expense = Expenses(parent=expenses_key(tx.date.month, tx.date.year)) new_expense.user = user new_expense.date = tx.date new_expense.amount = -float(str(tx.amount)) new_expense.category = tx.payee new_expense.exptype = 3 new_expense.put() finally: self.redirect('comptes')
def index(date=None, category=None, page=1, items_per_page=10): '''List expenses for the user''' model = Expenses(session.get('logged_in_user')) dict = entries.index(**locals()) for key in dict.keys(): exec(key + " = dict['" + key + "']") return render_template('admin_show_expenses.html', **locals())
def search(): '''Search expenses''' model = Expenses(session.get('logged_in_user')) # query query = request.form['q'] if 'q' in request.form else "" # fetch entries entries = model.get_entries() # filter entries = entries.filter(ExpensesTable.description.like("%"+query+"%")) # categories categories = model.get_categories() # date ranges for the template date_ranges = get_date_ranges() return render_template('admin_search_expenses.html', **locals())
def search(): '''Search expenses''' model = Expenses(session.get('logged_in_user')) # query query = request.form['q'] if 'q' in request.form else "" # fetch entries entries = model.get_entries() # filter entries = entries.filter(ExpensesTable.description.like("%" + query + "%")) # categories categories = model.get_categories() # date ranges for the template date_ranges = get_date_ranges() return render_template('admin_search_expenses.html', **locals())
def get(self): # print 'coucou' # query = db.GqlQuery('SELECT * FROM Expenses') query = Expenses.query() expenses = query.fetch(10000) self.jsonData = dict() self.jsonData["tags"] = dict() for exp in expenses: for tag in exp.tags: if tag != "": self.update_tag(tag, exp.amount, exp.date) self.persist() self.response.out.write(simplejson.dumps(self.jsonData))
def add_category(): '''Add an expense category''' error = None if request.method == 'POST': new_category_name, current_user_id = request.form['name'], session.get( 'logged_in_user') exp = Expenses(current_user_id) error = entries.add_category(exp, new_category_name) if not error: flash('Expense category added') return render_template('admin_add_expense_category.html', error=error)
def index(): '''Budget dashboard''' current_user_id = session.get('logged_in_user') # get uncategorized expenses exp = Expenses(current_user_id) uncategorized_expenses = exp.get_entries(category_name="Uncategorized") # get latest expenses exp = Expenses(current_user_id) latest_expenses = exp.get_entries(limit=5) # get latest income inc = Income(current_user_id) latest_income = inc.get_entries(limit=5) # get accounts acc = Accounts(current_user_id) accounts = acc.get_accounts_and_loans() # split, get totals assets, liabilities, loans, assets_total, liabilities_total = [], [], [], 0, 0 for a in accounts: if a[0].type == 'asset': assets.append(a) assets_total += float(a[0].balance) elif a[0].type == 'liability': liabilities.append(a) liabilities_total += float(a[0].balance) elif a[0].type == 'loan': # if we owe someone, it is our liability if float(a[0].balance) < 0: liabilities.append(a) liabilities_total += float(a[0].balance) else: assets.append(a) # monthly totals t, totals_list, highest_bar = Totals(current_user_id), [], 0. # object to dict for total in t.get_totals(): bar = {} bar['month'] = total.month if (float(total.expenses) > 0): bar['expenses'] = float(total.expenses) if (float(total.income) > 0): bar['income'] = float(total.income) totals_list.append(bar) if (total.expenses > highest_bar): highest_bar = total.expenses if (total.income > highest_bar): highest_bar = total.income # calculate height for each bar for total in totals_list: if 'expenses' in total: total['expenses-height'] = (total['expenses'] / highest_bar) * 100 if 'income' in total: total['income-height'] = (total['income'] / highest_bar) * 100 return render_template('admin_dashboard.html', **locals())
def post(self): try: selected_month = int(self.request.get("mois")) selected_year = int(self.request.get("annee")) except: dtnow = datetime.utcnow() selected_month = dtnow.month selected_year = dtnow.year if users.get_current_user(): urlsafe = self.request.get("urlsafe") if urlsafe != "": logging.info("get expense from key " + urlsafe) new_expense = Expenses.get_from_key(ndb.Key(urlsafe=urlsafe)) if new_expense is None: raise Exception("unable to retrieve expense for key " + urlsafe) else: new_expense = Expenses(parent=expenses_key(selected_month, selected_year)) new_expense.update(users.get_current_user(), selected_month, selected_year, self.request) else: raise Exception("bad user") self.redirect("/comptes?mois=%d&annee=%d" % (selected_month, selected_year))
def export(date=None, category=None, page=1, items_per_page=10): '''Export expenses on a filter''' model = Expenses(session.get('logged_in_user')) dict = entries.index(**locals()) for key in dict.keys(): exec(key + " = dict['" + key + "']") response = make_response( render_template('admin_export_expenses.html', **locals())) response.headers['Content-type'] = 'text/csv' response.headers[ 'Content-disposition'] = 'attachment;filename=' + 'expenses-' + str( today_date()) + '.csv' return response
def dashboard(): '''Test budget dashboard''' u = UsersTable(u"Admin", False, u"admin", u"admin") db_session.add(u) db_session.commit() current_user_id = u.id # get uncategorized expenses exp = Expenses(current_user_id) uncategorized_expenses = exp.get_entries(category_name="Uncategorized") # get latest expenses exp = Expenses(current_user_id) latest_expenses = exp.get_entries(limit=5) # get accounts acc = Accounts(current_user_id) accounts = acc.get_accounts_and_loans() # split, get totals assets, liabilities, loans, assets_total, liabilities_total = [], [], [], 0, 0 for a in accounts: if a[0].type == 'asset': assets.append(a) assets_total += float(a[0].balance) elif a[0].type == 'liability': liabilities.append(a) liabilities_total += float(a[0].balance) elif a[0].type == 'loan': # if we owe someone, it is our liability if float(a[0].balance) < 0: liabilities.append(a) liabilities_total += float(a[0].balance) else: assets.append(a) # get the monthly totals t = Totals(current_user_id) totals = t.get_totals() return render_template('admin_dashboard.html', **locals()) #class SQLiteSequenceTable(Base): # """SQLite sequence table""" # # __tablename__ = 'sqlite_master' # rowid = Column(Integer, primary_key=True) # name = Column(String(200)) # seq = Column(Integer)
def get_last_twelve_months_category_expenses(self): last_year = date_helper.get_last_year_date() self.compute_labels(last_year) #TODO refactor #query = db.GqlQuery("SELECT * FROM Expenses WHERE category = :1 AND date >= :2 AND exptype = 1", self.category, last_year) #expenses = query.fetch(5000) q = Expenses.query() q.filter(ndb.AND(Expenses.category == self.category, Expenses.date >= last_year, Expenses.exptype == 1)) expenses = q.fetch(5000) amounts = [] for i in range(0, 12): amounts.append(0) for exp in expenses: index = date_helper.get_month_index(exp.date) if index != -1: amounts[index] += exp.amount self.totalamount += exp.amount self.compute_max_amount(amounts)
def add_expense(): '''Add an expense entry''' error = None current_user_id = session.get('logged_in_user') our_accounts = Accounts(current_user_id) our_expenses = Expenses(current_user_id) users = Users(current_user_id) if request.method == 'POST': dict = __validate_expense_form() for key in dict.keys(): exec(key + " = dict['" + key + "']") # 'heavier' checks if not error: # valid amount? if is_float(amount): # valid date? if is_date(date): # valid account? if our_accounts.is_account(account_id=account_id): # valid category? if our_expenses.is_category(id=category_id): # is it a shared expense? if 'is_shared' in request.form: # fetch values and check they are actually provided if 'split' in request.form: split = request.form['split'] else: error = 'You need to provide a % split' if 'user' in request.form: shared_with_user = request.form['user'] else: error = 'You need to provide a user' # 'heavier' checks if not error: # valid percentage split? if is_percentage(split): # valid user sharing with? if users.is_connection(user_id=shared_with_user): # figure out percentage split loaned_amount = round((float(amount)*(100-float(split)))/100, 2) # create loans our_loans = Loans(current_user_id) our_loan_id = our_loans.add_loan(other_user_id=shared_with_user, date=date, account_id=account_id, description=description, amount=-float(loaned_amount)) our_loans = Loans(shared_with_user) their_loan_id = our_loans.add_loan(other_user_id=current_user_id, date=date, description=description, amount=loaned_amount) # generate slugs for the new loans our_slugs = Slugs(current_user_id) slug = our_slugs.add_slug(type='loan', object_id=our_loan_id, description=description) their_slugs = Slugs(shared_with_user) their_slugs.add_slug(type='loan', object_id=their_loan_id, slug=slug) flash('Loan given') # add new expense (loaner) our_expense_id = our_expenses.add_expense(date=date, category_id=category_id, account_id=account_id, amount=float(amount) - loaned_amount, description=description) # add new expenses (borrower) their_expenses = Expenses(shared_with_user) their_expense_id = their_expenses.add_expense(date=date, amount=loaned_amount, description=description, pass_thru=True) # fudge loan 'account' monies our_accounts.modify_loan_balance(amount=loaned_amount, with_user_id=shared_with_user) their_accounts = Accounts(shared_with_user) their_accounts.modify_loan_balance(amount=-float(loaned_amount), with_user_id=current_user_id) # link loan and the expenses (through us) our_expenses.link_to_loan(expense_id=our_expense_id, loan_id=our_loan_id, shared_with=shared_with_user, percentage=split, original_amount=amount) their_expenses.link_to_loan(expense_id=their_expense_id, loan_id=our_loan_id, shared_with=current_user_id, percentage=split, original_amount=amount) else: error = 'Not a valid user sharing with' else: error = 'Not a valid % split' else: # add new expense our_expenses.add_expense(date=date, category_id=category_id, account_id=account_id, amount=amount, description=description) if not error: # debit from account our_accounts.modify_user_balance(amount=-float(amount), account_id=account_id) flash('Expense added') else: error = 'Not a valid category' else: error = 'Not a valid account' else: error = 'Not a valid date' else: error = 'Not a valid amount' # fetch user's categories, accounts and users categories = our_expenses.get_categories() if not categories: error = 'You need to define at least one category' accounts = our_accounts.get_accounts() if not accounts: error = 'You need to define at least one account' # fetch users from connections from us users = users.get_connections() return render_template('admin_add_expense.html', **locals())
def add_expense(): '''Add an expense entry''' error = None current_user_id = session.get('logged_in_user') our_accounts = Accounts(current_user_id) our_expenses = Expenses(current_user_id) users = Users(current_user_id) if request.method == 'POST': dict = __validate_expense_form() for key in dict.keys(): exec(key + " = dict['" + key + "']") # 'heavier' checks if not error: # valid amount? if is_float(amount): # valid date? if is_date(date): # valid account? if our_accounts.is_account(account_id=account_id): # valid category? if our_expenses.is_category(id=category_id): # is it a shared expense? if 'is_shared' in request.form: # fetch values and check they are actually provided if 'split' in request.form: split = request.form['split'] else: error = 'You need to provide a % split' if 'user' in request.form: shared_with_user = request.form['user'] else: error = 'You need to provide a user' # 'heavier' checks if not error: # valid percentage split? if is_percentage(split): # valid user sharing with? if users.is_connection( user_id=shared_with_user): # figure out percentage split loaned_amount = round( (float(amount) * (100 - float(split))) / 100, 2) # create loans our_loans = Loans(current_user_id) our_loan_id = our_loans.add_loan( other_user_id=shared_with_user, date=date, account_id=account_id, description=description, amount=-float(loaned_amount)) our_loans = Loans(shared_with_user) their_loan_id = our_loans.add_loan( other_user_id=current_user_id, date=date, description=description, amount=loaned_amount) # generate slugs for the new loans our_slugs = Slugs(current_user_id) slug = our_slugs.add_slug( type='loan', object_id=our_loan_id, description=description) their_slugs = Slugs( shared_with_user) their_slugs.add_slug( type='loan', object_id=their_loan_id, slug=slug) flash('Loan given') # add new expense (loaner) our_expense_id = our_expenses.add_expense( date=date, category_id=category_id, account_id=account_id, amount=float(amount) - loaned_amount, description=description) # add new expenses (borrower) their_expenses = Expenses( shared_with_user) their_expense_id = their_expenses.add_expense( date=date, amount=loaned_amount, description=description, pass_thru=True) # fudge loan 'account' monies our_accounts.modify_loan_balance( amount=loaned_amount, with_user_id=shared_with_user) their_accounts = Accounts( shared_with_user) their_accounts.modify_loan_balance( amount=-float(loaned_amount), with_user_id=current_user_id) # link loan and the expenses (through us) our_expenses.link_to_loan( expense_id=our_expense_id, loan_id=our_loan_id, shared_with=shared_with_user, percentage=split, original_amount=amount) their_expenses.link_to_loan( expense_id=their_expense_id, loan_id=our_loan_id, shared_with=current_user_id, percentage=split, original_amount=amount) else: error = 'Not a valid user sharing with' else: error = 'Not a valid % split' else: # add new expense our_expenses.add_expense( date=date, category_id=category_id, account_id=account_id, amount=amount, description=description) if not error: # debit from account our_accounts.modify_user_balance( amount=-float(amount), account_id=account_id) flash('Expense added') else: error = 'Not a valid category' else: error = 'Not a valid account' else: error = 'Not a valid date' else: error = 'Not a valid amount' # fetch user's categories, accounts and users categories = our_expenses.get_categories() if not categories: error = 'You need to define at least one category' accounts = our_accounts.get_accounts() if not accounts: error = 'You need to define at least one account' # fetch users from connections from us users = users.get_connections() return render_template('admin_add_expense.html', **locals())
def edit_expense(expense_id): '''Edit expense entry''' current_user_id = session.get('logged_in_user') our_expenses = Expenses(current_user_id) # is it valid? expense = our_expenses.get_expense(expense_id) if expense: error = None # early exit for shared expenses from the perspective of the shared with user if (expense[0].pass_thru): return __edit_pass_thru_expense(**locals()) our_accounts = Accounts(current_user_id) our_users = Users(current_user_id) # fetch user's categories, accounts and users categories = our_expenses.get_categories() if not categories: error = 'You need to define at least one category' accounts = our_accounts.get_accounts() if not accounts: error = 'You need to define at least one account' # fetch users from connections from us users = our_users.get_connections() # fudge the total for the expense if we have a shared expense if expense[1]: expense[0].amount = expense[4] if request.method == 'POST': dict = __validate_expense_form() for key in dict.keys(): exec(key + " = dict['" + key + "']") # 'heavier' checks if not error: # valid amount? if is_float(amount): # valid date? if is_date(date): # valid account? if our_accounts.is_account(account_id=account_id): # valid category? if our_expenses.is_category(id=category_id): if expense[1]: if 'is_shared' in request.form: # shared expense that will be shared return __edit_shared_expense_into_shared( **locals()) else: # shared expense that will be simple return __edit_shared_expense_into_simple( **locals()) else: if 'is_shared' in request.form: # simple expense that will be shared return __edit_simple_expense_into_shared( **locals()) else: # simple expense that will be shared return __edit_simple_expense_into_simple( **locals()) else: error = 'Not a valid category' else: error = 'Not a valid account' else: error = 'Not a valid date' else: error = 'Not a valid amount' # show the form return render_template('admin_edit_expense.html', **locals()) else: return redirect(url_for('expenses.index'))
def __edit_shared_expense_into_shared(current_user_id, our_expenses, expense, our_accounts, our_users, date, description, account_id, amount, error, category_id, categories, accounts, users, expense_id, key=None, dict=None): '''Edit a shared expense entry into a shared entry still''' # fetch values and check they are actually provided if 'split' in request.form: split = request.form['split'] else: error = 'You need to provide a % split' if 'user' in request.form: shared_with_user = request.form['user'] else: error = 'You need to provide a user' # 'heavier' checks if not error: # valid percentage split? if is_percentage(split): # valid user sharing with? if our_users.is_connection(user_id=shared_with_user): # figure out percentage split loaned_amount = round((float(amount) * (100-float(split)))/100, 2) loaned_then_amount = round((float(expense[0].amount) * (100-float(expense[3])))/100, 2) # is our original and current account the same? if expense[0].deduct_from == account_id: # modify the difference between then and now our_accounts.modify_user_balance(amount=expense[0].amount-float(amount), account_id=account_id) else: # credit our original account back our_accounts.modify_user_balance(amount=expense[0].amount, account_id=expense[0].deduct_from) # debit from our current account our_accounts.modify_user_balance(amount=-float(amount), account_id=account_id) our_loans = Loans(current_user_id) their_loans = Loans(expense[2]) # get slug as a unique identifier slug = our_loans.get_loan_slug(loan_id=expense[1]) # are we sharing the expense with the same user as before? if expense[2] == int(shared_with_user): # edit the loan entries our_loans.edit_loan(other_user_id=shared_with_user, account_id=account_id, description=description, amount=-float(loaned_amount), date=date, loan_id=expense[1]) their_loans.edit_loan(other_user_id=current_user_id, amount=loaned_amount, date=date, slug=slug) # modify our loan account balance difference with the user our_accounts.modify_loan_balance(amount=loaned_amount - loaned_then_amount, with_user_id=shared_with_user) # now for the user we share with their_expenses = Expenses(shared_with_user) their_accounts = Accounts(shared_with_user) # the user now and then is the same, get their expense their_expense = their_expenses.get_expense(loan_id=expense[1]) # modify their loan account balance their_accounts.modify_loan_balance(amount=-loaned_amount + loaned_then_amount, with_user_id=current_user_id) # edit their expense amount their_expenses.edit_expense(date=date, account_id=account_id, amount=loaned_amount, expense_id=their_expense[0].id, pass_thru=True) # update loan links our_expenses.modify_loan_link(loan_id=expense[1], percentage=split, original_amount=amount) their_expenses.modify_loan_link(loan_id=expense[1], percentage=split, original_amount=amount) else: # the other user we WERE sharing with their_expenses = Expenses(expense[2]) their_accounts = Accounts(expense[2]) # credit our loan account our_accounts.modify_loan_balance(amount=-float(loaned_then_amount), with_user_id=expense[2]) # fetch their expense their_expense = their_expenses.get_expense(loan_id=expense[1]) # delete the shared user's expense their_expenses.delete_expense(expense_id=their_expense[0].id) # modify their loan status towards us their_accounts.modify_loan_balance(amount=loaned_then_amount, with_user_id=current_user_id) # unlink expenses to loan entries our_expenses.unlink_loan(loan_id=expense[1]) # delete the original loans our_loans.delete_loan(loan_id=expense[1]) their_loans.delete_loan(slug=slug) flash('Loan reverted') # create a loan from us to the new user our_loan_id = our_loans.add_loan(other_user_id=shared_with_user, date=date, account_id=account_id, description=description, amount=-float(loaned_amount)) # create a loan entry for the new user their_loans = Loans(shared_with_user) their_loan_id = their_loans.add_loan(other_user_id=current_user_id, date=date, description=description, amount=loaned_amount) # generate slugs for the new loans our_slugs = Slugs(current_user_id) slug = our_slugs.add_slug(type='loan', object_id=our_loan_id, description=description) their_slugs = Slugs(shared_with_user) their_slugs.add_slug(type='loan', object_id=their_loan_id, slug=slug) flash('Loan given') # modify loan monies for us our_accounts.modify_loan_balance(amount=loaned_amount, with_user_id=shared_with_user) # the CURRENT user we are sharing with their_accounts = Accounts(shared_with_user) # fudge loan 'account' monies for them their_accounts.modify_loan_balance(amount=-float(loaned_amount), with_user_id=current_user_id) their_expenses = Expenses(shared_with_user) # add new expenses (borrower) their_expense_id = their_expenses.add_expense(date=date, amount=loaned_amount, description=description, pass_thru=True) # create new loan - expense links our_expenses.link_to_loan(expense_id=expense_id, loan_id=our_loan_id, shared_with=shared_with_user, percentage=split, original_amount=amount) their_expenses.link_to_loan(expense_id=their_expense_id, loan_id=our_loan_id, shared_with=current_user_id, percentage=split, original_amount=amount) # edit expense (loaner - us) our_expenses.edit_expense(date=date, category_id=category_id, account_id=account_id, amount=float(amount) - loaned_amount, description=description, expense_id=expense_id) flash('Expense edited') # do a GET otherwise category will fail return redirect(url_for('expenses.edit_expense', expense_id=expense_id)) else: error = 'Not a valid user sharing with' else: error = 'Not a valid % split' # show the form return render_template('admin_edit_expense.html', **locals())
def __edit_simple_expense_into_shared(current_user_id, our_expenses, expense, our_accounts, our_users, date, description, account_id, amount, error, category_id, categories, accounts, users, expense_id, key=None, dict=None): '''Edit a simple expense entry into a shared one''' # fetch values and check they are actually provided if 'split' in request.form: split = request.form['split'] else: error = 'You need to provide a % split' if 'user' in request.form: shared_with_user = request.form['user'] else: error = 'You need to provide a user' # 'heavier' checks if not error: # valid percentage split? if is_percentage(split): # valid user sharing with? if our_users.is_connection(user_id=shared_with_user): # figure out percentage split loaned_amount = round((float(amount)*(100-float(split)))/100, 2) # create loans our_loans = Loans(current_user_id) our_loan_id = our_loans.add_loan(other_user_id=shared_with_user, date=date, account_id=account_id, description=description, amount=-float(loaned_amount)) their_loans = Loans(shared_with_user) their_loan_id = their_loans.add_loan(other_user_id=current_user_id, date=date, description=description, amount=loaned_amount) # generate slugs for the new loans our_slugs = Slugs(current_user_id) slug = our_slugs.add_slug(type='loan', object_id=our_loan_id, description=description) their_slugs = Slugs(shared_with_user) their_slugs.add_slug(type='loan', object_id=their_loan_id, slug=slug) flash('Loan given') # is our original and current account the same? if expense[0].deduct_from == account_id: # modify the difference between then and now our_accounts.modify_user_balance(amount=expense[0].amount-float(amount), account_id=account_id) else: # credit our original account back our_accounts.modify_user_balance(amount=expense[0].amount, account_id=expense[0].deduct_from) # debit from our current account our_accounts.modify_user_balance(amount=-float(amount), account_id=account_id) # edit expense (loaner - us) our_expenses.edit_expense(date=date, category_id=category_id, account_id=account_id, amount=float(amount) - loaned_amount, description=description, expense_id=expense_id) their_expenses = Expenses(shared_with_user) their_accounts = Accounts(shared_with_user) # add new expenses (borrower) their_expense_id = their_expenses.add_expense(date=date, amount=loaned_amount, description=description, pass_thru=True) # modify their loan account balance their_accounts.modify_loan_balance(amount=-float(loaned_amount), with_user_id=current_user_id) # modify our loan account balance our_accounts.modify_loan_balance(amount=loaned_amount, with_user_id=shared_with_user) # link loan and the expenses our_expenses.link_to_loan(expense_id=expense_id, loan_id=our_loan_id, shared_with=shared_with_user, percentage=split, original_amount=amount) their_expenses.link_to_loan(expense_id=their_expense_id, loan_id=our_loan_id, shared_with=current_user_id, percentage=split, original_amount=amount) flash('Expense edited') # do a GET otherwise category will fail return redirect(url_for('expenses.edit_expense', expense_id=expense_id)) else: error = 'Not a valid user sharing with' else: error = 'Not a valid % split' # show the form return render_template('admin_edit_expense.html', **locals())
def edit_expense(expense_id): '''Edit expense entry''' current_user_id = session.get('logged_in_user') our_expenses = Expenses(current_user_id) # is it valid? expense = our_expenses.get_expense(expense_id) if expense: error = None # early exit for shared expenses from the perspective of the shared with user if (expense[0].pass_thru): return __edit_pass_thru_expense(**locals()) our_accounts = Accounts(current_user_id) our_users = Users(current_user_id) # fetch user's categories, accounts and users categories = our_expenses.get_categories() if not categories: error = 'You need to define at least one category' accounts = our_accounts.get_accounts() if not accounts: error = 'You need to define at least one account' # fetch users from connections from us users = our_users.get_connections() # fudge the total for the expense if we have a shared expense if expense[1]: expense[0].amount = expense[4] if request.method == 'POST': dict = __validate_expense_form() for key in dict.keys(): exec(key + " = dict['" + key + "']") # 'heavier' checks if not error: # valid amount? if is_float(amount): # valid date? if is_date(date): # valid account? if our_accounts.is_account(account_id=account_id): # valid category? if our_expenses.is_category(id=category_id): if expense[1]: if 'is_shared' in request.form: # shared expense that will be shared return __edit_shared_expense_into_shared(**locals()) else: # shared expense that will be simple return __edit_shared_expense_into_simple(**locals()) else: if 'is_shared' in request.form: # simple expense that will be shared return __edit_simple_expense_into_shared(**locals()) else: # simple expense that will be shared return __edit_simple_expense_into_simple(**locals()) else: error = 'Not a valid category' else: error = 'Not a valid account' else: error = 'Not a valid date' else: error = 'Not a valid amount' # show the form return render_template('admin_edit_expense.html', **locals()) else: return redirect(url_for('expenses.index'))
def __edit_simple_expense_into_shared(current_user_id, our_expenses, expense, our_accounts, our_users, date, description, account_id, amount, error, category_id, categories, accounts, users, expense_id, key=None, dict=None): '''Edit a simple expense entry into a shared one''' # fetch values and check they are actually provided if 'split' in request.form: split = request.form['split'] else: error = 'You need to provide a % split' if 'user' in request.form: shared_with_user = request.form['user'] else: error = 'You need to provide a user' # 'heavier' checks if not error: # valid percentage split? if is_percentage(split): # valid user sharing with? if our_users.is_connection(user_id=shared_with_user): # figure out percentage split loaned_amount = round( (float(amount) * (100 - float(split))) / 100, 2) # create loans our_loans = Loans(current_user_id) our_loan_id = our_loans.add_loan( other_user_id=shared_with_user, date=date, account_id=account_id, description=description, amount=-float(loaned_amount)) their_loans = Loans(shared_with_user) their_loan_id = their_loans.add_loan( other_user_id=current_user_id, date=date, description=description, amount=loaned_amount) # generate slugs for the new loans our_slugs = Slugs(current_user_id) slug = our_slugs.add_slug(type='loan', object_id=our_loan_id, description=description) their_slugs = Slugs(shared_with_user) their_slugs.add_slug(type='loan', object_id=their_loan_id, slug=slug) flash('Loan given') # is our original and current account the same? if expense[0].deduct_from == account_id: # modify the difference between then and now our_accounts.modify_user_balance(amount=expense[0].amount - float(amount), account_id=account_id) else: # credit our original account back our_accounts.modify_user_balance( amount=expense[0].amount, account_id=expense[0].deduct_from) # debit from our current account our_accounts.modify_user_balance(amount=-float(amount), account_id=account_id) # edit expense (loaner - us) our_expenses.edit_expense(date=date, category_id=category_id, account_id=account_id, amount=float(amount) - loaned_amount, description=description, expense_id=expense_id) their_expenses = Expenses(shared_with_user) their_accounts = Accounts(shared_with_user) # add new expenses (borrower) their_expense_id = their_expenses.add_expense( date=date, amount=loaned_amount, description=description, pass_thru=True) # modify their loan account balance their_accounts.modify_loan_balance( amount=-float(loaned_amount), with_user_id=current_user_id) # modify our loan account balance our_accounts.modify_loan_balance(amount=loaned_amount, with_user_id=shared_with_user) # link loan and the expenses our_expenses.link_to_loan(expense_id=expense_id, loan_id=our_loan_id, shared_with=shared_with_user, percentage=split, original_amount=amount) their_expenses.link_to_loan(expense_id=their_expense_id, loan_id=our_loan_id, shared_with=current_user_id, percentage=split, original_amount=amount) flash('Expense edited') # do a GET otherwise category will fail return redirect( url_for('expenses.edit_expense', expense_id=expense_id)) else: error = 'Not a valid user sharing with' else: error = 'Not a valid % split' # show the form return render_template('admin_edit_expense.html', **locals())
def __edit_shared_expense_into_shared(current_user_id, our_expenses, expense, our_accounts, our_users, date, description, account_id, amount, error, category_id, categories, accounts, users, expense_id, key=None, dict=None): '''Edit a shared expense entry into a shared entry still''' # fetch values and check they are actually provided if 'split' in request.form: split = request.form['split'] else: error = 'You need to provide a % split' if 'user' in request.form: shared_with_user = request.form['user'] else: error = 'You need to provide a user' # 'heavier' checks if not error: # valid percentage split? if is_percentage(split): # valid user sharing with? if our_users.is_connection(user_id=shared_with_user): # figure out percentage split loaned_amount = round( (float(amount) * (100 - float(split))) / 100, 2) loaned_then_amount = round((float(expense[0].amount) * (100 - float(expense[3]))) / 100, 2) # is our original and current account the same? if expense[0].deduct_from == account_id: # modify the difference between then and now our_accounts.modify_user_balance(amount=expense[0].amount - float(amount), account_id=account_id) else: # credit our original account back our_accounts.modify_user_balance( amount=expense[0].amount, account_id=expense[0].deduct_from) # debit from our current account our_accounts.modify_user_balance(amount=-float(amount), account_id=account_id) our_loans = Loans(current_user_id) their_loans = Loans(expense[2]) # get slug as a unique identifier slug = our_loans.get_loan_slug(loan_id=expense[1]) # are we sharing the expense with the same user as before? if expense[2] == int(shared_with_user): # edit the loan entries our_loans.edit_loan(other_user_id=shared_with_user, account_id=account_id, description=description, amount=-float(loaned_amount), date=date, loan_id=expense[1]) their_loans.edit_loan(other_user_id=current_user_id, amount=loaned_amount, date=date, slug=slug) # modify our loan account balance difference with the user our_accounts.modify_loan_balance( amount=loaned_amount - loaned_then_amount, with_user_id=shared_with_user) # now for the user we share with their_expenses = Expenses(shared_with_user) their_accounts = Accounts(shared_with_user) # the user now and then is the same, get their expense their_expense = their_expenses.get_expense( loan_id=expense[1]) # modify their loan account balance their_accounts.modify_loan_balance( amount=-loaned_amount + loaned_then_amount, with_user_id=current_user_id) # edit their expense amount their_expenses.edit_expense(date=date, account_id=account_id, amount=loaned_amount, expense_id=their_expense[0].id, pass_thru=True) # update loan links our_expenses.modify_loan_link(loan_id=expense[1], percentage=split, original_amount=amount) their_expenses.modify_loan_link(loan_id=expense[1], percentage=split, original_amount=amount) else: # the other user we WERE sharing with their_expenses = Expenses(expense[2]) their_accounts = Accounts(expense[2]) # credit our loan account our_accounts.modify_loan_balance( amount=-float(loaned_then_amount), with_user_id=expense[2]) # fetch their expense their_expense = their_expenses.get_expense( loan_id=expense[1]) # delete the shared user's expense their_expenses.delete_expense( expense_id=their_expense[0].id) # modify their loan status towards us their_accounts.modify_loan_balance( amount=loaned_then_amount, with_user_id=current_user_id) # unlink expenses to loan entries our_expenses.unlink_loan(loan_id=expense[1]) # delete the original loans our_loans.delete_loan(loan_id=expense[1]) their_loans.delete_loan(slug=slug) flash('Loan reverted') # create a loan from us to the new user our_loan_id = our_loans.add_loan( other_user_id=shared_with_user, date=date, account_id=account_id, description=description, amount=-float(loaned_amount)) # create a loan entry for the new user their_loans = Loans(shared_with_user) their_loan_id = their_loans.add_loan( other_user_id=current_user_id, date=date, description=description, amount=loaned_amount) # generate slugs for the new loans our_slugs = Slugs(current_user_id) slug = our_slugs.add_slug(type='loan', object_id=our_loan_id, description=description) their_slugs = Slugs(shared_with_user) their_slugs.add_slug(type='loan', object_id=their_loan_id, slug=slug) flash('Loan given') # modify loan monies for us our_accounts.modify_loan_balance( amount=loaned_amount, with_user_id=shared_with_user) # the CURRENT user we are sharing with their_accounts = Accounts(shared_with_user) # fudge loan 'account' monies for them their_accounts.modify_loan_balance( amount=-float(loaned_amount), with_user_id=current_user_id) their_expenses = Expenses(shared_with_user) # add new expenses (borrower) their_expense_id = their_expenses.add_expense( date=date, amount=loaned_amount, description=description, pass_thru=True) # create new loan - expense links our_expenses.link_to_loan(expense_id=expense_id, loan_id=our_loan_id, shared_with=shared_with_user, percentage=split, original_amount=amount) their_expenses.link_to_loan(expense_id=their_expense_id, loan_id=our_loan_id, shared_with=current_user_id, percentage=split, original_amount=amount) # edit expense (loaner - us) our_expenses.edit_expense(date=date, category_id=category_id, account_id=account_id, amount=float(amount) - loaned_amount, description=description, expense_id=expense_id) flash('Expense edited') # do a GET otherwise category will fail return redirect( url_for('expenses.edit_expense', expense_id=expense_id)) else: error = 'Not a valid user sharing with' else: error = 'Not a valid % split' # show the form return render_template('admin_edit_expense.html', **locals())
def __edit_shared_expense_into_simple(current_user_id, our_expenses, expense, our_accounts, our_users, date, description, account_id, amount, error, category_id, categories, accounts, users, expense_id, key=None, dict=None): '''Edit a shared expense entry into a simple expense entry''' our_loans = Loans(current_user_id) # percentage split loaned_then_amount = round( (float(expense[0].amount) * (100 - float(expense[3]))) / 100, 2) # credit our loan account our_accounts.modify_loan_balance(amount=-float(loaned_then_amount), with_user_id=expense[2]) their_expenses = Expenses(expense[2]) their_accounts = Accounts(expense[2]) their_loans = Loans(expense[2]) # fetch their expense their_expense = their_expenses.get_expense(loan_id=expense[1]) # delete the shared user's expense their_expenses.delete_expense(expense_id=their_expense[0].id) # delete their loan status towards us their_accounts.modify_loan_balance(amount=expense[4], with_user_id=current_user_id) # unlink expenses to loan entries our_expenses.unlink_loan(loan_id=expense[1]) # get slug as a unique identifier slug = our_loans.get_loan_slug(loan_id=expense[1]) # delete the original loans our_loans.delete_loan(loan_id=expense[1]) their_loans.delete_loan(slug=slug) flash('Loan reverted') # credit our account back with the full amount (expense amount + loaned amount) our_accounts.modify_user_balance(amount=float(expense[0].amount), account_id=expense[0].deduct_from) # debit from account our_accounts.modify_user_balance(amount=-float(amount), account_id=account_id) # edit expense our_expenses.edit_expense(date=date, category_id=category_id, account_id=account_id, amount=amount, description=description, expense_id=expense_id) flash('Expense edited') # do a GET otherwise category will fail return redirect(url_for('expenses.edit_expense', expense_id=expense_id))