First Code Commit

This commit is contained in:
Lucas Mathews
2024-05-17 10:48:19 +02:00
parent eeb1468453
commit 745ed14c56
39 changed files with 2227 additions and 0 deletions

16
Dockerfile Normal file
View File

@@ -0,0 +1,16 @@
# Lucas Mathews - Fontys Student ID: 5023572
# Banking System DockerFile
FROM python:3.12.3
LABEL maintainer="522499@student.fontys.nl"
WORKDIR /bank
COPY / /bank/
EXPOSE 81
RUN pip install --no-cache-dir --upgrade -r /bank/requirements.txt
ENTRYPOINT [ "python", "./api.py", "--host", "0.0.0.0", "--port", "81"]

8
Flask App/ARG/agent.py Normal file
View File

@@ -0,0 +1,8 @@
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--x', type=int, required=True)
parser.add_argument('--y', type=int, required=True)
args = parser.parse_args()
product = args.x * args.y
print(f"{args.x} * {args.y} = {product}")

19
Flask App/app.py Normal file
View File

@@ -0,0 +1,19 @@
from flask import Flask, render_template, request
import requests
SERVER_URL = "http://127.0.0.1:8000"
app = Flask(__name__)
@app.route("/", methods=["GET"])
def loginGET():
return render_template("login.html")
@app.route("/", methods=["POST"])
def loginPOST():
username = request.form["username"]
password = request.form["password"]
response = requests.get( f"{SERVER_URL}/login?username={username}&password={password}")
return render_template("succes.html", data = response.content)
app.run()

0
Flask App/main.py Normal file
View File

View File

@@ -0,0 +1,17 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Login</title>
</head>
<body>
<form method="post">
<label>Username:</label>
<input type="text" name="username">
<label>Password:</label>
<input type="password" name="password">
<input type="submit" value="Login">
</form>
</body>
</html>

View File

@@ -0,0 +1,11 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<p>{{data}}</p>
</body>
</html>

686
Old/api.yml Normal file
View File

