Esempio n. 1
0
    def validate(self, data):
        """
        Validate the form data. Return None if it is valid, or else a hash of
        field names to list of error strings for each field.

        :param data: submitted form data
        :type data: dict
        :return: None if no errors, or hash of field name to errors for that
          field
        """
        _id = int(data['id'])
        # make sure the ID is valid
        db_session.query(ScheduledTransaction).get(_id)
        d = datetime.strptime(data['date'], '%Y-%m-%d').date()
        pp = BiweeklyPayPeriod.period_for_date(d, db_session)
        have_errors = False
        errors = {k: [] for k in data.keys()}
        if data.get('description', '').strip() == '':
            errors['description'].append('Description cannot be empty')
            have_errors = True
        if float(data['amount']) == 0:
            errors['amount'].append('Amount cannot be zero')
            have_errors = True
        if d < pp.start_date or d > pp.end_date:
            errors['date'].append('Date must be in current pay period')
            have_errors = True
        if have_errors:
            return errors
        return None
Esempio n. 2
0
 def get(self):
     accounts = {
         x.id: x.name for x in db_session.query(Account).all()
     }
     acct_names = accounts.values()
     datedict = {x: None for x in acct_names}
     data = {}
     for bal in db_session.query(AccountBalance).order_by(
         asc(AccountBalance.overall_date)
     ).all():
         ds = bal.overall_date.strftime('%Y-%m-%d')
         if ds not in data:
             data[ds] = copy(datedict)
             data[ds]['date'] = ds
         if bal.ledger is None:
             data[ds][bal.account.name] = 0.0
         else:
             data[ds][bal.account.name] = float(bal.ledger)
     resdata = []
     last = None
     for k in sorted(data.keys()):
         if last is None:
             last = data[k]
             continue
         d = copy(data[k])
         for subk in acct_names:
             if d[subk] is None:
                 d[subk] = last[subk]
         last = d
         resdata.append(d)
     res = {
         'data': resdata,
         'keys': sorted(acct_names)
     }
     return jsonify(res)
Esempio n. 3
0
 def get(self):
     standing = db_session.query(Budget).filter(
         Budget.is_active.__eq__(True),
         Budget.is_periodic.__eq__(False)).order_by(Budget.name).all()
     pp = BiweeklyPayPeriod.period_for_date(dtnow(), db_session)
     pp_curr_idx = 1
     pp_next_idx = 2
     pp_following_idx = 3
     periods = [pp]
     x = pp
     # add another
     for i in range(0, 8):
         x = x.next
         periods.append(x)
     # trigger calculation/cache of data before passing on to jinja
     for p in periods:
         p.overall_sums
     return render_template(
         'index.html',
         bank_accounts=db_session.query(Account).filter(
             Account.acct_type == AcctType.Bank,
             Account.is_active == True).all(),  # noqa
         credit_accounts=db_session.query(Account).filter(
             Account.acct_type == AcctType.Credit,
             Account.is_active == True).all(),  # noqa
         investment_accounts=db_session.query(Account).filter(
             Account.acct_type == AcctType.Investment,
             Account.is_active == True).all(),  # noqa
         standing_budgets=standing,
         periods=periods,
         curr_pp=pp,
         pp_curr_idx=pp_curr_idx,
         pp_next_idx=pp_next_idx,
         pp_following_idx=pp_following_idx)
Esempio n. 4
0
    def validate(self, data):
        """
        Validate the form data. Return None if it is valid, or else a hash of
        field names to list of error strings for each field.

        :param data: submitted form data
        :type data: dict
        :return: None if no errors, or hash of field name to errors for that
          field
        """
        logger.warning(data)
        have_errors = False
        errors = {k: [] for k in data.keys()}
        if data.get('name', '').strip() == '':
            errors['name'].append('Name cannot be empty')
            have_errors = True
        if data.get('id', '').strip() == '':
            v = db_session.query(Vehicle).filter(
                Vehicle.name.__eq__(data.get('name'))).all()
            if len(v) > 0:
                errors['name'].append('Name must be unique')
                have_errors = True
        else:
            v = db_session.query(Vehicle).filter(
                Vehicle.name.__eq__(data.get('name')),
                Vehicle.id.__ne__(int(data.get('id')))).all()
            if len(v) > 0:
                errors['name'].append('Name must be unique')
                have_errors = True
        if have_errors:
            return errors
        return None
