diff --git a/api/app/blueprints/portfolio.py b/api/app/blueprints/portfolio.py index 2cefe4d..9ead66b 100644 --- a/api/app/blueprints/portfolio.py +++ b/api/app/blueprints/portfolio.py @@ -2,7 +2,7 @@ __author__ = "Florian Kaiser" __copyright__ = "Copyright 2022, Project Aktienbot" __credits__ = ["Florian Kaiser", "Florian Kellermann", "Linus Eickhof", "Kevin Pauer"] __license__ = "GPL 3.0" -__version__ = "1.0.0" +__version__ = "1.0.1" import os @@ -27,22 +27,23 @@ def get_portfolio(): return_portfolio = [] # Get all transactions of current user - transactions = db.session.execute("SELECT symbol, SUM(count), SUM(price), MAX(time) FROM `transactions` WHERE email = '" + email + "' GROUP BY symbol;").all() + transactions = db.session.execute("SELECT isin, comment, SUM(count), SUM(price), MAX(time) FROM `transactions` WHERE email = '" + email + "' GROUP BY isin, comment;").all() # If there are no transactions, return empty portfolio # Otherwise calculate portfolio if transactions is not None: for row in transactions: data = { - "symbol": row[0], - "count": row[1], - # "calculated_price": row[2], - "last_transaction": row[3], + "isin": row[0], + "comment": row[1], + "count": row[2], + # "calculated_price": row[3], + "last_transaction": row[4], 'current_price': 0 } # Add current share value to portfolio - query_share_price = db.session.query(SharePrice).filter_by(symbol=row[0]).order_by(SharePrice.date.desc()).first() + query_share_price = db.session.query(SharePrice).filter_by(isin=row[0]).order_by(SharePrice.date.desc()).first() if query_share_price is not None: data['current_price'] = query_share_price.as_dict()['price'] diff --git a/api/app/blueprints/share_price.py b/api/app/blueprints/share_price.py index d63a844..50f57ae 100644 --- a/api/app/blueprints/share_price.py +++ b/api/app/blueprints/share_price.py @@ -2,17 +2,16 @@ __author__ = "Florian Kaiser" __copyright__ = "Copyright 2022, Project Aktienbot" __credits__ = ["Florian Kaiser", "Florian Kellermann", "Linus Eickhof", "Kevin Pauer"] __license__ = "GPL 3.0" -__version__ = "1.0.0" +__version__ = "1.0.1" import datetime import os from apiflask import APIBlueprint, abort - -from app.models import SharePrice +from app.auth import auth from app.db import database as db from app.helper_functions import make_response -from app.auth import auth +from app.models import SharePrice from app.schema import SymbolPriceSchema share_price_blueprint = APIBlueprint('share_price', __name__, url_prefix='/api') @@ -25,7 +24,7 @@ __location__ = os.path.realpath(os.path.join(os.getcwd(), os.path.dirname(__file @share_price_blueprint.doc(summary="Returns all transaction symbols", description="Returns all transaction symbols for all users") def get_transaction_symbols(): # Get all transaction symbols - symbols = db.session.execute("SELECT symbol FROM `transactions` GROUP BY symbol;").all() + symbols = db.session.execute("SELECT isin FROM `transactions` GROUP BY isin;").all() return_symbols = [] for s in symbols: @@ -38,11 +37,11 @@ def get_transaction_symbols(): @share_price_blueprint.output({}, 200) @share_price_blueprint.input(schema=SymbolPriceSchema) @share_price_blueprint.auth_required(auth) -@share_price_blueprint.doc(summary="Returns all transaction symbols", description="Returns all transaction symbols for all users") +@share_price_blueprint.doc(summary="Adds new price for isin", description="Adds new price to database") def add_symbol_price(data): # Check if required data is available - if not check_if_symbol_data_exists(data): - abort(400, message="Symbol missing") + if not check_if_isin_data_exists(data): + abort(400, message="ISIN missing") if not check_if_price_data_exists(data): abort(400, message="Price missing") @@ -52,7 +51,7 @@ def add_symbol_price(data): # Add share price share_price = SharePrice( - symbol=data['symbol'], + isin=data['isin'], price=data['price'], date=datetime.datetime.strptime(data['time'], '%Y-%m-%dT%H:%M:%S.%fZ'), ) @@ -63,11 +62,11 @@ def add_symbol_price(data): return make_response(share_price.as_dict(), 200, "Successfully added price") -def check_if_symbol_data_exists(data): - if 'symbol' not in data: +def check_if_isin_data_exists(data): + if 'isin' not in data: return False - if data['symbol'] == "" or data['symbol'] is None: + if data['isin'] == "" or data['isin'] is None: return False return True diff --git a/api/app/blueprints/shares.py b/api/app/blueprints/shares.py index e015585..ad0ffe2 100644 --- a/api/app/blueprints/shares.py +++ b/api/app/blueprints/shares.py @@ -2,17 +2,16 @@ __author__ = "Florian Kaiser" __copyright__ = "Copyright 2022, Project Aktienbot" __credits__ = ["Florian Kaiser", "Florian Kellermann", "Linus Eickhof", "Kevin Pauer"] __license__ = "GPL 3.0" -__version__ = "1.0.0" +__version__ = "1.0.1" import os from apiflask import APIBlueprint, abort - from app.auth import auth from app.db import database as db from app.helper_functions import make_response, get_email_or_abort_401 from app.models import Share -from app.schema import SymbolSchema, SymbolResponseSchema, DeleteSuccessfulSchema +from app.schema import SymbolSchema, SymbolResponseSchema, DeleteSuccessfulSchema, SymbolRemoveSchema shares_blueprint = APIBlueprint('share', __name__, url_prefix='/api') __location__ = os.path.realpath(os.path.join(os.getcwd(), os.path.dirname(__file__))) @@ -27,16 +26,20 @@ def add_symbol(data): email = get_email_or_abort_401() # Check if required data is available - if not check_if_symbol_data_exists(data): - abort(400, message="Symbol missing") + if not check_if_isin_data_exists(data): + abort(400, message="ISIN missing") + + if not check_if_comment_data_exists(data): + abort(400, message="Comment missing") # Check if share already exists - check_share = db.session.query(Share).filter_by(symbol=data['symbol'], email=email).first() + check_share = db.session.query(Share).filter_by(isin=data['isin'], email=email).first() if check_share is None: # Keyword doesn't exist yet for this user -> add it new_symbol = Share( email=email, - symbol=data['symbol'] + isin=data['isin'], + comment=data['comment'] ) db.session.add(new_symbol) db.session.commit() @@ -48,23 +51,23 @@ def add_symbol(data): @shares_blueprint.route('/share', methods=['DELETE']) @shares_blueprint.output(DeleteSuccessfulSchema, 200) -@shares_blueprint.input(schema=SymbolSchema) +@shares_blueprint.input(schema=SymbolRemoveSchema) @shares_blueprint.auth_required(auth) @shares_blueprint.doc(summary="Removes existing symbol", description="Removes existing symbol for current user") def remove_symbol(data): email = get_email_or_abort_401() # Check if required data is available - if not check_if_symbol_data_exists(data): - abort(400, message="Symbol missing") + if not check_if_isin_data_exists(data): + abort(400, message="ISIN missing") # Check if share exists - check_share = db.session.query(Share).filter_by(symbol=data['symbol'], email=email).first() + check_share = db.session.query(Share).filter_by(isin=data['isin'], email=email).first() if check_share is None: abort(500, "Symbol doesn't exist for this user") else: # Delete share - db.session.query(Share).filter_by(symbol=data['symbol'], email=email).delete() + db.session.query(Share).filter_by(isin=data['isin'], email=email).delete() db.session.commit() return make_response({}, 200, "Successfully removed symbol") @@ -89,11 +92,21 @@ def get_symbol(): return make_response(return_symbols, 200, "Successfully loaded symbols") -def check_if_symbol_data_exists(data): - if "symbol" not in data: +def check_if_isin_data_exists(data): + if "isin" not in data: return False - if data['symbol'] == "" or data['symbol'] is None: + if data['isin'] == "" or data['isin'] is None: + return False + + return True + + +def check_if_comment_data_exists(data): + if "comment" not in data: + return False + + if data['comment'] == "" or data['comment'] is None: return False return True diff --git a/api/app/blueprints/transactions.py b/api/app/blueprints/transactions.py index 2bc469b..d34c799 100644 --- a/api/app/blueprints/transactions.py +++ b/api/app/blueprints/transactions.py @@ -2,13 +2,12 @@ __author__ = "Florian Kaiser" __copyright__ = "Copyright 2022, Project Aktienbot" __credits__ = ["Florian Kaiser", "Florian Kellermann", "Linus Eickhof", "Kevin Pauer"] __license__ = "GPL 3.0" -__version__ = "1.0.0" +__version__ = "1.0.1" import datetime import os from apiflask import abort, APIBlueprint - from app.auth import auth from app.db import database as db from app.helper_functions import make_response, get_email_or_abort_401 @@ -28,12 +27,15 @@ def add_transaction(data): email = get_email_or_abort_401() # Check if required data is available - if not check_if_symbol_data_exists(data): - abort(400, "Symbol missing") + if not check_if_isin_data_exists(data): + abort(400, "ISIN missing") if not check_if_time_data_exists(data): abort(400, "Time missing") + if not check_if_comment_data_exists(data): + abort(400, "Comment missing") + if not check_if_count_data_exists(data): abort(400, "Count missing") @@ -43,7 +45,8 @@ def add_transaction(data): # Add transaction new_transaction = Transaction( email=email, - symbol=data['symbol'], + isin=data['isin'], + comment=data['comment'], time=datetime.datetime.strptime(data['time'], '%Y-%m-%dT%H:%M:%S.%fZ'), count=data['count'], price=data['price'] @@ -74,11 +77,11 @@ def get_transaction(): return make_response(return_transactions, 200, "Successfully loaded transactions") -def check_if_symbol_data_exists(data): - if "symbol" not in data: +def check_if_isin_data_exists(data): + if "isin" not in data: return False - if data['symbol'] == "" or data['symbol'] is None: + if data['isin'] == "" or data['isin'] is None: return False return True @@ -94,6 +97,16 @@ def check_if_time_data_exists(data): return True +def check_if_comment_data_exists(data): + if "comment" not in data: + return False + + if data['comment'] == "" or data['comment'] is None: + return False + + return True + + def check_if_count_data_exists(data): if "count" not in data: return False diff --git a/api/app/models.py b/api/app/models.py index 864ce32..8846184 100644 --- a/api/app/models.py +++ b/api/app/models.py @@ -2,7 +2,7 @@ __author__ = "Florian Kaiser" __copyright__ = "Copyright 2022, Project Aktienbot" __credits__ = ["Florian Kaiser", "Florian Kellermann", "Linus Eickhof", "Kevin Pauer"] __license__ = "GPL 3.0" -__version__ = "1.0.0" +__version__ = "1.0.1" from app.db import database as db @@ -30,7 +30,8 @@ class Transaction(db.Model): __tablename__ = 'transactions' t_id = db.Column('t_id', db.Integer(), nullable=False, unique=True, primary_key=True) email = db.Column('email', db.String(255), db.ForeignKey('users.email', ondelete='CASCADE')) - symbol = db.Column('symbol', db.String(255)) + isin = db.Column('isin', db.String(255)) + comment = db.Column('comment', db.String(255)) time = db.Column('time', db.DateTime()) count = db.Column('count', db.Integer()) price = db.Column('price', db.Float()) @@ -53,7 +54,8 @@ class Share(db.Model): __tablename__ = 'shares' a_id = db.Column('a_id', db.Integer(), nullable=False, unique=True, primary_key=True) email = db.Column('email', db.String(255), db.ForeignKey('users.email', ondelete='CASCADE')) - symbol = db.Column('symbol', db.String(255)) + isin = db.Column('isin', db.String(255)) + comment = db.Column('comment', db.String(255)) def as_dict(self): return {c.name: getattr(self, c.name) for c in self.__table__.columns} @@ -62,7 +64,7 @@ class Share(db.Model): class SharePrice(db.Model): __tablename__ = 'share_price' id = db.Column('id', db.Integer(), nullable=False, unique=True, primary_key=True) - symbol = db.Column('symbol', db.String(255)) + isin = db.Column('isin', db.String(255)) price = db.Column('price', db.Float()) date = db.Column('date', db.DateTime()) diff --git a/api/app/schema.py b/api/app/schema.py index 134c401..11be0e2 100644 --- a/api/app/schema.py +++ b/api/app/schema.py @@ -2,7 +2,7 @@ __author__ = "Florian Kaiser" __copyright__ = "Copyright 2022, Project Aktienbot" __credits__ = ["Florian Kaiser", "Florian Kellermann", "Linus Eickhof", "Kevin Pauer"] __license__ = "GPL 3.0" -__version__ = "1.0.0" +__version__ = "1.0.1" from apiflask import Schema from apiflask.fields import Integer, String, Boolean, Field, Float @@ -72,18 +72,24 @@ class KeywordSchema(Schema): class SymbolSchema(Schema): - symbol = String() + isin = String() + comment = String() + + +class SymbolRemoveSchema(Schema): + isin = String() class TransactionSchema(Schema): - symbol = String() + isin = String() + comment = String() time = String(validate=validate.Regexp(r"\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z")) count = Integer() price = Float() class SymbolPriceSchema(Schema): - symbol = String() + isin = String() time = String(validate=validate.Regexp(r"\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z")) price = Float() @@ -103,7 +109,8 @@ class KeywordResponseSchema(Schema): class SymbolResponseSchema(Schema): - symbol = String() + isin = String() + comment = String() s_id = Integer() email = Email() @@ -115,14 +122,16 @@ class PortfolioShareResponseSchema(Schema): class TransactionResponseSchema(Schema): email = Email() - symbol = String() + isin = String() + comment = String() time = String() count = Integer() price = Float() class PortfolioResponseSchema(Schema): - symbol = String() + isin = String() + comment = String() last_transaction = String() count = Integer() # price = Float()