@@ -0,0 +1,686 @@
openapi: 3.0.3
info:
title: Banking System - OpenAPI 3.0
description: |-
This is the banking system API for the programming project.
contact:
email: 522499@student.fontys.nl
version: 1.0.11
servers:
- url: /
tags:
- name: accounts
description: Everything about your Accounts
- name: user
description: Operations about user
paths:
/Accounts:
put:
tags:
- accounts
summary: Update an existing account
description: Update an existing account by Id
operationId: updateAccount
requestBody:
description: Update an existing bank account
content:
application/json:
schema:
$ref: '#/components/schemas/Account'
application/xml:
schema:
$ref: '#/components/schemas/Account'
text/html:
schema:
$ref: '#/components/schemas/Account'
required: true
responses:
'200':
description: Successful operation
content:
application/json:
schema:
$ref: '#/components/schemas/Account'
application/xml:
schema:
$ref: '#/components/schemas/Account'
'400':
description: Invalid ID supplied
'404':
description: Pet not found
'422':
description: Validation exception
security:
- petstore_auth:
- write:pets
- read:pets
post:
tags:
- accounts
summary: Add a new pet to the store
description: Add a new pet to the store
operationId: addPet
requestBody:
description: Create a new pet in the store
content:
application/json:
schema:
$ref: '#/components/schemas/Account'
application/xml:
schema:
$ref: '#/components/schemas/Account'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/Account'
required: true
responses:
'200':
description: Successful operation
content:
application/json:
schema:
$ref: '#/components/schemas/Account'
application/xml:
schema:
$ref: '#/components/schemas/Account'
'400':
description: Invalid input
'422':
description: Validation exception
security:
- petstore_auth:
- write:pets
- read:pets
/pet/findByStatus:
get:
tags:
- accounts
summary: Finds Pets by status
description: Multiple status values can be provided with comma separated strings
operationId: findPetsByStatus
parameters:
- name: status
in: query
description: Status values that need to be considered for filter
required: false
explode: true
schema:
type: string
default: available
enum:
- available
- pending
- sold
responses:
'200':
description: successful operation
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Account'
application/xml:
schema:
type: array
items:
$ref: '#/components/schemas/Account'
'400':
description: Invalid status value
security:
- petstore_auth:
- write:pets
- read:pets
/pet/findByTags:
get:
tags:
- accounts
summary: Finds Pets by tags
description: Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing.
operationId: findPetsByTags
parameters:
- name: tags
in: query
description: Tags to filter by
required: false
explode: true
schema:
type: array
items:
type: string
responses:
'200':
description: successful operation
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Account'
application/xml:
schema:
type: array
items:
$ref: '#/components/schemas/Account'
'400':
description: Invalid tag value
security:
- petstore_auth:
- write:pets
- read:pets
/pet/{petId}:
get:
tags:
- accounts
summary: Find pet by ID
description: Returns a single pet
operationId: getPetById
parameters:
- name: petId
in: path
description: ID of pet to return
required: true
schema:
type: integer
format: int64
responses:
'200':
description: successful operation
content:
application/json:
schema:
$ref: '#/components/schemas/Account'
application/xml:
schema:
$ref: '#/components/schemas/Account'
'400':
description: Invalid ID supplied
'404':
description: Pet not found
security:
- api_key: []
- petstore_auth:
- write:pets
- read:pets
post:
tags:
- accounts
summary: Updates a pet in the store with form data
description: ''
operationId: updatePetWithForm
parameters:
- name: petId
in: path
description: ID of pet that needs to be updated
required: true
schema:
type: integer
format: int64
- name: name
in: query
description: Name of pet that needs to be updated
schema:
type: string
- name: status
in: query
description: Status of pet that needs to be updated
schema:
type: string
responses:
'400':
description: Invalid input
security:
- petstore_auth:
- write:pets
- read:pets
delete:
tags:
- accounts
summary: Deletes a pet
description: delete a pet
operationId: deletePet
parameters:
- name: api_key
in: header
description: ''
required: false
schema:
type: string
- name: petId
in: path
description: Pet id to delete
required: true
schema:
type: integer
format: int64
responses:
'400':
description: Invalid pet value
security:
- petstore_auth:
- write:pets
- read:pets
/pet/{petId}/uploadImage:
post:
tags:
- accounts
summary: uploads an image
description: ''
operationId: uploadFile
parameters:
- name: petId
in: path
description: ID of pet to update
required: true
schema:
type: integer
format: int64
- name: additionalMetadata
in: query
description: Additional Metadata
required: false
schema:
type: string
requestBody:
content:
application/octet-stream:
schema:
type: string
format: binary
responses:
'200':
description: successful operation
content:
application/json:
schema:
$ref: '#/components/schemas/ApiResponse'
security:
- petstore_auth:
- write:pets
- read:pets
/user:
post:
tags:
- user
summary: Create user
description: This can only be done by the logged in user.
operationId: createUser
requestBody:
description: Created user object
content:
application/json:
schema:
$ref: '#/components/schemas/User'
application/xml:
schema:
$ref: '#/components/schemas/User'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/User'
responses:
default:
description: successful operation
content:
application/json:
schema:
$ref: '#/components/schemas/User'
application/xml:
schema:
$ref: '#/components/schemas/User'
/user/createWithList:
post:
tags:
- user
summary: Creates list of users with given input array
description: Creates list of users with given input array
operationId: createUsersWithListInput
requestBody:
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/User'
responses:
'200':
description: Successful operation
content:
application/json:
schema:
$ref: '#/components/schemas/User'
application/xml:
schema:
$ref: '#/components/schemas/User'
default:
description: successful operation
/user/login:
get:
tags:
- user
summary: Logs user into the system
description: ''
operationId: loginUser
parameters:
- name: username
in: query
description: The user name for login
required: false
schema:
type: string
- name: password
in: query
description: The password for login in clear text
required: false
schema:
type: string
responses:
'200':
description: successful operation
headers:
X-Rate-Limit:
description: calls per hour allowed by the user
schema:
type: integer
format: int32
X-Expires-After:
description: date in UTC when token expires
schema:
type: string
format: date-time
content:
application/xml:
schema:
type: string
application/json:
schema:
type: string
'400':
description: Invalid username/password supplied
/user/logout:
get:
tags:
- user
summary: Logs out current logged in user session
description: ''
operationId: logoutUser
parameters: []
responses:
default:
description: successful operation
/user/{username}:
get:
tags:
- user
summary: Get user by user name
description: ''
operationId: getUserByName
parameters:
- name: username
in: path
description: 'The name that needs to be fetched. Use user1 for testing. '
required: true
schema:
type: string
responses:
'200':
description: successful operation
content:
application/json:
schema:
$ref: '#/components/schemas/User'
application/xml:
schema:
$ref: '#/components/schemas/User'
'400':
description: Invalid username supplied
'404':
description: User not found
put:
tags:
- user
summary: Update user
description: This can only be done by the logged in user.
operationId: updateUser
parameters:
- name: username
in: path
description: name that need to be deleted
required: true
schema:
type: string
requestBody:
description: Update an existent user in the store
content:
application/json:
schema:
$ref: '#/components/schemas/User'
application/xml:
schema:
$ref: '#/components/schemas/User'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/User'
responses:
default:
description: successful operation
delete:
tags:
- user
summary: Delete user
description: This can only be done by the logged in user.
operationId: deleteUser
parameters:
- name: username
in: path
description: The name that needs to be deleted
required: true
schema:
type: string
responses:
'400':
description: Invalid username supplied
'404':
description: User not found
components:
schemas:
Order:
type: object
properties:
id:
type: integer
format: int64
example: 10
petId:
type: integer
format: int64
example: 198772
quantity:
type: integer
format: int32
example: 7
shipDate:
type: string
format: date-time
status:
type: string
description: Order Status
example: approved
enum:
- placed
- approved
- delivered
complete:
type: boolean
xml:
name: order
Customer:
type: object
properties:
id:
type: integer
format: int64
example: 100000
username:
type: string
example: fehguy
address:
type: array
xml:
name: addresses
wrapped: true
items:
$ref: '#/components/schemas/Address'
xml:
name: customer
Address:
type: object
properties:
street:
type: string
example: 437 Lytton
city:
type: string
example: Palo Alto
state:
type: string
example: CA
zip:
type: string
example: '94301'
xml:
name: address
Category:
type: object
properties:
id:
type: integer
format: int64
example: 1
name:
type: string
example: Dogs
xml:
name: category
User:
type: object
properties:
id:
type: integer
format: int64
example: 10
username:
type: string
example: theUser
firstName:
type: string
example: John
lastName:
type: string
example: James
email:
type: string
example: john@email.com
password:
type: string
example: '12345'
phone:
type: string
example: '12345'
userStatus:
type: integer
description: User Status
format: int32
example: 1
xml:
name: user
Tag:
type: object
properties:
id:
type: integer
format: int64
name:
type: string
xml:
name: tag
Account:
required:
- name
- photoUrls
type: object
properties:
id:
type: integer
format: int64
example: 10
name:
type: string
example: doggie
category:
$ref: '#/components/schemas/Category'
photoUrls:
type: array
xml:
wrapped: true
items:
type: string
xml:
name: photoUrl
tags:
type: array
xml:
wrapped: true
items:
$ref: '#/components/schemas/Tag'
status:
type: string
description: pet status in the store
enum:
- available
- pending
- sold
xml:
name: pet
ApiResponse:
type: object
properties:
code:
type: integer
format: int32
type:
type: string
message:
type: string
xml:
name: '##default'
requestBodies:
Pet:
description: Pet object that needs to be added to the store
content:
application/json:
schema:
$ref: '#/components/schemas/Account'
application/xml:
schema:
$ref: '#/components/schemas/Account'
UserArray:
description: List of user object
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/User'
securitySchemes:
petstore_auth:
type: oauth2
flows:
implicit:
authorizationUrl: https://petstore3.swagger.io/oauth/authorize
scopes:
write:pets: modify pets in your account
read:pets: read your pets
api_key:
type: apiKey
name: api_key
in: header

59
Old/class.py Normal file
View File

@@ -0,0 +1,59 @@
class Transaction:
def __init__(self, trans_id, from_id, to_id, amount, time, date, description, t_type):
self.trans_id = trans_id
self.from_id = from_id
self.to_id = to_id
self.amount = amount
self.time = time
self.date = date
self.description = description
self.t_type = t_type
class Account:
def __init__(self, account_id, name, balance, created_t, created_d, last_modified, closed, closure_t, closure_d,
notes, transactions=None):
if transactions is None:
transactions = []
self.account_id = account_id
self.name = name
self.balance = balance
self.created_t = created_t
self.created_d = created_d
self.last_modified = last_modified
self.closed = closed
self.closure_t = closure_t
self.closure_d = closure_d
self.notes = notes
self.transactions = transactions
class Customer:
def __init__(self, customer_id, f_name, l_name, phone, email, birthday, address, signup_d, signup_t, notes,
accounts=None):
if accounts is None:
accounts = []
self.customer_id = customer_id
self.f_name = f_name
self.l_name = l_name
self.phone = phone
self.email = email
self.birthday = birthday
self.address = address
self.signup_d = signup_d
self.signup_t = signup_t
self.notes = notes
self.accounts = accounts
#calculate the balance of an account
def calc_balance(account):
balance = 0
for transaction in account.transactions:
if transaction.from_id == account.account_id:
balance -= transaction.amount
elif transaction.to_id == account.account_id:
balance += transaction.amount
return balance