Esempio n. 5
0
    def submit(self, data):
        """
        Handle form submission; create or update models in the DB. Raises an
        Exception for any errors.

        :param data: submitted form data
        :type data: dict
        :return: message describing changes to DB (i.e. link to created record)
        :rtype: str
        """
        action = data.get('action', None)
        if action == 'add':
            proj = Project()
            proj.name = data['name'].strip()
            proj.notes = data['notes'].strip()
        elif action == 'activate':
            proj = db_session.query(Project).get(int(data['id']))
            logger.info('Activate %s', proj)
            proj.is_active = True
        elif action == 'deactivate':
            proj = db_session.query(Project).get(int(data['id']))
            logger.info('Deactivate %s', proj)
            proj.is_active = False
        else:
            raise RuntimeError('Invalid action: %s' % action)
        db_session.add(proj)
        db_session.commit()
        if action == 'add':
            logger.info('Created Project %s', proj)
        return 'Successfully saved Project %d in database.' % proj.id
Esempio n. 6
0
 def get(self):
     accts = {a.name: a.id for a in db_session.query(Account).all()}
     budgets = {}
     active_budgets = {}
     for b in db_session.query(Budget).all():
         k = b.name
         if b.is_income:
             k = '%s (i)' % b.name
         budgets[b.id] = k
         if b.is_active:
             active_budgets[b.id] = k
     return render_template(
         'accounts.html',
         bank_accounts=db_session.query(Account).filter(
             Account.acct_type == AcctType.Bank,
             Account.is_active == True).all(),  # noqa
         credit_accounts=db_session.query(Account).filter(
             Account.acct_type == AcctType.Credit,
             Account.is_active == True).all(),  # noqa
         investment_accounts=db_session.query(Account).filter(
             Account.acct_type == AcctType.Investment,
             Account.is_active == True).all(),  # noqa
         interest_class_names=INTEREST_CALCULATION_NAMES.keys(),
         min_pay_class_names=MIN_PAYMENT_FORMULA_NAMES.keys(),
         accts=accts,
         budgets=budgets,
         active_budgets=active_budgets)
Esempio n. 7
0
 def get(self, acct_id, fitid):
     txn = db_session.query(OFXTransaction).get((acct_id, fitid))
     stmt = txn.statement.as_dict
     res = {
         'acct_name': db_session.query(Account).get(acct_id).name,
         'acct_id': txn.account_id,
         'txn': txn.as_dict,
         'stmt': stmt,
         'account_amount': txn.account_amount
     }
     return jsonify(res)
Esempio n. 8
0
 def get(self, period_date):
     d = datetime.strptime(period_date, '%Y-%m-%d').date()
     pp = BiweeklyPayPeriod.period_for_date(d, db_session)
     curr_pp = BiweeklyPayPeriod.period_for_date(dtnow(), db_session)
     budgets = {}
     for b in db_session.query(Budget).all():
         k = b.name
         if b.is_income:
             k = '%s (i)' % b.name
         budgets[b.id] = k
     standing = {
         b.id: b.current_balance
         for b in db_session.query(Budget).filter(
             Budget.is_periodic.__eq__(False), Budget.is_active.__eq__(
                 True)).all()
     }
     periodic = {
         b.id: b.current_balance
         for b in db_session.query(Budget).filter(
             Budget.is_periodic.__eq__(True), Budget.is_active.__eq__(
                 True)).all()
     }
     accts = {a.name: a.id for a in db_session.query(Account).all()}
     txfr_date_str = dtnow().strftime('%Y-%m-%d')
     if dtnow().date() < pp.start_date or dtnow().date() > pp.end_date:
         # If we're looking at a non-current pay period, default the
         # transfer modal date to the start of the period.
         txfr_date_str = pp.start_date.strftime('%Y-%m-%d')
     return render_template(
         'payperiod.html',
         pp=pp,
         pp_prev_date=pp.previous.start_date,
         pp_prev_sums=pp.previous.overall_sums,
         pp_prev_suffix=self.suffix_for_period(curr_pp, pp.previous),
         pp_curr_date=pp.start_date,
         pp_curr_sums=pp.overall_sums,
         pp_curr_suffix=self.suffix_for_period(curr_pp, pp),
         pp_next_date=pp.next.start_date,
         pp_next_sums=pp.next.overall_sums,
         pp_next_suffix=self.suffix_for_period(curr_pp, pp.next),
         pp_following_date=pp.next.next.start_date,
         pp_following_sums=pp.next.next.overall_sums,
         pp_following_suffix=self.suffix_for_period(curr_pp, pp.next.next),
         pp_last_date=pp.next.next.next.start_date,
         pp_last_sums=pp.next.next.next.overall_sums,
         pp_last_suffix=self.suffix_for_period(curr_pp, pp.next.next.next),
         budget_sums=pp.budget_sums,
         budgets=budgets,
         standing=standing,
         periodic=periodic,
         transactions=pp.transactions_list,
         accts=accts,
         txfr_date_str=txfr_date_str)
