- Add `pinCheckOnly` parameter in scripts to support conditional account checks. - Prevent activation of bank profiles without active cards in `AccountSettingsWindow` and `DeviceWidget`. - Adjust logging flow in `AppLogger` for unified data handling.
661 lines
32 KiB
C++
661 lines
32 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 "ozon/LoginAndCheckAccountsScript.h"
|
||
#include "ozon/GetProfileInfoScript.h"
|
||
#include "ozon/GetCardInfoScript.h"
|
||
#include "black/GetLastTransactionsScript.h"
|
||
#include "ozon/GetLastTransactionsScript.h"
|
||
#include "black/LoginAndCheckAccountsScript.h"
|
||
#include "black/GetProfileInfoScript.h"
|
||
#include "black/GetCardInfoScript.h"
|
||
#include "dao/MaterialDAO.h"
|
||
#include "dao/BankProfileDAO.h"
|
||
#include "bank/TransactionWindow.h"
|
||
#include "device/EditBankAccountDialog.h"
|
||
#include "device/EditBankDialog.h"
|
||
#include "net/NetworkService.h"
|
||
|
||
AccountSettingsWindow::AccountSettingsWindow(
|
||
QWidget *parent, QString deviceId, QString deviceName, const BankProfileInfo &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 (on) {
|
||
const QList<MaterialInfo> materials = MaterialDAO::getAccounts(m_deviceId, m_applicationInfo.code);
|
||
bool hasActive = false;
|
||
for (const auto &m : materials) {
|
||
if (m.status == MaterialStatus::Active) { hasActive = true; break; }
|
||
}
|
||
if (!hasActive) {
|
||
QMessageBox::warning(this, "Невозможно включить",
|
||
"Ни одна карта не активна.\nВключите хотя бы одну карту перед включением профиля.");
|
||
return;
|
||
}
|
||
}
|
||
|
||
if (!BankProfileDAO::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);
|
||
|
||
QHBoxLayout *profileRow = new QHBoxLayout();
|
||
QString profileText;
|
||
if (m_applicationInfo.fullName.isEmpty() && m_applicationInfo.phone.isEmpty()) {
|
||
profileText = "<span style='color:gray;'>Данные не получены</span>";
|
||
} else {
|
||
profileText = m_applicationInfo.fullName + " | " + m_applicationInfo.phone;
|
||
}
|
||
m_profileLabel = new QLabel(profileText);
|
||
m_profileLabel->setTextFormat(Qt::RichText);
|
||
m_profileLabel->setStyleSheet("margin-bottom: 8px;");
|
||
profileRow->addWidget(m_profileLabel);
|
||
|
||
// Статус синхронизации с сервером
|
||
const QString syncText = m_applicationInfo.bankProfileId.isEmpty()
|
||
? "<span style='color:red;'>● Не синхронизирован</span>"
|
||
: "<span style='color:green;'>● Синхронизирован</span>";
|
||
auto *syncLabel = new QLabel(syncText);
|
||
syncLabel->setTextFormat(Qt::RichText);
|
||
syncLabel->setStyleSheet("margin-bottom: 8px; margin-left: 16px;");
|
||
profileRow->addWidget(syncLabel);
|
||
profileRow->addStretch();
|
||
|
||
layout->addLayout(profileRow);
|
||
|
||
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::warning(this, "Пин-код не задан",
|
||
"Сначала укажите пин-код банка через кнопку \"Редактировать\".");
|
||
return;
|
||
}
|
||
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);
|
||
|
||
if (m_applicationInfo.code == "ozon" && m_applicationInfo.pinCodeChecked) {
|
||
QHBoxLayout *ozonRow = new QHBoxLayout();
|
||
|
||
QPushButton *profileButton = new QPushButton("Обновить профиль");
|
||
profileButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
|
||
profileButton->setStyleSheet("background-color: #1565C0; color: white;");
|
||
QObject::connect(profileButton, &QPushButton::clicked, [this]() {
|
||
QMessageBox msgBox(this);
|
||
msgBox.setWindowTitle(tr("Обновить профиль?"));
|
||
msgBox.setText(
|
||
"Запустится скрипт получения профиля из " + m_applicationInfo.name +
|
||
". Окно с настройками закроется.");
|
||
QPushButton *runBtn = msgBox.addButton(tr("Запустить"), QMessageBox::AcceptRole);
|
||
QPushButton *cancelBtn = msgBox.addButton(tr("Отмена"), QMessageBox::RejectRole);
|
||
msgBox.setDefaultButton(cancelBtn);
|
||
msgBox.setModal(true);
|
||
msgBox.exec();
|
||
if (msgBox.clickedButton() == runBtn) {
|
||
startGetProfileInfo(m_applicationInfo.code);
|
||
close();
|
||
}
|
||
});
|
||
|
||
QPushButton *cardButton = new QPushButton("Проверить аккаунты");
|
||
cardButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
|
||
cardButton->setStyleSheet("background-color: #1565C0; color: white;");
|
||
QObject::connect(cardButton, &QPushButton::clicked, [this]() {
|
||
QMessageBox msgBox(this);
|
||
msgBox.setWindowTitle(tr("Проверить аккаунты?"));
|
||
msgBox.setText(
|
||
"Запустится скрипт получения данных карты из " + m_applicationInfo.name +
|
||
". Окно с настройками закроется.");
|
||
QPushButton *runBtn = msgBox.addButton(tr("Запустить"), QMessageBox::AcceptRole);
|
||
QPushButton *cancelBtn = msgBox.addButton(tr("Отмена"), QMessageBox::RejectRole);
|
||
msgBox.setDefaultButton(cancelBtn);
|
||
msgBox.setModal(true);
|
||
msgBox.exec();
|
||
if (msgBox.clickedButton() == runBtn) {
|
||
startGetCardInfo(m_applicationInfo.code);
|
||
close();
|
||
}
|
||
});
|
||
|
||
QPushButton *transactionsButton = new QPushButton("Проверить транзакции");
|
||
transactionsButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
|
||
transactionsButton->setStyleSheet("background-color: #1565C0; color: white;");
|
||
QObject::connect(transactionsButton, &QPushButton::clicked, [this]() {
|
||
QMessageBox msgBox(this);
|
||
msgBox.setWindowTitle(tr("Проверить транзакции?"));
|
||
msgBox.setText(
|
||
"Запустится скрипт получения последних транзакций из " + m_applicationInfo.name +
|
||
". Окно с настройками закроется.");
|
||
QPushButton *runBtn = msgBox.addButton(tr("За 24 часа"), QMessageBox::AcceptRole);
|
||
QPushButton *last5Btn = msgBox.addButton(tr("Последние 5"), QMessageBox::AcceptRole);
|
||
QPushButton *cancelBtn = msgBox.addButton(tr("Отмена"), QMessageBox::RejectRole);
|
||
msgBox.setDefaultButton(cancelBtn);
|
||
msgBox.setModal(true);
|
||
msgBox.exec();
|
||
if (msgBox.clickedButton() == runBtn) {
|
||
startGetLastTransactions(m_applicationInfo.code);
|
||
close();
|
||
} else if (msgBox.clickedButton() == last5Btn) {
|
||
startGetLastTransactions(m_applicationInfo.code, 5);
|
||
close();
|
||
}
|
||
});
|
||
|
||
ozonRow->addWidget(profileButton);
|
||
ozonRow->addWidget(cardButton);
|
||
ozonRow->addWidget(transactionsButton);
|
||
ozonRow->addStretch();
|
||
layout->addLayout(ozonRow);
|
||
}
|
||
|
||
if (m_applicationInfo.code == "black" && m_applicationInfo.pinCodeChecked) {
|
||
QHBoxLayout *blackRow = new QHBoxLayout();
|
||
|
||
QPushButton *profileButton = new QPushButton("Обновить профиль");
|
||
profileButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
|
||
profileButton->setStyleSheet("background-color: #1565C0; color: white;");
|
||
QObject::connect(profileButton, &QPushButton::clicked, [this]() {
|
||
QMessageBox msgBox(this);
|
||
msgBox.setWindowTitle(tr("Обновить профиль?"));
|
||
msgBox.setText(
|
||
"Запустится скрипт получения профиля из " + m_applicationInfo.name +
|
||
". Окно с настройками закроется.");
|
||
QPushButton *runBtn = msgBox.addButton(tr("Запустить"), QMessageBox::AcceptRole);
|
||
QPushButton *cancelBtn = msgBox.addButton(tr("Отмена"), QMessageBox::RejectRole);
|
||
msgBox.setDefaultButton(cancelBtn);
|
||
msgBox.setModal(true);
|
||
msgBox.exec();
|
||
if (msgBox.clickedButton() == runBtn) {
|
||
startGetProfileInfo(m_applicationInfo.code);
|
||
close();
|
||
}
|
||
});
|
||
|
||
QPushButton *cardButton = new QPushButton("Проверить аккаунты");
|
||
cardButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
|
||
cardButton->setStyleSheet("background-color: #1565C0; color: white;");
|
||
QObject::connect(cardButton, &QPushButton::clicked, [this]() {
|
||
QMessageBox msgBox(this);
|
||
msgBox.setWindowTitle(tr("Проверить аккаунты?"));
|
||
msgBox.setText(
|
||
"Запустится скрипт получения данных карты из " + m_applicationInfo.name +
|
||
". Окно с настройками закроется.");
|
||
QPushButton *runBtn = msgBox.addButton(tr("Запустить"), QMessageBox::AcceptRole);
|
||
QPushButton *cancelBtn = msgBox.addButton(tr("Отмена"), QMessageBox::RejectRole);
|
||
msgBox.setDefaultButton(cancelBtn);
|
||
msgBox.setModal(true);
|
||
msgBox.exec();
|
||
if (msgBox.clickedButton() == runBtn) {
|
||
startGetCardInfo(m_applicationInfo.code);
|
||
close();
|
||
}
|
||
});
|
||
|
||
QPushButton *transactionsButton = new QPushButton("Проверить транзакции");
|
||
transactionsButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
|
||
transactionsButton->setStyleSheet("background-color: #1565C0; color: white;");
|
||
QObject::connect(transactionsButton, &QPushButton::clicked, [this]() {
|
||
QMessageBox msgBox(this);
|
||
msgBox.setWindowTitle(tr("Проверить транзакции?"));
|
||
msgBox.setText(
|
||
"Запустится скрипт получения транзакций из " + m_applicationInfo.name +
|
||
". Окно с настройками закроется.");
|
||
QPushButton *runBtn = msgBox.addButton(tr("Проверить"), QMessageBox::AcceptRole);
|
||
QPushButton *cancelBtn = msgBox.addButton(tr("Отмена"), QMessageBox::RejectRole);
|
||
msgBox.setDefaultButton(cancelBtn);
|
||
msgBox.setModal(true);
|
||
msgBox.exec();
|
||
if (msgBox.clickedButton() == runBtn) {
|
||
startGetLastTransactions(m_applicationInfo.code);
|
||
close();
|
||
}
|
||
});
|
||
|
||
blackRow->addWidget(profileButton);
|
||
blackRow->addWidget(cardButton);
|
||
blackRow->addWidget(transactionsButton);
|
||
blackRow->addStretch();
|
||
layout->addLayout(blackRow);
|
||
}
|
||
|
||
layout->addWidget(new QLabel("Счета"));
|
||
QTableWidget *tableWidget = new QTableWidget(this);
|
||
tableWidget->setSelectionMode(QAbstractItemView::NoSelection);
|
||
tableWidget->setFocusPolicy(Qt::NoFocus);
|
||
|
||
reloadContent(tableWidget);
|
||
tableWidget->resizeColumnsToContents();
|
||
|
||
|
||
layout->addWidget(tableWidget);
|
||
|
||
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) {
|
||
QThread *thread = new QThread(nullptr);
|
||
const QString deviceId = m_deviceId;
|
||
|
||
auto onResult = [deviceId, appCode](const QString &result) {
|
||
if (result.isEmpty()) {
|
||
const BankProfileInfo app = BankProfileDAO::getApplication(deviceId, appCode);
|
||
if (app.id >= 0) {
|
||
BankProfileDAO::updatePinCodeStatus(app.id, "yes", "");
|
||
}
|
||
}
|
||
};
|
||
|
||
const bool pinCheckOnly = !m_applicationInfo.bankProfileId.isEmpty();
|
||
|
||
if (appCode == "ozon") {
|
||
auto *worker = new Ozon::LoginAndCheckAccountsScript(m_deviceId, appCode, nullptr, false, pinCheckOnly);
|
||
worker->moveToThread(thread);
|
||
connect(thread, &QThread::started, worker, &Ozon::LoginAndCheckAccountsScript::start);
|
||
connect(worker, &Ozon::LoginAndCheckAccountsScript::finishedWithResult, worker, onResult);
|
||
connect(worker, &Ozon::LoginAndCheckAccountsScript::finished, thread, &QThread::quit);
|
||
connect(worker, &Ozon::LoginAndCheckAccountsScript::finished, worker, &QObject::deleteLater);
|
||
connect(thread, &QThread::finished, thread, &QObject::deleteLater);
|
||
} else if (appCode == "black") {
|
||
auto *worker = new Black::LoginAndCheckAccountsScript(m_deviceId, appCode, nullptr, pinCheckOnly);
|
||
worker->moveToThread(thread);
|
||
connect(thread, &QThread::started, worker, &Black::LoginAndCheckAccountsScript::start);
|
||
connect(worker, &Black::LoginAndCheckAccountsScript::finishedWithResult, worker, onResult);
|
||
connect(worker, &Black::LoginAndCheckAccountsScript::finished, thread, &QThread::quit);
|
||
connect(worker, &Black::LoginAndCheckAccountsScript::finished, worker, &QObject::deleteLater);
|
||
connect(thread, &QThread::finished, thread, &QObject::deleteLater);
|
||
} else {
|
||
thread->deleteLater();
|
||
return;
|
||
}
|
||
|
||
thread->start();
|
||
}
|
||
|
||
void AccountSettingsWindow::startGetProfileInfo(const QString &appCode) {
|
||
QThread *thread = new QThread(nullptr);
|
||
|
||
if (appCode == "ozon") {
|
||
auto *worker = new Ozon::GetProfileInfoScript(m_deviceId, appCode, nullptr);
|
||
worker->moveToThread(thread);
|
||
connect(thread, &QThread::started, worker, &Ozon::GetProfileInfoScript::start);
|
||
connect(worker, &Ozon::GetProfileInfoScript::finished, thread, &QThread::quit);
|
||
connect(worker, &Ozon::GetProfileInfoScript::finished, worker, &QObject::deleteLater);
|
||
connect(thread, &QThread::finished, thread, &QObject::deleteLater);
|
||
} else if (appCode == "black") {
|
||
auto *worker = new Black::GetProfileInfoScript(m_deviceId, appCode, nullptr);
|
||
worker->moveToThread(thread);
|
||
connect(thread, &QThread::started, worker, &Black::GetProfileInfoScript::start);
|
||
connect(worker, &Black::GetProfileInfoScript::finished, thread, &QThread::quit);
|
||
connect(worker, &Black::GetProfileInfoScript::finished, worker, &QObject::deleteLater);
|
||
connect(thread, &QThread::finished, thread, &QObject::deleteLater);
|
||
} else {
|
||
thread->deleteLater();
|
||
return;
|
||
}
|
||
|
||
thread->start();
|
||
}
|
||
|
||
void AccountSettingsWindow::startGetCardInfo(const QString &appCode) {
|
||
if (appCode == "ozon") {
|
||
QThread *thread = new QThread(nullptr);
|
||
auto *worker = new Ozon::GetCardInfoScript(m_deviceId, appCode, "", nullptr);
|
||
worker->moveToThread(thread);
|
||
connect(thread, &QThread::started, worker, &Ozon::GetCardInfoScript::start);
|
||
connect(worker, &Ozon::GetCardInfoScript::finished, thread, &QThread::quit);
|
||
connect(worker, &Ozon::GetCardInfoScript::finished, worker, &QObject::deleteLater);
|
||
connect(thread, &QThread::finished, thread, &QObject::deleteLater);
|
||
thread->start();
|
||
} else if (appCode == "black") {
|
||
QThread *thread = new QThread(nullptr);
|
||
auto *worker = new Black::GetCardInfoScript(m_deviceId, appCode, nullptr);
|
||
worker->moveToThread(thread);
|
||
connect(thread, &QThread::started, worker, &Black::GetCardInfoScript::start);
|
||
connect(worker, &Black::GetCardInfoScript::finished, thread, &QThread::quit);
|
||
connect(worker, &Black::GetCardInfoScript::finished, worker, &QObject::deleteLater);
|
||
connect(thread, &QThread::finished, thread, &QObject::deleteLater);
|
||
thread->start();
|
||
}
|
||
}
|
||
|
||
void AccountSettingsWindow::startGetLastTransactions(const QString &appCode, int maxCount) {
|
||
if (appCode == "ozon") {
|
||
QThread *thread = new QThread(nullptr);
|
||
auto *worker = new Ozon::GetLastTransactionsScript(m_deviceId, appCode, maxCount);
|
||
worker->moveToThread(thread);
|
||
connect(thread, &QThread::started, worker, &Ozon::GetLastTransactionsScript::start);
|
||
connect(worker, &Ozon::GetLastTransactionsScript::finished, thread, &QThread::quit);
|
||
connect(worker, &Ozon::GetLastTransactionsScript::finished, worker, &QObject::deleteLater);
|
||
connect(thread, &QThread::finished, thread, &QObject::deleteLater);
|
||
thread->start();
|
||
} else if (appCode == "black") {
|
||
QThread *thread = new QThread(nullptr);
|
||
auto *worker = new Black::GetLastTransactionsScript(m_deviceId, appCode, nullptr);
|
||
worker->moveToThread(thread);
|
||
connect(thread, &QThread::started, worker, &Black::GetLastTransactionsScript::start);
|
||
connect(worker, &Black::GetLastTransactionsScript::finished, thread, &QThread::quit);
|
||
connect(worker, &Black::GetLastTransactionsScript::finished, worker, &QObject::deleteLater);
|
||
connect(thread, &QThread::finished, thread, &QObject::deleteLater);
|
||
thread->start();
|
||
}
|
||
}
|
||
|
||
void AccountSettingsWindow::sendAppStatus(const QString &deviceId, const QString &code, const QString &status) {
|
||
const BankProfileInfo app = BankProfileDAO::getApplication(deviceId, code);
|
||
if (app.bankProfileId.isEmpty()) {
|
||
qWarning() << "[AccountSettings] sendAppStatus: no bankProfileId for" << code;
|
||
return;
|
||
}
|
||
|
||
const bool enable = (status == "active");
|
||
auto *thread = new QThread;
|
||
auto *net = new NetworkService;
|
||
net->moveToThread(thread);
|
||
net->addExtra("bank_profile_id", app.bankProfileId);
|
||
net->addExtra("enable", enable);
|
||
connect(thread, &QThread::started, net, &NetworkService::toggleBankProfile);
|
||
connect(net, &NetworkService::finished, thread, &QThread::quit);
|
||
connect(net, &NetworkService::finished, net, &QObject::deleteLater);
|
||
connect(thread, &QThread::finished, thread, &QThread::deleteLater);
|
||
thread->start();
|
||
}
|
||
|
||
void AccountSettingsWindow::updateAccountData(const MaterialInfo &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"] = materialStatusToString(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::toggleMaterialStatus(const MaterialInfo &account, QTableWidget *tableWidget) {
|
||
const bool isActive = account.status == MaterialStatus::Active;
|
||
const QString newStatus = isActive ? "off" : "active";
|
||
|
||
if (!MaterialDAO::updateAccountById(account.id, newStatus, account.description, account.currency)) {
|
||
qWarning() << "[AccountSettings] Failed to update material status:" << account.id;
|
||
return;
|
||
}
|
||
|
||
// Отправляем на сервер PATCH /api/v1/profile/material/{id}/{true|false}
|
||
if (!account.materialId.isEmpty()) {
|
||
auto *thread = new QThread;
|
||
auto *net = new NetworkService;
|
||
net->moveToThread(thread);
|
||
net->addExtra("material_id", account.materialId);
|
||
net->addExtra("enable", !isActive);
|
||
connect(thread, &QThread::started, net, &NetworkService::toggleMaterial);
|
||
connect(net, &NetworkService::finished, thread, &QThread::quit);
|
||
connect(net, &NetworkService::finished, net, &QObject::deleteLater);
|
||
connect(thread, &QThread::finished, thread, &QThread::deleteLater);
|
||
thread->start();
|
||
}
|
||
|
||
// Если выключили материал — проверяем остались ли активные
|
||
if (isActive) {
|
||
const QList<MaterialInfo> materials = MaterialDAO::getAccounts(m_deviceId, m_applicationInfo.code);
|
||
bool hasActive = false;
|
||
for (const auto &m : materials) {
|
||
if (m.status == MaterialStatus::Active) { hasActive = true; break; }
|
||
}
|
||
if (!hasActive && m_applicationInfo.status == "active") {
|
||
BankProfileDAO::update(m_applicationInfo.id, m_applicationInfo.pinCode, m_applicationInfo.comment, "off");
|
||
m_applicationInfo.status = "off";
|
||
sendAppStatus(m_deviceId, m_applicationInfo.code, "off");
|
||
|
||
const QString status = QString("Статус: <span style='color:red;'>Неактивен</span>") +
|
||
QString(", пин-код: ") + (m_applicationInfo.pinCodeChecked
|
||
? "<span style='color:green;'>Проверен</span>"
|
||
: "<span style='color:red;'>Не проверен</span>");
|
||
m_statusLabel->setText(status);
|
||
|
||
QMessageBox::information(this, "Профиль выключен",
|
||
"Все карты выключены — банковский профиль автоматически деактивирован.");
|
||
}
|
||
}
|
||
|
||
reloadContent(tableWidget);
|
||
tableWidget->resizeColumnsToContents();
|
||
}
|
||
|
||
void AccountSettingsWindow::reloadContent(QTableWidget *tableWidget) {
|
||
QList<MaterialInfo> accounts = MaterialDAO::getAccounts(m_deviceId, m_applicationInfo.code);
|
||
|
||
tableWidget->clearContents();
|
||
tableWidget->setRowCount(accounts.length());
|
||
tableWidget->setColumnCount(8);
|
||
tableWidget->setHorizontalHeaderLabels({
|
||
"Время обновления",
|
||
"Номер",
|
||
"Сумма",
|
||
"Валюта",
|
||
"",
|
||
"Сервер",
|
||
"",
|
||
""
|
||
});
|
||
|
||
tableWidget->setWordWrap(true);
|
||
tableWidget->setTextElideMode(Qt::ElideNone);
|
||
tableWidget->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft | Qt::AlignVCenter);
|
||
tableWidget->horizontalHeader()->setSectionResizeMode(1, QHeaderView::Stretch);
|
||
|
||
|
||
for (int k = 0; k < accounts.size(); ++k) {
|
||
const MaterialInfo &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);
|
||
|
||
const QString displayNumber = account.cardNumber.isEmpty() ? account.description : account.cardNumber;
|
||
QTableWidgetItem *desc = new QTableWidgetItem(displayNumber);
|
||
desc->setTextAlignment(Qt::AlignLeft | Qt::AlignVCenter);
|
||
desc->setFlags(desc->flags() & ~Qt::ItemIsEditable);
|
||
tableWidget->setItem(k, 1, desc);
|
||
|
||
QTableWidgetItem *amount = new QTableWidgetItem(QString::number(account.amount));
|
||
amount->setTextAlignment(Qt::AlignLeft | Qt::AlignVCenter);
|
||
amount->setFlags(amount->flags() & ~Qt::ItemIsEditable);
|
||
tableWidget->setItem(k, 2, amount);
|
||
|
||
QTableWidgetItem *currency = new QTableWidgetItem(account.currency);
|
||
currency->setTextAlignment(Qt::AlignLeft | Qt::AlignVCenter);
|
||
currency->setFlags(currency->flags() & ~Qt::ItemIsEditable);
|
||
tableWidget->setItem(k, 3, currency);
|
||
|
||
// Кнопка вкл/выкл карты
|
||
const bool isActive = account.status == MaterialStatus::Active;
|
||
auto *toggleBtn = new QPushButton(isActive ? "Выкл" : "Вкл", tableWidget);
|
||
toggleBtn->setStyleSheet(isActive
|
||
? "background-color: orange; color: white;"
|
||
: "background-color: green; color: white;");
|
||
tableWidget->setCellWidget(k, 4, toggleBtn);
|
||
|
||
connect(toggleBtn, &QPushButton::clicked, this, [this, account, tableWidget]() {
|
||
toggleMaterialStatus(account, tableWidget);
|
||
});
|
||
|
||
auto *syncItem = new QTableWidgetItem(account.materialId.isEmpty() ? "Не синхр." : "Синхр.");
|
||
syncItem->setTextAlignment(Qt::AlignLeft | Qt::AlignVCenter);
|
||
syncItem->setForeground(account.materialId.isEmpty() ? QBrush(Qt::red) : QBrush(Qt::darkGreen));
|
||
syncItem->setFlags(syncItem->flags() & ~Qt::ItemIsEditable);
|
||
tableWidget->setItem(k, 5, syncItem);
|
||
|
||
auto *deleteBankAccountBtn = new QPushButton("Удалить", tableWidget);
|
||
deleteBankAccountBtn->setStyleSheet("background-color: red; color: white;");
|
||
tableWidget->setCellWidget(k, 6, deleteBankAccountBtn);
|
||
|
||
connect(deleteBankAccountBtn, &QPushButton::clicked, this, [this, tableWidget, account]() {
|
||
QMessageBox msgBox(this);
|
||
msgBox.setWindowTitle("Удалить аккаунт?");
|
||
msgBox.setText("Вы уверены, что хотите удалить аккаунт?");
|
||
QPushButton *deleteBtn = msgBox.addButton("Удалить", QMessageBox::AcceptRole);
|
||
QPushButton *cancelBtn = msgBox.addButton("Отмена", QMessageBox::RejectRole);
|
||
msgBox.setDefaultButton(cancelBtn);
|
||
msgBox.exec();
|
||
if (msgBox.clickedButton() == deleteBtn) {
|
||
if (MaterialDAO::deleteAccount(account.id)) {
|
||
reloadContent(tableWidget);
|
||
tableWidget->resizeColumnsToContents();
|
||
} else {
|
||
qWarning() << "Cant delete account" << account.id;
|
||
}
|
||
}
|
||
});
|
||
|
||
auto *transactionsBtn = new QPushButton("Транзакции", tableWidget);
|
||
transactionsBtn->setStyleSheet("background-color: #1565C0; color: white;");
|
||
tableWidget->setCellWidget(k, 7, transactionsBtn);
|
||
|
||
connect(transactionsBtn, &QPushButton::clicked, this, [this, account]() {
|
||
auto *txWindow = new TransactionWindow(account.id, this);
|
||
txWindow->show();
|
||
});
|
||
}
|
||
}
|