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)
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)
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)
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)
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))
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)
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 = []
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)
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)
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))
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))
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)
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)
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()
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)
def save_object(object_): _log.info("Saving '{}'".format(type(object_))) with session_scope() as session: session.add(object_)
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)
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)
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)
def __call__(self): with session_scope() as session: output = "" for account in session.query(Account).all(): output += account.name + "\n" return output
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)
def delete_object(object_): _log.info("Deleting '{}' with id {}".format(type(object_), object_.id)) with session_scope() as session: session.delete(object_)
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))
def save_objects(objects): _log.info("Saving '{}' object".format(len(objects))) with session_scope() as session: session.add_all(objects)