4
Old/manager_account.py Normal file
View File

@@ -0,0 +1,4 @@
# Lucas Mathews - Fontys Student ID: 5023572
# Banking System Manager for Account Class - Version 1

View File

@@ -0,0 +1,24 @@
# Lucas Mathews - Fontys Student ID: 5023572
# Banking System Manager for Transaction Class - Version 1
def add_transaction(transaction_id, transaction_type, amount, timestamp, description, account_number, recipient_account_number):
from api import session, Transaction
new_transaction = Transaction(transaction_id, transaction_type, amount, timestamp, description, account_number, recipient_account_number)
session.add(new_transaction)
session.commit()
return new_transaction
def delete_transaction(transaction_id:int):
DELETE_TRANSACTION = "DELETE FROM transaction WHERE transaction_id=?"
from api import session, Transaction
for transaction in session.query(Transaction).all():
if transaction.transaction_id == transaction_id:
input(f"Are you sure you would like permanenty delete transaction ID: {transaction_id}? WARNING: This action can not be reversed. (Y/N) ")
if input == "Y"or input == "y":
session.execute(DELETE_TRANSACTION, (transaction_id))
print(f"Transaction ID: {transaction_id} has been removed.")
else:
return f"Transaction ID: {transaction_id} has NOT been removed."
return
return f"Transaction ID: {transaction_id} is not found."

196
Old/server.py Normal file
View File

@@ -0,0 +1,196 @@
# Lucas Mathews - Fontys Student ID: 5023572
# Banking System Classes - Version 2
###############
### Modules ###
###############
import sqlite3
import os.path
import datetime
import connexion
from config import CONFIG
#################
### Functions ###
#################
###############
### Classes ###
###############
class Manager:
def __init__():
pass
class Client:
def __init__(self, client_id, name, opening_timestamp, birthdate, address, phone_number, email:str, password, accounts, notes):
self.client_id = client_id
self.name = name
self.birthdate = birthdate
self.opening_timestamp = opening_timestamp
self.address = address
self.phone_number = phone_number
self.email = email
self.password = password
self.accounts = accounts
self.notes = notes
#If you call a print function on the object, it will return the following string (does not include password for security reasons)
def __str__(self):
return f"Client ID: {self.client_id}, Name: {self.name}, Birthdate: {self.birthdate}, Address: {self.address}, Phone Number: {self.phone_number}, Email: {self.email}"
#This function will return the account list
def get_accounts(self)->str:
return f"Accounts: {self.accounts}"
#Change details (name, birthdate, address, phone number, email, password)
#Change password
class Account:
def __init__(self, account_id, description, open_timestamp, account_type, balance, enabled, notes, transactions):
self.account_id = account_id
self.description = description
self.open_timestamp = open_timestamp
self.account_type = account_type
self.balance = balance
self.enabled = enabled
self.notes = notes
self.transactions = transactions
#If you call a print function on the object, it will return the following string
def __str__(self):
return f"Account ID: {self.account_id}, Description: {self.description}, Open Timestamp: {self.open_timestamp}, Account Type: {self.account_type}, Balance: {self.balance}, Enabled: {self.enabled}, Notes: {self.notes}, Transactions: {self.transactions}"
# This function will return the transaction history of an account
def transaction_history(self, account_id:int):
return self.transactions
#This function will remove the account
def remove_account(self, account_id:int):
REMOVE_ACCOUNT = "DELETE FROM account WHERE account_id=?"
for account in self.accounts:
if account.balance != 0: #If the account has a balance, it can not be removed
return f"Account ID: {account_id} has a balance of {account.balance} and can not be removed."
if account.account_id == account_id: #Check if account exists
input(f"Are you sure you would like permanenty delete account ID: {account_id}? WARNING: This action can not be reversed. (Y/N) ")
if input == "Y"or input == "y": #If the user inputs Y or y, the account will be removed
db_conn = get_db_connection()
cursor = db_conn.cursor()
cursor.execute(REMOVE_ACCOUNT, (account_id, ) )
db_conn.commit()
print(f"Account ID: {account_id} has been removed.")
else:
return f"Account ID: {account_id} has NOT been removed."
return
return f"Account ID: {account_id} is not found."
#This function will return the account balance
def account_balance(account_id:int):
GET_ACCOUNT = "SELECT balance FROM account WHERE account_id = ?"
db_conn = get_db_connection()
cursor = db_conn.cursor()
cursor.execute(GET_ACCOUNT, (account_id) )
resultset = cursor.fetchall()
db_conn.close()
if len(resultset) < 1:
return "Not found", 404
elif len(resultset) > 2:
return "Too many results found.", 500
class Transaction:
def __init__(self, transaction_id, transaction_type, amount, timestamp, description, account_number, recipient_account_number = None):
self.transaction_id = transaction_id
self.transaction_type = transaction_type
self.amount = amount
self.timestamp = timestamp
self.description = description
self.account_number = account_number
self.recipient_account_number = recipient_account_number
def __str__(self):
return f"Transaction ID: {self.transaction_id}, Transaction Type: {self.transaction_type}, Amount: {self.amount}, Timestamp: {self.timestamp}, Description: {self.description} From Account Number: {self.account_number}, Recipient Account Number: {self.recipient_account_number}"
################
### Database ###
################
def Database():
CLIENT_TABLE_CREATION_QUERY = """
CREATE TABLE IF NOT EXISTS client (
client_id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
birthdate DATE NOT NULL,
opening_timestamp TIMESTAMP NOT NULL,
address TEXT NOT NULL,
phone_number TEXT NOT NULL,
email TEXT NOT NULL,
password TEXT NOT NULL,
notes TEXT NOT NULL
)
"""
ACCOUNT_TABLE_CREATION_QUERY = """
CREATE TABLE IF NOT EXISTS account (
account_id INTEGER PRIMARY KEY AUTOINCREMENT,
description TEXT NOT NULL,
open_timestamp TIMESTAMP NOT NULL,
account_type TEXT NOT NULL,
balance REAL NOT NULL,
enabled BOOLEAN NOT NULL,
notes TEXT NOT NULL,
client_id INTEGER NOT NULL,
FOREIGN KEY (client_id) REFERENCES client(client_id)
)
"""
TRANSACT_TABLE_CREATION_QUERY = """
CREATE TABLE IF NOT EXISTS transact (
transaction_id INTEGER PRIMARY KEY AUTOINCREMENT,
transaction_type TEXT NOT NULL,
amount REAL NOT NULL,
timestamp TIMESTAMP NOT NULL,
description TEXT NOT NULL,
account_id INTEGER NOT NULL,
recipient_account_id INTEGER,
FOREIGN KEY (account_id) REFERENCES account(account_id)
)
"""
# Check if the database exists
if os.path.exists('bank.db'):
print("Database already exists.")
else:
print("Database does not exist. Creating database.")
# Create the database and the tables if they do not exist, or connect to the database if it does exist
db_connection = sqlite3.connect('bank.db')
db_cursor = db_connection.cursor()
db_cursor.execute(CLIENT_TABLE_CREATION_QUERY)
db_cursor.execute(ACCOUNT_TABLE_CREATION_QUERY)
db_cursor.execute(TRANSACT_TABLE_CREATION_QUERY)
db_connection.commit()
#################
### Connexion ###
#################
def API():
app = connexion.App(__name__)
app.add_api('api.yml')
app.run(host=CONFIG["server"]["listen_address"], port=CONFIG["server"]["port"], debug=CONFIG["server"]["debug"])
################
### Run Code ###
################
if __name__ == "__main__":
Database()
API()

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

