Exemplo n.º 1
0
    def get_user_expenses(cls, month, year):
        """

        """
        first_day = date(year, month, 1)
        if month == 12:
            last_day = date(year + 1, 1, 1)
        else:
            last_day = date(year, month + 1, 1)

        logging.info("load user expenses between %s and %s" %
                     (first_day.strftime('%d %b %Y'), last_day.strftime('%d %b %Y')))

        q = Expenses.query(ancestor=expenses_key(month, year))
        q.filter(ndb.AND(Expenses.date >= first_day, Expenses.date < last_day))

        #query for old data that had no ancestor (before migration to High Replication Datastore)
        q_old = Expenses.query(ndb.AND(Expenses.date >= first_day, Expenses.date < last_day))

        users_expenses = dict()
        keys = set()
        if users_helper.is_autorized():
            # always start with the current user
            currentUser = users.get_current_user().nickname()
            users_expenses[currentUser] = UserExpenses(currentUser)

            x = 0
            #TODO Hem refactor this ugly code
            for exp in q.fetch(500):
                exp.update_urlsafe()
                keys.add(exp.urlsafe)
                user_nickname = exp.user.nickname()
                if user_nickname not in users_expenses.keys():
                    users_expenses[user_nickname] = UserExpenses(user_nickname)
                users_expenses[user_nickname].add(exp)
                x += 1
            logging.info('%d expenses with ancestor', x)

            x = 0
            for exp in q_old.fetch(500):
                exp.update_urlsafe()
                if exp.urlsafe not in keys:
                    user_nickname = exp.user.nickname()
                    if user_nickname not in users_expenses.keys():
                        users_expenses[user_nickname] = UserExpenses(user_nickname)
                    users_expenses[user_nickname].add(exp)
                    x += 1
            logging.info('%d expenses with no ancestor', x)

        for usr in users_expenses.keys():
            users_expenses[usr].taxratio = cls.get_tax_ratio(usr, year)
            users_expenses[usr].expenses = sorted(users_expenses[usr].expenses, key=lambda e: e.date)

        return users_expenses.values()
Exemplo n.º 2
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))
Exemplo n.º 3
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)
Exemplo n.º 4
0
 def post(self):
     try:
         bank_statement = self.get_uploads()[0]
         from ofxparse import OfxParser
         ofx = OfxParser.parse(bank_statement.open())
         user = users.get_current_user()
         logging.info(ofx.account.number)                  # The account number
         logging.info(ofx.account.routing_number)          # The transit id (sometimes called branch number)
         #logging.info(ofx.account.statement               # Account information for a period of time
         logging.info(ofx.account.statement.start_date)    # The start date of the transactions
         logging.info(ofx.account.statement.end_date)      # The end date of the transactions
         #ofx.account.statement.transactions  # A list of account activities
         logging.info(ofx.account.statement.balance)       # The money in the account as of the statement 
         for tx in ofx.account.statement.transactions:
             logging.info(vars(tx))
             if tx.type == 'debit':
                 # new expense:
                 new_expense = Expenses(parent=expenses_key(tx.date.month, tx.date.year))
                 new_expense.user = user
                 new_expense.date = tx.date
                 new_expense.amount = -float(str(tx.amount))
                 new_expense.category = tx.payee
                 new_expense.exptype = 3
                 new_expense.put()
     finally:
         self.redirect('comptes')
Exemplo n.º 5
0
def index(date=None, category=None, page=1, items_per_page=10):
    '''List expenses for the user'''

    model = Expenses(session.get('logged_in_user'))

    dict = entries.index(**locals())
    for key in dict.keys():
        exec(key + " = dict['" + key + "']")

    return render_template('admin_show_expenses.html', **locals())
Exemplo n.º 6
0
def search():
    '''Search expenses'''

    model = Expenses(session.get('logged_in_user'))

    # query
    query = request.form['q'] if 'q' in request.form else ""

    # fetch entries
    entries = model.get_entries()

    # filter
    entries = entries.filter(ExpensesTable.description.like("%"+query+"%"))

    # categories
    categories = model.get_categories()

    # date ranges for the template
    date_ranges = get_date_ranges()

    return render_template('admin_search_expenses.html', **locals())