Esempio n. 9
0
    def submit(self, data):
        """
        Handle form submission; create or update models in the DB. Raises an
        Exception for any errors.

        :param data: submitted form data
        :type data: dict
        :return: message describing changes to DB (i.e. link to created record)
        :rtype: str
        """
        # get the data
        trans_date = datetime.strptime(data['date'], '%Y-%m-%d').date()
        amt = Decimal(data['amount'])
        from_acct = db_session.query(Account).get(int(data['from_account']))
        if from_acct is None:
            raise RuntimeError("Error: no Account with ID %s" %
                               data['from_account'])
        to_acct = db_session.query(Account).get(int(data['to_account']))
        if to_acct is None:
            raise RuntimeError("Error: no Account with ID %s" %
                               data['to_account'])
        budget = db_session.query(Budget).get(int(data['budget']))
        if budget is None:
            raise RuntimeError("Error: no Budget with ID %s" % data['budget'])
        notes = data['notes'].strip()
        desc = 'Account Transfer - %s from %s (%d) to %s (%d)' % (
            amt, from_acct.name, from_acct.id, to_acct.name, to_acct.id)
        logger.info(desc)
        t1 = Transaction(date=trans_date,
                         budget_amounts={budget: amt},
                         budgeted_amount=amt,
                         description=desc,
                         account=from_acct,
                         notes=notes,
                         planned_budget=budget)
        db_session.add(t1)
        t2 = Transaction(date=trans_date,
                         budget_amounts={budget: (-1 * amt)},
                         budgeted_amount=(-1 * amt),
                         description=desc,
                         account=to_acct,
                         notes=notes,
                         planned_budget=budget)
        db_session.add(t2)
        t1.transfer = t2
        db_session.add(t1)
        t2.transfer = t1
        db_session.add(t2)
        db_session.commit()
        return 'Successfully saved Transactions %d and %d in database.' % (
            t1.id, t2.id)
Esempio n. 10
0
 def get(self):
     return render_template(
         'accounts.html',
         bank_accounts=db_session.query(Account).filter(
             Account.acct_type == AcctType.Bank,
             Account.is_active == True).all(),  # noqa
         credit_accounts=db_session.query(Account).filter(
             Account.acct_type == AcctType.Credit,
             Account.is_active == True).all(),  # noqa
         investment_accounts=db_session.query(Account).filter(
             Account.acct_type == AcctType.Investment,
             Account.is_active == True).all(),  # noqa
         interest_class_names=INTEREST_CALCULATION_NAMES.keys(),
         min_pay_class_names=MIN_PAYMENT_FORMULA_NAMES.keys())
Esempio n. 11
0
 def get(self):
     budgets = {}
     active_budgets = {}
     for b in db_session.query(Budget).all():
         k = b.name
         if b.is_income:
             k = '%s (i)' % b.name
         budgets[b.id] = k
         if b.is_active:
             active_budgets[b.id] = k
     accts = {a.name: a.id for a in db_session.query(Account).all()}
     return render_template('reconcile.html',
                            budgets=budgets,
                            accts=accts,
                            active_budgets=active_budgets)
Esempio n. 12
0
 def get(self):
     """
     Render the GET /transactions view using the ``transactions.html``
     template.
     """
     accts = {a.name: a.id for a in db_session.query(Account).all()}
     budgets = {}
     for b in db_session.query(Budget).all():
         if b.is_income:
             budgets['%s (income)' % b.name] = b.id
         else:
             budgets[b.name] = b.id
     return render_template('transactions.html',
                            accts=accts,
                            budgets=budgets)