26
api.py Normal file
View File

@@ -0,0 +1,26 @@
# Lucas Mathews - Fontys Student ID: 5023572
# Banking System API
###############
### Modules ###
###############
import connexion # Imports connexion module
from config import CONFIG # Imports the configuration file
from manager import * # Imports the Manager file that contains the functions for the API
#################
### Connexion ###
#################
def API():
app = connexion.FlaskApp(__name__)
app.add_api(CONFIG["api_file"]["name"])
app.run(host=CONFIG["server"]["listen_ip"], port=CONFIG["server"]["port"], debug=CONFIG["server"]["debug"]) # Runs the API using the configuration file
################
### Run Code ###
################
if __name__ == "__main__":
API()

701
api.yml Normal file
View File

@@ -0,0 +1,701 @@
openapi: 3.0.3
info:
title: Banking API
description: |-
Lucas Mathews - Fontys Student ID: 5023572
contact:
email: 522499@student.fontys.nl
version: 2.0.0
servers:
- url: http://127.0.0.1:81
tags:
- name: client
description: Operations for Client Accounts
- name: account
description: Operations for Bank Accounts
- name: transaction
description: Operations for Transactions
- name: manager
description: Operations for Bank Managers
paths:
/Client/Login:
post:
tags:
- client
summary: Log in to the system
description: Log in to the system
operationId: manager.login_user
requestBody:
description: Credentials for logging in
content:
application/json:
schema:
type: object
properties:
username:
type: string
password:
type: string
required: true
responses:
'200':
description: Successful operation
content:
application/json:
schema:
$ref: '#/components/schemas/Client'
'400':
description: Invalid username/password supplied
'401':
description: Unauthorized
/Client/Logout:
post:
tags:
- client
summary: Log out from the system
description: Log out from the system
operationId: manager.logout_user
responses:
'200':
description: Successful operation
'401':
description: Unauthorized
/Client/Password:
put:
tags:
- client
summary: Change password
description: Change password
operationId: manager.change_password
parameters:
- name: client_id
in: query
description: ID of client to change password
required: true
schema:
type: integer
format: int32
- name: password
in: query
description: New password
required: true
schema:
type: string
- name: new_password
in: query
description: New password
required: true
schema:
type: string
responses:
'200':
description: Password changed successfully
'400':
description: Old password incorrect
'404':
description: client_id not found
/Client:
post:
tags:
- client
summary: Add a new client
description: Add a new client to the system
operationId: manager.add_client
parameters:
- name: name
in: query
description: Client Name
required: true
schema:
type: string
- name: birthdate
in: query
description: Client Birthdate (dd-mm-yyyy)
required: true
schema:
type: string
- name: address
in: query
description: Client Address
required: false
schema:
type: string
- name: phone_number
in: query
description: Client Phone Number
required: true
schema:
type: string
- name: email
in: query
description: Client Email Address
required: true
schema:
type: string
- name: password
in: query
description: Client Email Address
required: true
schema:
type: string
- name: notes
in: query
description: Notes about client
required: false
schema:
type: string
responses:
'200':
description: "Client created"
'400':
description: Invalid input
'422':
description: Validation exception
put:
tags:
- client
summary: Update an existing client
description: Update an existing client Id
operationId: manager.update_client
requestBody:
description: Update an existing client's details
content:
application/json:
schema:
$ref: '#/components/schemas/Client'
required: true
responses:
'200':
description: Successful operation
content:
application/json:
schema:
$ref: '#/components/schemas/Client'
'400':
description: Invalid Client ID supplied
'404':
description: Client not found
'422':
description: Validation exception
get:
tags:
- client
summary: Get a client by ID
description: Get a client by ID
operationId: manager.get_client
parameters:
- name: client_id
in: query
description: ID of client to return
required: true
schema:
type: integer
format: int32
responses:
'200':
description: Successful operation
content:
application/json:
schema:
$ref: '#/components/schemas/Client'
'400':
description: Invalid Client ID supplied
'404':
description: Client not found
delete:
tags:
- client
summary: Delete a client by ID
description: Delete a client by ID
operationId: manager.delete_client
parameters:
- name: client_id
in: query
description: ID of client to delete
required: true
schema:
type: string
format: int32
responses:
'200':
description: Successful operation
'400':
description: Invalid Client ID supplied
'404':
description: Client not found
/Account:
post:
tags:
- account
summary: Add a new account
description: Add a new account to the system
operationId: manager.add_account
parameters:
- name: description
in: query
description: Account description
required: true
schema:
type: string
- name: account_type
in: query
description: Type of account
required: true
schema:
type: string
- name: notes
in: query
description: Notes about account
required: false
schema:
type: string
responses:
'200':
description: Successful operation
'400':
description: Invalid input
'422':
description: Validation exception
put:
tags:
- account
summary: Update an existing account
description: Update an existing account
operationId: manager.update_account
parameters:
- name: account_id
in: query
description: ID of account to update
required: true
schema:
type: integer
format: int32
requestBody:
description: Update an existing account
content:
application/json:
schema:
$ref: '#/components/schemas/Account'
required: true
responses:
'200':
description: Successful operation
content:
application/json:
schema:
$ref: '#/components/schemas/Account'
'400':
description: Invalid Account ID supplied
'404':
description: Account not found
'422':
description: Validation exception
get:
tags:
- account
summary: Get an account by ID
description: Get an account by ID
operationId: manager.get_account
parameters:
- name: account_id
in: query
description: ID of account to return
required: true
schema:
type: integer
format: int32
responses:
'200':
description: Successful operation
content:
application/json:
schema:
$ref: '#/components/schemas/Account'
'400':
description: Invalid Account ID supplied
'404':
description: Account not found
delete:
tags:
- account
summary: Delete an account by ID
description: Delete an account by ID
operationId: manager.delete_account
parameters:
- name: account_id
in: query
description: ID of account to delete
required: true
schema:
type: string
format: int32
responses:
'200':
description: Successful operation
'400':
description: Invalid account_id supplied
'404':
description: Account not found
/Transaction:
get:
tags:
- transaction
summary: Get a transaction by ID
description: Get a transaction by ID
operationId: manager.get_transaction
parameters:
- name: transaction_id
in: query
description: ID of transaction to return
required: true
schema:
type: integer
format: int32
responses:
'200':
description: Successful operation
content:
application/json:
schema:
$ref: '#/components/schemas/Transaction'
'400':
description: Invalid Transaction ID supplied
'404':
description: Transaction not found
post:
tags:
- transaction
summary: Add a new transaction
description: Add a new transaction to the system
operationId: manager.add_transaction
parameters:
- name: amount
in: query
description: Amount of transaction
required: true
schema:
type: integer
format: int32
- name: account_from
in: query
description: Account number the money paid from
required: true
schema:
type: string
- name: account_to
in: query
description: Recipient account number
required: true
schema:
type: string
- name: description
in: query
description: Description of transaction
required: false
schema:
type: string
responses:
'200':
description: Successful operation
'400':
description: Invalid input
'422':
description: Validation exception
/Transaction/History:
get:
tags:
- transaction
summary: Get transaction history
description: Get transaction history
operationId: manager.transaction_history
parameters:
- name: account_id
in: query
description: ID of account to return
required: true
schema:
type: integer
format: int32
responses:
'200':
description: Successful operation
content:
application/json:
schema:
$ref: '#/components/schemas/Transaction'
'400':
description: Invalid input
'404':
description: No transactions found
/Manager/Interest:
post:
tags:
- manager
summary: Apply interest
description: Apply interest to account
operationId: manager.apply_interest
requestBody:
description: Apply interest to account
content:
application/json:
schema:
$ref: '#/components/schemas/Account'
required: true
responses:
'200':
description: Successful operation
content:
application/json:
schema:
$ref: '#/components/schemas/Account'
'400':
description: Invalid input
'422':
description: Validation exception
put:
tags:
- manager
summary: Apply fee
description: Apply fee to account
operationId: manager.apply_fee
requestBody:
description: Apply fee to account
content:
application/json:
schema:
$ref: '#/components/schemas/Account'
required: true
responses:
'200':
description: Successful operation
content:
application/json:
schema:
$ref: '#/components/schemas/Account'
'400':
description: Invalid input
'422':
description: Validation exception
/Manager/Clients:
get:
tags:
- manager
summary: Get all clients
description: Get all clients
operationId: manager.get_all_clients
responses:
'200':
description: Successful operation
content:
application/json:
schema:
$ref: '#/components/schemas/Client'
'400':
description: Invalid input
'404':
description: No clients found
/Manager/Accounts:
get:
tags:
- manager
summary: Get all accounts
description: Get all accounts
operationId: manager.get_all_accounts
responses:
'200':
description: Successful operation
content:
application/json:
schema:
$ref: '#/components/schemas/Account'
'400':
description: Invalid input
'404':
description: No accounts found
/Manager/Transactions:
get:
tags:
- manager
summary: Get all transactions
description: Get all transactions
operationId: manager.get_all_transactions
responses:
'200':
description: Successful operation
content:
application/json:
schema:
$ref: '#/components/schemas/Transaction'
'400':
description: Invalid input
'404':
description: No transactions found
put:
tags:
- manager
summary: Update an existing transaction
description: Update an existing transaction
operationId: manager.update_transaction
requestBody:
description: Update an existing transaction
content:
application/json:
schema:
$ref: '#/components/schemas/Transaction'
required: true
responses:
'200':
description: Successful operation
content:
application/json:
schema:
$ref: '#/components/schemas/Transaction'
'400':
description: Invalid Transaction ID supplied
'404':
description: Transaction not found
'422':
description: Validation exception
/Manager/Hash:
get:
tags:
- manager
summary: Hash password
description: Pass a string through the hashing algorithm
operationId: manager.password_hash
parameters:
- name: password
in: query
description: Password to hash
required: true
schema:
type: string
responses:
'200':
description: Successful operation
content:
application/json:
schema:
type: string
'400':
description: Invalid input
'401':
description: Unauthorized
/Manager/Timestamp:
get:
tags:
- manager
summary: Get the timestamp
description: Gets the date and time in the appropriate format
operationId: manager.timestamp
responses:
'200':
description: Successful operation
content:
application/json:
schema:
type: string
'400':
description: Invalid input
'401':
description: Unauthorized
components:
schemas:
Client:
type: object
properties:
client_id:
type: integer
format: int32
name:
type: string
birthdate:
type: string
opening_timestamp:
type: string
address:
type: string
phone_number:
type: string
email:
type: string
password:
type: string
notes:
type: string
enabled:
type: boolean
administator:
type: boolean
accounts:
type: array
example:
client_id: 1
name: "Lucas Mathews"
birthdate: "21-05-1980"
opening_timestamp: "17-04-2022 16:21:12"
address: "Rachelsmolen 1, 5612MA, Eindhoven"
phone_number: "0612345678"
email: "john.d@fontys.nl"
password: "password"
notes: "This is a test client"
enabled: true
administator: false
accounts: []
Account:
type: object
properties:
account_id:
type: integer
format: int32
decription:
type: string
opening_timestamp:
type: string
account_type:
type: string
balance:
type: number
enabled:
type: boolean
notes:
type: string
transactons:
type: array
example:
account_id: 1
description: "Savings Account"
opening_timestamp: "17-04-2022 16:21:12"
account_type: "Rachelsmolen 1, 5612MA, Eindhoven"
balance: 2314.23
enabled: true
notes: "This is a savings account"
transactions: []
Transaction:
type: object
properties:
transaction_id:
type: integer
format: int32
transaction_type:
type: string
amount:
type: integer
format: int32
timestamp:
type: string
description:
type: string
account_number:
type: string
recipient_account_number:
type: string
example:
transaction_id: 1
transaction_type: "Deposit"
amount: 100.00
timestamp: "17-04-2022 16:21:12"
description: "Deposit to Savings Account"
account_number: "NL12ABNA0123456789"
recipient_account_number: "NL12ABNA1234567890"

