read platform details from database (WIP)

This commit is contained in:
Roland W-H 2025-04-22 13:37:43 +01:00
parent df436fa2b2
commit 0fa6db3bc0
6 changed files with 221 additions and 84 deletions

BIN
SIPPCompare.db Normal file

Binary file not shown.

View File

@ -1,5 +1,7 @@
import os
import sqlite3
import data_struct
from data_struct import Platform
class DBHandler:
@ -8,14 +10,15 @@ class DBHandler:
self.cur.execute("""
CREATE TABLE "tblPlatforms" (
"PlatformID" INTEGER NOT NULL UNIQUE,
"PlatformName" TEXT NOT NULL,
"PlatformName" TEXT,
"IsEnabled" INTEGER NOT NULL,
PRIMARY KEY("PlatformID")
)
""")
self.cur.execute("""
CREATE TABLE "tblFlatPlatFees" (
"PlatformID" INTEGER NOT NULL,
"PlatformID" INTEGER NOT NULL UNIQUE,
"SharePlatFee" REAL NOT NULL,
"SharePlatMaxFee" REAL,
PRIMARY KEY("PlatformID"),
@ -25,7 +28,7 @@ class DBHandler:
self.cur.execute("""
CREATE TABLE "tblFlatDealFees" (
"PlatformID" INTEGER NOT NULL,
"PlatformID" INTEGER NOT NULL UNIQUE,
"FundDealFee" REAL,
"ShareDealFee" REAL NOT NULL,
"ShareDealReduceTrades" REAL,
@ -47,10 +50,12 @@ class DBHandler:
self.cur.execute("""
CREATE TABLE "tblUserDetails" (
"PensionValue" REAL,
"SliderValue" INTEGER,
"ShareTrades" INTEGER,
"FundTrades" INTEGER
"UserID" INTEGER NOT NULL UNIQUE,
"PensionValue" REAL NOT NULL,
"SliderValue" INTEGER NOT NULL,
"ShareTrades" INTEGER NOT NULL,
"FundTrades" INTEGER NOT NULL,
PRIMARY KEY("UserID")
)
""")
@ -65,23 +70,71 @@ class DBHandler:
create_tables()
def retrieve_plat_list(self) -> list:
res = self.cur.execute("SELECT PlatformName FROM tblPlatforms")
res_list = res.fetchall()
res = self.cur.execute("SELECT PlatformName FROM tblPlatforms").fetchall()
plat_name_list = []
for platform in res_list:
for platform in res:
plat_name_list.append(platform[0])
return plat_name_list
def retrieve_platforms(self) -> list[Platform]:
platforms_res = self.cur.execute("""
SELECT
-- tblPlatforms
tblPlatforms.PlatformID, PlatformName, IsEnabled,
-- tblFlatPlatFees
SharePlatFee, SharePlatMaxFee,
-- tblFlatDealFees
FundDealFee,
ShareDealFee,
ShareDealReduceTrades,
ShareDealReduceAmount
FROM tblPlatforms
INNER JOIN tblFlatPlatFees ON
tblPlatforms.PlatformID = tblFlatPlatFees.PlatformID
INNER JOIN tblFlatDealFees ON
tblPlatforms.PlatformID = tblFlatDealFees.PlatformID
""").fetchall()
platforms = []
for platform in platforms_res:
# plat_id, plat_name, enabled, share_plat_fee, share_plat_max_fee, fund_deal_fee,
# share_deal_fee, share_deal_reduce_trades, share_deal_reduce_amount
this_platform = [platform[0], platform[1], platform[2], platform[3], platform[4],
platform[5], platform[6], platform[7], platform[8]]
platforms.append(this_platform)
for platform in platforms:
platform.insert(1, [[], []])
fund_plat_fee_res = self.cur.execute("SELECT * FROM tblFundPlatFee").fetchall()
for i in range(len(fund_plat_fee_res)):
plat_id = fund_plat_fee_res[i][0]
platforms[plat_id][1][0].append(fund_plat_fee_res[i][1])
platforms[plat_id][1][1].append(fund_plat_fee_res[i][2])
platform_obj_list: list[Platform] = []
for platform in platforms:
platform_obj_list.append(Platform(
platform[0], platform[1], platform[2], platform[3],
platform[6], platform[4], platform[5], platform[7],
platform[8], platform[9]
))
return platform_obj_list
def write_user_details(self, pension_val: float, slider_val: int, share_trades: int, fund_trades: int):
user_details_data = (pension_val, slider_val, share_trades, fund_trades)
# Hardcode UserID as 0
user_details_data = (0, pension_val, slider_val, share_trades, fund_trades)
res = self.cur.execute("SELECT EXISTS(SELECT 1 FROM tblUserDetails)").fetchone()
if res[0] == 0:
self.cur.execute("INSERT INTO tblUserDetails VALUES (?, ?, ?, ?)", user_details_data)
self.cur.execute("INSERT INTO tblUserDetails VALUES (?, ?, ?, ?, ?)", user_details_data)
else:
self.cur.execute("""
UPDATE tblUserDetails SET
UserID = ?,
PensionValue = ?,
SliderValue = ?,
ShareTrades = ?,
@ -95,12 +148,13 @@ class DBHandler:
return {"NO_RECORD": None}
res = self.cur.execute("SELECT * FROM tblUserDetails")
res_tuple = res.fetchone()
user_details_dict = {
"pension_val": res_tuple[0],
"slider_val": res_tuple[1],
"share_trades": res_tuple[2],
"fund_trades": res_tuple[3]
res_tuple: tuple = res.fetchone()
user_details_dict: dict[str, float | int] = {
"user_id": res_tuple[0],
"pension_val": res_tuple[1],
"slider_val": res_tuple[2],
"share_trades": res_tuple[3],
"fund_trades": res_tuple[4]
}
return user_details_dict

View File

@ -3,18 +3,21 @@ from PyQt6.QtWidgets import QApplication
import sys
import platform_edit
import main_window
app = QApplication(sys.argv)
# Show platform edit window first, before main win
# When debugging, can be useful to autofill values to save time
if len(sys.argv) > 1:
"""if len(sys.argv) > 1:
if sys.argv[1] == "--DEBUG_AUTOFILL":
window = platform_edit.PlatformEdit(True)
else:
window = platform_edit.PlatformEdit(False)
else:
window = platform_edit.PlatformEdit(False)
window = platform_edit.PlatformEdit(False)"""
#plat_edit_win = platform_edit.PlatformEdit()
window = main_window.SIPPCompare()
window.show()
app.exec()

View File

@ -9,8 +9,7 @@ import db_handler
class SIPPCompare(QMainWindow):
# Receive instance of PlatformEdit() as parameter
def __init__(self, plat_edit_win: QWidget):
def __init__(self):
super().__init__()
# Import Qt Designer UI XML file
uic.loadUi(resource_finder.get_res_path("gui/main_gui.ui"), self)
@ -36,14 +35,12 @@ class SIPPCompare(QMainWindow):
# Create window objects
self.db = db_handler.DBHandler()
self.platform_win = plat_edit_win
self.platform_list_win = platform_list.PlatformList(self.db)
self.output_win = output_window.OutputWindow()
# Handle events
self.calc_but.clicked.connect(self.calculate_fees)
# Menu bar entry (File -> Edit Platforms)
#self.actionEdit_Platforms.triggered.connect(self.show_platform_edit)
self.actionList_Platforms.triggered.connect(self.show_platform_list)
# Update percentage mix label when slider moved
self.mix_slider.valueChanged.connect(self.update_slider_lab)
@ -64,6 +61,8 @@ class SIPPCompare(QMainWindow):
self.fund_trades_combo.setCurrentText(str(prev_session_data["fund_trades"]))
self.calc_but.setFocus()
# Display slider position as mix between two nums (funds/shares)
def update_slider_lab(self):
slider_val = self.mix_slider.value()
@ -167,9 +166,5 @@ class SIPPCompare(QMainWindow):
)
self.output_win.show()
# Show the platform editor window (currently run-time only)
def show_platform_edit(self):
self.platform_win.show()
def show_platform_list(self):
self.platform_list_win.show()

View File

@ -4,36 +4,30 @@ from PyQt6.QtWidgets import QWidget, QLabel
from PyQt6 import uic
from widgets.fastedit_spinbox import FastEditQDoubleSpinBox
from data_struct import Platform
import main_window
import resource_finder
class PlatformEdit(QWidget):
def __init__(self, autofill: bool):
def __init__(self, plat: Platform):
super().__init__()
# Import Qt Designer UI XML file
uic.loadUi(resource_finder.get_res_path("gui/platform_edit.ui"), self)
self.setWindowIcon(QIcon(resource_finder.get_res_path("icon2.ico")))
# Initialise class variables
# Create main window object, passing this instance as param
self.main_win = main_window.SIPPCompare(self)
self.fund_plat_fee = []
self.plat_name = ""
self.fund_deal_fee = 0.0
self.share_plat_fee = 0.0
self.share_plat_max_fee = 0.0
self.share_deal_fee = 0.0
self.share_deal_reduce_trades = 0.0
self.share_deal_reduce_amount = 0.0
self.plat = plat
self.fund_plat_fee = self.plat.fund_plat_fee
self.widgets_list_list = []
self.fund_fee_rows = 1
self.fund_fee_rows = len(self.plat.fund_plat_fee[0])
"""
# Debugging feature: set with "--DEBUG_AUTOFILL" cmd argument
self.autofill = autofill
if autofill:
self.save_but.setEnabled(True)
"""
self.required_fields = [
self.share_plat_fee_box,
@ -64,6 +58,54 @@ class PlatformEdit(QWidget):
False
]
if self.plat.plat_name is None:
self.check_boxes_ticked[0] = False
self.plat_name_check.setChecked(False)
else:
self.check_boxes_ticked[0] = True
self.plat_name_check.setChecked(True)
self.plat_name_box.setText(self.plat.plat_name)
if self.plat.fund_deal_fee is None:
self.check_boxes_ticked[1] = False
self.plat_fund_deal_fee_check.setChecked(False)
else:
self.check_boxes_ticked[1] = True
self.fund_deal_fee_check.setChecked(True)
self.fund_deal_fee_box.setValue(self.plat.fund_deal_fee)
self.share_plat_fee_box.setValue(self.plat.share_plat_fee * 100)
if self.plat.share_plat_max_fee is None:
self.check_boxes_ticked[2] = False
self.share_plat_max_fee_check.setChecked(False)
else:
self.check_boxes_ticked[2] = True
self.share_plat_max_fee_check.setChecked(True)
self.share_plat_max_fee_box.setValue(self.plat.share_plat_max_fee)
self.share_deal_fee_box.setValue(self.plat.share_deal_fee)
if self.plat.share_deal_reduce_trades is None:
self.check_boxes_ticked[3] = False
self.share_deal_reduce_trades_check.setChecked(False)
else:
self.check_boxes_ticked[3] = True
self.share_deal_reduce_trades_check.setChecked(True)
self.share_deal_reduce_trades_box.setValue(int(self.plat.share_deal_reduce_trades))
if self.plat.share_deal_reduce_trades is None:
self.check_boxes_ticked[4] = False
self.share_deal_reduce_amount_check.setChecked(False)
else:
self.check_boxes_ticked[4] = True
self.share_deal_reduce_amount_check.setChecked(True)
self.share_deal_reduce_amount_box.setValue(self.plat.share_deal_reduce_amount)
self.first_tier_box.setValue(self.plat.fund_plat_fee[0][1])
self.first_tier_fee_box.setValue(self.plat.fund_plat_fee[1][1])
self.add_row(loading=True)
# Handle events
for field in self.required_fields:
field.valueChanged.connect(self.check_valid)
@ -108,6 +150,7 @@ class PlatformEdit(QWidget):
# Get fee structure variables from user input when "Save" clicked
def init_variables(self):
"""
# If debugging, save time by hardcoding
if self.autofill:
self.plat_name = "AJBell"
@ -123,6 +166,7 @@ class PlatformEdit(QWidget):
self.share_deal_reduce_amount = 3.50
self.check_boxes_ticked = [True, True, True, True, True]
else:
"""
self.plat_name = self.plat_name_box.text()
self.fund_plat_fee = self.create_plat_fee_struct()
self.fund_deal_fee = float(self.fund_deal_fee_box.value())
@ -215,8 +259,14 @@ class PlatformEdit(QWidget):
max_band = self.first_tier_box.value()
self.val_above_lab.setText(f"on the value above £{int(max_band)} there is no charge")
def add_row(self):
def add_row(self, loading: bool = False):
if loading:
rows_needed = self.fund_fee_rows
else:
rows_needed = 1
widgets = []
for x in range(rows_needed):
font = QFont()
font.setPointSize(11)
@ -228,6 +278,8 @@ class PlatformEdit(QWidget):
widgets[1].setMaximum(9999999)
widgets[1].setButtonSymbols(FastEditQDoubleSpinBox.ButtonSymbols.NoButtons)
widgets[1].setFont(font)
if loading:
widgets[1].setValue(self.plat.fund_plat_fee[0][x+1])
widgets[1].valueChanged.connect(self.check_valid)
widgets[1].valueChanged.connect(self.update_tier_labels)
@ -240,6 +292,8 @@ class PlatformEdit(QWidget):
widgets[3].setMaximum(100)
widgets[3].setButtonSymbols(FastEditQDoubleSpinBox.ButtonSymbols.NoButtons)
widgets[3].setFont(font)
if loading:
widgets[3].setValue(self.plat.fund_plat_fee[1][x+1])
widgets[3].valueChanged.connect(self.check_valid)
# TODO: why 28.5?
@ -247,6 +301,7 @@ class PlatformEdit(QWidget):
for i in range(len(widgets)):
self.gridLayout_2.addWidget(widgets[i], self.fund_fee_rows, i, 1, 1)
if not loading:
self.fund_fee_rows += 1
self.widgets_list_list.append(widgets)
@ -257,6 +312,8 @@ class PlatformEdit(QWidget):
prev_box_row = cur_box_pos[0] - 1
prev_box_item = self.gridLayout_2.itemAtPosition(prev_box_row, cur_box_pos[1]).widget()
#if loading:
# prev_box_item.setValue(self.plat.fund_plat_fee[0][x+1])
cur_label_item = self.gridLayout_2.itemAtPosition(cur_label_pos[0], cur_label_pos[1]).widget()
cur_label_item.setText(f"between £{int(prev_box_item.value())} and")

View File

@ -4,6 +4,8 @@ from PyQt6.QtCore import QRegularExpression
from PyQt6 import uic
import resource_finder
import data_struct
import platform_edit
class PlatformRename(QWidget):
@ -28,8 +30,11 @@ class PlatformList(QWidget):
self.setWindowIcon(QIcon(resource_finder.get_res_path("icon2.ico")))
self.plat_list_dialog = PlatformRename()
self.p_edit = None
self.db = db
self.plat_name_list = self.db.retrieve_plat_list()
self.plat_list = self.db.retrieve_platforms()
print(self.plat_list[1].fund_plat_fee)
print(self.plat_name_list)
for platform in self.plat_name_list:
@ -39,6 +44,29 @@ class PlatformList(QWidget):
# Handle events
self.add_plat_but.clicked.connect(self.add_platform)
self.del_plat_but.clicked.connect(self.remove_platform)
self.edit_plat_but.clicked.connect(self.edit_platform)
self.plat_enabled_check.checkStateChanged.connect(self.toggle_platform_state)
self.platListWidget.currentRowChanged.connect(self.get_enabled_state)
def add_platform(self):
self.plat_list_dialog.show()
def get_enabled_state(self):
index = self.platListWidget.currentRow()
is_enabled = self.plat_list[index].enabled
if is_enabled:
self.plat_enabled_check.setChecked(True)
else:
self.plat_enabled_check.setChecked(False)
def edit_platform(self):
index = self.platListWidget.currentRow()
self.p_edit = platform_edit.PlatformEdit(self.plat_list[index])
self.p_edit.show()
def toggle_platform_state(self):
return None
def remove_platform(self):
return None