def test_stats_two_transaction_diff_account_book_value( investment_account_setup, client): app = investment_account_setup with app.app_context(): db.session.add(InvestmentAccount(**investment_account_2)) db.session.add(StockTransaction(**stock_transaction_1)) stock_account_2 = stock_transaction_2.copy() stock_account_2['account_id'] = 2 db.session.add(StockTransaction(**stock_account_2)) db.session.commit() response = client.get('/transaction/stats') json_data = json.loads(response.data) assert json_data['book_cost'] == "$8,362.98"
def test_get_one_stock_acb(investment_account_setup, client): app = investment_account_setup with app.app_context(): db.session.add(InvestmentAccount(**investment_account_2)) db.session.add(StockTransaction(**stock_transaction_4)) db.session.add(StockTransaction(**stock_transaction_5)) db.session.add(StockTransaction(**stock_transaction_6)) db.session.commit() response = client.get('/investment_account/2/acb') json_data = json.loads(response.data) acbs = json_data['adjust_cost_base'] assert len(acbs) == 1 assert acbs['Bagel'] == '$5,054.08'
def test_stats_multi_stock_market_value(investment_account_setup, client): app = investment_account_setup with app.app_context(): db.session.add(StockTransaction(**stock_transaction_1)) db.session.add(StockTransaction(**stock_transaction_2)) db.session.commit() response = client.get('/transaction/stats') json_data = json.loads(response.data) assert json_data['market_value']['total'] == "$8,508.00" breakdown = json_data['market_value']['breakdown'] assert len(breakdown) == 2 assert breakdown['VCN.TO']["formatted_value"] == "$3,312.00" assert breakdown['VAB.TO']["formatted_value"] == "$5,196.00" assert breakdown['VCN.TO']['percent'] == '38.9%' assert breakdown['VAB.TO']['percent'] == '61.1%'
def test_stats_missing_stock_market_value(investment_account_setup, client): app = investment_account_setup with app.app_context(): db.session.add(StockTransaction(**stock_transaction_1)) vsb = stock_transaction_2.copy() vsb['stock_symbol'] = "VSB.TO" db.session.add(StockTransaction(**vsb)) db.session.commit() response = client.get('/transaction/stats') json_data = json.loads(response.data) assert json_data['market_value']['total'] == "$3,312.00" breakdown = json_data['market_value']['breakdown'] assert len(breakdown) == 1 assert breakdown['VCN.TO']["formatted_value"] == "$3,312.00" assert breakdown['VCN.TO']['percent'] == '100.0%'
def test_get_account_buy_sell_market_value(investment_account_setup, client): app = investment_account_setup with app.app_context(): db.session.add(StockTransaction(**stock_transaction_1)) sell_transaction = stock_transaction_1.copy() sell_transaction['quantity'] = 50 sell_transaction['transaction_type'] = StockTransactionType.sell sell_transaction['trade_date'] = date(2016, 4, 28) db.session.add(StockTransaction(**sell_transaction)) db.session.commit() response = client.get('/transaction/stats') json_data = json.loads(response.data) assert json_data['market_value']['total'] == "$1,656.00" breakdown = json_data['market_value']['breakdown'] assert breakdown['VCN.TO']["formatted_value"] == "$1,656.00" assert breakdown['VCN.TO']['percent'] == '100.0%'
def test_generate_markers_multiple_different(stock_transaction_setup, client): app = stock_transaction_setup with app.app_context(): db.session.add(StockTransaction(**stock_transaction_2)) db.session.add(StockTransaction(**stock_transaction_3)) db.session.commit() runner = app.test_cli_runner() runner.invoke(generate_markers) with app.app_context(): markers = StockMarker.query.all() assert len(markers) == 3 symbols = set(map(lambda x: x.stock_symbol, markers)) assert "VCN.TO" in symbols assert "VAB.TO" in symbols assert "ZPR.TO" in symbols
def test_stats_one_transaction_book_value(investment_account_setup, client): app = investment_account_setup with app.app_context(): db.session.add(StockTransaction(**stock_transaction_1)) db.session.commit() response = client.get('/transaction/stats') json_data = json.loads(response.data) assert json_data['book_cost'] == "$3,150.99"
def test_stats_multi_stock_user_market_value(investment_account_setup, client): app = investment_account_setup with app.app_context(): db.session.add(InvestmentAccount(**investment_account_2)) db.session.add(InvestmentAccount(**investment_account_3)) db.session.add(StockTransaction(**stock_transaction_1)) stock_account_2 = stock_transaction_2.copy() stock_account_2['user_id'] = 2 stock_account_2['account_id'] = 3 db.session.add(StockTransaction(**stock_account_2)) db.session.commit() response = client.get('/transaction/stats') json_data = json.loads(response.data) assert json_data['market_value']['total'] == "$3,312.00" breakdown = json_data['market_value']['breakdown'] assert len(breakdown) == 1 assert breakdown['VCN.TO']["formatted_value"] == "$3,312.00" assert breakdown['VCN.TO']['percent'] == '100.0%'
def update_transaction(id): """ Updates the stock transaction with the values provided """ try: json_data = json.loads(request.data) update_data = StockTransaction.deserialize(json_data) update_data['id'] = id db.session.query(StockTransaction) \ .filter((StockTransaction.id == id) & \ (StockTransaction.user_id == current_user.id)) \ .update(update_data) db.session.commit() return jsonify(StockTransaction.serialize(update_data)) except Exception as e: logging.error(e) logging.error(traceback.format_exc()) db.session.rollback() return jsonify(None)
def batch_create_transaction(): """ Reads the relevant transaction data from the csv and creates the transactions for the account provided. If no account id is provided then these will be created for the user's unassigned transactions which has an account_id of None """ try: if 'file' not in request.files: return '' account_id = None if 'account_id' in request.form: account_id = int(request.form['account_id']) csv_file = request.files['file'] stream = io.StringIO(csv_file.stream.read().decode("utf8"), newline=None) csv_iterator = csv.reader(stream) keys = StockTransaction.DATA_KEYS col_keys = csv_iterator.__next__() key_index_map = {} for index, col_key in enumerate(col_keys): if col_key in keys: key_index_map[col_key] = index transactions = [] for row in csv_iterator: row_data = {} for key, index in key_index_map.items(): value = row[index] row_data[key] = value row_data['account_id'] = account_id transactions.append( StockTransaction(**StockTransaction.deserialize(row_data))) db.session.bulk_save_objects(transactions) db.session.commit() return '' except Exception as e: logging.error(e) logging.error(traceback.format_exc()) db.session.rollback() return ''
def test_stats_one_transaction_market_value_other_user( investment_account_setup, auth_app_user_2, client): app = investment_account_setup with app.app_context(): db.session.add(StockTransaction(**stock_transaction_1)) db.session.commit() response = client.get('/transaction/stats') json_data = json.loads(response.data) assert json_data['market_value']['total'] == "$0.00" breakdown = json_data['market_value']['breakdown'] assert len(breakdown) == 0
def create_transaction(): """ Creates and returns a stock transaction with the data provided If an id is provided it will be ignored. The server will provide the id for the newly created transaction. """ try: json_data = json.loads(request.data) if 'id' in json_data: del json_data['id'] transaction = StockTransaction( **StockTransaction.deserialize(json_data)) db.session.add(transaction) db.session.commit() return jsonify(dict(transaction)) except Exception as e: logging.error(e) logging.error(traceback.format_exc()) db.session.rollback() return jsonify(None)
def test_stats_one_transaction_market_value(investment_account_setup, client): app = investment_account_setup with app.app_context(): db.session.add(StockTransaction(**stock_transaction_1)) db.session.commit() response = client.get('/investment_account/1/stats') json_data = json.loads(response.data) assert json_data['market_value']['total'] == "$3,312.00" breakdown = json_data['market_value']['breakdown'] assert breakdown['VCN.TO']["formatted_value"] == "$3,312.00" assert breakdown['VCN.TO']['percent'] == '100.0%'
def test_batch_delete_transactions_other_user(one_account, auth_app_user_2, client): with one_account.app_context(): for i in range(0, 5): db.session.add(StockTransaction(**stock_transaction_1)) db.session.commit() response = client.delete('/transaction/batch', data=json.dumps(dict( transaction_ids = [1, 2, 3, 4, 5] ))) with one_account.app_context(): transactions = StockTransaction.query.all() assert len(transactions) == 5
def test_get_multi_stock_acb(investment_account_setup, client): app = investment_account_setup with app.app_context(): db.session.add(InvestmentAccount(**investment_account_2)) s1 = stock_transaction_1.copy() s1['account_id'] = 2 s2 = stock_transaction_2.copy() s2['account_id'] = 2 db.session.add(StockTransaction(**s1)) db.session.add(StockTransaction(**s2)) db.session.add(StockTransaction(**stock_transaction_4)) db.session.add(StockTransaction(**stock_transaction_5)) db.session.add(StockTransaction(**stock_transaction_6)) db.session.commit() response = client.get('/investment_account/2/acb') json_data = json.loads(response.data) acbs = json_data['adjust_cost_base'] assert len(acbs) == 3 assert acbs['Bagel'] == '$5,054.08' assert acbs['VAB.TO'] == '$5,211.99' assert acbs['VCN.TO'] == '$3,150.99'
def stock_transaction_setup(auth_app_user_1): auth_app = auth_app_user_1 try: with auth_app.app_context(): db.session.add(StockTransaction(**stock_transaction_1)) db.session.commit() yield auth_app except Exception as e: assert False finally: with auth_app.app_context(): StockTransaction.query.delete() db.session.commit()
def test_generate_markers_multiple_same(stock_transaction_setup, client): app = stock_transaction_setup with app.app_context(): db.session.add(StockTransaction(**stock_transaction_1)) db.session.commit() runner = app.test_cli_runner() runner.invoke(generate_markers) with app.app_context(): markers = StockMarker.query.all() assert len(markers) == 1 assert markers[0].stock_symbol == "VCN.TO" assert markers[0].exists == None
def test_batch_move_transactions_other_user(one_account, auth_app_user_2, client): with one_account.app_context(): for i in range(0, 5): db.session.add(StockTransaction(**stock_transaction_1)) db.session.commit() response = client.put('/transaction/move', data=json.dumps(dict( new_account_id = 1, transaction_ids = [1, 2, 3, 4, 5] ))) with one_account.app_context(): transactions = StockTransaction.query.all() for transaction in transactions: assert transaction.account_id is None
def test_stats_large_market_value(investment_account_setup, client): app = investment_account_setup with app.app_context(): large = stock_transaction_1.copy() large['quantity'] = 123456 db.session.add(StockTransaction(**large)) db.session.commit() response = client.get('/transaction/stats') json_data = json.loads(response.data) assert json_data['market_value']['total'] == "$4,088,862.72" breakdown = json_data['market_value']['breakdown'] assert len(breakdown) == 1 assert breakdown['VCN.TO']["formatted_value"] == "$4,088,862.72" assert breakdown['VCN.TO']['percent'] == '100.0%'
def test_export_one_transaction(one_account, client): expected_row = [] with one_account.app_context(): stock_1 = StockTransaction(**stock_transaction_1) db.session.add(stock_1) db.session.commit() stock_fields = dict(stock_1) for key in StockTransaction.DATA_KEYS: expected_row.append(str(stock_fields[key])) response = client.get('/transaction/export') csv_rows = response.data.decode('utf8').strip().split('\r\n') assert len(csv_rows) == 2 assert csv_rows[0] == ",".join(StockTransaction.DATA_KEYS) assert csv_rows[1] == ",".join(expected_row)
def test_generate_markers_partial_existing(stock_transaction_setup, client): app = stock_transaction_setup with app.app_context(): db.session.add(StockMarker(stock_symbol="VCN.TO", exists=True)) db.session.add(StockTransaction(**stock_transaction_2)) db.session.commit() runner = app.test_cli_runner() runner.invoke(generate_markers) with app.app_context(): markers = StockMarker.query.all() assert len(markers) == 2 marker_map = dict() for marker in markers: marker_map[marker.stock_symbol] = marker.exists assert "VCN.TO" in marker_map assert "VAB.TO" in marker_map assert marker_map["VCN.TO"] == True assert marker_map["VAB.TO"] is None
def test_delete_account_with_transactions(account_with_transaction, client): app = account_with_transaction with app.app_context(): db.session.add( StockTransaction(transaction_type=StockTransactionType.buy, stock_symbol="XAW.TO", cost_per_unit=2612, quantity=600, trade_fee=995, trade_date=datetime.date(2016, 4, 26), account_id=1, user_id=1)) db.session.commit() response = client.delete('/investment_account/1') assert json.loads(response.data) == None with app.app_context(): account = InvestmentAccount.query.get(1) assert account == None transaction = StockTransaction.query.get(1) assert transaction is None StockTransaction.query.delete()
def account_with_transaction(investment_account_setup): auth_app = investment_account_setup try: with auth_app.app_context(): db.session.add( StockTransaction(transaction_type=StockTransactionType.buy, stock_symbol="XAW.TO", cost_per_unit=2612, quantity=600, trade_fee=995, trade_date=datetime.date(2016, 4, 26), account_id=1, user_id=1)) db.session.commit() yield auth_app except Exception as e: assert False finally: with auth_app.app_context(): StockTransaction.query.delete() InvestmentAccount.query.delete() db.session.commit()