Exemplo n.º 1
0
def step_add_transactions(context):
    """
    Add transactions from a table in the format given below

    | account | date       | desc | amount | reconciled | category |
    | test    | 01-01-2014 |      | 100.0  | False      | cat1     |

    Where category is optional.
    """
    for row in context.table:
        with session_scope() as session:
            account = session.query(Account) \
                             .filter_by(name=row['account']) \
                             .one()
        tx = Transaction(
            account, datetime.datetime.strptime(row['date_time'],
                                                '%d-%m-%Y'), row['desc'],
            float(row['amount']),
            True if row['reconciled'] == 'True' else False)

        if 'category' in row.as_dict():
            with session_scope() as session:
                category = session.query(Category) \
                                  .filter_by(name=row['category']) \
                                  .one()
            tx.category = category
        save_object(tx)
Exemplo n.º 2
0
def step_add_transactions(context):
    """
    Add transactions from a table in the format given below

    | account | date       | desc | amount | reconciled | category |
    | test    | 01-01-2014 |      | 100.0  | False      | cat1     |

    Where category is optional.
    """
    for row in context.table:
        with session_scope() as session:
            account = session.query(Account) \
                             .filter_by(name=row['account']) \
                             .one()
        tx = Transaction(account,
                         datetime.datetime.strptime(row['date_time'],
                                                    '%d-%m-%Y'),
                         row['desc'],
                         float(row['amount']),
                         True if row['reconciled'] == 'True' else False)

        if 'category' in row.as_dict():
            with session_scope() as session:
                category = session.query(Category) \
                                  .filter_by(name=row['category']) \
                                  .one()
            tx.category = category
        save_object(tx)
Exemplo n.º 3
0
    def __call__(self):
        with open(_IMPORT_YAML_PATH, 'r') as f:
            i_txs = self._load_parsed_txs(f)

        num_processed = 0
        for i, i_tx in enumerate(i_txs, start=1):
            # Check that the account number in the transaction matches an
            # existing account. If not, the process is halted; however, any
            # transactions that have been processed remain so.
            with session_scope() as session:
                try:
                    session.query(Account)\
                           .filter_by(number=i_tx.parsed_tx.account)\
                           .one()
                except NoResultFound:
                    raise ValueError(
                        "Account number '{}' does not exist.".format(
                            i_tx.parsed_tx.account))

            if i in self.tx_ids:
                i_tx.processed = True
                num_processed += 1

        assert num_processed == len(self.tx_ids)

        # Write the changes back to the file.
        with open(_IMPORT_YAML_PATH, "w+") as f:
            self._save_parsed_txs(i_txs, f)

        return "{} transactions added to the staging area.".format(
            num_processed)
Exemplo n.º 4
0
    def __call__(self):
        with open(_IMPORT_YAML_PATH, 'r') as f:
            i_txs = self._load_parsed_txs(f)

        num_processed = 0
        for i, i_tx in enumerate(i_txs, start=1):
            # Check that the account number in the transaction matches an
            # existing account. If not, the process is halted; however, any
            # transactions that have been processed remain so.
            with session_scope() as session:
                try:
                    session.query(Account)\
                           .filter_by(number=i_tx.parsed_tx.account)\
                           .one()
                except NoResultFound:
                    raise ValueError(
                        "Account number '{}' does not exist.".format(
                            i_tx.parsed_tx.account))

            if i in self.tx_ids:
                i_tx.processed = True
                num_processed += 1

        assert num_processed == len(self.tx_ids)

        # Write the changes back to the file.
        with open(_IMPORT_YAML_PATH, "w+") as f:
            self._save_parsed_txs(i_txs, f)

        return "{} transactions added to the staging area.".format(
            num_processed)
Exemplo n.º 5
0
def step_unreconciled_transactions(context, account_name, count):
    with session_scope() as session:
        account = session.query(Account).filter_by(name=account_name).one()
        unreconciled_count = 0
        for tx in account.transactions:
            if not tx.reconciled:
                unreconciled_count += 1
        eq_(count, unreconciled_count)
Exemplo n.º 6
0
def step_unreconciled_transactions(context, account_name, count):
    with session_scope() as session:
        account = session.query(Account).filter_by(name=account_name).one()
        unreconciled_count = 0
        for tx in account.transactions:
            if not tx.reconciled:
                unreconciled_count += 1
        eq_(count, unreconciled_count)