Esempio n. 13
0
 def _by_pay_period(self):
     min_txn = db_session.query(Transaction).order_by(
         Transaction.date.asc()
     ).first()
     budget_names = self._budget_names()
     logger.debug('budget_names=%s', budget_names)
     records = []
     budgets_present = set()
     pp = BiweeklyPayPeriod.period_for_date(min_txn.date, db_session)
     dt_now = dtnow().date()
     while pp.end_date <= dt_now:
         sums = pp.budget_sums
         logger.debug('sums=%s', sums)
         records.append({
             budget_names[y]: sums[y]['spent'] for y in sums.keys()
             if y in budget_names
         })
         records[-1]['date'] = pp.start_date.strftime('%Y-%m-%d')
         budgets_present.update(
             [budget_names[y] for y in sums.keys() if y in budget_names]
         )
         pp = pp.next
     res = {
         'data': records,
         'keys': sorted(list(budgets_present))
     }
     return jsonify(res)
Esempio n. 14
0
 def _by_month(self):
     dt_now = dtnow().date()
     budget_names = self._budget_names()
     logger.debug('budget_names=%s', budget_names)
     records = {}
     budgets_present = set()
     for t in db_session.query(Transaction).filter(
         Transaction.budget.has(is_income=False),
         Transaction.date.__le__(dt_now)
     ).all():
         if t.budget_id not in budget_names:
             continue
         budgets_present.add(t.budget.name)
         ds = t.date.strftime('%Y-%m')
         if ds not in records:
             records[ds] = {'date': ds}
         if t.budget.name not in records[ds]:
             records[ds][t.budget.name] = Decimal('0')
         records[ds][t.budget.name] += t.actual_amount
     result = [records[k] for k in sorted(records.keys())]
     res = {
         'data': result,
         'keys': sorted(list(budgets_present))
     }
     return jsonify(res)
Esempio n. 15
0
    def submit(self, data):
        """
        Handle form submission; create or update models in the DB. Raises an
        Exception for any errors.

        :param data: submitted form data
        :type data: dict
        :return: message describing changes to DB (i.e. link to created record)
        :rtype: str
        """
        st_id = int(data['id'])
        st = db_session.query(ScheduledTransaction).get(st_id)
        d = datetime.strptime(data['payperiod_start_date'], '%Y-%m-%d').date()
        desc = 'Skip ScheduledTransaction %d in period %s' % (
            st_id, data['payperiod_start_date'])
        t = Transaction(date=d,
                        budget_amounts={st.budget: Decimal('0.0')},
                        budgeted_amount=Decimal('0.0'),
                        description=desc,
                        notes=data['notes'],
                        account=st.account,
                        scheduled_trans=st,
                        planned_budget=st.budget)
        db_session.add(t)
        db_session.add(TxnReconcile(transaction=t, note=desc))
        db_session.commit()
        logger.info(
            'Created Transaction %d to skip '
            'ScheduledTransaction %d', t.id, st.id)
        return 'Successfully created Transaction %d to skip ' \
               'ScheduledTransaction %d.' % (t.id, st.id)
Esempio n. 16
0
    def get(self, reconcile_id):
        rec = db_session.query(TxnReconcile).get(reconcile_id)

        res = {
            'reconcile': rec.as_dict,
            'transaction': rec.transaction.as_dict
        }
        res['transaction']['budgets'] = [{
            'name': bt.budget.name,
            'id': bt.budget_id,
            'amount': bt.amount,
            'is_income': bt.budget.is_income
        } for bt in sorted(rec.transaction.budget_transactions,
                           key=lambda x: x.amount,
                           reverse=True)]
        if rec.ofx_trans is not None:
            res['ofx_trans'] = rec.ofx_trans.as_dict
            res['ofx_stmt'] = rec.ofx_trans.statement.as_dict
            res['acct_id'] = rec.ofx_trans.account_id
            res['acct_name'] = rec.ofx_trans.account.name
        else:
            res['ofx_trans'] = None
            res['ofx_stmt'] = None
            res['acct_id'] = rec.transaction.account_id
            res['acct_name'] = rec.transaction.account.name
        return jsonify(res)
