1
0
forked from BRT/arc
arc/android/black/GetCardInfoScript.cpp
slava 8ed25698e8 Add GetLastTransactionsScript and PayByCardScript implementations for Black app
Implemented `GetLastTransactionsScript` for automated retrieval of transactions, handling home screen navigation, "Ver más" button detection, and transaction list parsing with database storage. Introduced `PayByCardScript` for automated card payments, covering recipient selection, amount input, payment confirmation, and transaction logging. Added XML assets and updates to support these workflows.
2026-03-12 18:42:38 +07:00

153 lines
5.6 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "GetCardInfoScript.h"
#include <QThread>
#include <QJsonDocument>
#include <QJsonObject>
#include "adb/AdbUtils.h"
#include "dao/AccountDAO.h"
#include "dao/ApplicationDAO.h"
#include "dao/DeviceDAO.h"
#include "net/NetworkService.h"
namespace Black {
GetCardInfoScript::GetCardInfoScript(
QString deviceId,
QString appCode,
QObject *parent
) : CommonScript(parent),
m_deviceId(std::move(deviceId)),
m_appCode(std::move(appCode)) {
}
GetCardInfoScript::~GetCardInfoScript() = default;
void GetCardInfoScript::doStart() {
const DeviceInfo device = DeviceDAO::getDeviceById(m_deviceId);
const ApplicationInfo app = ApplicationDAO::getApplication(m_deviceId, m_appCode);
if (device.id.isEmpty() || app.id == -1) {
m_error = "Device or app not found: " + m_deviceId + " " + m_appCode;
qCritical() << m_error;
emit finishedWithResult(m_error);
return;
}
// Читаем текущий экран
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
// Если не на домашнем экране — перезапускаем
if (!xmlScreenParser.isHomeScreen()) {
qDebug() << "[Black::GetCardInfo] Not on home screen, restarting app...";
if (!runAppAndGoToHomeScreen(device.id, app.package, app.pinCode,
device.screenWidth, device.screenHeight)) {
m_error = "Cannot reach home screen: " + m_deviceId + " " + m_appCode;
qWarning() << m_error;
AdbUtils::tryToKillApplication(m_deviceId, app.package);
emit finishedWithResult(m_error);
return;
}
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
}
// 1. Парсим баланс с домашнего экрана
const double balance = xmlScreenParser.parseBalanceFromHomeScreen();
qDebug() << "[Black::GetCardInfo] balance from home:" << balance;
ApplicationDAO::updateAmount(app.id, balance);
// 2. Нажимаем "Tu CVU" на домашнем экране
Node cvuButton = xmlScreenParser.findButtonNode("Tu CVU", false);
if (cvuButton.isEmpty()) {
m_error = "Cannot find Tu CVU button: " + m_deviceId;
qWarning() << m_error;
AdbUtils::tryToKillApplication(m_deviceId, app.package);
emit finishedWithResult(m_error);
return;
}
AdbUtils::makeTap(m_deviceId, cvuButton.x(), cvuButton.y());
QThread::msleep(2000);
// 3. Ждём экран CVU
bool cvuScreenFound = false;
for (int attempt = 0; attempt < 5; ++attempt) {
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
if (xmlScreenParser.isCVUScreen()) {
cvuScreenFound = true;
break;
}
QThread::msleep(1000);
}
if (!cvuScreenFound) {
m_error = "CVU screen not detected: " + m_deviceId;
qWarning() << m_error;
AdbUtils::tryToKillApplication(m_deviceId, app.package);
emit finishedWithResult(m_error);
return;
}
// 4. Парсим номер CVU
const QString cvuNumber = xmlScreenParser.parseCVUNumber();
qDebug() << "[Black::GetCardInfo] CVU number:" << cvuNumber;
if (cvuNumber.isEmpty()) {
m_error = "Cannot parse CVU number: " + m_deviceId;
qWarning() << m_error;
AdbUtils::tryToKillApplication(m_deviceId, app.package);
emit finishedWithResult(m_error);
return;
}
// 5. Сохраняем аккаунт в БД (lastNumbers = последние 4 цифры CVU)
const QString lastNumbers = cvuNumber.right(4);
AccountInfo account;
account.deviceId = m_deviceId;
account.appCode = m_appCode;
account.lastNumbers = lastNumbers;
account.cardNumber = cvuNumber;
account.amount = balance;
account.currency = "USD";
account.description = "CVU";
account.status = AccountStatus::Active;
account.updateTime = QDateTime::currentDateTimeUtc();
if (!AccountDAO::upsertAccount(account)) {
qWarning() << "[Black::GetCardInfo] Failed to upsert account";
}
// 6. Отправляем материал на сервер (если ещё нет material_id)
const AccountInfo savedAccount = AccountDAO::findAppAccount(m_deviceId, m_appCode, lastNumbers);
const ApplicationInfo updatedApp = ApplicationDAO::getApplication(m_deviceId, m_appCode);
if (savedAccount.id != -1 && !updatedApp.bankProfileId.isEmpty()) {
if (savedAccount.materialId.isEmpty()) {
NetworkService ns;
ns.setDeviceId(m_deviceId);
QJsonObject materialBody;
materialBody["bank_profile_id"] = updatedApp.bankProfileId;
materialBody["card_number"] = savedAccount.cardNumber;
materialBody["name"] = updatedApp.fullName;
ns.setPayload(QJsonDocument(materialBody).toJson());
ns.addExtra("account_id", savedAccount.id);
ns.postMaterial();
qDebug() << "[Black::GetCardInfo] postMaterial done for CVU" << lastNumbers;
} else {
qDebug() << "[Black::GetCardInfo] material already exists for CVU" << lastNumbers << ", skipping";
}
} else {
qWarning() << "[Black::GetCardInfo] bankProfileId empty or account not found, skipping material";
}
qDebug() << "[Black::GetCardInfo] Done. CVU:" << cvuNumber << "balance:" << balance;
AdbUtils::tryToKillApplication(m_deviceId, app.package);
emit finishedWithResult(m_error);
}
} // namespace Black