Exemplo n.º 7
0
    def __call__(self):
        # Get the transactions ready to import
        with open(_IMPORT_YAML_PATH, 'r') as f:
            i_txs = self._load_parsed_txs(f)

        # Create transaction model objects from parsed transaction. If an error
        # occurs during this process, stop.
        txs = []
        cats = []
        for i_tx in i_txs:
            # Get the account
            with session_scope() as session:
                account = session.query(Account)\
                                 .filter_by(number=i_tx.parsed_tx.account)\
                                 .one()

            # Get the category, and if it doesn't exist, create it
            with session_scope() as session:
                try:
                    category = session.query(Category) \
                                      .filter_by(name=i_tx.category) \
                                      .one()
                except NoResultFound:
                    category = Category(i_tx.category)
                    cats.append(category)

            # Commits must be in the staging area.
            if not i_tx.processed:
                raise ValueError("All transactions must be in the staging " +
                                 "area")

            tx = Transaction(account,
                             i_tx.parsed_tx.date,
                             i_tx.parsed_tx.description,
                             i_tx.parsed_tx.amount,
                             False)
            tx.category = category
            txs.append(tx)

        # Add to the database
        save_objects(cats)
        save_objects(txs)

        return "{} transactions imported.".format(len(txs))
Exemplo n.º 8
0
def after_scenario(context, scenario):
    # Clear all records from the database
    with session_scope() as session:
        session.query(Account).delete()
        session.query(BudgetItem).delete()
        session.query(Category).delete()
        session.query(Transaction).delete()

    for test_data_file in context.test_data_files:
        os.remove(test_data_file)
Exemplo n.º 9
0
def before_scenario(context, scenario):
    # Ensure that the database is indeed empty
    with session_scope() as session:
        assert session.query(Account).count() == 0
        assert session.query(BudgetItem).count() == 0
        assert session.query(Category).count() == 0
        assert session.query(Transaction).count() == 0

    # Give the context a test_data_files list
    context.test_data_files = []
Exemplo n.º 10
0
def after_scenario(context, scenario):
    # Clear all records from the database
    with session_scope() as session:
        session.query(Account).delete()
        session.query(BudgetItem).delete()
        session.query(Category).delete()
        session.query(Transaction).delete()

    for test_data_file in context.test_data_files:
        os.remove(test_data_file)
Exemplo n.º 11
0
def before_scenario(context, scenario):
    # Ensure that the database is indeed empty
    with session_scope() as session:
        assert session.query(Account).count() == 0
        assert session.query(BudgetItem).count() == 0
        assert session.query(Category).count() == 0
        assert session.query(Transaction).count() == 0

    # Give the context a test_data_files list
    context.test_data_files = []
Exemplo n.º 12
0
    def __call__(self):
        # Get the transactions ready to import
        with open(_IMPORT_YAML_PATH, 'r') as f:
            i_txs = self._load_parsed_txs(f)

        # Create transaction model objects from parsed transaction. If an error
        # occurs during this process, stop.
        txs = []
        cats = []
        for i_tx in i_txs:
            # Get the account
            with session_scope() as session:
                account = session.query(Account)\
                                 .filter_by(number=i_tx.parsed_tx.account)\
                                 .one()

            # Get the category, and if it doesn't exist, create it
            with session_scope() as session:
                try:
                    category = session.query(Category) \
                                      .filter_by(name=i_tx.category) \
                                      .one()
                except NoResultFound:
                    category = Category(i_tx.category)
                    cats.append(category)

            # Commits must be in the staging area.
            if not i_tx.processed:
                raise ValueError("All transactions must be in the staging " +
                                 "area")

            tx = Transaction(account, i_tx.parsed_tx.date,
                             i_tx.parsed_tx.description, i_tx.parsed_tx.amount,
                             False)
            tx.category = category
            txs.append(tx)

        # Add to the database
        save_objects(cats)
        save_objects(txs)

        return "{} transactions imported.".format(len(txs))
Exemplo n.º 13
0
def test_cmd_assign_tx_similar_category():
    account = Account(u'test', u'12345')
    save_object(account)
    save_object(Category(u'cat1'))
    save_object(Transaction(account,
                            datetime.datetime.now().date(), u'desc', 1.0))

    CmdAssignTx(u'Cat1', '1')()

    with session_scope() as session:
        count = session.query(Category).count()
        eq_(count, 1)
Exemplo n.º 14
0
def test_cmd_assign_tx_similar_category():
    account = Account(u'test', u'12345')
    save_object(account)
    save_object(Category(u'cat1'))
    save_object(
        Transaction(account,
                    datetime.datetime.now().date(), u'desc', 1.0))

    CmdAssignTx(u'Cat1', '1')()

    with session_scope() as session:
        count = session.query(Category).count()
        eq_(count, 1)
Exemplo n.º 15
0
    def __call__(self):
        # Get the transactions
        with session_scope() as session:
            txs = session.query(Transaction) \
                         .filter(Transaction.id.in_(self.tx_ids)) \
                         .all()

        # Unassign the category
        for tx in txs:
            tx.reconciled = True

        save_objects(txs)

        return ("Reconciled {} transactions").format(len(txs))
