#include "AccountSettingsWindow.h" #include #include #include #include #include #include #include #include #include #include #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" ? "Активен" : "Неактивен") + QString(", пин-код: ") + (m_applicationInfo.pinCodeChecked ? "Проверен" : "Не проверен"); 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 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 ? "Активен" : "Неактивен") + QString(", пин-код: ") + (m_applicationInfo.pinCodeChecked ? "Проверен" : "Не проверен"); 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 = "Данные не получены"; } 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() ? "● Не синхронизирован" : "● Синхронизирован"; 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 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("Статус: Неактивен") + QString(", пин-код: ") + (m_applicationInfo.pinCodeChecked ? "Проверен" : "Не проверен"); m_statusLabel->setText(status); QMessageBox::information(this, "Профиль выключен", "Все карты выключены — банковский профиль автоматически деактивирован."); } } reloadContent(tableWidget); tableWidget->resizeColumnsToContents(); } void AccountSettingsWindow::reloadContent(QTableWidget *tableWidget) { QList 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(); }); } }