BIN
bank.db Normal file

Binary file not shown.

20
bank.ini Normal file
View File

@@ -0,0 +1,20 @@
[database]
name=bank.db
add_sample_data=True
[api_file]
name=api.yml
[server]
listen_ip=127.0.0.1
port=81
debug=True
[frontend]
listen_ip=127.0.0.1
port=80
debug=True
[api]
url=http://127.0.0.1:81/

31
class_account.py Normal file
View File

@@ -0,0 +1,31 @@
# Lucas Mathews - Fontys Student ID: 5023572
# Banking System Account Class
from sqlalchemy import ForeignKey, Column, String, Integer, Boolean
from class_base import Base
class Account(Base):
__tablename__ = 'accounts'
account_id = Column("account_id", String, primary_key=True)
description = Column("description", String)
open_timestamp = Column("open_timestamp", String)
account_type = Column("account_type", String)
balance = Column("balance", Integer)
enabled = Column("enabled", Boolean)
notes = Column("notes", String)
transactions = ("transactions", String, ForeignKey("transactions.transaction_id"))
def __init__(self, account_id, description, open_timestamp, account_type, balance, enabled, notes, transactions):
self.account_id = account_id
self.description = description
self.open_timestamp = open_timestamp
self.account_type = account_type
self.balance = balance
self.enabled = enabled
self.notes = notes
self.transactions = transactions
def __repr__(self):
return f"Account ID: {self.account_id}, Description: {self.description}, Open Timestamp: {self.open_timestamp}, Account Type: {self.account_type}, Balance: {self.balance}, Enabled: {self.enabled}, Notes: {self.notes}, Transactions: {self.transactions}"

