예제 #1
0
    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
예제 #2
0
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())
예제 #3
0
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())
예제 #4
0
    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
예제 #5
0
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())
예제 #6
0
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())
예제 #7
0
    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
예제 #8
0
    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
예제 #9
0
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)
예제 #10
0
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))
예제 #11
0
    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
예제 #12
0
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)
예제 #13
0
 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
예제 #14
0
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())
예제 #15
0
 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
예제 #16
0
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())
예제 #17
0
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())
예제 #18
0
 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")
예제 #19
0
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'))
예제 #20
0
    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
예제 #21
0
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'))
예제 #22
0
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())
예제 #23
0
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())
예제 #24
0
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'))
예제 #25
0
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())
예제 #26
0
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())
예제 #27
0
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'))
예제 #28
0
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'))
예제 #29
0
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"))
예제 #30
0
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 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)
예제 #32
0
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")
예제 #33
0
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))
예제 #34
0
    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))
예제 #35
0
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'))
예제 #36
0
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())
예제 #37
0
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'))
예제 #38
0
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())
예제 #39
0
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())
예제 #40
0
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())
예제 #41
0
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())
예제 #42
0
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'))
예제 #43
0
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())
예제 #44
0
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"))
예제 #45
0
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'))
예제 #46
0
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())
예제 #47
0
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())
예제 #48
0
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())
예제 #49
0
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())