Esempio n. 17
0
 def get(self):
     """
     Render and return JSON response for GET /ajax/ofx
     """
     args = request.args.to_dict()
     args_dict = self._args_dict(args)
     if self._have_column_search(args_dict) and args['search[value]'] == '':
         args['search[value]'] = 'FILTERHACK'
     table = DataTable(args, Transaction, db_session.query(Transaction),
                       [('date', lambda i: i.date.strftime('%Y-%m-%d')),
                        ('amount', 'actual_amount',
                         lambda a: float(a.actual_amount)), 'description',
                        ('account', 'account.name',
                         lambda i: "{} ({})".format(i.name, i.id)),
                        ('scheduled', 'scheduled_trans_id'),
                        ('budgeted_amount'),
                        ('reconcile_id', 'reconcile', lambda i: None
                         if i.reconcile is None else i.reconcile.id)])
     table.add_data(
         acct_id=lambda o: o.account_id,
         budgets=lambda o: [{
             'name': bt.budget.name,
             'id': bt.budget_id,
             'amount': bt.amount,
             'is_income': bt.budget.is_income
         } for bt in sorted(
             o.budget_transactions, key=lambda x: x.amount, reverse=True)],
         id=lambda o: o.id)
     if args['search[value]'] != '':
         table.searchable(lambda qs, s: self._filterhack(qs, s, args_dict))
     return jsonify(table.json())
Esempio n. 18
0
 def get(self):
     """
     Render and return JSON response for GET /ajax/ofx
     """
     args = request.args.to_dict()
     args_dict = self._args_dict(args)
     if self._have_column_search(args_dict) and args['search[value]'] == '':
         args['search[value]'] = 'FILTERHACK'
     table = DataTable(
         args, OFXTransaction, db_session.query(OFXTransaction),
         [('date', 'date_posted',
           lambda i: i.date_posted.strftime('%Y-%m-%d')),
          ('amount', lambda a: float(a.amount)),
          ('account',
           'account.name', lambda i: "{} ({})".format(i.name, i.id)),
          ('type', 'trans_type'), 'name', 'memo', 'description', 'fitid',
          ('last_stmt', 'statement.id'),
          ('last_stmt_date', 'statement.as_of',
           lambda i: i.as_of.strftime('%Y-%m-%d')),
          ('reconcile_id', 'reconcile', lambda i: None
           if i.reconcile is None else i.reconcile.id)])
     table.add_data(acct_id=lambda o: o.account_id)
     if args['search[value]'] != '':
         table.searchable(lambda qs, s: self._filterhack(qs, s, args_dict))
     return jsonify(table.json())
Esempio n. 19
0
    def submit(self, data):
        """
        Handle form submission; create or update models in the DB. Raises an
        Exception for any errors.

        :param data: submitted form data
        :type data: dict
        :return: message describing changes to DB (i.e. link to created record)
        :rtype: str
        """
        if 'id' in data and data['id'].strip() != '':
            # updating an existing Vehicle
            veh = db_session.query(Vehicle).get(int(data['id']))
            if veh is None:
                raise RuntimeError("Error: no Vehicle with ID %s" % data['id'])
            action = 'updating Vehicle ' + data['id']
        else:
            veh = Vehicle()
            action = 'creating new Vehicle'
        veh.name = data['name'].strip()
        if data['is_active'] == 'true':
            veh.is_active = True
        else:
            veh.is_active = False
        logger.info('%s: %s', action, veh.as_dict)
        db_session.add(veh)
        db_session.commit()
        return 'Successfully saved Vehicle %d in database.' % veh.id
Esempio n. 20
0
    def submit(self, data):
        """
        Handle form submission; create or update models in the DB. Raises an
        Exception for any errors.

        :param data: submitted form data
        :type data: dict
        :return: message describing changes to DB (i.e. link to created record)
        :rtype: str
        """
        st_id = int(data['id'])
        st = db_session.query(ScheduledTransaction).get(st_id)
        d = datetime.strptime(data['date'], '%Y-%m-%d').date()
        t = Transaction(date=d,
                        budget_amounts={st.budget: Decimal(data['amount'])},
                        budgeted_amount=st.amount,
                        description=data['description'],
                        notes=data['notes'],
                        account=st.account,
                        planned_budget=st.budget,
                        scheduled_trans=st)
        db_session.add(t)
        db_session.commit()
        logger.info('Created Transaction %d for ScheduledTransaction %d', t.id,
                    st.id)
        return 'Successfully created Transaction %d ' \
               'for ScheduledTransaction %d.' % (t.id, st.id)
