343 lines
15 KiB
C++
343 lines
15 KiB
C++
#include "AccountSettingsWindow.h"
|
||
|
||
#include <QLabel>
|
||
#include <QMessageBox>
|
||
#include <QPushButton>
|
||
#include <QScrollArea>
|
||
#include <QCoreApplication>
|
||
#include <QVBoxLayout>
|
||
#include <QHeaderView>
|
||
#include <QJsonArray>
|
||
#include <QJsonObject>
|
||
#include <QThread>
|
||
|
||
#include "birbank/LoginAndCheckAccountsBirbankScript.h"
|
||
#include "common/PaddedItemDelegate.h"
|
||
#include "dao/AccountDAO.h"
|
||
#include "dao/ApplicationDAO.h"
|
||
#include "device/EditBankAccountDialog.h"
|
||
#include "device/EditBankDialog.h"
|
||
#include "net/NetworkService.h"
|
||
|
||
AccountSettingsWindow::AccountSettingsWindow(
|
||
QWidget *parent, QString deviceId, QString deviceName, const ApplicationInfo &app
|
||
) : QWidget(parent,
|
||
Qt::Window
|
||
| Qt::WindowTitleHint
|
||
| Qt::WindowSystemMenuHint
|
||
| Qt::WindowCloseButtonHint
|
||
| Qt::WindowMinMaxButtonsHint),
|
||
m_deviceId(std::move(deviceId)),
|
||
m_deviceName(std::move(deviceName)),
|
||
m_applicationInfo(app) {
|
||
setWindowTitle("Настройки банка [" + app.name + "]");
|
||
setMinimumSize(800, 400);
|
||
setMaximumSize(1000, 800);
|
||
resize(800, 400);
|
||
|
||
|
||
// 1. Редактирование пин-кода
|
||
// 2. Включение/отключения банка
|
||
// 3. Работа с картами (вкл/выкл) и редактирование цифр
|
||
// 4. Запуск проверки пин-код и парсинга аккаунтов
|
||
|
||
auto *mainLayout = new QVBoxLayout(this);
|
||
|
||
// Скролл-область
|
||
auto *scrollArea = new QScrollArea(this);
|
||
scrollArea->setWidgetResizable(true);
|
||
|
||
// Виджет-контейнер, в котором будет layout с таблицами и лейблами
|
||
auto *contentWidget = new QWidget;
|
||
auto *layout = new QVBoxLayout(contentWidget);
|
||
|
||
// Убираем отступы и рамку
|
||
contentWidget->setContentsMargins(0, 0, 0, 0); // Убираем отступы
|
||
layout->setContentsMargins(4, 4, 4, 4); // Убираем отступы у layout
|
||
// scrollArea->setStyleSheet("border: none;"); // Убираем рамку
|
||
layout->setAlignment(Qt::AlignTop);
|
||
|
||
|
||
QHBoxLayout *row1 = new QHBoxLayout();
|
||
QString status = QString("Статус: ") + (m_applicationInfo.status == "active"
|
||
? "<span style='color:green;'>Активен</span>"
|
||
: "<span style='color:red;'>Неактивен</span>") +
|
||
QString(", пин-код: ") + (m_applicationInfo.pinCodeChecked
|
||
? "<span style='color:green;'>Проверен</span>"
|
||
: "<span style='color:red;'>Не проверен</span>");
|
||
m_statusLabel = new QLabel(status);
|
||
m_statusLabel->setTextFormat(Qt::RichText);
|
||
row1->addWidget(m_statusLabel);
|
||
|
||
QPushButton *editBankBtn = new QPushButton("Редактировать");
|
||
editBankBtn->setStyleSheet(
|
||
"background-color: green;"
|
||
"color: white;"
|
||
);
|
||
editBankBtn->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
|
||
row1->addWidget(editBankBtn);
|
||
connect(editBankBtn, &QPushButton::clicked, this, [this]() {
|
||
BankEditDialog dlg(m_applicationInfo, this);
|
||
if (dlg.exec() == QDialog::Accepted) {
|
||
const QString pinCode = dlg.firstValue();
|
||
const QString comment = dlg.secondValue();
|
||
bool on = dlg.toggled();
|
||
|
||
if (!ApplicationDAO::update(m_applicationInfo.id, pinCode, comment, on ? "active" : "off")) {
|
||
qDebug() << "Cant update bank data";
|
||
} else {
|
||
m_applicationInfo.pinCode = pinCode;
|
||
m_applicationInfo.comment = comment;
|
||
m_applicationInfo.status = on ? "active" : "off";
|
||
|
||
QString status = QString("Статус: ") + (on
|
||
? "<span style='color:green;'>Активен</span>"
|
||
: "<span style='color:red;'>Неактивен</span>") +
|
||
QString(", пин-код: ") + (m_applicationInfo.pinCodeChecked
|
||
? "<span style='color:green;'>Проверен</span>"
|
||
: "<span style='color:red;'>Не проверен</span>");
|
||
m_statusLabel->setText(status);
|
||
m_commentLabel->setText(comment);
|
||
sendAppStatus(m_applicationInfo.deviceId, m_applicationInfo.code, on ? "active" : "off");
|
||
}
|
||
}
|
||
});
|
||
|
||
layout->addLayout(row1);
|
||
|
||
QHBoxLayout *commentRow = new QHBoxLayout();
|
||
m_commentLabel = new QLabel(m_applicationInfo.comment);
|
||
m_commentLabel->setStyleSheet(
|
||
"color: gray;"
|
||
"margin-bottom: 8px;"
|
||
);
|
||
commentRow->addWidget(m_commentLabel);
|
||
layout->addLayout(commentRow);
|
||
|
||
QPushButton *soloButton = new QPushButton("Запустить проверку пин-кода");
|
||
soloButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
|
||
// soloButton->setStyleSheet("");
|
||
soloButton->setStyleSheet(
|
||
"background-color: orange;"
|
||
"color: white;"
|
||
);
|
||
QObject::connect(soloButton, &QPushButton::clicked, [&, this]() {
|
||
if (!m_applicationInfo.pinCode.isEmpty()) {
|
||
QMessageBox msgBox(this);
|
||
msgBox.setWindowTitle(tr("Запустить проверку пин-кода?"));
|
||
msgBox.setText("Запуститься скрипт проверки входа в банк " + m_applicationInfo.name + " по пин-коду. Окно с настройками закроется.");
|
||
|
||
QPushButton *deleteBtn = msgBox.addButton(tr("Запустить"), QMessageBox::AcceptRole);
|
||
QPushButton *closeBtn = msgBox.addButton(tr("Отмена"), QMessageBox::RejectRole);
|
||
msgBox.setDefaultButton(closeBtn);
|
||
msgBox.setModal(true);
|
||
msgBox.exec();
|
||
|
||
if (msgBox.clickedButton() == deleteBtn) {
|
||
startCheckPinCode(m_applicationInfo.code);
|
||
close();
|
||
}
|
||
}
|
||
});
|
||
layout->addWidget(soloButton);
|
||
|
||
|
||
layout->addWidget(new QLabel("Счета"));
|
||
QTableWidget *tableWidget = new QTableWidget(this);
|
||
tableWidget->setSelectionMode(QAbstractItemView::NoSelection);
|
||
tableWidget->setFocusPolicy(Qt::NoFocus);
|
||
|
||
reloadContent(tableWidget);
|
||
tableWidget->resizeColumnsToContents();
|
||
|
||
|
||
layout->addWidget(tableWidget);
|
||
QPushButton *addAccountButton = new QPushButton("Добавить аккаунт");
|
||
addAccountButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
|
||
AccountInfo account;
|
||
connect(addAccountButton, &QPushButton::clicked, this, [this, tableWidget, account]() {
|
||
EditBankAccountDialog dlg(account, this);
|
||
if (dlg.exec() == QDialog::Accepted) {
|
||
const QString cardNumber = dlg.cardNumberValue();
|
||
const QString currency = dlg.currencyValue();
|
||
bool on = dlg.toggled();
|
||
|
||
AccountInfo accountInfo;
|
||
accountInfo.currency = currency;
|
||
accountInfo.description = cardNumber;
|
||
accountInfo.amount = 0;
|
||
accountInfo.appCode = m_applicationInfo.code;
|
||
accountInfo.deviceId = m_deviceId;
|
||
accountInfo.status = on ? AccountStatus::Active : AccountStatus::Off;
|
||
accountInfo.lastNumbers = cardNumber.right(4);
|
||
if (!AccountDAO::upsertAccount(accountInfo)) {
|
||
qDebug() << "Cant insert bank account data";
|
||
} else {
|
||
reloadContent(tableWidget);
|
||
tableWidget->resizeColumnsToContents();
|
||
updateAccountData(accountInfo);
|
||
}
|
||
}
|
||
});
|
||
|
||
layout->addWidget(addAccountButton);
|
||
|
||
tableWidget->resizeRowsToContents();
|
||
|
||
|
||
// Добавим вертикальный Spacer в конец, чтобы прокручиваемая область не растягивала контент
|
||
// QSpacerItem *spacer = new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding);
|
||
// layout->addItem(spacer);
|
||
|
||
contentWidget->setLayout(layout);
|
||
scrollArea->setWidget(contentWidget);
|
||
mainLayout->addWidget(scrollArea);
|
||
setLayout(mainLayout);
|
||
}
|
||
|
||
void AccountSettingsWindow::startCheckPinCode(const QString &appCode) {
|
||
if (appCode == "birbank") {
|
||
const auto thread = new QThread(nullptr);
|
||
auto *worker = new LoginAndCheckAccountsBirbankScript(m_deviceId, appCode, nullptr);
|
||
worker->moveToThread(thread);
|
||
connect(thread, &QThread::started, worker, &LoginAndCheckAccountsBirbankScript::start);
|
||
connect(worker, &LoginAndCheckAccountsBirbankScript::finished, thread, &QThread::quit);
|
||
connect(worker, &LoginAndCheckAccountsBirbankScript::finished, worker, &QObject::deleteLater);
|
||
connect(thread, &QThread::finished, thread, &QObject::deleteLater);
|
||
thread->start();
|
||
} else if (appCode == "ziraat") {
|
||
}
|
||
}
|
||
|
||
void AccountSettingsWindow::sendAppStatus(const QString &deviceId, const QString &code, const QString &status) {
|
||
QJsonObject obj;
|
||
obj["code"] = code;
|
||
obj["status"] = status;
|
||
|
||
auto *paymentThread = new QThread;
|
||
auto *networkService = new NetworkService;
|
||
networkService->moveToThread(paymentThread);
|
||
networkService->setDeviceId(deviceId);
|
||
networkService->setPayload(QJsonDocument(obj).toJson());
|
||
QObject::connect(paymentThread, &QThread::started, networkService, &NetworkService::postAppStatus);
|
||
QObject::connect(networkService, &NetworkService::finished, paymentThread, &QThread::quit);
|
||
QObject::connect(networkService, &NetworkService::finished, networkService, &QObject::deleteLater);
|
||
QObject::connect(paymentThread, &QThread::finished, paymentThread, &QThread::deleteLater);
|
||
paymentThread->start();
|
||
}
|
||
|
||
void AccountSettingsWindow::updateAccountData(const AccountInfo &account) {
|
||
QJsonArray list;
|
||
QJsonObject obj;
|
||
obj["appName"] = account.appCode;
|
||
obj["lastNumbers"] = account.lastNumbers;
|
||
obj["amount"] = account.amount;
|
||
obj["description"] = account.description;
|
||
obj["currency"] = account.currency;
|
||
obj["status"] = accountStatusToString(account.status);
|
||
|
||
list.append(obj);
|
||
|
||
auto *paymentThread = new QThread;
|
||
auto *networkService = new NetworkService;
|
||
networkService->moveToThread(paymentThread);
|
||
networkService->setDeviceId(account.deviceId);
|
||
networkService->setPayload(QJsonDocument(list).toJson());
|
||
QObject::connect(paymentThread, &QThread::started, networkService, &NetworkService::postAccountsData);
|
||
QObject::connect(networkService, &NetworkService::finished, paymentThread, &QThread::quit);
|
||
QObject::connect(networkService, &NetworkService::finished, networkService, &QObject::deleteLater);
|
||
QObject::connect(paymentThread, &QThread::finished, paymentThread, &QThread::deleteLater);
|
||
paymentThread->start();
|
||
}
|
||
|
||
void AccountSettingsWindow::reloadContent(QTableWidget *tableWidget) {
|
||
QList<AccountInfo> accounts = AccountDAO::getAccounts(m_deviceId, m_applicationInfo.code);
|
||
|
||
tableWidget->clearContents();
|
||
tableWidget->setRowCount(accounts.length());
|
||
tableWidget->setColumnCount(7);
|
||
tableWidget->setHorizontalHeaderLabels({
|
||
"Время обновления",
|
||
"Номер",
|
||
"",
|
||
"Сумма",
|
||
"Валюта",
|
||
"Статус",
|
||
""
|
||
});
|
||
|
||
tableWidget->setWordWrap(true);
|
||
tableWidget->setTextElideMode(Qt::ElideNone);
|
||
tableWidget->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft | Qt::AlignVCenter);
|
||
tableWidget->horizontalHeader()->setSectionResizeMode(5, QHeaderView::ResizeToContents);
|
||
tableWidget->verticalHeader()->setSectionResizeMode(6, QHeaderView::ResizeToContents);
|
||
tableWidget->horizontalHeader()->setSectionResizeMode(1, QHeaderView::Stretch);
|
||
|
||
|
||
for (int k = 0; k < accounts.size(); ++k) {
|
||
const AccountInfo &account = accounts[k];
|
||
|
||
QTableWidgetItem *time = new QTableWidgetItem(account.updateTime.toString("dd.MM.yyyy HH:mm:ss"));
|
||
time->setTextAlignment(Qt::AlignLeft | Qt::AlignVCenter);
|
||
time->setFlags(time->flags() & ~Qt::ItemIsEditable);
|
||
tableWidget->setItem(k, 0, time);
|
||
|
||
QTableWidgetItem *desc = new QTableWidgetItem(account.description);
|
||
desc->setTextAlignment(Qt::AlignLeft | Qt::AlignVCenter);
|
||
desc->setFlags(desc->flags() & ~Qt::ItemIsEditable);
|
||
tableWidget->setItem(k, 1, desc);
|
||
|
||
QTableWidgetItem *lastNumbers = new QTableWidgetItem(account.lastNumbers);
|
||
lastNumbers->setTextAlignment(Qt::AlignLeft | Qt::AlignVCenter);
|
||
lastNumbers->setFlags(lastNumbers->flags() & ~Qt::ItemIsEditable);
|
||
tableWidget->setItem(k, 2, lastNumbers);
|
||
|
||
QTableWidgetItem *amount = new QTableWidgetItem(QString::number(account.amount));
|
||
amount->setTextAlignment(Qt::AlignLeft | Qt::AlignVCenter);
|
||
amount->setFlags(amount->flags() & ~Qt::ItemIsEditable);
|
||
tableWidget->setItem(k, 3, amount);
|
||
|
||
QTableWidgetItem *currency = new QTableWidgetItem(account.currency);
|
||
currency->setTextAlignment(Qt::AlignLeft | Qt::AlignVCenter);
|
||
currency->setFlags(currency->flags() & ~Qt::ItemIsEditable);
|
||
tableWidget->setItem(k, 4, currency);
|
||
|
||
QTableWidgetItem *status = new QTableWidgetItem(accountStatusToUiString(account.status));
|
||
status->setTextAlignment(Qt::AlignLeft | Qt::AlignVCenter);
|
||
status->setFlags(status->flags() & ~Qt::ItemIsEditable);
|
||
if (account.status != AccountStatus::Active) {
|
||
status->setForeground(QBrush(Qt::red));
|
||
}
|
||
tableWidget->setItem(k, 5, status);
|
||
|
||
|
||
auto *editBankAccountBtn = new QPushButton("Редактировать", tableWidget);
|
||
tableWidget->setCellWidget(k, 6, editBankAccountBtn);
|
||
|
||
connect(editBankAccountBtn, &QPushButton::clicked, this, [this, tableWidget, account]() {
|
||
EditBankAccountDialog dlg(account, this);
|
||
if (dlg.exec() == QDialog::Accepted) {
|
||
const QString cardNumber = dlg.cardNumberValue();
|
||
const QString currency = dlg.currencyValue();
|
||
bool on = dlg.toggled();
|
||
|
||
if (!AccountDAO::updateAccountById(account.id, on ? "active" : "off", cardNumber, currency)) {
|
||
qDebug() << "Cant update bank account data";
|
||
} else {
|
||
reloadContent(tableWidget);
|
||
AccountInfo accountInfo;
|
||
accountInfo.currency = currency;
|
||
accountInfo.description = cardNumber;
|
||
accountInfo.amount = account.amount;
|
||
accountInfo.currency = currency;
|
||
accountInfo.appCode = m_applicationInfo.code;
|
||
accountInfo.deviceId = m_deviceId;
|
||
accountInfo.status = on ? AccountStatus::Active : AccountStatus::Off;
|
||
accountInfo.lastNumbers = cardNumber.right(4);
|
||
updateAccountData(accountInfo);
|
||
}
|
||
}
|
||
});
|
||
}
|
||
}
|