6
class_base.py Normal file
View File

@@ -0,0 +1,6 @@
# Lucas Mathews - Fontys Student ID: 5023572
# Banking System Base Class
from sqlalchemy.orm import declarative_base
Base = declarative_base()

38
class_client.py Normal file
View File

@@ -0,0 +1,38 @@
# Lucas Mathews - Fontys Student ID: 5023572
# Banking System Client Class
from sqlalchemy import Column, String, Boolean
from class_base import Base
class Client(Base):
__tablename__ = 'clients'
client_id = Column("client_id", String, primary_key=True)
name = Column("name", String)
birthdate = Column("birthdate", String)
opening_timestamp = Column("opening_timestamp", String)
address = Column("address", String)
phone_number = Column("phone_number", String)
email = Column("email", String)
hash = Column("hash", String)
notes = Column("notes", String)
enabled = Column("enabled", Boolean)
administrator = Column("administrator", Boolean)
accounts = Column("accounts", String)
def __init__(self, client_id, name, birthdate, opening_timestamp, address, phone_number, email, hash, notes, enabled, administrator, accounts):
self.client_id = client_id
self.name = name
self.birthdate = birthdate
self.opening_timestamp = opening_timestamp
self.address = address
self.phone_number = phone_number
self.email = email
self.hash = hash
self.notes = notes
self.enabled = enabled
self.administrator = administrator
self.accounts = accounts
def __repr__(self):
return f"Client ID: {self.client_id}, Name: {self.name}, Birthdate: {self.birthdate}, Address: {self.address}, Phone Number: {self.phone_number}, Email: {self.email}, Enabled: {self.enabled}, Accounts: {self.accounts}"

28
class_transaction.py Normal file
View File

@@ -0,0 +1,28 @@
# Lucas Mathews - Fontys Student ID: 5023572
# Banking System Transaction Class
from sqlalchemy import Column, String, Integer
from class_base import Base
class Transaction(Base):
__tablename__ = 'transactions'
transaction_id = Column("transaction_id", String, primary_key=True)
transaction_type = Column("transaction_type", String)
amount = Column("amount", Integer)
timestamp = Column("timestamp", String)
description = Column("description", String)
account_number = Column("account_number", Integer)
recipient_account_number = Column("recipient_account_number", Integer)
def __init__(self, transaction_id, transaction_type, amount, timestamp, description, account_number, recipient_account_number = None):
self.transaction_id = transaction_id
self.transaction_type = transaction_type
self.amount = amount
self.timestamp = timestamp
self.description = description
self.account_number = account_number
self.recipient_account_number = recipient_account_number
def __repr__(self):
return f"Transaction ID: {self.transaction_id}, Transaction Type: {self.transaction_type}, Amount: {self.amount}, Timestamp: {self.timestamp}, Description: {self.description} From Account Number: {self.account_number}, Recipient Account Number: {self.recipient_account_number}"

19
cli.py Normal file
View File

@@ -0,0 +1,19 @@
# Lucas Mathews - Fontys Student ID: 5023572
# Banking System CLI Utility
import requests
SERVER_URL = "http://127.0.0.1:5000"
def main():
username = "john"
password = "doe"
print(f"Login with {username} and {password}:")
response = requests.get( f"{SERVER_URL}/login?username={username}&password={password}")
print(f"{response}, {response.content}")
print(f"Logout:")
response = requests.get( f"{SERVER_URL}/logout")
print(f"{response}, {response.content}")
print(f"Closing")
main()

7
config.py Normal file
View File

@@ -0,0 +1,7 @@
# Lucas Mathews - Fontys Student ID: 5023572
# Banking System Config Parser
import configparser
CONFIG = configparser.ConfigParser()
CONFIG.read("bank.ini")

58
database.py Normal file
View File