Exemplo n.º 16
0
    def __call__(self):
        # Get the transactions
        with session_scope() as session:
            txs = session.query(Transaction) \
                         .filter(Transaction.id.in_(self.tx_ids)) \
                         .all()

        # Unassign the category
        for tx in txs:
            tx.category = None

        save_objects(txs)

        return ("Unassigned {} transactions from their " +
                "category").format(len(txs))
Exemplo n.º 17
0
    def __call__(self):
        # Get the category if it already exists, or create a new one.
        with session_scope() as session:
            try:
                category = session.query(Category) \
                                  .filter_by(name=self.category_name) \
                                  .one()
            except NoResultFound:
                category = Category(self.category_name)

        # Get the transactions
        with session_scope() as session:
            txs = session.query(Transaction) \
                         .filter(Transaction.id.in_(self.tx_ids)) \
                         .all()

        # Assign the category to the transactions
        for tx in txs:
            tx.category = category

        save_objects(txs)

        return ("Assigned {} transactions to the {} " +
                "category").format(len(txs), self.category_name)
Exemplo n.º 18
0
def step_add_categories(context):
    """
    Add budget items from a table in the format given below

    | category | period | amount |
    | cat1     | month  | 100.00 |
    """
    for row in context.table:
        with session_scope() as session:
            category = session.query(Category) \
                              .filter_by(name=row['category']) \
                              .one()
        budget_item = BudgetItem(datetime.datetime.now(), row['period'],
                                 row['amount'])

        category.budget_items.append(budget_item)
        session.add(category)
Exemplo n.º 19
0
    def __call__(self):
        # Get all the transactions
        with session_scope() as session:
            txs = session.query(Transaction) \
                         .filter(Transaction.account.has(
                             name=self.account_name)) \
                         .order_by(Transaction.date) \
                         .all()

        output = defaultdict(list)
        for tx in txs:
            output['id'].append(tx.id)
            output['date'].append(str(tx.date))
            output['description'].append(
                tx.description[:130].replace('\n', ' '))
            output['amount'].append(tx.amount)
            output['reconciled'].append(tx.reconciled)
            if tx.category:
                output['category'].append(tx.category.name)
            else:
                output['category'].append('')

        def format_amount(x):
            if x < 0:
                color = Fore.RED
            else:
                color = Fore.GREEN
            output = "{}{:.2f}{}".format(color, x, Fore.RESET)
            return output

        output_io = StringIO()
        asciitable.write(output, output_io,
                         Writer=asciitable.FixedWidthNoHeader,
                         names=['id', 'date', 'description', 'category',
                                'reconciled', 'amount'],
                         formats={'amount': lambda x: format_amount(x),
                                  'reconciled': lambda x: 'Y' if x else 'N'})

        return output_io.getvalue()
Exemplo n.º 20
0
def step_category_exists(context, category_name):
    with session_scope() as session:
        count = session.query(Category).filter_by(name=category_name).count()
        eq_(count, 1)
Exemplo n.º 21
0
def save_object(object_):
    _log.info("Saving '{}'".format(type(object_)))
    with session_scope() as session:
        session.add(object_)
Exemplo n.º 22
0
def step_account_doesnt_exist(context, account_name):
    with session_scope() as session:
        count = session.query(Account).filter_by(name=account_name).count()
        eq_(count, 0)
Exemplo n.º 23
0
def step_num_txs_in_category(context, category_name, num_txs):
    with session_scope() as session:
        count = session.query(Transaction) \
                       .filter(Transaction.category.has(name=category_name)) \
                       .count()
        eq_(count, num_txs)
Exemplo n.º 24
0
def test_cmd_delete_account():
    CmdAddAccount(u'test', u'987654321')()
    CmdDeleteAccount(u'test')()
    with session_scope() as session:
        num = session.query(Account).filter_by(name=u"test").count()
        eq_(num, 0)
Exemplo n.º 25
0
 def __call__(self):
     with session_scope() as session:
         output = ""
         for account in session.query(Account).all():
             output += account.name + "\n"
         return output
Exemplo n.º 26
0
 def __call__(self):
     with session_scope() as session:
         account = session.query(Account).filter_by(name=self.name).one()
     delete_object(account)
     return "Account '{}' deleted".format(self.name)
Exemplo n.º 27
0
def delete_object(object_):
    _log.info("Deleting '{}' with id {}".format(type(object_), object_.id))
    with session_scope() as session:
        session.delete(object_)
Exemplo n.º 28
0
def step_num_budget_items_in_category(context, category_name,
                                      num_budget_items):
    with session_scope() as session:
        category = session.query(Category).filter_by(name=category_name).one()
        eq_(num_budget_items, len(category.budget_items))
Exemplo n.º 29
0
def save_objects(objects):
    _log.info("Saving '{}' object".format(len(objects)))
    with session_scope() as session:
        session.add_all(objects)