Merge branch 'main' of g.8f.al:ir/budget
This commit is contained in:
commit
152255428a
4 changed files with 73 additions and 39 deletions
|
@ -88,11 +88,11 @@ class AccountTab(TabPage):
|
||||||
|
|
||||||
# 构造查询语句
|
# 构造查询语句
|
||||||
a_id = self.rows[index][0]
|
a_id = self.rows[index][0]
|
||||||
print(a_id)
|
|
||||||
self.pg.execute(
|
self.pg.execute(
|
||||||
"SELECT meta->>'name', replace(substring(balance::text, 2), ',', ''), meta->'description' FROM account WHERE a_id=%s", (a_id,))
|
"SELECT meta->>'name', replace(substring(balance::text, 2), ',', ''), meta->'description' FROM account WHERE a_id=%s", (a_id,))
|
||||||
data = self.pg.fetchall()
|
data = self.pg.fetchall()
|
||||||
print(data)
|
|
||||||
|
|
||||||
oldBalance = float(data[0][1])
|
oldBalance = float(data[0][1])
|
||||||
|
|
||||||
|
@ -149,7 +149,6 @@ class AccountTab(TabPage):
|
||||||
# JSONB插入数据
|
# JSONB插入数据
|
||||||
data = {"name": accountNameLine.text(), "balance": balance, "description": description}
|
data = {"name": accountNameLine.text(), "balance": balance, "description": description}
|
||||||
data = json.dumps(data)
|
data = json.dumps(data)
|
||||||
print("insert data:",data)
|
|
||||||
|
|
||||||
self.pg.execute("UPDATE account SET meta=%s WHERE a_id=%s", (data, a_id))
|
self.pg.execute("UPDATE account SET meta=%s WHERE a_id=%s", (data, a_id))
|
||||||
|
|
||||||
|
@ -217,7 +216,6 @@ class AccountTab(TabPage):
|
||||||
# JSONB插入数据
|
# JSONB插入数据
|
||||||
data = {"name": accountNameLine.text(), "description": description}
|
data = {"name": accountNameLine.text(), "description": description}
|
||||||
data = json.dumps(data)
|
data = json.dumps(data)
|
||||||
print("insert data:",data)
|
|
||||||
|
|
||||||
self.pg.execute("INSERT INTO account (balance, meta) VALUES (%s, %s) RETURNING a_id", (balance, data,))
|
self.pg.execute("INSERT INTO account (balance, meta) VALUES (%s, %s) RETURNING a_id", (balance, data,))
|
||||||
a_id = self.pg.fetchall()[0][0]
|
a_id = self.pg.fetchall()[0][0]
|
||||||
|
@ -244,7 +242,7 @@ class AccountTab(TabPage):
|
||||||
try:
|
try:
|
||||||
self.pg.execute("SELECT a_id, meta ->> 'name' FROM account ORDER BY a_id")
|
self.pg.execute("SELECT a_id, meta ->> 'name' FROM account ORDER BY a_id")
|
||||||
self.rows = self.pg.cur.fetchall()
|
self.rows = self.pg.cur.fetchall()
|
||||||
print(self.rows)
|
|
||||||
for row in self.rows:
|
for row in self.rows:
|
||||||
data = row[1]
|
data = row[1]
|
||||||
self.accountComboBox.addItem(data)
|
self.accountComboBox.addItem(data)
|
||||||
|
@ -259,7 +257,6 @@ class AccountTab(TabPage):
|
||||||
self.pg.execute("SELECT c_id, meta ->> 'name' FROM category ORDER BY c_id")
|
self.pg.execute("SELECT c_id, meta ->> 'name' FROM category ORDER BY c_id")
|
||||||
self.categoryData = self.pg.fetchall()
|
self.categoryData = self.pg.fetchall()
|
||||||
|
|
||||||
print(self.accountData)
|
|
||||||
|
|
||||||
# 初始化表格
|
# 初始化表格
|
||||||
self.accountTable.clear()
|
self.accountTable.clear()
|
||||||
|
|
|
@ -16,6 +16,7 @@ class CategoryTab(TabPage):
|
||||||
def initUI(self):
|
def initUI(self):
|
||||||
# 创建连接信息控件
|
# 创建连接信息控件
|
||||||
self.categoryComboBox = QComboBox()
|
self.categoryComboBox = QComboBox()
|
||||||
|
self.categoryComboBox.currentIndexChanged.connect(self.onCategoryIndexChanged)
|
||||||
|
|
||||||
self.categoryModifyButton = QPushButton('Modify')
|
self.categoryModifyButton = QPushButton('Modify')
|
||||||
self.categoryModifyButton.clicked.connect(self.onCategoryModifyClicked)
|
self.categoryModifyButton.clicked.connect(self.onCategoryModifyClicked)
|
||||||
|
@ -57,11 +58,11 @@ class CategoryTab(TabPage):
|
||||||
|
|
||||||
# 构造查询语句
|
# 构造查询语句
|
||||||
c_id = self.rows[index][0]
|
c_id = self.rows[index][0]
|
||||||
print(c_id)
|
|
||||||
self.pg.execute(
|
self.pg.execute(
|
||||||
"SELECT meta->>'name', meta->>'type', meta->'description' FROM category WHERE c_id=%s", (c_id,))
|
"SELECT meta->>'name', meta->>'type', meta->'description' FROM category WHERE c_id=%s", (c_id,))
|
||||||
data = self.pg.fetchall()
|
data = self.pg.fetchall()
|
||||||
print(data)
|
|
||||||
|
|
||||||
# 绘制界面并填充数据
|
# 绘制界面并填充数据
|
||||||
label1 = QLabel("Category Name:")
|
label1 = QLabel("Category Name:")
|
||||||
|
@ -122,7 +123,7 @@ class CategoryTab(TabPage):
|
||||||
data = {"name": line1.text(), "type": type,
|
data = {"name": line1.text(), "type": type,
|
||||||
"description": description}
|
"description": description}
|
||||||
data = json.dumps(data)
|
data = json.dumps(data)
|
||||||
print("insert data:", data)
|
|
||||||
|
|
||||||
self.pg.execute("UPDATE category SET meta=%s WHERE c_id=%s",(data,c_id,))
|
self.pg.execute("UPDATE category SET meta=%s WHERE c_id=%s",(data,c_id,))
|
||||||
|
|
||||||
|
@ -187,7 +188,7 @@ class CategoryTab(TabPage):
|
||||||
data = {"name": line1.text(), "type": type,
|
data = {"name": line1.text(), "type": type,
|
||||||
"description": description}
|
"description": description}
|
||||||
data = json.dumps(data)
|
data = json.dumps(data)
|
||||||
print("insert data:", data)
|
|
||||||
|
|
||||||
self.pg.execute(
|
self.pg.execute(
|
||||||
"INSERT INTO category (meta) VALUES (%s)", (data,))
|
"INSERT INTO category (meta) VALUES (%s)", (data,))
|
||||||
|
@ -208,7 +209,7 @@ class CategoryTab(TabPage):
|
||||||
self.pg.execute(
|
self.pg.execute(
|
||||||
"SELECT c_id, meta ->> 'name' FROM category ORDER BY c_id")
|
"SELECT c_id, meta ->> 'name' FROM category ORDER BY c_id")
|
||||||
self.rows = self.pg.cur.fetchall()
|
self.rows = self.pg.cur.fetchall()
|
||||||
print(self.rows)
|
|
||||||
for row in self.rows:
|
for row in self.rows:
|
||||||
data = row[1]
|
data = row[1]
|
||||||
self.categoryComboBox.addItem(data)
|
self.categoryComboBox.addItem(data)
|
||||||
|
@ -216,35 +217,32 @@ class CategoryTab(TabPage):
|
||||||
print(e)
|
print(e)
|
||||||
QMessageBox.critical(self, 'Error', str(e))
|
QMessageBox.critical(self, 'Error', str(e))
|
||||||
|
|
||||||
# self.pg.execute("SELECT c_id, meta ->> 'name' FROM category ORDER BY c_id")
|
|
||||||
# self.categoryData = self.pg.fetchall()
|
def onCategoryIndexChanged(self, index):
|
||||||
self.pg.execute("SELECT t_id, a_id, c_id, s_id, time, translate(amount::varchar,'$','¥'), meta->>'description' FROM transaction ORDER BY time DESC")
|
# 获取comboBox中的c_id
|
||||||
|
c_id = self.rows[index][0]
|
||||||
|
|
||||||
|
self.pg.execute("SELECT t_id, a_id, c_id, s_id, time, translate(amount::varchar,'$','¥'),\
|
||||||
|
meta->>'description' FROM transaction \
|
||||||
|
WHERE c_id = %s ORDER BY time DESC", (c_id,))
|
||||||
self.transData = self.pg.fetchall()
|
self.transData = self.pg.fetchall()
|
||||||
self.pg.execute("SELECT a_id, meta ->> 'name' FROM account ORDER BY a_id")
|
self.pg.execute("SELECT a_id, meta ->> 'name' FROM account ORDER BY a_id")
|
||||||
self.accountData = self.pg.fetchall()
|
self.accountData = self.pg.fetchall()
|
||||||
self.pg.execute("SELECT c_id, meta ->> 'name' FROM category ORDER BY c_id")
|
self.pg.execute("SELECT c_id, meta ->> 'name' FROM category ORDER BY c_id")
|
||||||
self.categoryData = self.pg.fetchall()
|
self.categoryData = self.pg.fetchall()
|
||||||
|
|
||||||
print(self.rows)
|
|
||||||
|
|
||||||
# 初始化表格
|
# 初始化表格
|
||||||
self.categoryTable.clear()
|
self.categoryTable.clear()
|
||||||
self.categoryTable.setRowCount(len(self.transData))
|
self.categoryTable.setRowCount(len(self.transData))
|
||||||
self.categoryTable.setColumnCount(3) # 类别名称 类别 描述
|
self.categoryTable.setColumnCount(4) # 时间 账户 金额 描述
|
||||||
self.categoryTable.setHorizontalHeaderLabels(['Category Name', 'Category Type','Description'])
|
self.categoryTable.setHorizontalHeaderLabels(['Time', 'Account', 'Amount', 'Description'])
|
||||||
# 设置自动调整列宽
|
# 设置自动调整列宽
|
||||||
self.categoryTable.horizontalHeader().setSectionResizeMode(QHeaderView.ResizeMode.Stretch)
|
self.categoryTable.horizontalHeader().setSectionResizeMode(QHeaderView.ResizeMode.Stretch)
|
||||||
|
|
||||||
# 填充表格
|
# 填充表格
|
||||||
for i in range(len(self.transData)):
|
for i in range(len(self.transData)):
|
||||||
# self.categoryTable.setItem(i, 2, QTableWidgetItem(self.accountData[self.transData[i][1]-1][1]))
|
self.categoryTable.setItem(i, 0, QTableWidgetItem(self.transData[i][4].strftime("%Y-%m-%d %H:%M:%S")))
|
||||||
if self.transData[i][2] is None:
|
self.categoryTable.setItem(i, 1, QTableWidgetItem(self.accountData[self.transData[i][1]-1][1]))
|
||||||
self.categoryTable.setItem(i, 0, QTableWidgetItem("None"))
|
self.categoryTable.setItem(i, 2, QTableWidgetItem(str(self.transData[i][5])))
|
||||||
else:
|
self.categoryTable.setItem(i, 3, QTableWidgetItem(self.transData[i][6]))
|
||||||
self.categoryTable.setItem(i, 0, QTableWidgetItem(data))
|
|
||||||
# self.categoryTable.setItem(i, 0, QTableWidgetItem(self.accountData[self.transData[i][2]-1][1]))
|
|
||||||
# self.categoryTable.setItem(i, 0, QTableWidgetItem(data[0][0]))
|
|
||||||
self.categoryTable.setItem(i, 1, QTableWidgetItem(str(self.transData[i][5])))
|
|
||||||
self.categoryTable.setItem(i, 2, QTableWidgetItem(self.transData[i][6]))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ from PyQt6.QtGui import QDoubleValidator
|
||||||
import datetime
|
import datetime
|
||||||
import json
|
import json
|
||||||
|
|
||||||
|
|
||||||
class StatTab(TabPage):
|
class StatTab(TabPage):
|
||||||
def __init__(self, parent):
|
def __init__(self, parent):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
@ -25,10 +26,11 @@ class StatTab(TabPage):
|
||||||
|
|
||||||
# 饼状图
|
# 饼状图
|
||||||
self.chart = QChart()
|
self.chart = QChart()
|
||||||
self.chart.setTitle('Month Statistics')
|
|
||||||
self.chart.setAnimationOptions(QChart.AnimationOption.SeriesAnimations)
|
self.chart.setAnimationOptions(QChart.AnimationOption.SeriesAnimations)
|
||||||
chartLayout = QVBoxLayout()
|
chartLayout = QVBoxLayout()
|
||||||
chartLayout.addWidget(QChartView(self.chart))
|
chartLayout.addWidget(QChartView(self.chart))
|
||||||
|
# 关闭图例
|
||||||
|
self.chart.legend().setVisible(False)
|
||||||
|
|
||||||
leftLayout = QVBoxLayout()
|
leftLayout = QVBoxLayout()
|
||||||
leftLayout.addLayout(buttonLayout)
|
leftLayout.addLayout(buttonLayout)
|
||||||
|
@ -48,6 +50,9 @@ class StatTab(TabPage):
|
||||||
statLayout = QHBoxLayout()
|
statLayout = QHBoxLayout()
|
||||||
statLayout.addLayout(leftLayout)
|
statLayout.addLayout(leftLayout)
|
||||||
statLayout.addLayout(calenderLayout)
|
statLayout.addLayout(calenderLayout)
|
||||||
|
# 设置左右空间占比为2:1
|
||||||
|
statLayout.setStretchFactor(leftLayout, 2)
|
||||||
|
statLayout.setStretchFactor(calenderLayout, 1)
|
||||||
self.setLayout(statLayout)
|
self.setLayout(statLayout)
|
||||||
|
|
||||||
def onOutButtonClicked(self):
|
def onOutButtonClicked(self):
|
||||||
|
@ -59,26 +64,26 @@ class StatTab(TabPage):
|
||||||
self.selected()
|
self.selected()
|
||||||
|
|
||||||
def onCalendarClicked(self, date):
|
def onCalendarClicked(self, date):
|
||||||
pass
|
# 清除饼状图
|
||||||
|
self.chart.removeAllSeries()
|
||||||
|
# 构建日期查询
|
||||||
def onCalendarPageChanged(self, year, month):
|
startTime = datetime.datetime(date.year(), date.month(), date.day(), 0, 0, 0)
|
||||||
# 合计分类的交易量
|
endTime = datetime.datetime(date.year(), date.month(), date.day(), 23, 59, 59)
|
||||||
|
# 查询交易
|
||||||
self.pg.execute("SELECT c_id, sum(amount)::numeric::float8 FROM transaction WHERE c_id IS NOT NULL and \
|
self.pg.execute("SELECT c_id, sum(amount)::numeric::float8 FROM transaction WHERE c_id IS NOT NULL and \
|
||||||
time BETWEEN %s AND %s GROUP BY c_id ORDER BY c_id", \
|
time BETWEEN %s AND %s GROUP BY c_id ORDER BY c_id", \
|
||||||
(datetime.date(year, month, 1), datetime.date(year, month+1, 1),))
|
(startTime, endTime,))
|
||||||
self.statData = self.pg.fetchall()
|
self.statData = self.pg.fetchall()
|
||||||
print(self.statData)
|
|
||||||
|
|
||||||
# 获取此月所有交易类别
|
# 获取此日所有交易类别
|
||||||
self.pg.execute("SELECT c_id, meta->>'type', meta->>'name' FROM category \
|
self.pg.execute("SELECT c_id, meta->>'type', meta->>'name' FROM category \
|
||||||
WHERE c_id in (SELECT c_id FROM transaction WHERE time between %s and %s GROUP BY c_id) \
|
WHERE c_id in (SELECT c_id FROM transaction WHERE time between %s and %s GROUP BY c_id) \
|
||||||
ORDER BY c_id", \
|
ORDER BY c_id", \
|
||||||
(datetime.date(year, month, 1), datetime.date(year, month+1, 1),))
|
(startTime, endTime,))
|
||||||
self.categoryData = self.pg.fetchall()
|
self.categoryData = self.pg.fetchall()
|
||||||
print(self.categoryData)
|
|
||||||
|
|
||||||
# 填充饼状图
|
# 填充饼状图
|
||||||
|
self.chart.setTitle('Day Statistics')
|
||||||
self.chart.removeAllSeries()
|
self.chart.removeAllSeries()
|
||||||
series = QPieSeries()
|
series = QPieSeries()
|
||||||
|
|
||||||
|
@ -87,6 +92,41 @@ class StatTab(TabPage):
|
||||||
series.append(self.categoryData[i][2], self.statData[i][1])
|
series.append(self.categoryData[i][2], self.statData[i][1])
|
||||||
self.chart.addSeries(series)
|
self.chart.addSeries(series)
|
||||||
|
|
||||||
|
# 在饼状图内显示数额
|
||||||
|
for slice in series.slices():
|
||||||
|
slice.setLabelVisible(True)
|
||||||
|
slice.setLabel(slice.label()+" "+"{:.2f}%".format(100 * slice.percentage()))
|
||||||
|
|
||||||
|
|
||||||
|
def onCalendarPageChanged(self, year, month):
|
||||||
|
# 合计分类的交易量
|
||||||
|
self.pg.execute("SELECT c_id, sum(amount)::numeric::float8 FROM transaction WHERE c_id IS NOT NULL and \
|
||||||
|
time BETWEEN %s AND %s GROUP BY c_id ORDER BY c_id", \
|
||||||
|
(datetime.date(year, month, 1), datetime.date(year, month+1, 1),))
|
||||||
|
self.statData = self.pg.fetchall()
|
||||||
|
|
||||||
|
# 获取此月所有交易类别
|
||||||
|
self.pg.execute("SELECT c_id, meta->>'type', meta->>'name' FROM category \
|
||||||
|
WHERE c_id in (SELECT c_id FROM transaction WHERE time between %s and %s GROUP BY c_id) \
|
||||||
|
ORDER BY c_id", \
|
||||||
|
(datetime.date(year, month, 1), datetime.date(year, month+1, 1),))
|
||||||
|
self.categoryData = self.pg.fetchall()
|
||||||
|
|
||||||
|
# 填充饼状图
|
||||||
|
self.chart.setTitle('Month Statistics')
|
||||||
|
self.chart.removeAllSeries()
|
||||||
|
series = QPieSeries()
|
||||||
|
|
||||||
|
for i in range(len(self.statData)):
|
||||||
|
if (self.categoryData[i][1] == self.mode):
|
||||||
|
series.append(self.categoryData[i][2], self.statData[i][1])
|
||||||
|
self.chart.addSeries(series)
|
||||||
|
|
||||||
|
# 在饼状图内显示数额
|
||||||
|
for slice in series.slices():
|
||||||
|
slice.setLabelVisible(True)
|
||||||
|
slice.setLabel(slice.label()+" "+"{:.2f}%".format(100 * slice.percentage()))
|
||||||
|
|
||||||
def selected(self):
|
def selected(self):
|
||||||
# 刷新图表
|
# 刷新图表
|
||||||
self.onCalendarPageChanged(self.calendar.yearShown(), self.calendar.monthShown())
|
self.onCalendarPageChanged(self.calendar.yearShown(), self.calendar.monthShown())
|
||||||
|
|
|
@ -107,7 +107,7 @@ class TransTab(TabPage):
|
||||||
# JSONB插入数据
|
# JSONB插入数据
|
||||||
data = {"type":type, "description": description}
|
data = {"type":type, "description": description}
|
||||||
data = json.dumps(data)
|
data = json.dumps(data)
|
||||||
print("insert data:", data)
|
|
||||||
|
|
||||||
self.pg.execute(
|
self.pg.execute(
|
||||||
"INSERT INTO transaction (c_id, a_id, time, amount, meta) VALUES (%s,%s,now(), %s,%s)", (category, account, amount, data,))
|
"INSERT INTO transaction (c_id, a_id, time, amount, meta) VALUES (%s,%s,now(), %s,%s)", (category, account, amount, data,))
|
||||||
|
@ -181,7 +181,7 @@ class TransTab(TabPage):
|
||||||
if num != amountLine.text():
|
if num != amountLine.text():
|
||||||
amount = float(amountLine.text())
|
amount = float(amountLine.text())
|
||||||
amount = amount - float(num)
|
amount = amount - float(num)
|
||||||
print(amount)
|
|
||||||
self.pg.execute("UPDATE account SET balance = balance + (%s::NUMERIC)::MONEY WHERE a_id = %s",\
|
self.pg.execute("UPDATE account SET balance = balance + (%s::NUMERIC)::MONEY WHERE a_id = %s",\
|
||||||
(amount, self.transData[self.rows[0].row()][1],))
|
(amount, self.transData[self.rows[0].row()][1],))
|
||||||
|
|
||||||
|
@ -216,7 +216,7 @@ class TransTab(TabPage):
|
||||||
def onDialogTypeChanged(self, index):
|
def onDialogTypeChanged(self, index):
|
||||||
# 获取当前选择的类型
|
# 获取当前选择的类型
|
||||||
type = self.dialogLayout.itemAt(1).widget().currentText()
|
type = self.dialogLayout.itemAt(1).widget().currentText()
|
||||||
print(type)
|
|
||||||
if(type=="Income"):
|
if(type=="Income"):
|
||||||
self.pg.execute(
|
self.pg.execute(
|
||||||
"SELECT c_id, meta->>'name' FROM category WHERE meta->>'type'='in' ORDER BY c_id")
|
"SELECT c_id, meta->>'name' FROM category WHERE meta->>'type'='in' ORDER BY c_id")
|
||||||
|
@ -224,7 +224,7 @@ class TransTab(TabPage):
|
||||||
self.pg.execute(
|
self.pg.execute(
|
||||||
"SELECT c_id, meta->>'name' FROM category WHERE meta->>'type'='out' ORDER BY c_id")
|
"SELECT c_id, meta->>'name' FROM category WHERE meta->>'type'='out' ORDER BY c_id")
|
||||||
self.categoryData = self.pg.fetchall()
|
self.categoryData = self.pg.fetchall()
|
||||||
print(self.categoryData)
|
|
||||||
self.dialogLayout.itemAt(3).widget().clear()
|
self.dialogLayout.itemAt(3).widget().clear()
|
||||||
for i in range(len(self.categoryData)):
|
for i in range(len(self.categoryData)):
|
||||||
self.dialogLayout.itemAt(3).widget().addItem(self.categoryData[i][1])
|
self.dialogLayout.itemAt(3).widget().addItem(self.categoryData[i][1])
|
||||||
|
@ -232,7 +232,7 @@ class TransTab(TabPage):
|
||||||
# 填充账户
|
# 填充账户
|
||||||
self.pg.execute("SELECT a_id, meta ->> 'name' FROM account ORDER BY a_id")
|
self.pg.execute("SELECT a_id, meta ->> 'name' FROM account ORDER BY a_id")
|
||||||
self.accountData = self.pg.fetchall()
|
self.accountData = self.pg.fetchall()
|
||||||
print(self.accountData)
|
|
||||||
self.dialogLayout.itemAt(5).widget().clear()
|
self.dialogLayout.itemAt(5).widget().clear()
|
||||||
for i in range(len(self.accountData)):
|
for i in range(len(self.accountData)):
|
||||||
self.dialogLayout.itemAt(5).widget().addItem(self.accountData[i][1])
|
self.dialogLayout.itemAt(5).widget().addItem(self.accountData[i][1])
|
||||||
|
@ -245,7 +245,6 @@ class TransTab(TabPage):
|
||||||
self.pg.execute("SELECT c_id, meta ->> 'name' FROM category ORDER BY c_id")
|
self.pg.execute("SELECT c_id, meta ->> 'name' FROM category ORDER BY c_id")
|
||||||
self.categoryData = self.pg.fetchall()
|
self.categoryData = self.pg.fetchall()
|
||||||
|
|
||||||
print(self.transData)
|
|
||||||
|
|
||||||
# 初始化表格
|
# 初始化表格
|
||||||
self.transTable.clear()
|
self.transTable.clear()
|
||||||
|
|
Loading…
Reference in a new issue