@@ -0,0 +1,58 @@
# Lucas Mathews - Fontys Student ID: 5023572
# Banking System Manager File
import os.path
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
#Import Config
from config import CONFIG
# Check if the database exists
if os.path.exists(CONFIG["database"]["name"]):
print(f"Database {CONFIG["database"]["name"]} already exists.")
else:
print(f"Database {CONFIG["database"]["name"]} does not exist. Creating it now.")
# Sets the database file to be used from the configuration file
db_url : str = "sqlite:///" + CONFIG["database"]["name"]
print(f"Database file set to: {db_url}")
# Creates the database engine (does not create the database file if it already exists)
engine = create_engine(db_url, echo=True)
#Import Classes
from class_base import Base # Imports the base class required by SQLAlchemy
from class_client import Client
from class_account import Account
from class_transaction import Transaction
# Create the tables in the database
Base.metadata.create_all(bind=engine) # Creates the tables in the database from the classes
# Creates a session to interact with the database
Session = sessionmaker(bind=engine) # Creates a session to interact with the database
session = Session() # Creates a session object
# Add sample data if enabled in the configuration file if the database is empty
if CONFIG["database"]["add_sample_data"] == "True": # Checks if sample data addition is enabled
if session.query(Client).count() == 0: # Checks if the database is empty
print(f"Sample data addition is disabled because the database is not empty.")
print(f"Adding sample data to new database file {CONFIG["database"]["name"]}.")
session.add(Client("f9a16945-b570-4153-ba63-413f2cc2768a", "Lucas Mathews", "24/08/1998", "17/04/2024", "Rachelsmolen 1, 5612MA, Eindhoven", "0612345678", "522499@student.fontys.nl", "7835062ec36ed529fe22cc63baf3ec18d347dacb21c9801da8ba0848cc18efdf1e51717dd5b1240f7556aca3947aa0722452858be6002c1d46b1f1c311b0e9d8", "Notes", True, True, "1, 2"))
session.add(Client("5be2a74d-d55c-4de6-85a1-2ed6a355f2cd", "Rigby", "16/03/2018", "06/05/2024", "Rachelsmolen 1, 5612MA, Eindhoven", "0612345678", "522499@cat.fontys.nl", "d3e7df3c78682fbb51e8c6110b3926349bb426bc9834c640cd666519901aef3dfab7822d66fb2dd9e39eb5a8492f6801c2e17ba4c16b8fbcd159c036fe27d8bd", "Is a cat", True, False, "3"))
session.add(Account("4c227b02-348c-4611-99a2-8967680cdee6", "Savings Account", "17/04/2024", "Savings", 3000, True, "Savings account", "1"))
session.add(Account("b9d9b801-eaab-45be-a4d1-1f7b0bbf798f", "Spending Account", "17/04/2024", "Spending", 150, True, "Spending account", "1"))
session.add(Account("f182f186-0a88-4f98-8a02-3a568c65aba7", "Cat Account", "06/05/2024", "Cat Account", 497, True, "Food savings", "2"))
session.add(Transaction("9d989788-f983-4590-8de2-9aa0c8bec7d2", "Deposit", 5000, "17/04/2024", "Initial Deposit", 1, "23542335"))
session.add(Transaction("153cee93-51c7-4114-b9ef-e307fbf0bf87", "Deposit", 100, "17/04/2024", "Initial Deposit", 2, "23542335"))
session.add(Transaction("4bec761a-0f36-452f-a48a-127dcf526e47", "Deposit", 500, "06/05/2024", "Initial Deposit", 3, "23542335"))
session.add(Transaction("227a2a9e-a13b-484b-b037-78deeeb0258c", "Withdrawal", 2000, "06/05/2024", "Uni Fees", 3, "Fontys University"))
session.add(Transaction("7248a706-29a8-478b-a674-c12ebf9a904a", "Withdrawal", 50, "06/05/2024", "Groceries", 3, "Aldi"))
session.add(Transaction("ba367c28-41e6-4f8a-9bfa-3819f7b89a58", "Withdrawal", 3, "06/05/2024", "Treats", 3, "ZooPlus"))
session.commit()
else:
print(f"The database is not empty, skipping sample data addition.")
else:
print(f"Sample data addition is disabled.")

249
manager.py Normal file
View File