Exemplo n.º 7
0
def search():
    '''Search expenses'''

    model = Expenses(session.get('logged_in_user'))

    # query
    query = request.form['q'] if 'q' in request.form else ""

    # fetch entries
    entries = model.get_entries()

    # filter
    entries = entries.filter(ExpensesTable.description.like("%" + query + "%"))

    # categories
    categories = model.get_categories()

    # date ranges for the template
    date_ranges = get_date_ranges()

    return render_template('admin_search_expenses.html', **locals())
Exemplo n.º 8
0
 def get(self):
     # print 'coucou'
     # query = db.GqlQuery('SELECT * FROM Expenses')
     query = Expenses.query()
     expenses = query.fetch(10000)
     self.jsonData = dict()
     self.jsonData["tags"] = dict()
     for exp in expenses:
         for tag in exp.tags:
             if tag != "":
                 self.update_tag(tag, exp.amount, exp.date)
     self.persist()
     self.response.out.write(simplejson.dumps(self.jsonData))
Exemplo n.º 9
0
def add_category():
    '''Add an expense category'''

    error = None
    if request.method == 'POST':
        new_category_name, current_user_id = request.form['name'], session.get(
            'logged_in_user')

        exp = Expenses(current_user_id)

        error = entries.add_category(exp, new_category_name)
        if not error: flash('Expense category added')

    return render_template('admin_add_expense_category.html', error=error)
Exemplo n.º 10
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())
Exemplo n.º 11
0
    def post(self):
        try:
            selected_month = int(self.request.get("mois"))
            selected_year = int(self.request.get("annee"))
        except:
            dtnow = datetime.utcnow()
            selected_month = dtnow.month
            selected_year = dtnow.year

        if users.get_current_user():
            urlsafe = self.request.get("urlsafe")
            if urlsafe != "":
                logging.info("get expense from key " + urlsafe)
                new_expense = Expenses.get_from_key(ndb.Key(urlsafe=urlsafe))
                if new_expense is None:
                    raise Exception("unable to retrieve expense for key " + urlsafe)
            else:
                new_expense = Expenses(parent=expenses_key(selected_month, selected_year))

            new_expense.update(users.get_current_user(), selected_month, selected_year, self.request)
        else:
            raise Exception("bad user")

        self.redirect("/comptes?mois=%d&annee=%d" % (selected_month, selected_year))
Exemplo n.º 12
0
def export(date=None, category=None, page=1, items_per_page=10):
    '''Export expenses on a filter'''

    model = Expenses(session.get('logged_in_user'))

    dict = entries.index(**locals())
    for key in dict.keys():
        exec(key + " = dict['" + key + "']")

    response = make_response(
        render_template('admin_export_expenses.html', **locals()))
    response.headers['Content-type'] = 'text/csv'
    response.headers[
        'Content-disposition'] = 'attachment;filename=' + 'expenses-' + str(
            today_date()) + '.csv'
    return response
Exemplo n.º 13
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)
Exemplo n.º 14
0
    def get_last_twelve_months_category_expenses(self):
        last_year = date_helper.get_last_year_date()
        self.compute_labels(last_year)

        #TODO refactor
        #query = db.GqlQuery("SELECT * FROM Expenses WHERE category = :1 AND date >= :2 AND exptype = 1", self.category, last_year)
        #expenses = query.fetch(5000)
        q = Expenses.query()
        q.filter(ndb.AND(Expenses.category == self.category, Expenses.date >= last_year, Expenses.exptype == 1))
        expenses = q.fetch(5000)
        amounts = []
        for i in range(0, 12):
            amounts.append(0)

        for exp in expenses:
            index = date_helper.get_month_index(exp.date)
            if index != -1:
                amounts[index] += exp.amount
                self.totalamount += exp.amount

        self.compute_max_amount(amounts)
Exemplo n.º 15
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())
Exemplo n.º 16
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())
Exemplo n.º 17
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'))
Exemplo n.º 18
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())
Exemplo n.º 19
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())
Exemplo n.º 20
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'))
Exemplo n.º 21
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())
Exemplo n.º 22
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())
Exemplo n.º 23
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))