#include #include #include #include #include #include "BankProfileDAO.h" #include "DatabaseManager.h" #include "SettingsDAO.h" #include "db/BankProfileInfo.h" bool BankProfileDAO::upsertApplication(const BankProfileInfo &info) { QSqlQuery query(DatabaseManager::instance().database()); query.prepare(R"( INSERT INTO bank_profiles (device_id, pin_code, name, code, package, status, comment, install, pin_code_checked, bank_profile_id, full_name, phone) VALUES (:device_id, :pin_code, :name, :code, :package, :status, :comment, :install, :pin_code_checked, :bank_profile_id, :full_name, :phone) ON CONFLICT(device_id, code) DO UPDATE SET pin_code = CASE WHEN excluded.pin_code != '' THEN excluded.pin_code ELSE bank_profiles.pin_code END, name = excluded.name, package = CASE WHEN excluded.package != '' THEN excluded.package ELSE bank_profiles.package END, status = excluded.status, comment = excluded.comment, install = excluded.install, pin_code_checked = excluded.pin_code_checked, bank_profile_id = CASE WHEN excluded.bank_profile_id != '' THEN excluded.bank_profile_id ELSE bank_profiles.bank_profile_id END, full_name = CASE WHEN excluded.full_name != '' THEN excluded.full_name ELSE bank_profiles.full_name END, phone = CASE WHEN excluded.phone != '' THEN excluded.phone ELSE bank_profiles.phone END )"); query.bindValue(":device_id", info.deviceId); query.bindValue(":pin_code", info.pinCode); query.bindValue(":name", info.name); query.bindValue(":code", info.code); query.bindValue(":package", info.package); query.bindValue(":status", info.status); query.bindValue(":comment", info.comment); query.bindValue(":install", info.install ? "yes" : "no"); query.bindValue(":pin_code_checked", info.pinCodeChecked ? "yes" : "no"); query.bindValue(":bank_profile_id", info.bankProfileId); query.bindValue(":full_name", info.fullName); query.bindValue(":phone", QString(info.phone).remove(' ').remove(QChar(0x00A0))); if (!query.exec()) { qWarning() << "Ошибка при вставке/обновлении application:" << query.lastError().text(); return false; } return true; } bool BankProfileDAO::updatePinCode(const QString &appId, const QString &pinCode) { QSqlQuery query(DatabaseManager::instance().database()); query.prepare(R"( UPDATE bank_profiles SET pin_code = :pin_code WHERE id = :id )"); query.bindValue(":pin_code", pinCode); query.bindValue(":id", appId); if (!query.exec()) { qWarning() << "Ошибка при обновлении PIN-кода приложения:" << query.lastError().text(); return false; } return true; } bool BankProfileDAO::update( const int &appId, const QString &pinCode, const QString &comment, const QString &status ) { QSqlQuery query(DatabaseManager::instance().database()); query.prepare(R"( UPDATE bank_profiles SET pin_code = :pin_code, comment = :comment, status = :status WHERE id = :id )"); query.bindValue(":id", appId); query.bindValue(":comment", comment); query.bindValue(":pin_code", pinCode); query.bindValue(":status", status); if (!query.exec()) { qWarning() << "Ошибка при обновлении PIN-кода приложения:" << query.lastError().text(); return false; } return true; } bool BankProfileDAO::updatePinCodeStatus( const int &appId, const QString &pinCodeStatus, const QString &comment ) { QSqlQuery query(DatabaseManager::instance().database()); query.prepare(R"( UPDATE bank_profiles SET pin_code_checked = :pin_code_checked, comment = :comment WHERE id = :id )"); query.bindValue(":id", appId); query.bindValue(":comment", comment); query.bindValue(":pin_code_checked", pinCodeStatus); if (!query.exec()) { qWarning() << "Ошибка при обновлении PIN-кода приложения:" << query.lastError().text(); return false; } return true; } bool BankProfileDAO::updateComment(const int appId, const QString &comment) { QSqlQuery query(DatabaseManager::instance().database()); query.prepare("UPDATE bank_profiles SET comment = :comment WHERE id = :id"); query.bindValue(":comment", comment); query.bindValue(":id", appId); if (!query.exec()) { qWarning() << "Ошибка при обновлении комментария:" << query.lastError().text(); return false; } return true; } BankProfileInfo parseApplication(const QSqlQuery &query) { BankProfileInfo app; app.id = query.value("id").toInt(); app.deviceId = query.value("device_id").toString(); app.pinCode = query.value("pin_code").toString(); app.code = query.value("code").toString(); app.name = query.value("name").toString(); app.package = query.value("package").toString(); app.status = query.value("status").toString(); app.comment = query.value("comment").toString(); app.install = query.value("install").toString() == "yes"; app.pinCodeChecked = query.value("pin_code_checked").toString() == "yes"; app.phone = query.value("phone").toString().remove(' ').remove(QChar(0x00A0)); app.email = query.value("email").toString(); app.fullName = query.value("full_name").toString(); app.bankProfileId = query.value("bank_profile_id").toString(); app.currency = query.value("currency").toString(); app.amount = query.value("amount").toDouble(); app.appVersion = query.value("app_version").toString(); app.appVersionCheckedAt = query.value("app_version_checked_at").toDateTime(); return app; } BankProfileInfo BankProfileDAO::getApplication(const QString &deviceId, const QString &appCode) { QSqlQuery query(DatabaseManager::instance().database()); query.prepare(R"( SELECT id, device_id, pin_code, code, name, package, status, comment, install, pin_code_checked, phone, email, full_name, bank_profile_id, currency, amount, app_version, app_version_checked_at FROM bank_profiles WHERE device_id = :device_id AND code = :code LIMIT 1 )"); query.bindValue(":device_id", deviceId); query.bindValue(":code", appCode); if (!query.exec()) { qWarning() << "Ошибка при получении приложений по deviceId:" << query.lastError().text(); return {}; } while (query.next()) { return parseApplication(query); } return {}; } QList BankProfileDAO::getApplicationsByDeviceId(const QString &deviceId) { QSqlQuery query(DatabaseManager::instance().database()); QList list; query.prepare(R"( SELECT id, device_id, pin_code, code, name, package, status, comment, install, pin_code_checked, phone, email, full_name, bank_profile_id, currency, amount, app_version, app_version_checked_at FROM bank_profiles WHERE device_id = :device_id AND install = 'yes' )"); query.bindValue(":device_id", deviceId); if (!query.exec()) { qWarning() << "Ошибка при получении приложений по deviceId:" << query.lastError().text(); return {}; } while (query.next()) { list.append(parseApplication(query)); } return list; } QList BankProfileDAO::getAllApplicationsByDeviceId(const QString &deviceId) { QSqlQuery query(DatabaseManager::instance().database()); QList list; query.prepare(R"( SELECT id, device_id, pin_code, code, name, package, status, comment, install, pin_code_checked, phone, email, full_name, bank_profile_id, currency, amount, app_version, app_version_checked_at FROM bank_profiles WHERE device_id = :device_id )"); query.bindValue(":device_id", deviceId); if (!query.exec()) { qWarning() << "Ошибка при получении всех приложений по deviceId:" << query.lastError().text(); return {}; } while (query.next()) { list.append(parseApplication(query)); } return list; } bool BankProfileDAO::updateProfileInfo( const int &appId, const QString &fullName, const QString &phone, const QString &email ) { QSqlQuery query(DatabaseManager::instance().database()); query.prepare(R"( UPDATE bank_profiles SET full_name = :full_name, phone = :phone, email = :email WHERE id = :id )"); query.bindValue(":id", appId); query.bindValue(":full_name", fullName); query.bindValue(":phone", QString(phone).remove(' ').remove(QChar(0x00A0))); query.bindValue(":email", email); if (!query.exec()) { qWarning() << "Ошибка при обновлении профиля приложения:" << query.lastError().text(); return false; } return true; } bool BankProfileDAO::updateAmount(const int appId, const double amount) { QSqlQuery query(DatabaseManager::instance().database()); query.prepare("UPDATE bank_profiles SET amount = :amount WHERE id = :id"); query.bindValue(":amount", amount); query.bindValue(":id", appId); if (!query.exec()) { qWarning() << "Ошибка при обновлении amount в application:" << query.lastError().text(); return false; } return true; } bool BankProfileDAO::adjustAmount(const int appId, const double delta) { QSqlQuery query(DatabaseManager::instance().database()); query.prepare("UPDATE bank_profiles SET amount = amount - :delta WHERE id = :id"); query.bindValue(":delta", delta); query.bindValue(":id", appId); if (!query.exec()) { qWarning() << "[BankProfileDAO] adjustAmount failed:" << query.lastError().text(); return false; } return true; } bool BankProfileDAO::updateAppVersion(const int appId, const QString &appVersion) { QSqlQuery query(DatabaseManager::instance().database()); query.prepare(R"( UPDATE bank_profiles SET app_version = :app_version, app_version_checked_at = :checked_at WHERE id = :id )"); query.bindValue(":app_version", appVersion); query.bindValue(":checked_at", QDateTime::currentDateTimeUtc()); query.bindValue(":id", appId); if (!query.exec()) { qWarning() << "Ошибка при обновлении app_version:" << query.lastError().text(); return false; } return true; } bool BankProfileDAO::updateBankProfileId(const int appId, const QString &bankProfileId) { QSqlQuery query(DatabaseManager::instance().database()); query.prepare("UPDATE bank_profiles SET bank_profile_id = :bank_profile_id WHERE id = :id"); query.bindValue(":bank_profile_id", bankProfileId); query.bindValue(":id", appId); if (!query.exec()) { qWarning() << "Ошибка при обновлении bank_profile_id:" << query.lastError().text(); return false; } return true; } QList BankProfileDAO::findAllByBankProfileId(const QString &bankProfileId) { QList list; QSqlQuery query(DatabaseManager::instance().database()); query.prepare(R"( SELECT id, device_id, pin_code, code, name, package, status, comment, install, pin_code_checked, phone, email, full_name, bank_profile_id, currency, amount, app_version, app_version_checked_at FROM bank_profiles WHERE bank_profile_id = :bank_profile_id )"); query.bindValue(":bank_profile_id", bankProfileId); if (!query.exec()) { qWarning() << "Ошибка при поиске bank_profiles по bank_profile_id:" << query.lastError().text(); return list; } while (query.next()) { list.append(parseApplication(query)); } return list; } QStringList BankProfileDAO::getActiveBankProfileIds() { QStringList ids; QSqlQuery query(DatabaseManager::instance().database()); query.prepare(R"( SELECT bank_profile_id FROM bank_profiles WHERE status = 'active' AND bank_profile_id IS NOT NULL AND bank_profile_id != '' )"); if (!query.exec()) { qWarning() << "Ошибка при получении активных bank_profile_id:" << query.lastError().text(); return ids; } while (query.next()) { ids.append(query.value(0).toString()); } return ids; } bool BankProfileDAO::activateAppsForDevice(const QString &deviceId) { QSqlQuery query(DatabaseManager::instance().database()); query.prepare(R"( UPDATE bank_profiles SET status = 'active' WHERE device_id = :device_id AND install = 'yes' AND pin_code_checked = 'yes' )"); query.bindValue(":device_id", deviceId); if (!query.exec()) { qWarning() << "Ошибка при активации приложений:" << query.lastError().text(); return false; } return true; } bool BankProfileDAO::deactivateAppsForDevice(const QString &deviceId) { QSqlQuery query(DatabaseManager::instance().database()); query.prepare(R"( UPDATE bank_profiles SET status = 'off' WHERE device_id = :device_id AND install = 'yes' )"); query.bindValue(":device_id", deviceId); if (!query.exec()) { qWarning() << "Ошибка при деактивации приложений:" << query.lastError().text(); return false; } return true; } bool BankProfileDAO::checkInstalledApps(const QString &deviceId, const QSet &apps) { QSqlQuery query(DatabaseManager::instance().database()); const QSettings settings("config.ini", QSettings::IniFormat); QStringList banks = settings.value("apps/list", QStringList()).toStringList(); // Фильтруем банки по стране профиля (если страна задана) const QString profileCountry = SettingsDAO::get("country"); if (!profileCountry.isEmpty()) { QStringList filtered; for (const QString &raw : banks) { const QString b = raw.trimmed(); if (b.isEmpty()) continue; const QString bankCountry = settings.value(b + "/country").toString(); if (bankCountry.compare(profileCountry, Qt::CaseInsensitive) == 0) { filtered << b; } } banks = filtered; } // Сбросить install = 'no' для банков которых нет в текущем apps/list if (!banks.isEmpty()) { QStringList placeholders; for (int i = 0; i < banks.size(); ++i) placeholders << "?"; query.prepare(QString(R"( UPDATE bank_profiles SET install = 'no' WHERE device_id = ? AND code NOT IN (%1) )").arg(placeholders.join(","))); query.addBindValue(deviceId); for (const QString &bank : banks) query.addBindValue(bank); if (!query.exec()) { qWarning() << "Ошибка при сбросе install:" << query.lastError().text(); } } for (const QString &bank: banks) { QString package = settings.value(bank + "/android_package_name").toString(); QString name = settings.value(bank + "/name").toString(); const QString currency = settings.value(bank + "/currency").toString(); query.prepare(R"( INSERT INTO bank_profiles (device_id, name, code, package, status, install, pin_code_checked, currency) VALUES (:device_id, :name, :code, :package, :status, :install, :pin_code_checked, :currency) ON CONFLICT(device_id, code) DO UPDATE SET install = excluded.install, currency = CASE WHEN excluded.currency != '' THEN excluded.currency ELSE currency END )"); query.bindValue(":device_id", deviceId); query.bindValue(":code", bank); query.bindValue(":name", name); query.bindValue(":package", package); query.bindValue(":status", "off"); query.bindValue(":pin_code_checked", "no"); query.bindValue(":install", apps.contains(package) ? "yes" : "no"); query.bindValue(":currency", currency); if (!query.exec()) { qWarning() << "Ошибка при проверке приложений:" << query.lastError().text(); return false; } } return true; } bool BankProfileDAO::migrateDeviceId(const QString &oldDeviceId, const QString &newDeviceId) { QSqlQuery query(DatabaseManager::instance().database()); query.prepare("UPDATE bank_profiles SET device_id = :new_id WHERE device_id = :old_id"); query.bindValue(":new_id", newDeviceId); query.bindValue(":old_id", oldDeviceId); if (!query.exec()) { qWarning() << "[BankProfileDAO] migrateDeviceId failed:" << query.lastError().text(); return false; } qDebug() << "[BankProfileDAO] migrated" << query.numRowsAffected() << "profiles from" << oldDeviceId << "to" << newDeviceId; return true; } bool BankProfileDAO::deleteProfile(const QString &deviceId, const QString &appCode) { QSqlQuery query(DatabaseManager::instance().database()); query.prepare("DELETE FROM bank_profiles WHERE device_id = :device_id AND code = :code"); query.bindValue(":device_id", deviceId); query.bindValue(":code", appCode); if (!query.exec()) { qWarning() << "[BankProfileDAO] deleteProfile failed:" << query.lastError().text(); return false; } return true; }