@@ -0,0 +1,249 @@
# Lucas Mathews - Fontys Student ID: 5023572
# Banking System Manager File
from class_client import Client
from class_account import Account
from class_transaction import Transaction
from flask import jsonify
import hashlib # hashlib for password hashing
import datetime # datetime for timestamps
import uuid # uuid for unique identifiers
from database import * # Importing the database connection
##############
### System ###
##############
def timestamp(): # Returns the current timestamp
return (datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
def password_hash(password:str): # Converts a string to SHA512 hash
return hashlib.sha512(password.encode()).hexdigest()
def generate_uuid(): # Generates a unique identifier for transactions
return str(uuid.uuid4())
def generate_uuid_short(): # Generates a short uuid
return str(uuid.uuid4())[:8]
##############
### Client ###
##############
def get_client(client_id:int): # Returns a specific client in the database
client = session.query(Client).filter_by(client_id=client_id).one_or_none()
if client is None:
return jsonify({"error": "Client not found"}), 404
if client is not None:
return jsonify({"name": client.name, "birthdate": client.birthdate, "opening_timestamp": client.opening_timestamp, "address": client.address, "phone_number": client.phone_number, "email": client.email}), 200
def change_password(client_id, password:str, new_password:str): # Changes the password of a client
old_hash = password_hash(password)
new_hash = password_hash(new_password)
for client in session.query(Client).all():
if client.client_id == client_id:
if client.hash == old_hash:
client.hash = new_hash
session.commit()
return "Password changed successfully.", 200
return "Incorrect old password.", 400
return f"client_id: {client_id} is not found.", 404
def add_client(name:str, birthdate:str, address:str, phone_number:str, email:str, password:str, **kwargs): # Adds a new client to the database
client_id = generate_uuid_short()
notes = kwargs.get("notes", None)
new_client = Client(client_id, name, birthdate, timestamp(), address, phone_number, email, password_hash(password), notes, 1, 0, None)
session.add(new_client)
session.commit()
return f"New client has been added: name: {name}, uuid: {client_id} ", 200
def delete_client(client_id): # Deletes a client from the database
for client in session.query(Client).all():
if client.client_id == client_id:
if client.accounts == None:
session.delete(client)
session.commit()
return f"client_id: {client_id} has been removed.", 200
else:
return f"client_id: {client_id} has active accounts and can not be removed.", 400
return f"client_id: {client_id} is not found.", 404
def login_user(email:str, password:str):
for client in session.query(Client).all():
if client.email == email and client.password == password:
return f"Welcome {client.name}."
return "Invalid email or password."
def logout_user():
return "You have been logged out."
def update_client(client_id, name, birthdate, address, phone_number, email, notes):
for client in session.query(Client).all():
if client.client_id == client_id:
client.name = name
client.birthdate = birthdate
client.address = address
client.phone_number = phone_number
client.email = email
client.notes = notes
session.commit()
return f"client_id: {client_id} has been updated."
return f"Client ID: {client_id} is not found."
###############
### Account ###
###############
def get_account(account_id:int): # Returns a specific account in the database
account = session.query(Account).filter_by(account_id=account_id).one_or_none()
if account is None:
return jsonify({"error": "Account not found"}), 404
if account is not None:
for account in account:
return jsonify({"description": account.description, "account_type": account.account_type, "balance": account.balance, "enabled": account.enabled, "notes": account.notes}), 200
def add_account(description:str, account_type, **kwargs): # Adds a new account to the database
account_id = generate_uuid_short()
notes = kwargs.get("notes", None)
new_account = Account(account_id, description, timestamp(), account_type, 0, 1, notes, None)
session.add(new_account)
session.commit()
return f"New account has been added: description: {description}, uuid: {account_id} ", 200
def delete_account(account_id): # Deletes an account from the database
for account in session.query(Account).all():
if account.account_id == account_id:
if account.balance == 0:
session.delete(account)
session.commit()
return f"account_id: {account_id} has been removed.", 200
else:
return f"account_id: {account_id} has a balance and can not be removed.", 400
return f"account_id: {account_id} is not found.", 404
def update_account(account_id:int, update:dict):
for account in session.query(Account).all():
if account.account_id == account_id:
account.description = update["description"]
account.account_type = update["account_type"]
account.balance = update["balance"]
account.enabled = update["enabled"]
account.notes = update["notes"]
session.commit()
return f"account_id: {update['account_id']} has been updated."
return f"account_id: {update['account_id']} is not found."
###################
### Transaction ###
###################
def get_transaction(transaction_id:int): # Returns a specific transaction in the database
transaction = session.query(Transaction).filter_by(transaction_id=transaction_id).one_or_none()
if transaction is None:
return jsonify({"error": "Transaction not found"}), 404
if transaction is not None:
return jsonify({"transaction_type": transaction.transaction_type, "amount": transaction.amount, "timestamp": transaction.timestamp, "description": transaction.description, "account_number": transaction.account_number, "recipient_account_number": transaction.recipient_account_number}), 200
def transaction_history(account_id:int): # Returns all transactions for a specific account
result = session.query(Transaction).filter(Transaction.account_number == account_id)
return jsonify([{"transaction_id": transaction.transaction_id, "transaction_type": transaction.transaction_type, "amount": transaction.amount, "timestamp": transaction.timestamp, "description": transaction.description, "account_number": transaction.account_number, "recipient_account_number": transaction.recipient_account_number} for transaction in result]), 200
def add_transaction(amount:int, account_from, account_to, **kwargs): # Adds a new transaction to the database
transaction_id = generate_uuid()
for account in session.query(Account).all():
if account.account_id == account_from:
if account.balance < amount:
return f"Account ID: {account_from} does not have enough funds to transfer {amount}.", 401
account.balance -= amount
transaction_type = "withdraw"
session.commit()
if account.account_id == account_to:
account.balance += amount
transaction_type = "transfer"
session.commit()
description = kwargs.get("description", None)
new_transaction = Transaction(transaction_id, transaction_type, amount, timestamp(), description, account_from, account_to)
session.add(new_transaction)
session.commit()
return f"New transaction has been added: description: {description}, uuid: {transaction_id} ", 200
#####################
### Administrator ###
#####################
def get_all_clients(): # Returns all clients in the database
clients = session.query(Client).all()
return jsonify([{"client_id": client.client_id, "name": client.name, "birthdate": client.birthdate, "opening_timestamp": client.opening_timestamp, "address": client.address, "phone_number": client.phone_number, "email": client.email} for client in clients])
def get_all_accounts(): # Returns all accounts in the database
accounts = session.query(Account).all()
return jsonify([{"account_id": account.account_id, "description": account.description, "open_timestamp": account.open_timestamp, "account_type": account.account_type, "balance": account.balance, "enabled": account.enabled, "notes": account.notes} for account in accounts])
def get_all_transactions(): # Returns all transactions in the database
transactions = session.query(Transaction).all()
return jsonify([{"transaction_id": transaction.transaction_id, "transaction_type": transaction.transaction_type, "amount": transaction.amount, "timestamp": transaction.timestamp, "description": transaction.description, "account_number": transaction.account_number, "recipient_account_number": transaction.recipient_account_number} for transaction in transactions])
def update_transaction(transaction_id, transaction_type, amount, description, account_number, recipient_account_number):
for transaction in session.query(Transaction).all():
if transaction.transaction_id == transaction_id:
transaction.transaction_type = transaction_type
transaction.amount = amount
transaction.description = description
transaction.account_number = account_number
transaction.recipient_account_number = recipient_account_number
session.commit()
return f"Transaction ID: {transaction_id} has been updated."
return f"Transaction ID: {transaction_id} is not found."
def apply_interest(account_id:int, interest_rate:float):
for account in session.query(Account).filter(Account.account_id == account_id):
if account.account_id == account_id:
account.balance += account.balance * interest_rate
session.commit()
return f"Interest has been applied to Account ID: {account_id}."
return f"Account ID: {account_id} is not found."
def apply_fee(account_id:int, fee:float):
for account in session.query(Account).all():
if account.account_id == account_id:
account.balance -= fee
session.commit()
return f"Fee has been applied to Account ID: {account_id}."
return f"Account ID: {account_id} is not found."
def delete_transaction(transaction_id:int):
DELETE_TRANSACTION = "DELETE FROM transaction WHERE transaction_id=?"
from api import session, Transaction
for transaction in session.query(Transaction).all():
if transaction.transaction_id == transaction_id:
input(f"Are you sure you would like permanenty delete transaction ID: {transaction_id}? WARNING: This action can not be reversed. (Y/N) ")
if input == "Y"or input == "y":
session.execute(DELETE_TRANSACTION, (transaction_id))
print(f"Transaction ID: {transaction_id} has been removed.")
else:
return f"Transaction ID: {transaction_id} has NOT been removed."
return
return f"Transaction ID: {transaction_id} is not found."

4
requirements.txt Normal file
View File

@@ -0,0 +1,4 @@
flask
connexion[swagger-ui]==2.14.2
requests
sqlalchemy