Esempio n. 21
0
 def _budget_names(self):
     return {
         x.id: x.name
         for x in db_session.query(Budget).filter(
             Budget.is_income.__eq__(False),
             Budget.omit_from_graphs.__eq__(False)).all()
     }
Esempio n. 22
0
    def validate(self, data):
        """
        Validate the form data. Return None if it is valid, or else a hash of
        field names to list of error strings for each field.

        :param data: submitted form data
        :type data: dict
        :return: None if no errors, or hash of field name to errors for that
          field
        """
        errors = {k: [] for k in data.keys()}
        errors = self._validate_date_ymd('date', data, errors)
        if data['add_trans'] == 'true':
            if data['account'] == 'None':
                errors['account'].append('Transactions must have an account')
            if data['budget'] == 'None':
                errors['budget'].append('Transactions must have a budget')
        if db_session.query(Vehicle).get(int(data['vehicle'])) is None:
            errors['vehicle'].append('Invalid Vehicle ID %s' % data['vehicle'])
        errors = self._validate_int('odometer_miles', data, errors)
        errors = self._validate_int('reported_miles', data, errors)
        errors = self._validate_not_empty('fill_location', data, errors)
        errors = self._validate_float('cost_per_gallon', data, errors)
        errors = self._validate_float('total_cost', data, errors)
        errors = self._validate_float('gallons', data, errors)
        errors = self._validate_float('reported_mpg', data, errors)
        errors = self._validate_int('vehicle', data, errors)
        errors = self._validate_int('level_before', data, errors)
        errors = self._validate_int('level_after', data, errors)
        if len(errors['total_cost']) == 0 and float(data['total_cost']) == 0:
            errors['total_cost'].append('Total Cost cannot be zero')
        for v in errors.values():
            if len(v) > 0:
                return errors
        return None
Esempio n. 23
0
    def submit(self, data):
        """
        Handle form submission; create or update models in the DB. Raises an
        Exception for any errors.

        :param data: submitted form data
        :type data: dict
        :return: message describing changes to DB (i.e. link to created record)
        :rtype: str
        """
        if 'id' in data and data['id'].strip() != '':
            # updating an existing budget
            budget = db_session.query(Budget).get(int(data['id']))
            if budget is None:
                raise RuntimeError("Error: no Budget with ID %s" % data['id'])
            action = 'updating Budget ' + data['id']
        else:
            budget = Budget()
            action = 'creating new Budget'
        budget.name = data['name'].strip()
        budget.description = data['description'].strip()
        budget.is_periodic = data['is_periodic']
        if data['is_periodic'] is True:
            budget.starting_balance = Decimal(data['starting_balance'])
        else:
            budget.current_balance = Decimal(data['current_balance'])
        budget.is_active = data['is_active']
        budget.is_income = data['is_income']
        budget.omit_from_graphs = data['omit_from_graphs']
        logger.info('%s: %s', action, budget.as_dict)
        db_session.add(budget)
        db_session.commit()
        return 'Successfully saved Budget %d in database.' % budget.id
Esempio n. 24
0
 def get(self, project_id):
     proj = db_session.query(Project).get(project_id)
     return render_template('bomitem.html',
                            project_id=project_id,
                            project_name=proj.name,
                            project_notes=proj.notes,
                            remaining=proj.remaining_cost,
                            total=proj.total_cost)
