def add_expense(self, date, description, amount, category_id=None, account_id=None, pass_thru=False): # add into uncategorized expenses if category not provided if not category_id: category_id = self.is_category(name="Uncategorized") if not category_id: # crete a new one c = ExpenseCategoriesTable(self.user_id, u'Uncategorized') db_session.add(c) db_session.commit() category_id = c.id # find default account if not provided if not account_id: acc = Accounts(self.user_id) account_id = acc.get_default_account() if not account_id: account_id = acc.add_default_account() # add the actual expense e = ExpensesTable(self.user_id, date, category_id, description, account_id, amount, pass_thru) db_session.add(e) db_session.commit() # update the totals self.totals.update_expense(amount, date) return e.id
def edit_account(): '''Edit an account balance''' current_user_id = session.get('logged_in_user') acc = Accounts(current_user_id) if request.method == 'POST': error = None if 'balance' in request.form: balance = request.form['balance'] else: error = 'You need to provide a balance' if 'account' in request.form: account = request.form['account'] else: error = 'You need to provide an account' if not error: # valid amount? if is_float(balance): # valid account? if acc.is_account(account_id=account): # modify accounts acc.change_account_balance(account, balance) flash('Balance modified') else: error = 'Not a valid account' else: error = 'Not a valid amount' accounts = acc.get_accounts() return render_template('admin_edit_account.html', **locals())
def add_account(): '''Add an account''' error = None if request.method == 'POST': new_account_name, account_type, account_balance, current_user_id =\ request.form['name'], request.form['type'], request.form['balance'], session.get('logged_in_user') # blank name? if new_account_name: # type? if account_type == 'asset' or account_type == 'liability':\ # if balance blank, pass in 0 if not account_balance: account_balance = 0 # is balance a valid float? if is_float(account_balance): acc = Accounts(current_user_id) # already exists? if not acc.is_account(account_slug=new_account_name): # create new account acc.add_account(name=new_account_name, type=account_type, balance=account_balance) flash('Account added') else: error = 'You already have an account under that name' else: error = 'The initial balance needs to be a floating number' else: error = 'The account needs to either be an asset or a liability' else: error = 'You need to provide a name for the account' return render_template('admin_add_account.html', **locals())
def add_transfer(): """Add an account transfer""" current_user_id = session.get("logged_in_user") acc = Accounts(current_user_id) if request.method == "POST": dict = __validate_transfer_form() for key in dict.keys(): exec(key + " = dict['" + key + "']") # 'heavier' checks if not error: # source and target the same? if not deduct_from_account == credit_to_account: # valid amount? if is_float(amount): # is it a positive amount? if float(amount) > 0: # valid date? if is_date(date): # valid debit account? if acc.is_account(account_id=deduct_from_account): # valid credit account? if acc.is_account(account_id=credit_to_account): # add a new transfer row acc.add_account_transfer( date=date, deduct_from_account=deduct_from_account, credit_to_account=credit_to_account, amount=amount, ) # modify accounts acc.modify_account_balance(deduct_from_account, -float(amount)) acc.modify_account_balance(credit_to_account, amount) flash("Monies transferred") else: error = "Not a valid target account" else: error = "Not a valid source account" else: error = "Not a valid date" else: error = "Provide a positive amount" else: error = "Not a valid amount" else: error = "Source and target accounts cannot be the same" accounts = acc.get_accounts() return render_template("admin_add_transfer.html", **locals())
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 all_accts(): sql = "SELECT * FROM banking.accounts" cursor = connection.cursor() cursor.execute(sql) records = cursor.fetchall() acct_list = [] for record in records: acct = Accounts(record[0], record[1], record[2], record[3]) acct_list.append(acct.json()) return acct_list
def get_account_userid(userid): sql = "SELECT * FROM banking.accounts where userid = %s" cursor = connection.cursor() cursor.execute(sql, [userid]) records = cursor.fetchall() acct_list = [] for record in records: acct = Accounts(record[0], record[1], record[2], record[3]) acct_list.append(acct.json()) return acct_list
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 __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 add_loan(self, other_user_id, date, description, amount, account_id=None): # if an account id is not provided, get a 'default' account if not account_id: accounts = Accounts(self.user_id) account_id = accounts.get_default_account() # create a default account if no joy getting a default account if not account_id: account_id = accounts.add_default_account() l = LoansTable(self.user_id, other_user_id, date, account_id, description, amount) db_session.add(l) db_session.commit() return l.id
def get_account_userid_rng(userid, high, low): sql = "SELECT * FROM banking.accounts where userid = %s and balance <= %s and balance >=%s" cursor = connection.cursor() cursor.execute(sql, [userid], [high], [low]) records = cursor.fetchall() acct_list = [] for record in records: acct = Accounts(record[0], record[1], record[2], record[3]) if float(acct.balance) < int(high) and float( acct.balance) > int(low): acct_list.append(acct.json()) else: acct_list.clear() return acct_list
def show_transfers(account=None, date=None, page=1, items_per_page=10): '''Show account transfers for a given user''' current_user_id = session.get('logged_in_user') acc = Accounts(current_user_id) # fetch account transfers transfers = acc.get_account_transfers() # provided a date range? date_range = translate_date_range(date) if date_range: transfers = acc.get_account_transfers(date_from=date_range['low'], date_to=date_range['high']) # date ranges for the template date_ranges = get_date_ranges() # fetch accounts accounts = acc.get_accounts() # provided an account? if account: # valid slug? if acc.is_account(account_slug=account): transfers = acc.get_account_transfers(account_slug=account) # build a paginator paginator = Pagination( transfers, page, items_per_page, transfers.count(), transfers.offset((page - 1) * items_per_page).limit(items_per_page)) return render_template('admin_show_transfers.html', **locals())
def create_acct(account): sql = "Insert into banking.accounts values (default,%s,%s,%s) returning *" cursor = connection.cursor() cursor.execute(sql, (account.acct_num, account.balance, account.userid)) connection.commit() record = cursor.fetchone() new_acct = Accounts(record[0], record[1], record[2], record[3]) return new_acct
def add_income(): '''Add an income entry''' current_user_id = session.get('logged_in_user') inc = Income(current_user_id) acc = Accounts(current_user_id) if request.method == 'POST': dict = __validate_income_form() for key in dict.keys(): exec(key + " = dict['" + key + "']") # 'heavier' checks if not error: # valid date? if is_date(date): # valid amount? if is_float(amount): # valid category? if inc.is_category(id=category_id): # valid account? if acc.is_account(account_id=account_id): # add new income inc.add_income(account_id=account_id, amount=amount, category_id=category_id, date=date, description=description) # credit to account acc.modify_account_balance(account_id, amount) flash('Income added') else: error = 'Not a valid account' else: error = 'Not a valid category' else: error = 'Not a valid amount' else: error = 'Not a valid date' # fetch user's categories and accounts categories = inc.get_categories() accounts = acc.get_accounts() return render_template('admin_add_income.html', **locals())
def add_account(): """Add an account""" error = None if request.method == "POST": new_account_name, account_type, account_balance, current_user_id = ( request.form["name"], request.form["type"], request.form["balance"], session.get("logged_in_user"), ) # blank name? if new_account_name: # type? if account_type == "asset" or account_type == "liability": # if balance blank, pass in 0 if not account_balance: account_balance = 0 # is balance a valid float? if is_float(account_balance): acc = Accounts(current_user_id) # already exists? if not acc.is_account(account_slug=new_account_name): # create new account acc.add_account(name=new_account_name, type=account_type, balance=account_balance) flash("Account added") else: error = "You already have an account under that name" else: error = "The initial balance needs to be a floating number" else: error = "The account needs to either be an asset or a liability" else: error = "You need to provide a name for the account" return render_template("admin_add_account.html", **locals())
def get_account(acct_id): try: sql = "SELECT * FROM banking.accounts where acctid = %s" cursor = connection.cursor() cursor.execute(sql, [acct_id]) records = cursor.fetchall() for record in records: acct1 = Accounts(int(record[0]), int(record[1]), int(record[2]), int(record[3])) return acct1 except KeyError: raise ResourceNotFound(f"Account with id: {acct_id} - NOT FOUND")
def delete_income(income_id): '''Delete income entry''' current_user_id = session.get('logged_in_user') incomes = Income(current_user_id) # is it valid? income = incomes.get_income(income_id) if income: # revert accounts = Accounts(current_user_id) accounts.modify_account_balance(amount=-float(income.amount), account_id=income.credit_to) incomes.delete_income(income_id) flash('Income deleted') else: flash('Not a valid income entry', 'error') return redirect(url_for('income.index'))
def update_acct(acct): sql = "UPDATE banking.accounts SET acctnum = %s,balance= %s, userid = %s WHERE acctid = %s RETURNING *" cursor = connection.cursor() cursor.execute( sql, (acct.acct_num, acct.balance, acct.userid, acct.acct_id)) connection.commit() record = cursor.fetchone() acct1 = Accounts(int(record[0]), int(record[1]), int(record[2]), int(record[3])) return acct1
def show_transfers(account=None, date=None, page=1, items_per_page=10): '''Show account transfers for a given user''' current_user_id = session.get('logged_in_user') acc = Accounts(current_user_id) # fetch account transfers transfers = acc.get_account_transfers() # provided a date range? date_range = translate_date_range(date) if date_range: transfers = acc.get_account_transfers(date_from=date_range['low'], date_to=date_range['high']) # date ranges for the template date_ranges = get_date_ranges() # fetch accounts accounts = acc.get_accounts() # provided an account? if account: # valid slug? if acc.is_account(account_slug=account): transfers = acc.get_account_transfers(account_slug=account) # build a paginator paginator = Pagination(transfers, page, items_per_page, transfers.count(), transfers.offset((page - 1) * items_per_page).limit(items_per_page)) return render_template('admin_show_transfers.html', **locals())
def edit_income(income_id): '''Edit income entry''' current_user_id = session.get('logged_in_user') inc = Income(current_user_id) # is it valid? income = inc.get_income(income_id) if income: # fetch user's categories and accounts categories = inc.get_categories() acc = Accounts(current_user_id) accounts = acc.get_accounts() if request.method == 'POST': # POST dict = __validate_income_form() for key in dict.keys(): exec(key + " = dict['" + key + "']") # 'heavier' checks if not error: # valid date? if is_date(date): # valid amount? if is_float(amount): # valid category? if inc.is_category(id=category_id): # valid account? if acc.is_account(account_id=account_id): # debit the original account acc.modify_account_balance(income.credit_to, -float(income.amount)) # credit the 'new' account acc.modify_account_balance(account_id, amount) # edit income entry inc.edit_income(account_id=account_id, amount=amount, category_id=category_id, date=date, description=description, income_id=income.id) flash('Income edited') return redirect(url_for('income.edit_income', income_id=income_id)) else: error = 'Not a valid account' else: error = 'Not a valid category' else: error = 'Not a valid amount' else: error = 'Not a valid date' return render_template('admin_edit_income.html', **locals()) else: return redirect(url_for('income.index'))
def add_account(): '''Add an account''' error = None if request.method == 'POST': new_account_name, account_type, account_balance, current_user_id =\ request.form['name'], request.form['type'], request.form['balance'], session.get('logged_in_user') # blank name? if new_account_name: # type? if account_type == 'asset' or account_type == 'liability': \ # if balance blank, pass in 0 if not account_balance: account_balance = 0 # is balance a valid float? if is_float(account_balance): acc = Accounts(current_user_id) # already exists? if not acc.is_account(account_slug=new_account_name): # create new account acc.add_account(name=new_account_name, type=account_type, balance=account_balance) flash('Account added') else: error = 'You already have an account under that name' else: error = 'The initial balance needs to be a floating number' else: error = 'The account needs to either be an asset or a liability' else: error = 'You need to provide a name for the account' return render_template('admin_add_account.html', **locals())
def edit_account(): """Edit an account balance""" current_user_id = session.get("logged_in_user") acc = Accounts(current_user_id) if request.method == "POST": error = None if "balance" in request.form: balance = request.form["balance"] else: error = "You need to provide a balance" if "account" in request.form: account = request.form["account"] else: error = "You need to provide an account" if not error: # valid amount? if is_float(balance): # valid account? if acc.is_account(account_id=account): # modify accounts acc.change_account_balance(account, balance) flash("Balance modified") else: error = "Not a valid account" else: error = "Not a valid amount" accounts = acc.get_accounts() return render_template("admin_edit_account.html", **locals())
def delete_transfer(transfer_id): '''Delete account transfer''' current_user_id = session.get('logged_in_user') accounts = Accounts(current_user_id) # is it valid? transfer = accounts.get_transfer(transfer_id) if transfer: # revert accounts.modify_account_balance(transfer.from_account, transfer.amount) accounts.modify_account_balance(transfer.to_account, -float(transfer.amount)) accounts.delete_transfer(transfer_id) flash('Transfer deleted') else: flash('Not a valid account transfer', 'error') return redirect(url_for('accounts.show_transfers'))
def delete_transfer(transfer_id): """Delete account transfer""" current_user_id = session.get("logged_in_user") accounts = Accounts(current_user_id) # is it valid? transfer = accounts.get_transfer(transfer_id) if transfer: # revert accounts.modify_account_balance(transfer.from_account, transfer.amount) accounts.modify_account_balance(transfer.to_account, -float(transfer.amount)) accounts.delete_transfer(transfer_id) flash("Transfer deleted") else: flash("Not a valid account transfer", "error") return redirect(url_for("accounts.show_transfers"))
def create(account_name=None, account_guid=None, account_type=None, company=None, is_active=True, is_deleted=False, owner=None): try: account = Accounts(account_name=account_name, account_guid=account_guid, account_type=account_type, company=company, is_active=is_active, is_deleted=is_deleted) if owner: account.users.append(owner) db.add(account) db.commit() return account.account_id except Exception as e: db.rollback() raise Exception(e.message)
import os from flask import Flask, render_template, flash, url_for, logging, request, redirect from flask_login import LoginManager, login_user, current_user, logout_user, login_required from werkzeug.utils import secure_filename from flask import send_from_directory from forms import RegisterForm, AddSchemeForm from models.accounts import Accounts from models.user import User UPLOAD_FOLDER = 'C:/Users/Shadow Master/PycharmProjects/Scheema/FileUploads' ALLOWED_EXTENSIONS = {'txt', 'pdf', "png", 'jpeg', 'jpg', 'gif'} app = Flask(__name__) account = Accounts() app.secret_key = '\xcd]\x1f\x8a\xa7\xd0J\xd6\x99\x8c/\x1e\x91~hU4tgd\xe5\xa2\xab3' login_manager = LoginManager() login_manager.init_app(app) app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024 app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER @login_manager.user_loader def load_user(username): return account.get_specific_user(username) @app.route('/') def home(): return render_template("home.html")
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 accounts_page(self): user = users.get_current_user() if user and (user.email() in ACTIVE_USER_EMAILS or users.is_current_user_admin()): reloadPage = False simpleText = False usedby = {} user_amount_map = {} user_adjustment = {} paymentMap = {} error_message = "" calculation_error = "" total_amount = 0 if(self.request.get('simpletext') and self.request.get('simpletext') == "True"): simpleText = True # split month into tokens month = self.request.get('month') if (self.request.get('month') and not self.request.get('month') == "") else datetime.date.today().replace(day=1).strftime("%Y-%m-%d") # if there's a cmd param if(self.request.get('cmd')): if(self.request.get('cmd') == "delete"): eid = long(self.request.get('eid')) entry = Accounts.get_by_id(eid) entry.deleted = True entry.put() self.redirect('/accounts') return else: description = self.request.get('description') if (self.request.get('description') and not self.request.get('description') == "") else False error_messages = [] if(not description): error_messages.append("Description is mandatory") amount = self.request.get('amount') if (self.request.get('amount') and not self.request.get('amount') == "") else False if(not amount): error_messages.append("Amount is mandatory") try: int(amount) except: error_messages.append("Amount should be a number") expenseby = self.request.get('expenseby') if (self.request.get('expenseby') and not self.request.get('expenseby') == "") else False if(not expenseby): error_messages.append("Expense by is mandatory") # TODO: fix this expenseby = User(expenseby) count = 0 user_objects = {} for email in ACTIVE_USER_EMAILS: current_user = User(email) user_objects[email] = current_user usedby[email] = 1 if (self.request.get(email) and self.request.get(email) == "on") else 0 if(usedby[email] == 1): count += 1 # all = 1 if (self.request.get('all') and self.request.get('all') == "on") else 0 if(count == 0): error_messages.append("Atleast one person should be selected") if(len(error_messages) == 0): amount = int(amount) individual_amount = amount / count # #Add new entry newAccountEntry = Accounts() newAccountEntry.expenseby = expenseby newAccountEntry.expensefor = description newAccountEntry.expenseamount = amount newAccountEntry.expensemonth = datetime.date.today().replace(day=1) newAccountEntry.put() for email, current_user in user_objects.iteritems(): contribution = Contribution(account=newAccountEntry) contribution.contributor = current_user if(current_user == expenseby): if(usedby[email] == 1): contribution.amount = float(individual_amount - amount) else: contribution.amount = float(0 - amount) else: if(usedby[email] == 1): contribution.amount = float(individual_amount) else: contribution.amount = float(0) contribution.put() """ description="" amount="" expenseby="" usedby = [] """ reloadPage = True else: for error in error_messages: error_message += "[x] " + error + "<br />" # GqlQuery("SELECT DISTINCT expensedate ") q = GqlQuery("SELECT DISTINCT expensemonth FROM Accounts") available_months = q.fetch(24) # let's limit to 2 yrs expenses = Accounts.gql("WHERE expensemonth=DATE('" + month + "') ORDER BY expensedate DESC").fetch(1000) for expense in expenses: if not expense.deleted: total_amount += expense.expenseamount for contribution in expense.contributions: if not expense.deleted: if(not contribution.contributor.email() in user_amount_map): user_amount_map[contribution.contributor.email()] = 0 user_amount_map[contribution.contributor.email()] += contribution.amount setattr(expense, contribution.contributor.email(), contribution.amount) if (total_amount > 0): user_adjustment = user_amount_map.copy() asc_adjustment_keys = get_sorted_keys(user_adjustment) desc_amount_keys = get_sorted_keys(user_amount_map, True) minUser = asc_adjustment_keys[0] for mapuser in desc_amount_keys: if(user_adjustment[minUser] < 0 and not user_adjustment[mapuser] == 0 and mapuser != minUser): # calcualte amount to pay payamount = user_adjustment[mapuser] user_adjustment[minUser] += payamount user_adjustment[mapuser] = 0 paymentMap[mapuser] = [minUser, payamount] elif int(user_adjustment[mapuser]) > 0: logging.error("calculation error: " + str(user_adjustment[mapuser]) + " " + mapuser + "" + minUser) calculation_error = "calculation error: " + str(user_adjustment[mapuser]) + " " + mapuser + "" + minUser asc_adjustment_keys = get_sorted_keys(user_adjustment) minUser = asc_adjustment_keys[0] template_values = { 'page':{'title':"Accounts"}, 'user':user, 'error_message': error_message, 'simpleText': simpleText, 'logout_url': users.create_logout_url("/"), 'active_tab': "accounts", 'reloadPage': reloadPage, 'user_emails': ACTIVE_USER_EMAILS, 'users': ACTIVE_USERS, 'available_months': available_months, 'usedby': usedby, 'paymentMap': paymentMap, 'expenses': expenses, 'calculation_error':calculation_error, 'totals': {'amount':total_amount, 'useramounts': user_amount_map} } template = JINJA_ENVIRONMENT.get_template('accounts/index.html') self.response.write(template.render(template_values)) elif (user): template_values = {'logout_url': users.create_logout_url("/")} template = JINJA_ENVIRONMENT.get_template('403.html') self.response.write(template.render(template_values)) else: self.redirect(users.create_login_url(self.request.uri))
def edit_income(income_id): '''Edit income entry''' current_user_id = session.get('logged_in_user') inc = Income(current_user_id) # is it valid? income = inc.get_income(income_id) if income: # fetch user's categories and accounts categories = inc.get_categories() acc = Accounts(current_user_id) accounts = acc.get_accounts() if request.method == 'POST': # POST dict = __validate_income_form() for key in dict.keys(): exec(key + " = dict['" + key + "']") # 'heavier' checks if not error: # valid date? if is_date(date): # valid amount? if is_float(amount): # valid category? if inc.is_category(id=category_id): # valid account? if acc.is_account(account_id=account_id): # debit the original account acc.modify_account_balance( income.credit_to, -float(income.amount)) # credit the 'new' account acc.modify_account_balance(account_id, amount) # edit income entry inc.edit_income(account_id=account_id, amount=amount, category_id=category_id, date=date, description=description, income_id=income.id) flash('Income edited') return redirect( url_for('income.edit_income', income_id=income_id)) else: error = 'Not a valid account' else: error = 'Not a valid category' else: error = 'Not a valid amount' else: error = 'Not a valid date' return render_template('admin_edit_income.html', **locals()) else: return redirect(url_for('income.index'))
def add_transfer(): '''Add an account transfer''' current_user_id = session.get('logged_in_user') acc = Accounts(current_user_id) if request.method == 'POST': dict = __validate_transfer_form() for key in dict.keys(): exec(key + " = dict['" + key + "']") # 'heavier' checks if not error: # source and target the same? if not deduct_from_account == credit_to_account: # valid amount? if is_float(amount): # is it a positive amount? if float(amount) > 0: # valid date? if is_date(date): # valid debit account? if acc.is_account(account_id=deduct_from_account): # valid credit account? if acc.is_account( account_id=credit_to_account): # add a new transfer row acc.add_account_transfer( date=date, deduct_from_account=deduct_from_account, credit_to_account=credit_to_account, amount=amount) # modify accounts acc.modify_account_balance( deduct_from_account, -float(amount)) acc.modify_account_balance( credit_to_account, amount) flash('Monies transferred') else: error = 'Not a valid target account' else: error = 'Not a valid source account' else: error = 'Not a valid date' else: error = 'Provide a positive amount' else: error = 'Not a valid amount' else: error = 'Source and target accounts cannot be the same' accounts = acc.get_accounts() return render_template('admin_add_transfer.html', **locals())
def edit_transfer(transfer_id): '''Edit account transfer''' current_user_id = session.get('logged_in_user') acc = Accounts(current_user_id) accounts = acc.get_accounts() # is it valid? transfer = acc.get_transfer(transfer_id) if transfer: if request.method == 'POST': # POST dict = __validate_transfer_form() for key in dict.keys(): exec(key + " = dict['" + key + "']") # 'heavier' checks if not error: # source and target the same? if not deduct_from_account == credit_to_account: # valid amount? if is_float(amount): # valid date? if is_date(date): # valid debit account? if acc.is_account(account_id=deduct_from_account): # valid credit account? if acc.is_account( account_id=credit_to_account): # modify accounts to original state acc.modify_account_balance( transfer.from_account, transfer.amount) acc.modify_account_balance( transfer.to_account, -float(transfer.amount)) # new state acc.modify_account_balance( deduct_from_account, -float(amount)) acc.modify_account_balance( credit_to_account, amount) # edit transfer row transfer = acc.edit_account_transfer( date=date, deduct_from_account=deduct_from_account, credit_to_account=credit_to_account, amount=amount, transfer_id=transfer_id) flash('Transfer edited') else: error = 'Not a valid target account' else: error = 'Not a valid source account' else: error = 'Not a valid date' else: error = 'Not a valid amount' else: error = 'Source and target accounts cannot be the same' return render_template('admin_edit_transfer.html', **locals()) else: return redirect(url_for('accounts.show_transfers'))
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_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 give(): '''Give a loan or pay someone back''' current_user_id = session.get('logged_in_user') our_accounts = Accounts(current_user_id) if request.method == 'POST': dict = __validate_give_loan_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=deduct_from_account): # add our loans entry our_loans = Loans(current_user_id) our_loan_id = our_loans.add_loan(other_user_id=to_user, date=date, account_id=deduct_from_account, description=description, amount=-float(amount)) # add their loans entry their_loans = Loans(to_user) their_loan_id = their_loans.add_loan(other_user_id=current_user_id, date=date, account_id=deduct_from_account, description=description, amount=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(to_user) their_slugs.add_slug(type='loan', object_id=their_loan_id, slug=slug) their_accounts = Accounts(to_user) # transfer money from/to respective accounts our_accounts.modify_user_balance(account_id=deduct_from_account, amount=-float(amount)) their_accounts.modify_user_balance(amount=amount) # fudge loan 'account' monies our_accounts.modify_loan_balance(amount=amount, with_user_id=to_user) their_accounts.modify_loan_balance(amount=-float(amount), with_user_id=current_user_id) flash('Loan given') else: error = 'Not a valid source account' else: error = 'Not a valid date' else: error = 'Not a valid amount' # fetch users from connections from us our_users = Users(current_user_id) users = our_users.get_connections() accounts = our_accounts.get_accounts() return render_template('admin_give_loan.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 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_transfer(transfer_id): """Edit account transfer""" current_user_id = session.get("logged_in_user") acc = Accounts(current_user_id) accounts = acc.get_accounts() # is it valid? transfer = acc.get_transfer(transfer_id) if transfer: if request.method == "POST": # POST dict = __validate_transfer_form() for key in dict.keys(): exec(key + " = dict['" + key + "']") # 'heavier' checks if not error: # source and target the same? if not deduct_from_account == credit_to_account: # valid amount? if is_float(amount): # valid date? if is_date(date): # valid debit account? if acc.is_account(account_id=deduct_from_account): # valid credit account? if acc.is_account(account_id=credit_to_account): # modify accounts to original state acc.modify_account_balance(transfer.from_account, transfer.amount) acc.modify_account_balance(transfer.to_account, -float(transfer.amount)) # new state acc.modify_account_balance(deduct_from_account, -float(amount)) acc.modify_account_balance(credit_to_account, amount) # edit transfer row transfer = acc.edit_account_transfer( date=date, deduct_from_account=deduct_from_account, credit_to_account=credit_to_account, amount=amount, transfer_id=transfer_id, ) flash("Transfer edited") else: error = "Not a valid target account" else: error = "Not a valid source account" else: error = "Not a valid date" else: error = "Not a valid amount" else: error = "Source and target accounts cannot be the same" return render_template("admin_edit_transfer.html", **locals()) else: return redirect(url_for("accounts.show_transfers"))
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_give_loan(loan_id, our_loans, loan, current_user_id): '''Editing of loan entries where we were giving money''' our_accounts = Accounts(current_user_id) if request.method == 'POST': # POST dict = __validate_give_loan_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=deduct_from_account): their_accounts = Accounts(loan.other_user) # first roll back user balances our_accounts.modify_user_balance(account_id=loan.account, amount=loan.amount) their_accounts.modify_user_balance(amount=-float(loan.amount)) # now roll back loan account monies our_accounts.modify_loan_balance(amount=-float(loan.amount), with_user_id=loan.other_user) their_accounts.modify_loan_balance(amount=loan.amount, with_user_id=current_user_id) # the user might have changed... if loan.other_user != to_user: their_accounts = Accounts(to_user) # transfer money from/to respective accounts our_accounts.modify_user_balance(account_id=deduct_from_account, amount=-float(amount)) their_accounts.modify_user_balance(amount=amount) # fudge loan 'account' monies our_accounts.modify_loan_balance(amount=amount, with_user_id=to_user) their_accounts.modify_loan_balance(amount=-float(amount), with_user_id=current_user_id) # get slug as a unique identifier slug = our_loans.get_loan_slug(loan_id=loan_id) # the user might have changed... their_loans = Loans(loan.other_user) if loan.other_user != to_user: # delete their original loan entry (and its slug) their_loans.delete_loan(slug=slug) # new user their_loans = Loans(to_user) their_loan_id = their_loans.add_loan(other_user_id=current_user_id, date=date, description=description, amount=amount) # save their new slug their_slugs = Slugs(to_user) their_slugs.add_slug(type='loan', object_id=their_loan_id, slug=slug) else: # update their loans entry their_loans.edit_loan(other_user_id=current_user_id, date=date, description=description, amount=amount, slug=slug) # update our loans entry our_loans.edit_loan(other_user_id=to_user, date=date, description=description, amount=-float(amount), account_id=deduct_from_account, loan_id=loan_id) flash('Loan edited') else: error = 'Not a valid target account' else: error = 'Not a valid date' else: error = 'Not a valid amount' our_users = Users(current_user_id) users = our_users.get_connections() accounts = our_accounts.get_accounts() return render_template('admin_edit_give_loan.html', **locals())
def add_private(): '''Add a private user connection for a user''' error = None if request.method == 'POST': new_user_name, current_user_id = request.form['name'], session.get('logged_in_user') # setup objects in a context useri = Users(current_user_id) # blank name? if new_user_name: # already exists? if not useri.is_connection(name=new_user_name): # create new private user new_user_id = useri.add_private_user(new_user_name) # give the user a default account so we can do loans acc = Accounts(new_user_id) acc.add_default_account() # have we provided initial balance? if 'balance' in request.form: # get balance balance = request.form['balance'] # balance could be "empty" if balance != "": # valid amount? if is_float(balance): balance = float(balance) # do we have a pre-existing balance with the user? if balance != 0: if balance > 0: # they owe us # models loa, acc = Loans(current_user_id), Accounts(current_user_id) # add loan entry loa.add_loan(other_user_id=new_user_id, date=today_date(), account_id=acc.get_default_account(), description="Initial balance with the user", amount=balance) # fudge loan monies balance acc.modify_loan_balance(amount=balance, with_user_id=new_user_id) else: # we owe them # models loa, acc = Loans(new_user_id), Accounts(current_user_id) # add loan entry loa.add_loan(other_user_id=current_user_id, date=today_date(), account_id=acc.get_default_account(), description="Initial balance with the user", amount=-balance) # fudge loan monies balance acc.modify_loan_balance(amount=balance, with_user_id=new_user_id) else: error = 'Not a valid amount' # create connections from us to them and back useri.add_connection(new_user_id) flash('Private user added') else: error = 'You already have a user under that name' else: error = 'You need to provide a name' return render_template('admin_add_private_user.html', **locals())