Esempio n. 25
0
    def submit(self, data):
        """
        Handle form submission; create or update models in the DB. Raises an
        Exception for any errors.

        :param data: submitted form data
        :type data: dict
        :return: message describing changes to DB (i.e. link to created record)
        :rtype: str
        """
        acct = db_session.query(Account).get(int(data['id']))
        if acct is None:
            raise RuntimeError('ERROR: No Account with ID %s' % data['id'])
        stmt = db_session.query(OFXStatement).filter(
            OFXStatement.account_id.__eq__(acct.id),
            OFXStatement.filename.__eq__(data['filename'])
        ).one()
        if stmt is None:
            raise RuntimeError(
                'ERROR: No OFXStatement for account %d with filename %s' % (
                    acct.id, data['filename']
                )
            )
        int_amt = Decimal(data['interest_amt'])
        if int_amt < Decimal('0'):
            int_amt = int_amt * Decimal('-1')
        trans = OFXTransaction(
            account=acct,
            statement=stmt,
            fitid='%s-MANUAL-CCPAYOFF' % dtnow().strftime('%Y%m%d%H%M%S'),
            trans_type='debit',
            date_posted=stmt.as_of,
            amount=int_amt,
            name='Interest Charged - MANUALLY ENTERED',
            is_interest_charge=True
        )
        logger.info(
            'Adding manual interest transaction to OFXTransactions: '
            'account_id=%d statement_filename=%s statement=%s '
            'OFXTransaction=%s', acct.id, data['filename'], stmt,
            trans
        )
        db_session.add(trans)
        db_session.commit()
        return 'Successfully saved OFXTransaction with FITID %s in database' \
               '.' % trans.fitid
Esempio n. 26
0
    def submit(self, data):
        """
        Handle form submission; create or update models in the DB. Raises an
        Exception for any errors.

        :param data: submitted form data
        :type data: dict
        :return: message describing changes to DB (i.e. link to created record)
        :rtype: str
        """
        if 'id' in data and data['id'].strip() != '':
            # updating an existing budget
            trans = db_session.query(Transaction).get(int(data['id']))
            if trans is None:
                raise RuntimeError("Error: no Transaction with ID "
                                   "%s" % data['id'])
            if trans.reconcile is not None:
                raise RuntimeError(
                    "Transaction %d is already reconciled; cannot be edited."
                    "" % trans.id)
            action = 'updating Transaction ' + data['id']
        else:
            trans = Transaction()
            action = 'creating new Transaction'
        trans.description = data['description'].strip()
        trans.date = datetime.strptime(data['date'], '%Y-%m-%d').date()
        trans.account_id = int(data['account'])
        trans.notes = data['notes'].strip()
        budg_amts = {}
        for bid, budg_amt in data['budgets'].items():
            budg = db_session.query(Budget).get(int(bid))
            budg_amts[budg] = Decimal(budg_amt)
        trans.set_budget_amounts(budg_amts)
        logger.info('%s: %s', action, trans.as_dict)
        db_session.add(trans)
        db_session.commit()
        return {
            'success_message':
            'Successfully saved Transaction %d  in database.'
            '' % trans.id,
            'success':
            True,
            'trans_id':
            trans.id
        }
Esempio n. 27
0
 def get(self, sched_trans_id):
     """
     Render the GET /scheduled/<int:sched_trans_id> view using the
     ``scheduled.html`` template.
     """
     accts = {a.name: a.id for a in db_session.query(Account).all()}
     budgets = {}
     for b in db_session.query(Budget).all():
         if b.is_income:
             budgets['%s (income)' % b.name] = b.id
         else:
             budgets[b.name] = b.id
     return render_template(
         'scheduled.html',
         accts=accts,
         budgets=budgets,
         sched_trans_id=sched_trans_id
     )
Esempio n. 28
0
 def get(self):
     resdata = []
     prices = db_session.query(FuelFill).filter(
         FuelFill.cost_per_gallon.__ne__(None)).order_by(asc(FuelFill.date))
     for point in prices.all():
         ds = point.date.strftime('%Y-%m-%d')
         resdata.append({'date': ds, 'price': float(point.cost_per_gallon)})
     res = {'data': resdata}
     return jsonify(res)
Esempio n. 29
0
 def get(self):
     accts = {a.name: a.id for a in db_session.query(Account).all()}
     budgets = {}
     for b in db_session.query(Budget).all():
         if b.is_income:
             budgets['%s (income)' % b.name] = b.id
         else:
             budgets[b.name] = b.id
     vehicles = {
         v.id: {
             'name': v.name,
             'is_active': v.is_active
         }
         for v in db_session.query(Vehicle).all()
     }
     return render_template('fuel.html',
                            accts=accts,
                            budgets=budgets,
                            vehicles=vehicles)
Esempio n. 30
0
 def get(self):
     total_active = 0.0
     remain_active = 0.0
     for p in db_session.query(Project).filter(
             Project.is_active.__eq__(True)).all():
         total_active += p.total_cost
         remain_active += p.remaining_cost
     return render_template('projects.html',
                            total_active=total_active,
                            remain_active=remain_active)