Remove CommonBirbankScript and its derived classes from the codebase
Deleted `CommonBirbankScript` and its associated derived classes (`GetLastDaysHistoryBirbankScript`, `LoginAndCheckAccountsBirbankScript`, `PayByCardBirbankScript`). Removed dependencies on these scripts, including XML parsing, account handling, and transaction workflows related to the Birbank app.
@ -92,6 +92,10 @@ add_executable(ARCDesktopProject WIN32
|
|||||||
${ANDROID_SOURCES}
|
${ANDROID_SOURCES}
|
||||||
views/bank/BankSettingsWindow.cpp
|
views/bank/BankSettingsWindow.cpp
|
||||||
views/bank/BankSettingsWindow.h
|
views/bank/BankSettingsWindow.h
|
||||||
|
views/log/FileLogWindow.cpp
|
||||||
|
views/log/FileLogWindow.h
|
||||||
|
database/dao/GeneralLogDAO.cpp
|
||||||
|
database/dao/GeneralLogDAO.h
|
||||||
)
|
)
|
||||||
elseif (APPLE)
|
elseif (APPLE)
|
||||||
add_executable(ARCDesktopProject
|
add_executable(ARCDesktopProject
|
||||||
@ -103,6 +107,10 @@ elseif (APPLE)
|
|||||||
${ANDROID_SOURCES}
|
${ANDROID_SOURCES}
|
||||||
views/bank/BankSettingsWindow.cpp
|
views/bank/BankSettingsWindow.cpp
|
||||||
views/bank/BankSettingsWindow.h
|
views/bank/BankSettingsWindow.h
|
||||||
|
views/log/FileLogWindow.cpp
|
||||||
|
views/log/FileLogWindow.h
|
||||||
|
database/dao/GeneralLogDAO.cpp
|
||||||
|
database/dao/GeneralLogDAO.h
|
||||||
)
|
)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
|
|||||||
@ -4,6 +4,7 @@
|
|||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
|
#include <QThread>
|
||||||
|
|
||||||
AdbUtils::AdbUtils(QObject *parent) : QObject(parent) {
|
AdbUtils::AdbUtils(QObject *parent) : QObject(parent) {
|
||||||
}
|
}
|
||||||
@ -198,9 +199,18 @@ QString AdbUtils::getScreenDumpAsXml(const QString &deviceId, int idx, bool scre
|
|||||||
const QString adb = adbPath();
|
const QString adb = adbPath();
|
||||||
QString output;
|
QString output;
|
||||||
|
|
||||||
// 1. Dump UI hierarchy
|
// 1. Dump UI hierarchy (retry up to 3 times — uiautomator may be killed by Android)
|
||||||
if (!startProcess(adb, {"-s", deviceId, "shell", "uiautomator", "dump", "/sdcard/uidump.xml"})) {
|
bool dumpOk = false;
|
||||||
qWarning() << "Failed to dump UI hierarchy.";
|
for (int attempt = 0; attempt < 3; ++attempt) {
|
||||||
|
if (startProcess(adb, {"-s", deviceId, "shell", "uiautomator", "dump", "/sdcard/uidump.xml"})) {
|
||||||
|
dumpOk = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
qWarning() << "[AdbUtils] uiautomator dump failed, attempt" << (attempt + 1) << "of 3";
|
||||||
|
QThread::msleep(1000);
|
||||||
|
}
|
||||||
|
if (!dumpOk) {
|
||||||
|
qWarning() << "Failed to dump UI hierarchy after 3 attempts.";
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
// 2. Optionally pull and save the XML file
|
// 2. Optionally pull and save the XML file
|
||||||
|
|||||||
@ -1,217 +0,0 @@
|
|||||||
#include "CommonBirbankScript.h"
|
|
||||||
|
|
||||||
#include <QJsonArray>
|
|
||||||
#include <QJsonObject>
|
|
||||||
#include <QRandomGenerator>
|
|
||||||
#include <QThread>
|
|
||||||
|
|
||||||
#include "adb/AdbUtils.h"
|
|
||||||
#include "net/NetworkService.h"
|
|
||||||
#include "time/DateUtils.h"
|
|
||||||
|
|
||||||
CommonBirbankScript::CommonBirbankScript(QObject *parent)
|
|
||||||
: QObject(parent) {
|
|
||||||
}
|
|
||||||
|
|
||||||
CommonBirbankScript::~CommonBirbankScript() = default;
|
|
||||||
|
|
||||||
void CommonBirbankScript::start() {
|
|
||||||
doStart();
|
|
||||||
emit finished();
|
|
||||||
}
|
|
||||||
|
|
||||||
Node CommonBirbankScript::swipeToButton(
|
|
||||||
const QString &deviceId,
|
|
||||||
const QString &text, int &counter, const int width, const int height
|
|
||||||
) {
|
|
||||||
for (int i = 0; i < 10; ++i) {
|
|
||||||
if (Node button = xmlScreenParser.findButtonNode(text, true); button.x() > 0 && button.y() > 0) {
|
|
||||||
return button;
|
|
||||||
}
|
|
||||||
const int x = width / 2;
|
|
||||||
const int offset = height / 4;
|
|
||||||
AdbUtils::makeSwipe(deviceId, x, height - offset, x, offset);
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++counter));
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CommonBirbankScript::runAppAndGoToHomeScreen(
|
|
||||||
const QString &deviceId,
|
|
||||||
const QString &packageName,
|
|
||||||
const QString &pinCode,
|
|
||||||
const int width,
|
|
||||||
const int height
|
|
||||||
) {
|
|
||||||
// Запустить устройство
|
|
||||||
if (const QString pid = AdbUtils::tryToGetRunningAppPid(deviceId, packageName); !pid.isEmpty()) {
|
|
||||||
qDebug() << "Process already running, pid: " << pid;
|
|
||||||
AdbUtils::getScreenDumpAsXml(deviceId, 1000);
|
|
||||||
AdbUtils::tryToKillApplication(deviceId, packageName);
|
|
||||||
}
|
|
||||||
if (!AdbUtils::tryToStartApplication(deviceId, packageName)) {
|
|
||||||
AdbUtils::takeScreenshot(deviceId, "run_app_error");
|
|
||||||
qWarning() << "Process has not started";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Даем минимальное время на запуск
|
|
||||||
QThread::msleep(2500);
|
|
||||||
int counter = 0;
|
|
||||||
bool findAndInputPincode = false;
|
|
||||||
|
|
||||||
while (true) {
|
|
||||||
counter++;
|
|
||||||
|
|
||||||
// Если более 10 раз мы пытаемся перейти на домашнюю
|
|
||||||
if (counter > 10) {
|
|
||||||
AdbUtils::takeScreenshot(deviceId, "too_many_attempts");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
|
|
||||||
|
|
||||||
Node closeBannerNode = xmlScreenParser.findButtonNode("Maraqlı deyil", false);
|
|
||||||
if (!closeBannerNode.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(deviceId, closeBannerNode.x(), closeBannerNode.y());
|
|
||||||
QThread::msleep(1000);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (xmlScreenParser.isHomeScreen()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Проверяем, что это экран ввода пин-кода
|
|
||||||
if (!findAndInputPincode) {
|
|
||||||
if (const QList<Node> pincode = xmlScreenParser.findPinCodeNodes(pinCode); pincode.size() == 4) {
|
|
||||||
for (const Node &node: pincode) {
|
|
||||||
AdbUtils::makeTap(deviceId, node.x(), node.y());
|
|
||||||
QThread::msleep(QRandomGenerator::global()->bounded(200, 901));
|
|
||||||
}
|
|
||||||
// После ввода пин-код нужно сделать задержку, пока подгрузка идет, чтобы снова не спарсить
|
|
||||||
findAndInputPincode = true;
|
|
||||||
QThread::msleep(3000);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QThread::msleep(1000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CommonBirbankScript::goToAllProducts(
|
|
||||||
const QString &deviceId,
|
|
||||||
const int width,
|
|
||||||
const int height
|
|
||||||
) {
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, m_counter));
|
|
||||||
Node closeBannerNode = xmlScreenParser.findButtonNode("Maraqlı deyil", false);
|
|
||||||
if (!closeBannerNode.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(deviceId, closeBannerNode.x(), closeBannerNode.y());
|
|
||||||
QThread::msleep(500);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (xmlScreenParser.isHomeScreen()) {
|
|
||||||
Node allMyAccountBtn = xmlScreenParser.findButtonNode("All My Accounts", false);
|
|
||||||
if (!allMyAccountBtn.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(deviceId, allMyAccountBtn.x(), allMyAccountBtn.y());
|
|
||||||
QThread::msleep(500);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CommonBirbankScript::postAccountsData(const QList<AccountInfo> &accounts) {
|
|
||||||
if (accounts.isEmpty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto *thread = new QThread;
|
|
||||||
auto *worker = new NetworkService;
|
|
||||||
|
|
||||||
QJsonArray list;
|
|
||||||
for (const AccountInfo &account: accounts) {
|
|
||||||
QJsonObject obj;
|
|
||||||
obj["appName"] = account.appCode;
|
|
||||||
obj["lastNumbers"] = account.lastNumbers;
|
|
||||||
obj["amount"] = account.amount;
|
|
||||||
obj["currency"] = account.currency;
|
|
||||||
obj["description"] = account.description;
|
|
||||||
obj["status"] = accountStatusToString(account.status);
|
|
||||||
|
|
||||||
list.append(obj);
|
|
||||||
}
|
|
||||||
// FIXME доставить десктоп ид из настроеек
|
|
||||||
worker->setDeviceId(accounts.first().deviceId);
|
|
||||||
worker->setPayload(QJsonDocument(list).toJson());
|
|
||||||
worker->moveToThread(thread);
|
|
||||||
connect(thread, &QThread::started, worker, &NetworkService::postAccountsData);
|
|
||||||
connect(worker, &NetworkService::finished, thread, &QThread::quit);
|
|
||||||
connect(worker, &NetworkService::finished, worker, &QObject::deleteLater);
|
|
||||||
connect(thread, &QThread::finished, thread, &QThread::deleteLater);
|
|
||||||
thread->start();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CommonBirbankScript::postNewTransactionData(const AccountInfo &account, const TransactionInfo &transaction) {
|
|
||||||
auto *thread = new QThread;
|
|
||||||
auto *worker = new NetworkService;
|
|
||||||
|
|
||||||
QJsonObject obj;
|
|
||||||
obj["id"] = transaction.id;
|
|
||||||
obj["amount"] = transaction.amount;
|
|
||||||
obj["name"] = transaction.name;
|
|
||||||
obj["fee"] = transaction.fee;
|
|
||||||
obj["status"] = transactionStatusToString(transaction.status);
|
|
||||||
obj["type"] = transactionTypeToString(transaction.type);
|
|
||||||
obj["phone"] = transaction.phone;
|
|
||||||
obj["description"] = transaction.description + " | " + transaction.bankTime;
|
|
||||||
obj["updatedDescription"] = transaction.updatedDescription;
|
|
||||||
obj["bankName"] = transaction.bankName;
|
|
||||||
obj["bankTime"] = DateUtils::toUtcString(transaction.completeTime);
|
|
||||||
obj["bankTransactionId"] = transaction.bankTrExternalId;
|
|
||||||
|
|
||||||
// FIXME доставить десктоп ид из настроеек
|
|
||||||
worker->setDeviceId(account.deviceId);
|
|
||||||
worker->addExtra("lastNumbers", account.lastNumbers);
|
|
||||||
worker->addExtra("transactionId", transaction.id);
|
|
||||||
worker->setPayload(QJsonDocument(obj).toJson());
|
|
||||||
worker->moveToThread(thread);
|
|
||||||
connect(thread, &QThread::started, worker, &NetworkService::insertTransactionData);
|
|
||||||
connect(worker, &NetworkService::finished, thread, &QThread::quit);
|
|
||||||
connect(worker, &NetworkService::finished, worker, &QObject::deleteLater);
|
|
||||||
connect(thread, &QThread::finished, thread, &QThread::deleteLater);
|
|
||||||
thread->start();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CommonBirbankScript::updateTransactionData(
|
|
||||||
const AccountInfo &account,
|
|
||||||
const int transactionId,
|
|
||||||
const TransactionStatus status,
|
|
||||||
const QString &oldDesc,
|
|
||||||
const QString &newDesc
|
|
||||||
) {
|
|
||||||
auto *thread = new QThread;
|
|
||||||
auto *worker = new NetworkService;
|
|
||||||
|
|
||||||
QJsonObject obj;
|
|
||||||
obj["id"] = transactionId;
|
|
||||||
obj["status"] = transactionStatusToString(status);
|
|
||||||
obj["description"] = newDesc;
|
|
||||||
obj["updatedDescription"] = oldDesc;
|
|
||||||
|
|
||||||
// FIXME доставить десктоп ид из настроеек
|
|
||||||
worker->setDeviceId(account.deviceId);
|
|
||||||
worker->addExtra("lastNumbers", account.lastNumbers);
|
|
||||||
worker->setPayload(QJsonDocument(obj).toJson());
|
|
||||||
worker->moveToThread(thread);
|
|
||||||
connect(thread, &QThread::started, worker, &NetworkService::updateTransactionData);
|
|
||||||
connect(worker, &NetworkService::finished, thread, &QThread::quit);
|
|
||||||
connect(worker, &NetworkService::finished, worker, &QObject::deleteLater);
|
|
||||||
connect(thread, &QThread::finished, thread, &QThread::deleteLater);
|
|
||||||
thread->start();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CommonBirbankScript::stop() {
|
|
||||||
m_running = false;
|
|
||||||
}
|
|
||||||
@ -1,68 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <QObject>
|
|
||||||
#include "ScreenXmlBirbankParser.h"
|
|
||||||
#include "android/xml/Node.h"
|
|
||||||
#include "db/AccountInfo.h"
|
|
||||||
#include "db/TransactionInfo.h"
|
|
||||||
|
|
||||||
class CommonBirbankScript : public QObject {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit CommonBirbankScript(QObject *parent = nullptr);
|
|
||||||
|
|
||||||
~CommonBirbankScript() override;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual void doStart() = 0;
|
|
||||||
|
|
||||||
bool goToAllProducts(
|
|
||||||
const QString &deviceId,
|
|
||||||
int width,
|
|
||||||
int height
|
|
||||||
);
|
|
||||||
|
|
||||||
void postAccountsData(const QList<AccountInfo> &accounts);
|
|
||||||
|
|
||||||
void postNewTransactionData(const AccountInfo &account, const TransactionInfo &transaction);
|
|
||||||
|
|
||||||
void updateTransactionData(
|
|
||||||
const AccountInfo &account,
|
|
||||||
int transactionId,
|
|
||||||
TransactionStatus status,
|
|
||||||
const QString &oldDesc,
|
|
||||||
const QString &newDesc
|
|
||||||
);
|
|
||||||
|
|
||||||
Node swipeToButton(
|
|
||||||
const QString &deviceId,
|
|
||||||
const QString &text,
|
|
||||||
int &counter, int width, int height
|
|
||||||
);
|
|
||||||
|
|
||||||
bool runAppAndGoToHomeScreen(
|
|
||||||
const QString &deviceId,
|
|
||||||
const QString &packageName,
|
|
||||||
const QString &pinCode,
|
|
||||||
int width,
|
|
||||||
int height
|
|
||||||
);
|
|
||||||
|
|
||||||
bool m_running = true;
|
|
||||||
ScreenXmlBirbankParser xmlScreenParser;
|
|
||||||
int m_counter = 0;
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void finished();
|
|
||||||
|
|
||||||
void finishedWithResult(const QString &result);
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
virtual void start() final;
|
|
||||||
|
|
||||||
virtual void stop() final;
|
|
||||||
|
|
||||||
private:
|
|
||||||
Q_DISABLE_COPY(CommonBirbankScript);
|
|
||||||
};
|
|
||||||
@ -1,164 +0,0 @@
|
|||||||
#include "GetLastDaysHistoryBirbankScript.h"
|
|
||||||
|
|
||||||
#include <QJsonObject>
|
|
||||||
#include <QRandomGenerator>
|
|
||||||
#include <QThread>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
#include "DatabaseManager.h"
|
|
||||||
#include "adb/AdbUtils.h"
|
|
||||||
#include "dao/AccountDAO.h"
|
|
||||||
#include "dao/ApplicationDAO.h"
|
|
||||||
#include "dao/DeviceDAO.h"
|
|
||||||
#include "dao/TransactionDAO.h"
|
|
||||||
#include "db/DeviceInfo.h"
|
|
||||||
#include "net/NetworkService.h"
|
|
||||||
#include "time/DateUtils.h"
|
|
||||||
|
|
||||||
GetLastDaysHistoryBirbankScript::GetLastDaysHistoryBirbankScript(
|
|
||||||
AccountInfo account,
|
|
||||||
QObject *parent
|
|
||||||
) : CommonBirbankScript(parent),
|
|
||||||
m_account(std::move(account)) {
|
|
||||||
}
|
|
||||||
|
|
||||||
GetLastDaysHistoryBirbankScript::~GetLastDaysHistoryBirbankScript() = default;
|
|
||||||
|
|
||||||
bool GetLastDaysHistoryBirbankScript::saveAndPostNewTransactionData(
|
|
||||||
const AccountInfo &account,
|
|
||||||
const TransactionInfo &transaction,
|
|
||||||
const TransactionStatus &status
|
|
||||||
) {
|
|
||||||
TransactionInfo tr;
|
|
||||||
tr.accountId = account.id;
|
|
||||||
tr.description = transaction.description;
|
|
||||||
tr.bankTime = transaction.bankTime;
|
|
||||||
tr.bankName = transaction.bankName;
|
|
||||||
tr.amount = transaction.amount;
|
|
||||||
tr.phone = transaction.phone;
|
|
||||||
tr.updateTime = DateUtils::getUtcNow();
|
|
||||||
tr.fee = transaction.fee;
|
|
||||||
tr.name = transaction.name;
|
|
||||||
tr.bankTrExternalId = transaction.bankTrExternalId;
|
|
||||||
tr.status = status;
|
|
||||||
tr.type = TransactionType::Card;
|
|
||||||
tr.completeTime = transaction.completeTime;
|
|
||||||
tr.id = TransactionDAO::insertTransaction(tr);
|
|
||||||
|
|
||||||
if (tr.id == -1) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
postNewTransactionData(account, tr);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GetLastDaysHistoryBirbankScript::updateAndPostTransactionData(
|
|
||||||
const AccountInfo &account,
|
|
||||||
const int transactionId,
|
|
||||||
const TransactionStatus status,
|
|
||||||
const QString &oldDesc,
|
|
||||||
const QString &newDesc
|
|
||||||
) {
|
|
||||||
if (TransactionDAO::updateTransaction(transactionId, status, oldDesc, newDesc)) {
|
|
||||||
updateTransactionData(account, transactionId, status, oldDesc, newDesc);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GetLastDaysHistoryBirbankScript::doStart() {
|
|
||||||
// берем все транзакции из БД
|
|
||||||
const DeviceInfo device = DeviceDAO::getDeviceById(m_account.deviceId);
|
|
||||||
const ApplicationInfo app = ApplicationDAO::getApplication(m_account.deviceId, m_account.appCode);
|
|
||||||
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter));
|
|
||||||
if (!xmlScreenParser.isHomeScreen()) {
|
|
||||||
if (!runAppAndGoToHomeScreen(device.id, app.package, app.pinCode, device.screenWidth, device.screenHeight)) {
|
|
||||||
m_error = "Не смогли дойти до домашней страницы";
|
|
||||||
qCritical() << m_error;
|
|
||||||
emit finishedWithResult(m_error);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter));
|
|
||||||
|
|
||||||
Node closeBannerNode = xmlScreenParser.findButtonNode("Maraqlı deyil", false);
|
|
||||||
if (!closeBannerNode.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(device.id, closeBannerNode.x(), closeBannerNode.y());
|
|
||||||
QThread::msleep(1000);
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (xmlScreenParser.isHomeScreen()) {
|
|
||||||
// QList<TransactionInfo> localTransactions = TransactionDAO::getTransactionsWithinHours(m_account.id, 48);
|
|
||||||
|
|
||||||
QList<AccountInfo> oldAccounts = AccountDAO::getAccounts(m_account.deviceId, m_account.appCode);
|
|
||||||
QMap<QString, AccountInfo> accountMap;
|
|
||||||
for (AccountInfo &oldAccount: oldAccounts) {
|
|
||||||
if (oldAccount.status == AccountStatus::Active) {
|
|
||||||
accountMap.insert(oldAccount.lastNumbers, oldAccount);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
QList<AccountInfo> accounts = xmlScreenParser.parseAccountsInfo();
|
|
||||||
for (auto account: accounts) {
|
|
||||||
if (accountMap.contains(account.lastNumbers)) {
|
|
||||||
account.deviceId = m_account.deviceId;
|
|
||||||
account.appCode = m_account.appCode;
|
|
||||||
account.currency = accountMap[account.lastNumbers].currency;
|
|
||||||
account.description = accountMap[account.lastNumbers].description;
|
|
||||||
account.status = AccountStatus::Active;
|
|
||||||
if (!AccountDAO::upsertAccount(account)) {
|
|
||||||
m_error = "Not updated: " + account.lastNumbers;
|
|
||||||
qCritical() << m_error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<AccountInfo> savedAccounts = AccountDAO::getAccounts(m_account.deviceId, m_account.appCode);
|
|
||||||
postAccountsData(savedAccounts);
|
|
||||||
|
|
||||||
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter));
|
|
||||||
Node cardText = xmlScreenParser.findTextNode(m_account.lastNumbers);
|
|
||||||
if (!cardText.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(device.id, cardText.x(), cardText.y());
|
|
||||||
QThread::msleep(2000);
|
|
||||||
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter));
|
|
||||||
Node cardTitleText = xmlScreenParser.findTextNode(m_account.lastNumbers);
|
|
||||||
Node cardHistory = xmlScreenParser.findTextNode("История платежей");
|
|
||||||
if (!cardTitleText.isEmpty() && !cardHistory.isEmpty()) {
|
|
||||||
QList<TransactionInfo> transactions = xmlScreenParser.parsePositiveTransactions();
|
|
||||||
QList<TransactionInfo> savedTransactions = TransactionDAO::getTransactionsWithinHours(m_account.id, 48);
|
|
||||||
for (TransactionInfo &transaction: transactions) {
|
|
||||||
bool isSaved = false;
|
|
||||||
for (TransactionInfo &savedTransaction: savedTransactions) {
|
|
||||||
if (savedTransaction.amount == transaction.amount
|
|
||||||
&& savedTransaction.bankTime == transaction.bankTime) {
|
|
||||||
isSaved = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!isSaved) {
|
|
||||||
if (!saveAndPostNewTransactionData(m_account, transaction, TransactionStatus::Complete)) {
|
|
||||||
qDebug() << "--- saveAndPostNewTransactionData failed";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
m_error = "Card page not found: " + m_account.deviceId + " " + m_account.lastNumbers;
|
|
||||||
qWarning() << m_error;
|
|
||||||
emit finishedWithResult(m_error);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
m_error = "Card not found: " + m_account.deviceId + " " + m_account.lastNumbers;
|
|
||||||
qWarning() << m_error;
|
|
||||||
emit finishedWithResult(m_error);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
AdbUtils::goBack(m_account.deviceId);
|
|
||||||
emit finishedWithResult(m_error);
|
|
||||||
}
|
|
||||||
@ -1,35 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include "CommonBirbankScript.h"
|
|
||||||
|
|
||||||
class GetLastDaysHistoryBirbankScript final : public CommonBirbankScript {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
~GetLastDaysHistoryBirbankScript() override;
|
|
||||||
|
|
||||||
explicit GetLastDaysHistoryBirbankScript(
|
|
||||||
AccountInfo account,
|
|
||||||
QObject *parent = nullptr
|
|
||||||
);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void doStart() override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
const AccountInfo m_account;
|
|
||||||
QString m_error;
|
|
||||||
|
|
||||||
bool saveAndPostNewTransactionData(
|
|
||||||
const AccountInfo &account,
|
|
||||||
const TransactionInfo &transaction,
|
|
||||||
const TransactionStatus &status
|
|
||||||
);
|
|
||||||
|
|
||||||
bool updateAndPostTransactionData(
|
|
||||||
const AccountInfo &account,
|
|
||||||
int transactionId,
|
|
||||||
TransactionStatus status,
|
|
||||||
const QString &oldDesc,
|
|
||||||
const QString &newDesc
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@ -1,161 +0,0 @@
|
|||||||
#include "LoginAndCheckAccountsBirbankScript.h"
|
|
||||||
|
|
||||||
#include <QThread>
|
|
||||||
|
|
||||||
#include "adb/AdbUtils.h"
|
|
||||||
#include "dao/AccountDAO.h"
|
|
||||||
#include "dao/ApplicationDAO.h"
|
|
||||||
#include "dao/DeviceDAO.h"
|
|
||||||
#include "dao/TransactionDAO.h"
|
|
||||||
#include "time/DateUtils.h"
|
|
||||||
|
|
||||||
LoginAndCheckAccountsBirbankScript::LoginAndCheckAccountsBirbankScript(
|
|
||||||
QString deviceId,
|
|
||||||
QString appCode,
|
|
||||||
QObject *parent
|
|
||||||
) : CommonBirbankScript(parent),
|
|
||||||
m_deviceId(std::move(deviceId)), m_appCode(std::move(appCode)) {
|
|
||||||
}
|
|
||||||
|
|
||||||
LoginAndCheckAccountsBirbankScript::~LoginAndCheckAccountsBirbankScript() = default;
|
|
||||||
|
|
||||||
|
|
||||||
void LoginAndCheckAccountsBirbankScript::doStart() {
|
|
||||||
const DeviceInfo device = DeviceDAO::getDeviceById(m_deviceId);
|
|
||||||
const ApplicationInfo app = ApplicationDAO::getApplication(m_deviceId, m_appCode);
|
|
||||||
|
|
||||||
|
|
||||||
if (true) {
|
|
||||||
// xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
|
|
||||||
// if (!xmlScreenParser.isHomeScreen()) {
|
|
||||||
// if (!runAppAndGoToHomeScreen(device.id, app.package, app.pinCode, device.screenWidth, device.screenHeight)) {
|
|
||||||
// m_error = "Не смогли дойти до домашней страницы";
|
|
||||||
// qCritical() << m_error;
|
|
||||||
// emit finishedWithResult(m_error);
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
|
|
||||||
|
|
||||||
Node closeBannerNode = xmlScreenParser.findButtonNode("Maraqlı deyil", false);
|
|
||||||
if (!closeBannerNode.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(m_deviceId, closeBannerNode.x(), closeBannerNode.y());
|
|
||||||
QThread::msleep(1000);
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (xmlScreenParser.isHomeScreen()) {
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
|
|
||||||
Node cardText = xmlScreenParser.findTextNode("2480");
|
|
||||||
if (!cardText.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(m_deviceId, cardText.x(), cardText.y());
|
|
||||||
QThread::msleep(2000);
|
|
||||||
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
|
|
||||||
Node payBtn = xmlScreenParser.findTextNode("Перевести");
|
|
||||||
if (!payBtn.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(m_deviceId, payBtn.x(), payBtn.y());
|
|
||||||
QThread::msleep(1000);
|
|
||||||
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
|
|
||||||
Node payByCardBtn = xmlScreenParser.findTextNode("На карту любого банка");
|
|
||||||
if (!payByCardBtn.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(m_deviceId, payByCardBtn.x(), payByCardBtn.y());
|
|
||||||
QThread::msleep(1000);
|
|
||||||
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
|
|
||||||
Node cardEditText = xmlScreenParser.findEditText("Номер карты");
|
|
||||||
Node amountEditText = xmlScreenParser.findEditText("Сумма");
|
|
||||||
if (!cardEditText.isEmpty() && !amountEditText.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(m_deviceId, cardEditText.x(), cardEditText.y());
|
|
||||||
QThread::msleep(200);
|
|
||||||
AdbUtils::inputText(m_deviceId, "1111222233334444");
|
|
||||||
|
|
||||||
AdbUtils::hideKeyboard(m_deviceId);
|
|
||||||
|
|
||||||
AdbUtils::makeTap(m_deviceId, amountEditText.x(), amountEditText.y());
|
|
||||||
QThread::msleep(200);
|
|
||||||
AdbUtils::inputText(m_deviceId, "10");
|
|
||||||
|
|
||||||
AdbUtils::hideKeyboard(m_deviceId);
|
|
||||||
|
|
||||||
|
|
||||||
// дальше оплата, но хз как
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
m_error = "Pay by card button not found: " + m_deviceId + " " + m_appCode;
|
|
||||||
qWarning() << m_error;
|
|
||||||
emit finishedWithResult(m_error);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
m_error = "Pay button not found: " + m_deviceId + " " + m_appCode;
|
|
||||||
qWarning() << m_error;
|
|
||||||
emit finishedWithResult(m_error);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// "Maraqlı deyil" - не интересно
|
|
||||||
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 (!runAppAndGoToHomeScreen(device.id, app.package, app.pinCode, device.screenWidth, device.screenHeight)) {
|
|
||||||
m_error = "Cant open the home screen: " + m_deviceId + " " + m_appCode;
|
|
||||||
qWarning() << m_error;
|
|
||||||
if (!ApplicationDAO::updatePinCodeStatus(app.id, "no", "Не прошла проверка [дата]")) {
|
|
||||||
qWarning() << "Cant update the pincode: " << m_deviceId << " " << m_appCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
AdbUtils::tryToKillApplication(m_deviceId, app.package);
|
|
||||||
emit finishedWithResult(m_error);
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
if (!ApplicationDAO::updatePinCodeStatus(app.id, "yes", "")) {
|
|
||||||
qWarning() << "Cant update the pincode: " << m_deviceId << " " << m_appCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
QThread::msleep(2000);
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
|
|
||||||
QList<AccountInfo> oldAccounts = AccountDAO::getAccounts(m_deviceId, m_appCode);
|
|
||||||
QMap<QString, AccountInfo> accountMap;
|
|
||||||
for (AccountInfo &oldAccount: oldAccounts) {
|
|
||||||
if (oldAccount.status == AccountStatus::Active) {
|
|
||||||
accountMap.insert(oldAccount.lastNumbers, oldAccount);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<AccountInfo> accounts = xmlScreenParser.parseAccountsInfo();
|
|
||||||
for (auto account: accounts) {
|
|
||||||
if (accountMap.contains(account.lastNumbers)) {
|
|
||||||
account.deviceId = m_deviceId;
|
|
||||||
account.appCode = m_appCode;
|
|
||||||
account.currency = accountMap[account.lastNumbers].currency;
|
|
||||||
account.description = accountMap[account.lastNumbers].description;
|
|
||||||
account.status = AccountStatus::Active;
|
|
||||||
if (!AccountDAO::upsertAccount(account)) {
|
|
||||||
m_error = "Not updated: " + account.lastNumbers;
|
|
||||||
qCritical() << m_error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<AccountInfo> savedAccounts = AccountDAO::getAccounts(m_deviceId, m_appCode);
|
|
||||||
postAccountsData(savedAccounts);
|
|
||||||
}
|
|
||||||
|
|
||||||
AdbUtils::tryToKillApplication(m_deviceId, app.package);
|
|
||||||
}
|
|
||||||
emit finishedWithResult(m_error);
|
|
||||||
}
|
|
||||||
@ -1,23 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include "CommonBirbankScript.h"
|
|
||||||
|
|
||||||
class LoginAndCheckAccountsBirbankScript final : public CommonBirbankScript {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
~LoginAndCheckAccountsBirbankScript() override;
|
|
||||||
|
|
||||||
explicit LoginAndCheckAccountsBirbankScript(
|
|
||||||
QString deviceId,
|
|
||||||
QString appCode,
|
|
||||||
QObject *parent = nullptr
|
|
||||||
);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void doStart() override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
const QString m_deviceId;
|
|
||||||
const QString m_appCode;
|
|
||||||
QString m_error;
|
|
||||||
};
|
|
||||||
@ -1,128 +0,0 @@
|
|||||||
#include "PayByCardBirbankScript.h"
|
|
||||||
|
|
||||||
#include <QRandomGenerator>
|
|
||||||
#include <QThread>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
#include "DatabaseManager.h"
|
|
||||||
#include "adb/AdbUtils.h"
|
|
||||||
#include "dao/AccountDAO.h"
|
|
||||||
#include "dao/ApplicationDAO.h"
|
|
||||||
#include "dao/DeviceDAO.h"
|
|
||||||
#include "dao/TransactionDAO.h"
|
|
||||||
#include "db/ApplicationInfo.h"
|
|
||||||
#include "db/DeviceInfo.h"
|
|
||||||
#include "time/DateUtils.h"
|
|
||||||
|
|
||||||
PayByCardBirbankScript::PayByCardBirbankScript(
|
|
||||||
AccountInfo account,
|
|
||||||
QString card,
|
|
||||||
QString fullName,
|
|
||||||
const double amount,
|
|
||||||
QObject *parent
|
|
||||||
) : CommonBirbankScript(parent),
|
|
||||||
m_account(std::move(account)), m_card(std::move(card)),
|
|
||||||
m_fullName(std::move(fullName)), m_amount(amount) {
|
|
||||||
}
|
|
||||||
|
|
||||||
PayByCardBirbankScript::~PayByCardBirbankScript() = default;
|
|
||||||
|
|
||||||
|
|
||||||
void PayByCardBirbankScript::makePayment(const DeviceInfo &device) {
|
|
||||||
// Оплата со страницы карты
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(device.id, ++m_counter));
|
|
||||||
|
|
||||||
Node cardEditText = xmlScreenParser.findEditText("Номер карты");
|
|
||||||
Node amountEditText = xmlScreenParser.findEditText("Сумма");
|
|
||||||
if (!cardEditText.isEmpty() && !amountEditText.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(device.id, cardEditText.x(), cardEditText.y());
|
|
||||||
QThread::msleep(200);
|
|
||||||
AdbUtils::inputText(device.id, m_card);
|
|
||||||
|
|
||||||
AdbUtils::hideKeyboard(device.id);
|
|
||||||
|
|
||||||
AdbUtils::makeTap(device.id, amountEditText.x(), amountEditText.y());
|
|
||||||
QThread::msleep(200);
|
|
||||||
AdbUtils::inputText(device.id, QString::number(m_amount));
|
|
||||||
|
|
||||||
AdbUtils::hideKeyboard(device.id);
|
|
||||||
|
|
||||||
// дальше оплата, но хз как
|
|
||||||
|
|
||||||
|
|
||||||
} else {
|
|
||||||
m_error = "Не нашли поля ввода 'Номер карты' или 'Сумма'";
|
|
||||||
qDebug() << m_error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void PayByCardBirbankScript::doStart() {
|
|
||||||
const DeviceInfo device = DeviceDAO::getDeviceById(m_account.deviceId);
|
|
||||||
const ApplicationInfo app = ApplicationDAO::getApplication(m_account.deviceId, m_account.appCode);
|
|
||||||
|
|
||||||
if (device.id.isEmpty() || app.id == -1) {
|
|
||||||
m_error = "Device or app not found.";
|
|
||||||
qDebug() << m_error;
|
|
||||||
emit finishedWithResult(m_error);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter));
|
|
||||||
if (!xmlScreenParser.isHomeScreen()) {
|
|
||||||
if (!runAppAndGoToHomeScreen(device.id, app.package, app.pinCode, device.screenWidth, device.screenHeight)) {
|
|
||||||
m_error = "Не смогли дойти до домашней страницы";
|
|
||||||
qDebug() << m_error;
|
|
||||||
emit finishedWithResult(m_error);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter));
|
|
||||||
Node closeBannerNode = xmlScreenParser.findButtonNode("Maraqlı deyil", false);
|
|
||||||
if (!closeBannerNode.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(m_account.deviceId, closeBannerNode.x(), closeBannerNode.y());
|
|
||||||
QThread::msleep(1000);
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (xmlScreenParser.isHomeScreen()) {
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter));
|
|
||||||
Node cardText = xmlScreenParser.findTextNode("2480");
|
|
||||||
if (!cardText.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(m_account.deviceId, cardText.x(), cardText.y());
|
|
||||||
QThread::msleep(2000);
|
|
||||||
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter));
|
|
||||||
Node payBtn = xmlScreenParser.findTextNode("Перевести");
|
|
||||||
if (!payBtn.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(m_account.deviceId, payBtn.x(), payBtn.y());
|
|
||||||
QThread::msleep(1000);
|
|
||||||
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter));
|
|
||||||
Node payByCardBtn = xmlScreenParser.findTextNode("На карту любого банка");
|
|
||||||
if (!payByCardBtn.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(m_account.deviceId, payByCardBtn.x(), payByCardBtn.y());
|
|
||||||
QThread::msleep(1000);
|
|
||||||
|
|
||||||
makePayment(device);
|
|
||||||
} else {
|
|
||||||
m_error = "Pay by card button not found: " + m_account.deviceId + " " + m_account.appCode;
|
|
||||||
qWarning() << m_error;
|
|
||||||
emit finishedWithResult(m_error);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
m_error = "Pay button not found: " + m_account.deviceId + " " + m_account.appCode;
|
|
||||||
qWarning() << m_error;
|
|
||||||
emit finishedWithResult(m_error);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!m_error.isEmpty()) {
|
|
||||||
AdbUtils::takeXmlDump(device.id, "pay_by_Card_Birbank_fail_transactions_" + QString::number(m_account.id));
|
|
||||||
}
|
|
||||||
|
|
||||||
emit finishedWithResult(m_error);
|
|
||||||
}
|
|
||||||
@ -1,30 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include "CommonBirbankScript.h"
|
|
||||||
#include "db/DeviceInfo.h"
|
|
||||||
|
|
||||||
class PayByCardBirbankScript final : public CommonBirbankScript {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
~PayByCardBirbankScript() override;
|
|
||||||
|
|
||||||
PayByCardBirbankScript(
|
|
||||||
AccountInfo account,
|
|
||||||
QString card,
|
|
||||||
QString fullName,
|
|
||||||
double amount,
|
|
||||||
QObject *parent = nullptr
|
|
||||||
);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void doStart() override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
const AccountInfo m_account;
|
|
||||||
const QString m_card;
|
|
||||||
const QString m_fullName;
|
|
||||||
const double m_amount;
|
|
||||||
QString m_error;
|
|
||||||
|
|
||||||
void makePayment(const DeviceInfo &device);
|
|
||||||
};
|
|
||||||
@ -1,747 +0,0 @@
|
|||||||
#include "ScreenXmlBirbankParser.h"
|
|
||||||
|
|
||||||
#include <QRegularExpression>
|
|
||||||
#include <QMap>
|
|
||||||
#include <QSet>
|
|
||||||
#include <QList>
|
|
||||||
#include <QXmlStreamReader>
|
|
||||||
#include <QDomDocument>
|
|
||||||
#include <QFile>
|
|
||||||
#include <QDateTime>
|
|
||||||
|
|
||||||
#include "adb/AdbUtils.h"
|
|
||||||
#include "android/xml/Node.h"
|
|
||||||
#include "db/AccountInfo.h"
|
|
||||||
#include "db/TransactionInfo.h"
|
|
||||||
#include "time/DateUtils.h"
|
|
||||||
|
|
||||||
ScreenXmlBirbankParser::ScreenXmlBirbankParser(QObject *parent) : QObject(parent) {
|
|
||||||
}
|
|
||||||
|
|
||||||
ScreenXmlBirbankParser::~ScreenXmlBirbankParser() = default;
|
|
||||||
|
|
||||||
static const QRegularExpression boundsRegex(R"(\[([0-9]+),([0-9]+)\]\[([0-9]+),([0-9]+)\])");
|
|
||||||
static const QRegularExpression onlyDigitsRegex(R"([^0-9])");
|
|
||||||
static const QRegularExpression onlyDigitsAndDotRegex(R"([^0-9.])");
|
|
||||||
|
|
||||||
static const QRegularExpression rePhone(R"raw((\+7\(?\d{3}\)?[- ]?\d{3}[- ]?\d{2}[- ]?\d{2}))raw");
|
|
||||||
static const QRegularExpression reFromBank(R"raw(из (.+?) на)raw");
|
|
||||||
static const QRegularExpression reToBank(R"raw(в (.+?) через)raw");
|
|
||||||
static const QRegularExpression reSbpId(R"(СБП(?: С2С)? ([A-Z0-9]{30,}))");
|
|
||||||
static const QRegularExpression reIdAlt(R"(ID перевода (\d+))");
|
|
||||||
static const QRegularExpression reDate(R"((?:Дата операции|дата) (\d{2}\.\d{2}\.\d{4}(?: \d{2}:\d{2}:\d{2})?))");
|
|
||||||
static const QRegularExpression reSender(R"(от ([^\(]+))");
|
|
||||||
static const QRegularExpression reNameAlt(R"(Перевод ([А-Яа-яЁё\s\*]+) в)");
|
|
||||||
|
|
||||||
static const QRegularExpression reCardData(R"(цифрами\s+(\d\s\d\s\d\s\d).*?Сумма:\s([\d\s]+)\sруб)");
|
|
||||||
|
|
||||||
Node ScreenXmlBirbankParser::tryToFindBannerOrDialog(const int width, const int height) {
|
|
||||||
// 1. Ищем push banner - он перекрывает весь экран
|
|
||||||
Node first = m_nodes[0];
|
|
||||||
for (const Node &node: m_nodes) {
|
|
||||||
// Если это однозначно, что пуш-баннер
|
|
||||||
if (node.resourceId == "aft-popup-pushNotification-iconClose" && node.className == "android.widget.Button") {
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
// Если есть кнопка "Позже"
|
|
||||||
if (node.text.trimmed() == "Позже" && node.className == "android.widget.Button") {
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
// Если нашли пустую кнпоку
|
|
||||||
if (node.className == "android.widget.Button" && node.clickable
|
|
||||||
&& node.text.isEmpty() && node.contentDesc.isEmpty()) {
|
|
||||||
// <node class="android.widget.Button" package="ru.rshb.dbo" clickable="true" bounds="[630,142][691,205]"/>
|
|
||||||
if (node.x() > width / 2 && node.y() < width / 2) {
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
Node ScreenXmlBirbankParser::findAccountButton(const QString &numbers) {
|
|
||||||
// TODO возможно это не так, надо уточнять
|
|
||||||
return findTextNode(QString("LEVENT - %1").arg(numbers));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Смотрим что есть текс "Мы заботимся о вашей безопасности" и
|
|
||||||
* кнопка "Отложить"
|
|
||||||
* @return координаты кнопки для закрытия
|
|
||||||
*/
|
|
||||||
Node ScreenXmlBirbankParser::tryToFindSecurityBanner() {
|
|
||||||
Node text;
|
|
||||||
Node closeBtn;
|
|
||||||
for (const Node &node: m_nodes) {
|
|
||||||
if (node.text.trimmed() == "Мы заботимся о вашей безопасности" && node.className == "android.app.Dialog") {
|
|
||||||
text = node;
|
|
||||||
}
|
|
||||||
if (node.text.trimmed() == "Отложить" && node.className == "android.widget.Button") {
|
|
||||||
closeBtn = node;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Не нужно проверять все, если хотя бы одна координата есть
|
|
||||||
if (!text.isEmpty() && !closeBtn.isEmpty()) {
|
|
||||||
return closeBtn;
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
Node ScreenXmlBirbankParser::tryToFindSelectBottomSheet() {
|
|
||||||
Node closeBtn;
|
|
||||||
for (const Node &node: m_nodes) {
|
|
||||||
if ((node.text.trimmed() == "Отмена" || node.text.trimmed() == "Отложить") && node.className ==
|
|
||||||
"android.widget.Button") {
|
|
||||||
closeBtn = node;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Не нужно проверять все, если хотя бы одна координата есть
|
|
||||||
if (!closeBtn.isEmpty()) {
|
|
||||||
return closeBtn;
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
Node ScreenXmlBirbankParser::findTextNode(const QString &text) {
|
|
||||||
for (const Node &node: m_nodes) {
|
|
||||||
if (node.className == "android.widget.TextView" && node.text.trimmed() == text) {
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
Node ScreenXmlBirbankParser::findTextNode(const QString &text, const int x1, const int y1, const int x2, const int y2) {
|
|
||||||
for (const Node &node: m_nodes) {
|
|
||||||
if (node.className == "android.widget.TextView" && node.text.trimmed() == text
|
|
||||||
&& node.x() >= x1 && node.x() <= x2 && node.y() >= y1 && node.y() <= y2) {
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
Node ScreenXmlBirbankParser::findEditText(const QString &text) {
|
|
||||||
for (const Node &node: m_nodes) {
|
|
||||||
if (node.className == "android.widget.EditText" && node.text == text) {
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
Node ScreenXmlBirbankParser::findEditTextByResourceId(const QString &resourceId) {
|
|
||||||
for (const Node &node: m_nodes) {
|
|
||||||
if (node.className == "android.widget.EditText" && node.resourceId == resourceId) {
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
Node ScreenXmlBirbankParser::findButtonNode(const QString &text, const bool contains) {
|
|
||||||
for (const Node &node: m_nodes) {
|
|
||||||
if (contains) {
|
|
||||||
if (node.className == "android.widget.Button" && node.text.contains(text)) {
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (node.className == "android.widget.Button" && node.text.trimmed() == text) {
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ScreenXmlBirbankParser::isHomeScreen() {
|
|
||||||
Node activitiesBtn;
|
|
||||||
for (const Node &node: m_nodes) {
|
|
||||||
if (node.text.trimmed() == "Карты и счета") {
|
|
||||||
activitiesBtn = node;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return !activitiesBtn.isEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<Node> ScreenXmlBirbankParser::findPinCodeNodes(const QString &pinCode) {
|
|
||||||
QMap<QString, Node> buttons;
|
|
||||||
const QSet<QString> numberSet = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"};
|
|
||||||
|
|
||||||
for (const Node &node: m_nodes) {
|
|
||||||
const QString &text = node.text.trimmed();
|
|
||||||
if (node.className == "android.widget.TextView" && numberSet.contains(text)) {
|
|
||||||
buttons[text] = node;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<Node> nodes;
|
|
||||||
for (int i = 0; i < pinCode.length(); ++i) {
|
|
||||||
nodes.append(buttons[QString(pinCode.at(i))]);
|
|
||||||
}
|
|
||||||
return nodes;
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<Node> ScreenXmlBirbankParser::getLast2DaysTransactions() {
|
|
||||||
QList<Node> nodes;
|
|
||||||
for (const Node &node: m_nodes) {
|
|
||||||
if (node.className == "android.widget.Button" && node.text.contains("рубл")
|
|
||||||
&& (node.text.contains("Минус") || node.text.contains("Плюс"))) {
|
|
||||||
nodes.append(node);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nodes;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <node NAF="true" index="1" text="" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[952,159][1039,248]"/>
|
|
||||||
*/
|
|
||||||
void ScreenXmlBirbankParser::parseAndSaveXml(const QString &xml) {
|
|
||||||
QDomDocument doc;
|
|
||||||
doc.setContent(xml);
|
|
||||||
m_xml = doc.documentElement();
|
|
||||||
m_nodes.clear();
|
|
||||||
|
|
||||||
QXmlStreamReader reader(xml);
|
|
||||||
while (!reader.atEnd()) {
|
|
||||||
reader.readNext();
|
|
||||||
if (reader.isStartElement() && reader.name() == "node") {
|
|
||||||
Node node = Node();
|
|
||||||
if (reader.attributes().hasAttribute("bounds")) {
|
|
||||||
QString bounds = reader.attributes().value("bounds").toString();
|
|
||||||
if (QRegularExpressionMatch match = boundsRegex.match(bounds); match.hasMatch()) {
|
|
||||||
node.setBounds(
|
|
||||||
match.captured(1).toInt(),
|
|
||||||
match.captured(2).toInt(),
|
|
||||||
match.captured(3).toInt(),
|
|
||||||
match.captured(4).toInt()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (reader.attributes().hasAttribute("text")) {
|
|
||||||
node.text = reader.attributes().value("text").toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (reader.attributes().hasAttribute("content-desc")) {
|
|
||||||
node.contentDesc = reader.attributes().value("content-desc").toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (reader.attributes().hasAttribute("class")) {
|
|
||||||
node.className = reader.attributes().value("class").toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (reader.attributes().hasAttribute("clickable")) {
|
|
||||||
node.clickable = reader.attributes().value("clickable").toString() == "true";
|
|
||||||
}
|
|
||||||
if (reader.attributes().hasAttribute("focusable")) {
|
|
||||||
node.focusable = reader.attributes().value("focusable").toString() == "true";
|
|
||||||
}
|
|
||||||
if (reader.attributes().hasAttribute("resource-id")) {
|
|
||||||
node.resourceId = reader.attributes().value("resource-id").toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
m_nodes.append(node);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QDomElement findSubElementBirbank(const QDomElement &elem, const QString &index) {
|
|
||||||
if (elem.hasChildNodes()) {
|
|
||||||
QDomNodeList subInfoList = elem.childNodes();
|
|
||||||
for (QDomNode subInfoNode: subInfoList) {
|
|
||||||
if (!subInfoNode.isElement()) continue;
|
|
||||||
QDomElement subInfo = subInfoNode.toElement();
|
|
||||||
if (subInfo.attribute("index") == index) {
|
|
||||||
return subInfo;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
QString findSubInfoBirbank(const QDomElement &elem, const QString &index) {
|
|
||||||
QDomElement subInfo = findSubElementBirbank(elem, index);
|
|
||||||
if (!subInfo.isNull()) {
|
|
||||||
return subInfo.attribute("text");
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
bool hasTimeComponentBirbank(const QString &datetimeStr) {
|
|
||||||
QDateTime dt = QDateTime::fromString(datetimeStr, "dd.MM.yyyy HH:mm:ss");
|
|
||||||
if (!dt.isValid()) {
|
|
||||||
return false; // Строка не соответствует формату даты и времени
|
|
||||||
}
|
|
||||||
return dt.time() != QTime(0, 0, 0); // Проверка, что время не равно 00:00:00
|
|
||||||
}
|
|
||||||
|
|
||||||
QString transformBankDateTimeBirbank(const QString &date) {
|
|
||||||
QDateTime dt;
|
|
||||||
if (date.contains(",")) {
|
|
||||||
// 10.05.2025, 15:03
|
|
||||||
dt = QDateTime::fromString(date, "dd.MM.yyyy, HH:mm");
|
|
||||||
} else {
|
|
||||||
dt = QDateTime::fromString(date, "dd.MM.yyyy HH:mm:ss");
|
|
||||||
}
|
|
||||||
if (!dt.isValid()) {
|
|
||||||
dt = QDateTime::fromString(date, "dd.MM.yyyy HH:mm");
|
|
||||||
}
|
|
||||||
if (!dt.isValid()) {
|
|
||||||
return date; // не распарсили
|
|
||||||
}
|
|
||||||
return dt.toString("dd.MM.yyyy HH:mm:ss");
|
|
||||||
}
|
|
||||||
|
|
||||||
void parseTransferInfoBirbank(const QString &text, TransactionInfo &info) {
|
|
||||||
if (const auto m = reSender.match(text); m.hasMatch()) {
|
|
||||||
info.name = m.captured(1).trimmed();
|
|
||||||
} else if (const auto m1 = reNameAlt.match(text); m1.hasMatch()) {
|
|
||||||
info.name = m1.captured(1).trimmed();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (const auto m = rePhone.match(text); m.hasMatch()) {
|
|
||||||
info.phone = m.captured(1).trimmed().remove(onlyDigitsRegex);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (const auto m = reFromBank.match(text); m.hasMatch()) {
|
|
||||||
if (const QString bank = m.captured(1).trimmed(); !bank.isEmpty()) {
|
|
||||||
info.bankName = bank;
|
|
||||||
}
|
|
||||||
} else if (const auto m1 = reToBank.match(text); m1.hasMatch()) {
|
|
||||||
if (const QString bank = m1.captured(1).trimmed(); !bank.isEmpty()) {
|
|
||||||
info.bankName = bank;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (const auto m = reSbpId.match(text); m.hasMatch()) {
|
|
||||||
info.bankTrExternalId = m.captured(1);
|
|
||||||
} else if (const auto m1 = reIdAlt.match(text); m1.hasMatch()) {
|
|
||||||
info.bankTrExternalId = m1.captured(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (const auto m = reDate.match(text); m.hasMatch()) {
|
|
||||||
const QString date = m.captured(1);
|
|
||||||
// если не пустая и дата у нас с 00:00
|
|
||||||
// if (hasTimeComponent2(date)) {
|
|
||||||
info.bankTime = transformBankDateTimeBirbank(date);
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void traverseNodesBirbank(const QDomNode &node) {
|
|
||||||
if (node.isElement()) {
|
|
||||||
QDomElement elem = node.toElement();
|
|
||||||
|
|
||||||
if (node.isElement()) {
|
|
||||||
QDomElement elem = node.toElement();
|
|
||||||
|
|
||||||
if (elem.tagName() == "node" &&
|
|
||||||
elem.attribute("class") == "android.widget.Button" &&
|
|
||||||
elem.attribute("text") == "Детали операции") {
|
|
||||||
// Все что ниже деталей операции
|
|
||||||
QDomNodeList detailInfo = elem.parentNode().childNodes();
|
|
||||||
|
|
||||||
|
|
||||||
for (int j = 0; j < detailInfo.count(); ++j) {
|
|
||||||
QDomNode info = detailInfo.at(j);
|
|
||||||
if (!info.isElement()) continue;
|
|
||||||
QDomElement infoElement = info.toElement();
|
|
||||||
QString index = infoElement.attribute("index");
|
|
||||||
switch (index.toInt()) {
|
|
||||||
case 2:
|
|
||||||
qDebug() << "Дата операции:" << findSubInfoBirbank(infoElement, "1");
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
qDebug() << "Название:" << findSubInfoBirbank(infoElement, "1");
|
|
||||||
qDebug() << "-------------------------------------";
|
|
||||||
// parseTransfer(findSubInfo2(infoElement));
|
|
||||||
break;
|
|
||||||
case 7:
|
|
||||||
qDebug() << "Комиссия:" << findSubInfoBirbank(infoElement, "1");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
qDebug() << "Прочее:" << findSubInfoBirbank(infoElement, "1");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Рекурсивно обходим всех детей
|
|
||||||
QDomNode child = node.firstChild();
|
|
||||||
while (!child.isNull()) {
|
|
||||||
traverseNodesBirbank(child);
|
|
||||||
child = child.nextSibling();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QDomNode findNodeBirbank(const QDomNode &node, const QString &text) {
|
|
||||||
if (node.isElement()) {
|
|
||||||
QString nodeText = node.toElement().attribute("text");
|
|
||||||
if (nodeText.toLower().startsWith(text)) {
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
QDomNode child = node.firstChild();
|
|
||||||
while (!child.isNull()) {
|
|
||||||
QDomNode result = findNodeBirbank(child, text);
|
|
||||||
if (!result.isNull()) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
child = child.nextSibling();
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
float extractAmountsBirbank(const QString &text) {
|
|
||||||
// Разрешаем пробелы внутри чисел, захватываем "рубль", "рубля", "рублей" и т.д.
|
|
||||||
// QRegularExpression re(R"((Плюс|Минус)\s+([\d\s]+)\s+рубл\w*\s+(\d+)\s+копе\w*)");
|
|
||||||
QRegularExpression re(
|
|
||||||
R"((Плюс|Минус)\s+([\d\s]+)\s+рубл\w*\s+(\d+)\s+копе\w*)",
|
|
||||||
QRegularExpression::UseUnicodePropertiesOption
|
|
||||||
);
|
|
||||||
|
|
||||||
QRegularExpressionMatch match = re.match(text);
|
|
||||||
if (match.hasMatch()) {
|
|
||||||
QString signStr = match.captured(1); // "Плюс" или "Минус"
|
|
||||||
QString rublesStr = match.captured(2).remove(' '); // "1 000" → "1000"
|
|
||||||
int rubles = rublesStr.toInt();
|
|
||||||
int kopecks = match.captured(3).toInt();
|
|
||||||
|
|
||||||
int totalKopecks = rubles * 100 + kopecks;
|
|
||||||
if (signStr == "Минус") {
|
|
||||||
totalKopecks *= -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return totalKopecks / 100.0f;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString beforeAmountBirbank(const QString &text) {
|
|
||||||
int index = text.indexOf(QRegularExpression("Плюс|Минус"));
|
|
||||||
if (index != -1) {
|
|
||||||
return text.left(index).trimmed();
|
|
||||||
}
|
|
||||||
return text; // если не найдено — вернуть всю строку
|
|
||||||
}
|
|
||||||
|
|
||||||
double parseAmountBirbank(const QString &amountAsString) {
|
|
||||||
QString numberString = amountAsString;
|
|
||||||
numberString.remove(QRegularExpression(R"([^\dточка])"));
|
|
||||||
numberString.replace("точка", ".");
|
|
||||||
double amount = numberString.toDouble();
|
|
||||||
|
|
||||||
if (amountAsString.startsWith("-")) {
|
|
||||||
amount *= -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return amount;
|
|
||||||
}
|
|
||||||
|
|
||||||
QDomElement findElementWithPaymentsBirbank(const QDomElement &parent, const QString &resourceId) {
|
|
||||||
QDomElement element = parent.firstChildElement();
|
|
||||||
while (!element.isNull()) {
|
|
||||||
QDomElement child = element.firstChildElement();
|
|
||||||
while (!child.isNull()) {
|
|
||||||
if (child.hasAttribute("resource-id") && child.attribute("resource-id") == resourceId) {
|
|
||||||
return child;
|
|
||||||
}
|
|
||||||
child = child.nextSiblingElement();
|
|
||||||
}
|
|
||||||
|
|
||||||
QDomElement found = findElementWithPaymentsBirbank(element, resourceId);
|
|
||||||
if (!found.isNull()) {
|
|
||||||
return found;
|
|
||||||
}
|
|
||||||
element = element.nextSiblingElement();
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
QDateTime getUtcFromBakuDate(const QString &date, const QString &time) {
|
|
||||||
QDate baseDate;
|
|
||||||
QTime parsedTime = QTime::fromString(time, "H:mm");
|
|
||||||
if (!parsedTime.isValid()) {
|
|
||||||
qWarning() << "Невалидное время:" << time;
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
QString dateLower = date.trimmed().toLower();
|
|
||||||
|
|
||||||
if (dateLower == "сегодня") {
|
|
||||||
baseDate = QDate::currentDate();
|
|
||||||
} else if (dateLower == "вчера") {
|
|
||||||
baseDate = QDate::currentDate().addDays(-1);
|
|
||||||
} else if (dateLower == "позавчера") {
|
|
||||||
baseDate = QDate::currentDate().addDays(-2);
|
|
||||||
} else {
|
|
||||||
// Пробуем разобрать обычную дату, например "24 июля"
|
|
||||||
QLocale ruLocale(QLocale::Russian, QLocale::Russia);
|
|
||||||
int year = QDate::currentDate().year();
|
|
||||||
QString combined = QString("%1 %2 %3").arg(date).arg(year).arg(time); // "24 июля 2025 0:31"
|
|
||||||
QDateTime dt = ruLocale.toDateTime(combined, "d MMMM yyyy H:mm");
|
|
||||||
if (!dt.isValid()) {
|
|
||||||
qWarning() << "Ошибка разбора даты:" << combined;
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
dt.setTimeZone(QTimeZone("Asia/Baku"));
|
|
||||||
return dt.toTimeZone(QTimeZone::utc());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Собираем и переводим в UTC, если дата относительная
|
|
||||||
QDateTime bakuDateTime(baseDate, parsedTime, QTimeZone("Asia/Baku"));
|
|
||||||
return bakuDateTime.toTimeZone(QTimeZone::utc());
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<TransactionInfo> ScreenXmlBirbankParser::parsePositiveTransactions() {
|
|
||||||
QList<TransactionInfo> transactions;
|
|
||||||
|
|
||||||
QDomElement child = findElementWithPaymentsBirbank(m_xml, "az.kapitalbank.mbanking:id/rv_pfm_operations");
|
|
||||||
// QDomElement child = findElementWithPaymentsBirbank(m_xml, "az.kapitalbank.mbanking:id/rv_operations");
|
|
||||||
QDomNodeList listView = child.childNodes();
|
|
||||||
qDebug() << listView.count();
|
|
||||||
if (!listView.isEmpty()) {
|
|
||||||
QString date = "";
|
|
||||||
|
|
||||||
for (QDomNode node: listView) {
|
|
||||||
const QDomNodeList trBoxGroup = node.childNodes();
|
|
||||||
if (trBoxGroup.count() > 0) {
|
|
||||||
TransactionInfo transaction;
|
|
||||||
for (QDomNode item: trBoxGroup) {
|
|
||||||
QDomElement groupItem = item.toElement();
|
|
||||||
if ("az.kapitalbank.mbanking:id/tv_date" == groupItem.attribute("resource-id")) {
|
|
||||||
date = groupItem.attribute("text");
|
|
||||||
} else if ("az.kapitalbank.mbanking:id/transaction_title" == groupItem.attribute("resource-id")) {
|
|
||||||
transaction.description = groupItem.attribute("text");
|
|
||||||
} else if ("az.kapitalbank.mbanking:id/transaction_time" == groupItem.attribute("resource-id")) {
|
|
||||||
transaction.bankTime = date + " " + groupItem.attribute("text");
|
|
||||||
transaction.completeTime = getUtcFromBakuDate(date, groupItem.attribute("text"));
|
|
||||||
} else if ("az.kapitalbank.mbanking:id/transaction_amount" == groupItem.attribute("resource-id")) {
|
|
||||||
auto amount = groupItem.attribute("text");
|
|
||||||
if (amount.startsWith("+")) {
|
|
||||||
transaction.amount = amount.remove("+").remove("₼").replace(",", ".").trimmed().toFloat();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (transaction.amount > 0) {
|
|
||||||
transactions.append(transaction);
|
|
||||||
qDebug().noquote().nospace() << convertTransactionToString(transaction);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
qDebug() << "ListView is empty";
|
|
||||||
}
|
|
||||||
return transactions;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
TransactionInfo parseExpandedInfoHistoryBirbank(const QDomElement &root) {
|
|
||||||
if (root.isElement()) {
|
|
||||||
QDomElement elem = root.toElement();
|
|
||||||
if (elem.tagName() == "node"
|
|
||||||
&& elem.attribute("class") == "android.widget.Button"
|
|
||||||
&& elem.attribute("text") == "Детали операции"
|
|
||||||
) {
|
|
||||||
TransactionInfo transaction;
|
|
||||||
// Все что ниже деталей операции
|
|
||||||
QDomNodeList detailInfo = elem.parentNode().childNodes();
|
|
||||||
|
|
||||||
for (int i = 0; i < detailInfo.count(); ++i) {
|
|
||||||
QDomNode info = detailInfo.at(i);
|
|
||||||
if (!info.isElement()) continue;
|
|
||||||
|
|
||||||
switch (QDomElement e = info.toElement(); e.attribute("index").toInt()) {
|
|
||||||
case 2:
|
|
||||||
// Дата операции
|
|
||||||
transaction.bankTime = transformBankDateTimeBirbank(findSubInfoBirbank(e, "1"));
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
transaction.description = findSubInfoBirbank(e, "1");
|
|
||||||
parseTransferInfoBirbank(transaction.description, transaction);
|
|
||||||
break;
|
|
||||||
case 7:
|
|
||||||
// Комиссия
|
|
||||||
transaction.fee = findSubInfoBirbank(e, "1").remove(onlyDigitsRegex).toFloat();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
// qDebug() << "Прочее:" << findSubInfo2(e);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return transaction;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Рекурсивно обходим всех детей
|
|
||||||
QDomNode child = root.firstChild();
|
|
||||||
while (!child.isNull()) {
|
|
||||||
if (TransactionInfo info = parseExpandedInfoHistoryBirbank(child.toElement()); !info.bankTime.isEmpty()) {
|
|
||||||
return info;
|
|
||||||
}
|
|
||||||
child = child.nextSibling();
|
|
||||||
}
|
|
||||||
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
TransactionInfo ScreenXmlBirbankParser::parseTransactionInfoHistory(int screenWidth, int screenHeight) {
|
|
||||||
// 1. Распарсить описание транзакции
|
|
||||||
TransactionInfo transaction = parseExpandedInfoHistoryBirbank(m_xml);
|
|
||||||
// 1. Найти статус: Исполнен | Операция исполнена
|
|
||||||
transaction.status = TransactionStatus::Wait;
|
|
||||||
Node status1 = findTextNode("Исполнен", 0, 0, screenWidth, screenHeight / 2);
|
|
||||||
Node status2 = findTextNode("Операция исполнена", 0, 0, screenWidth, screenHeight / 2);
|
|
||||||
if (!status1.isEmpty() || !status2.isEmpty()) {
|
|
||||||
transaction.status = TransactionStatus::Complete;
|
|
||||||
}
|
|
||||||
return transaction;
|
|
||||||
}
|
|
||||||
|
|
||||||
TransactionInfo parseExpandedInfoBirbank(const QDomElement &root) {
|
|
||||||
if (root.isElement()) {
|
|
||||||
QDomElement elem = root.toElement();
|
|
||||||
if (elem.tagName() == "node"
|
|
||||||
&& elem.attribute("class") == "android.widget.Button"
|
|
||||||
&& elem.attribute("text") == "Детали операции"
|
|
||||||
) {
|
|
||||||
TransactionInfo transaction;
|
|
||||||
// Все что ниже деталей операции
|
|
||||||
QDomNodeList detailInfo = elem.parentNode().childNodes();
|
|
||||||
|
|
||||||
for (int i = 0; i < detailInfo.count(); ++i) {
|
|
||||||
QDomNode info = detailInfo.at(i);
|
|
||||||
if (!info.isElement()) continue;
|
|
||||||
|
|
||||||
QDomElement infoElement = info.toElement();
|
|
||||||
QString index = infoElement.attribute("index");
|
|
||||||
QDomElement ee;
|
|
||||||
switch (index.toInt()) {
|
|
||||||
case 3:
|
|
||||||
transaction.bankTime = transformBankDateTimeBirbank(findSubInfoBirbank(infoElement, "1"));
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
ee = findSubElementBirbank(infoElement, "0");
|
|
||||||
ee = findSubElementBirbank(ee, "1");
|
|
||||||
transaction.phone = findSubInfoBirbank(ee, "0").remove(onlyDigitsRegex);
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
transaction.name = findSubInfoBirbank(infoElement, "1");
|
|
||||||
break;
|
|
||||||
case 6:
|
|
||||||
transaction.bankName = findSubInfoBirbank(infoElement, "1");
|
|
||||||
break;
|
|
||||||
case 9:
|
|
||||||
transaction.fee = findSubInfoBirbank(infoElement, "1").remove(onlyDigitsAndDotRegex).toFloat();
|
|
||||||
break;
|
|
||||||
case 10:
|
|
||||||
ee = findSubElementBirbank(infoElement, "1");
|
|
||||||
transaction.bankTrExternalId = findSubInfoBirbank(ee, "1");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return transaction;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Рекурсивно обходим всех детей
|
|
||||||
QDomNode child = root.firstChild();
|
|
||||||
while (!child.isNull()) {
|
|
||||||
if (TransactionInfo info = parseExpandedInfoBirbank(child.toElement()); !info.bankTime.isEmpty()) {
|
|
||||||
return info;
|
|
||||||
}
|
|
||||||
child = child.nextSibling();
|
|
||||||
}
|
|
||||||
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
TransactionInfo ScreenXmlBirbankParser::parseTransactionInfo(int screenWidth, int screenHeight) {
|
|
||||||
// 1. Распарсить описание транзакции
|
|
||||||
TransactionInfo transaction = parseExpandedInfoBirbank(m_xml);
|
|
||||||
// 1. Найти статус: Исполнен | Операция исполнена
|
|
||||||
transaction.status = TransactionStatus::Wait;
|
|
||||||
Node status1 = findTextNode("Исполнен", 0, 0, screenWidth, screenHeight / 2);
|
|
||||||
Node status2 = findTextNode("Операция исполнена", 0, 0, screenWidth, screenHeight / 2);
|
|
||||||
if (!status1.isEmpty() || !status2.isEmpty()) {
|
|
||||||
transaction.status = TransactionStatus::Complete;
|
|
||||||
}
|
|
||||||
return transaction;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
QList<AccountInfo> ScreenXmlBirbankParser::parseAccountsInfo() {
|
|
||||||
const QDomNodeList nodes = m_xml.elementsByTagName("node");
|
|
||||||
QList<AccountInfo> accounts;
|
|
||||||
|
|
||||||
for (int i = 0; i < nodes.count(); ++i) {
|
|
||||||
const QDomElement el = nodes.at(i).toElement();
|
|
||||||
if (el.attribute("text").contains("₼")) {
|
|
||||||
// Нашли сумму
|
|
||||||
// el.attribute("text") - ₼ и трим
|
|
||||||
auto amount = el.attribute("text").replace("₼", "").trimmed();
|
|
||||||
const QDomElement parent = el.parentNode().parentNode().toElement();
|
|
||||||
// Перебираем потомков
|
|
||||||
QDomNode n = parent.firstChild().firstChild().firstChild().firstChild();
|
|
||||||
while (!n.isNull()) {
|
|
||||||
const QDomElement e = n.toElement();
|
|
||||||
if (e.attribute("resource-id") == "az.kapitalbank.mbanking:id/tvNumber") {
|
|
||||||
const QString account = e.attribute("text");
|
|
||||||
|
|
||||||
AccountInfo info;
|
|
||||||
info.lastNumbers = account;
|
|
||||||
info.amount = amount.toFloat();
|
|
||||||
info.description = account;
|
|
||||||
info.updateTime = DateUtils::getUtcNow();
|
|
||||||
|
|
||||||
accounts.append(info);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
n = n.nextSibling();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return accounts;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ScreenXmlBirbankParser::test() {
|
|
||||||
// TransactionInfo info2 = parseExpandedInfo(m_xml);
|
|
||||||
// qDebug().noquote().nospace() << convertTransactionToString(info2);
|
|
||||||
// return;
|
|
||||||
|
|
||||||
QFile file("assets/rshb/all_products.xml");
|
|
||||||
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
|
||||||
qDebug() << "Cannot open file";
|
|
||||||
}
|
|
||||||
|
|
||||||
QDomDocument doc;
|
|
||||||
if (!doc.setContent(&file)) {
|
|
||||||
qDebug() << "Failed to parse XML";
|
|
||||||
}
|
|
||||||
file.close();
|
|
||||||
|
|
||||||
qDebug() << "Start parsing XML:";
|
|
||||||
|
|
||||||
// Номер карты с последними цифрами
|
|
||||||
QDomElement root = doc.documentElement();
|
|
||||||
parseAndSaveXml(doc.toString());
|
|
||||||
// for (const AccountInfo &info: parseAccountsInfo()) {
|
|
||||||
// qDebug().noquote().nospace() << convertAccountToString(info);
|
|
||||||
// }
|
|
||||||
// TransactionInfo info = parseExpandedInfo(root);
|
|
||||||
// qDebug().noquote().nospace() << convertTransactionToString(info);
|
|
||||||
// ЕСПП
|
|
||||||
}
|
|
||||||
@ -1,57 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <QObject>
|
|
||||||
#include <QDomElement>
|
|
||||||
#include "android/xml/Node.h"
|
|
||||||
#include "db/AccountInfo.h"
|
|
||||||
#include "db/TransactionInfo.h"
|
|
||||||
|
|
||||||
class ScreenXmlBirbankParser final : public QObject {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit ScreenXmlBirbankParser(QObject *parent = nullptr);
|
|
||||||
|
|
||||||
~ScreenXmlBirbankParser() override;
|
|
||||||
|
|
||||||
Node tryToFindBannerOrDialog(int width, int height);
|
|
||||||
|
|
||||||
Node tryToFindSecurityBanner();
|
|
||||||
|
|
||||||
Node tryToFindSelectBottomSheet();
|
|
||||||
|
|
||||||
Node findAccountButton(const QString &numbers);
|
|
||||||
|
|
||||||
Node findTextNode(const QString &text);
|
|
||||||
|
|
||||||
Node findTextNode(const QString &text, int x1, int y1, int x2, int y2);
|
|
||||||
|
|
||||||
Node findEditText(const QString &text);
|
|
||||||
|
|
||||||
Node findEditTextByResourceId(const QString &resourceId);
|
|
||||||
|
|
||||||
Node findButtonNode(const QString &text, bool contains);
|
|
||||||
|
|
||||||
bool isHomeScreen();
|
|
||||||
|
|
||||||
QList<Node> getLast2DaysTransactions();
|
|
||||||
|
|
||||||
void parseAndSaveXml(const QString &xml);
|
|
||||||
|
|
||||||
TransactionInfo parseTransactionInfoHistory(int screenWidth, int screenHeight);
|
|
||||||
|
|
||||||
TransactionInfo parseTransactionInfo(int screenWidth, int screenHeight);
|
|
||||||
|
|
||||||
QList<TransactionInfo> parsePositiveTransactions();
|
|
||||||
|
|
||||||
QList<AccountInfo> parseAccountsInfo();
|
|
||||||
|
|
||||||
QList<Node> findPinCodeNodes(const QString &pinCode);
|
|
||||||
|
|
||||||
void test();
|
|
||||||
|
|
||||||
private:
|
|
||||||
QList<Node> m_nodes;
|
|
||||||
QDomElement m_xml;
|
|
||||||
|
|
||||||
};
|
|
||||||
@ -3,6 +3,8 @@
|
|||||||
#include <QJsonArray>
|
#include <QJsonArray>
|
||||||
#include <QJsonObject>
|
#include <QJsonObject>
|
||||||
#include <QRandomGenerator>
|
#include <QRandomGenerator>
|
||||||
|
#include <QRegularExpression>
|
||||||
|
#include <QSettings>
|
||||||
#include <QThread>
|
#include <QThread>
|
||||||
|
|
||||||
#include "adb/AdbUtils.h"
|
#include "adb/AdbUtils.h"
|
||||||
@ -197,18 +199,37 @@ void CommonScript::updateTransactionData(
|
|||||||
void CommonScript::createBankProfileIfNeeded(const QString &deviceId, const QString &appCode) {
|
void CommonScript::createBankProfileIfNeeded(const QString &deviceId, const QString &appCode) {
|
||||||
const ApplicationInfo app = ApplicationDAO::getApplication(deviceId, appCode);
|
const ApplicationInfo app = ApplicationDAO::getApplication(deviceId, appCode);
|
||||||
|
|
||||||
|
if (app.fullName.trimmed().isEmpty() || app.phone.trimmed().isEmpty()) {
|
||||||
|
qWarning() << "[Black] createBankProfileIfNeeded: skipping — fullName or phone is empty";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const QMap<QString, int> currencyCodes = {
|
const QMap<QString, int> currencyCodes = {
|
||||||
{"RUB", 643}, {"USD", 840}, {"KRW", 410}, {"AZN", 944}, {"ARS", 32}
|
{"RUB", 643}, {"USD", 840}, {"KRW", 410}, {"AZN", 944}, {"ARS", 32}
|
||||||
};
|
};
|
||||||
const int currencyCode = currencyCodes.value(app.currency.toUpper(), 840);
|
const int currencyCode = currencyCodes.value(app.currency.toUpper(), 840);
|
||||||
const QStringList parts = app.fullName.split(' ', Qt::SkipEmptyParts);
|
const QStringList parts = app.fullName.split(' ', Qt::SkipEmptyParts);
|
||||||
|
|
||||||
|
// Нормализуем телефон: оставляем только цифры, добавляем код страны и "+"
|
||||||
|
const QSettings settings("config.ini", QSettings::IniFormat);
|
||||||
|
const QString phoneCode = settings.value(appCode + "/phone_code").toString();
|
||||||
|
QString phone = app.phone;
|
||||||
|
phone.remove(QRegularExpression("[^0-9]"));
|
||||||
|
if (!phoneCode.isEmpty() && !phone.startsWith(phoneCode)) {
|
||||||
|
if (phone.startsWith('8') && phoneCode != "8") {
|
||||||
|
phone.replace(0, 1, phoneCode);
|
||||||
|
} else {
|
||||||
|
phone.prepend(phoneCode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
phone.prepend('+');
|
||||||
|
|
||||||
QJsonObject profileBody;
|
QJsonObject profileBody;
|
||||||
profileBody["first_name"] = parts.value(0);
|
profileBody["first_name"] = parts.value(0);
|
||||||
profileBody["middle_name"] = parts.size() >= 3 ? parts.value(1) : QString("");
|
profileBody["middle_name"] = parts.size() >= 3 ? parts.value(1) : QString("");
|
||||||
profileBody["last_name"] = parts.size() >= 3 ? parts.value(2) : parts.value(1);
|
profileBody["last_name"] = parts.size() >= 3 ? parts.value(2) : parts.value(1);
|
||||||
profileBody["bank_name"] = appCode;
|
profileBody["bank_name"] = appCode;
|
||||||
profileBody["phone_number"] = app.phone.simplified().remove(' ');
|
profileBody["phone_number"] = phone;
|
||||||
profileBody["balance"] = QString::number(qRound64(app.amount * 100));
|
profileBody["balance"] = QString::number(qRound64(app.amount * 100));
|
||||||
profileBody["state"] = (app.status == "active") ? "enabled" : "disabled";
|
profileBody["state"] = (app.status == "active") ? "enabled" : "disabled";
|
||||||
profileBody["currency"] = currencyCode;
|
profileBody["currency"] = currencyCode;
|
||||||
|
|||||||
@ -3,6 +3,8 @@
|
|||||||
#include <QJsonArray>
|
#include <QJsonArray>
|
||||||
#include <QJsonObject>
|
#include <QJsonObject>
|
||||||
#include <QRandomGenerator>
|
#include <QRandomGenerator>
|
||||||
|
#include <QRegularExpression>
|
||||||
|
#include <QSettings>
|
||||||
#include <QThread>
|
#include <QThread>
|
||||||
|
|
||||||
#include "adb/AdbUtils.h"
|
#include "adb/AdbUtils.h"
|
||||||
@ -293,18 +295,37 @@ void CommonScript::updateTransactionData(
|
|||||||
void CommonScript::createBankProfileIfNeeded(const QString &deviceId, const QString &appCode) {
|
void CommonScript::createBankProfileIfNeeded(const QString &deviceId, const QString &appCode) {
|
||||||
const ApplicationInfo app = ApplicationDAO::getApplication(deviceId, appCode);
|
const ApplicationInfo app = ApplicationDAO::getApplication(deviceId, appCode);
|
||||||
|
|
||||||
|
if (app.fullName.trimmed().isEmpty() || app.phone.trimmed().isEmpty()) {
|
||||||
|
qWarning() << "[Ozon] createBankProfileIfNeeded: skipping — fullName or phone is empty";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const QMap<QString, int> currencyCodes = {
|
const QMap<QString, int> currencyCodes = {
|
||||||
{"RUB", 643}, {"USD", 840}, {"KRW", 410}, {"AZN", 944}, {"ARS", 32}
|
{"RUB", 643}, {"USD", 840}, {"KRW", 410}, {"AZN", 944}, {"ARS", 32}
|
||||||
};
|
};
|
||||||
const int currencyCode = currencyCodes.value(app.currency.toUpper(), 643);
|
const int currencyCode = currencyCodes.value(app.currency.toUpper(), 643);
|
||||||
const QStringList parts = app.fullName.split(' ', Qt::SkipEmptyParts);
|
const QStringList parts = app.fullName.split(' ', Qt::SkipEmptyParts);
|
||||||
|
|
||||||
|
// Нормализуем телефон: оставляем только цифры, добавляем код страны и "+"
|
||||||
|
const QSettings settings("config.ini", QSettings::IniFormat);
|
||||||
|
const QString phoneCode = settings.value(appCode + "/phone_code").toString();
|
||||||
|
QString phone = app.phone;
|
||||||
|
phone.remove(QRegularExpression("[^0-9]"));
|
||||||
|
if (!phoneCode.isEmpty() && !phone.startsWith(phoneCode)) {
|
||||||
|
if (phone.startsWith('8') && phoneCode != "8") {
|
||||||
|
phone.replace(0, 1, phoneCode);
|
||||||
|
} else {
|
||||||
|
phone.prepend(phoneCode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
phone.prepend('+');
|
||||||
|
|
||||||
QJsonObject profileBody;
|
QJsonObject profileBody;
|
||||||
profileBody["first_name"] = parts.value(0);
|
profileBody["first_name"] = parts.value(0);
|
||||||
profileBody["middle_name"] = parts.size() >= 3 ? parts.value(1) : QString("");
|
profileBody["middle_name"] = parts.size() >= 3 ? parts.value(1) : QString("");
|
||||||
profileBody["last_name"] = parts.size() >= 3 ? parts.value(2) : parts.value(1);
|
profileBody["last_name"] = parts.size() >= 3 ? parts.value(2) : parts.value(1);
|
||||||
profileBody["bank_name"] = appCode;
|
profileBody["bank_name"] = appCode;
|
||||||
profileBody["phone_number"] = app.phone.simplified().remove(' ');
|
profileBody["phone_number"] = phone;
|
||||||
profileBody["balance"] = QString::number(qRound64(app.amount * 100));
|
profileBody["balance"] = QString::number(qRound64(app.amount * 100));
|
||||||
profileBody["state"] = (app.status == "active") ? "enabled" : "disabled";
|
profileBody["state"] = (app.status == "active") ? "enabled" : "disabled";
|
||||||
profileBody["currency"] = currencyCode;
|
profileBody["currency"] = currencyCode;
|
||||||
|
|||||||
@ -1,297 +0,0 @@
|
|||||||
#include "CommonScript.h"
|
|
||||||
|
|
||||||
#include <QJsonArray>
|
|
||||||
#include <QJsonObject>
|
|
||||||
#include <QRandomGenerator>
|
|
||||||
#include <QThread>
|
|
||||||
|
|
||||||
#include "adb/AdbUtils.h"
|
|
||||||
#include "net/NetworkService.h"
|
|
||||||
|
|
||||||
namespace Rshb {
|
|
||||||
|
|
||||||
CommonScript::CommonScript(QObject *parent)
|
|
||||||
: QObject(parent) {
|
|
||||||
}
|
|
||||||
|
|
||||||
CommonScript::~CommonScript() = default;
|
|
||||||
|
|
||||||
void CommonScript::start() {
|
|
||||||
doStart();
|
|
||||||
emit finished();
|
|
||||||
}
|
|
||||||
|
|
||||||
Node CommonScript::swipeToButton(
|
|
||||||
const QString &deviceId,
|
|
||||||
const QString &text, int &counter, const int width, const int height
|
|
||||||
) {
|
|
||||||
for (int i = 0; i < 10; ++i) {
|
|
||||||
if (Node button = xmlScreenParser.findButtonNode(text, true); button.x() > 0 && button.y() > 0) {
|
|
||||||
return button;
|
|
||||||
}
|
|
||||||
const int x = width / 2;
|
|
||||||
const int offset = height / 4;
|
|
||||||
AdbUtils::makeSwipe(deviceId, x, height - offset, x, offset);
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++counter));
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CommonScript::inputPinCode(const QString &deviceId, const QList<Node> &pincode) {
|
|
||||||
for (const Node &node: pincode) {
|
|
||||||
const bool completePincode = AdbUtils::makeTap(deviceId, node.x(), node.y());
|
|
||||||
if (!completePincode) {
|
|
||||||
AdbUtils::makeTap(deviceId, node.x(), node.y());
|
|
||||||
}
|
|
||||||
QThread::msleep(QRandomGenerator::global()->bounded(100, 901));
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CommonScript::runAppAndGoToHomeScreen(
|
|
||||||
const QString &deviceId,
|
|
||||||
const QString &packageName,
|
|
||||||
const QString &pinCode,
|
|
||||||
const int width,
|
|
||||||
const int height
|
|
||||||
) {
|
|
||||||
// Запустить устройство
|
|
||||||
if (const QString pid = AdbUtils::tryToGetRunningAppPid(deviceId, packageName); !pid.isEmpty()) {
|
|
||||||
qDebug() << "Process already running, pid: " << pid;
|
|
||||||
AdbUtils::getScreenDumpAsXml(deviceId, 1000);
|
|
||||||
AdbUtils::tryToKillApplication(deviceId, packageName);
|
|
||||||
}
|
|
||||||
if (!AdbUtils::tryToStartApplication(deviceId, packageName)) {
|
|
||||||
AdbUtils::takeScreenshot(deviceId, "run_app_error");
|
|
||||||
qWarning() << "Process has not started";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Даем минимальное время на запуск
|
|
||||||
QThread::msleep(4500);
|
|
||||||
int counter = 0;
|
|
||||||
bool findAndInputPincode = false;
|
|
||||||
|
|
||||||
while (true) {
|
|
||||||
counter++;
|
|
||||||
|
|
||||||
// Если более 10 раз мы пытаемся перейти на домашнюю
|
|
||||||
if (counter > 10) {
|
|
||||||
AdbUtils::takeScreenshot(deviceId, "too_many_attempts");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
|
|
||||||
|
|
||||||
if (xmlScreenParser.isHomeScreen()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Проверяем на банеры после пин-кодом
|
|
||||||
Node closeBannerOrDialogNode = xmlScreenParser.tryToFindBannerOrDialog(width, height);
|
|
||||||
if (closeBannerOrDialogNode.x() != -1 && closeBannerOrDialogNode.y() != -1) {
|
|
||||||
AdbUtils::makeTap(deviceId, closeBannerOrDialogNode.x(), closeBannerOrDialogNode.y());
|
|
||||||
QThread::msleep(1000);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Проверяем на банеры перед пин-кодом
|
|
||||||
Node closeBannerNode = xmlScreenParser.tryToFindSecurityBanner();
|
|
||||||
if (!closeBannerNode.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(deviceId, closeBannerNode.x(), closeBannerNode.y());
|
|
||||||
QThread::msleep(1000);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Проверяем, что это экран ввода пин-кода
|
|
||||||
if (!findAndInputPincode) {
|
|
||||||
if (const QList<Node> pincode = xmlScreenParser.tryToFindPinCode(pinCode, "Введите ПИН");
|
|
||||||
pincode.size() == 4) {
|
|
||||||
// чтобы пробудить экран
|
|
||||||
if (Node textPinCodeNode = xmlScreenParser.findTextNode("Введите ПИН"); !textPinCodeNode.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(deviceId, textPinCodeNode.x(), textPinCodeNode.y());
|
|
||||||
}
|
|
||||||
inputPinCode(deviceId, pincode);
|
|
||||||
// После ввода пин-код нужно сделать задержку, пока подгрузка идет, чтобы снова не спарсить
|
|
||||||
findAndInputPincode = true;
|
|
||||||
QThread::msleep(3000);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QThread::msleep(1000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CommonScript::tryToCloseAllBannersOnHomePage(const QString &deviceId, const int width, const int height) {
|
|
||||||
Node closeBannerOrDialogNode = xmlScreenParser.tryToFindBannerOrDialog(width, height);
|
|
||||||
if (closeBannerOrDialogNode.x() != -1 && closeBannerOrDialogNode.y() != -1) {
|
|
||||||
AdbUtils::makeTap(deviceId, closeBannerOrDialogNode.x(), closeBannerOrDialogNode.y());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO тут все другие банеры попробовать закрыть
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CommonScript::goToAllProducts(
|
|
||||||
const QString &deviceId,
|
|
||||||
const int width,
|
|
||||||
const int height
|
|
||||||
) {
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, m_counter));
|
|
||||||
if (tryToCloseAllBannersOnHomePage(deviceId, width, height)) {
|
|
||||||
QThread::msleep(500);
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (xmlScreenParser.isHomeScreen()) {
|
|
||||||
// идем на экран "Все продукты"
|
|
||||||
if (Node allCardTitle = xmlScreenParser.findTextNode("Счета и карты"); !allCardTitle.isEmpty()) {
|
|
||||||
// 1. Если нет кнопки видимой, свайпаем. Кликаем на "Все продукты"
|
|
||||||
for (int i = 0; i < 5; ++i) {
|
|
||||||
Node allProductsBtn = xmlScreenParser.findButtonNode("Все продукты", false);
|
|
||||||
if (allProductsBtn.x() > 0 && allProductsBtn.y() > 0 && allProductsBtn.y() < height - 200) {
|
|
||||||
AdbUtils::makeTap(deviceId, allProductsBtn.x(), allProductsBtn.y());
|
|
||||||
QThread::msleep(1000);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
AdbUtils::makeSwipe(deviceId,
|
|
||||||
allCardTitle.x(), allCardTitle.y(),
|
|
||||||
allCardTitle.x(), allCardTitle.y() - 200);
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < 5; ++i) {
|
|
||||||
Node allProductsTitle = xmlScreenParser.findTextNode("Все продукты");
|
|
||||||
// Проверяем что вверху заголовок
|
|
||||||
if (!allProductsTitle.isEmpty() && allProductsTitle.y() < 300) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
QThread::msleep(1000);
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// FIXME пишем в БД, что не дошли до домашней страницы, и завершаемся
|
|
||||||
// сохраняем скрин приложения
|
|
||||||
// дделаем алерт
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// FIXME
|
|
||||||
qDebug() << "Not home screen...";
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CommonScript::findAndTapOnAccount(const QString &deviceId, const QString &accountNumbers) {
|
|
||||||
QList<QPair<AccountInfo, Node> > accounts = xmlScreenParser.parseAccountsInfo();
|
|
||||||
for (auto &[account, node]: accounts) {
|
|
||||||
// FIXME будем считать что числа последние везде уникальные
|
|
||||||
if (accountNumbers == account.lastNumbers) {
|
|
||||||
qDebug() << "findAndTapOnAccount: " << accountNumbers;
|
|
||||||
AdbUtils::makeTap(deviceId, node.x(), node.y());
|
|
||||||
QThread::msleep(1000);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void CommonScript::postAccountsData(const QList<QPair<AccountInfo, Node> > &accounts) {
|
|
||||||
if (accounts.isEmpty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto *thread = new QThread;
|
|
||||||
auto *worker = new NetworkService;
|
|
||||||
|
|
||||||
QJsonArray list;
|
|
||||||
for (const QPair<AccountInfo, Node> &pair: accounts) {
|
|
||||||
QJsonObject obj;
|
|
||||||
AccountInfo account = pair.first;
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
// FIXME доставить десктоп ид из настроеек
|
|
||||||
worker->setDeviceId(accounts.first().first.deviceId);
|
|
||||||
worker->setPayload(QJsonDocument(list).toJson());
|
|
||||||
worker->moveToThread(thread);
|
|
||||||
connect(thread, &QThread::started, worker, &NetworkService::postAccountsData);
|
|
||||||
connect(worker, &NetworkService::finished, thread, &QThread::quit);
|
|
||||||
connect(worker, &NetworkService::finished, worker, &QObject::deleteLater);
|
|
||||||
connect(thread, &QThread::finished, thread, &QThread::deleteLater);
|
|
||||||
thread->start();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CommonScript::postNewTransactionData(const AccountInfo &account, const TransactionInfo &transaction) {
|
|
||||||
auto *thread = new QThread;
|
|
||||||
auto *worker = new NetworkService;
|
|
||||||
|
|
||||||
QJsonObject obj;
|
|
||||||
obj["id"] = transaction.id;
|
|
||||||
obj["amount"] = transaction.amount;
|
|
||||||
obj["name"] = transaction.name;
|
|
||||||
obj["fee"] = transaction.fee;
|
|
||||||
obj["status"] = transactionStatusToString(transaction.status);
|
|
||||||
obj["type"] = transactionTypeToString(transaction.type);
|
|
||||||
obj["phone"] = transaction.phone;
|
|
||||||
obj["description"] = transaction.description;
|
|
||||||
obj["updatedDescription"] = transaction.updatedDescription;
|
|
||||||
obj["bankName"] = transaction.bankName;
|
|
||||||
obj["bankTime"] = transaction.bankTime;
|
|
||||||
obj["bankTransactionId"] = transaction.bankTrExternalId;
|
|
||||||
|
|
||||||
// FIXME доставить десктоп ид из настроеек
|
|
||||||
worker->setDeviceId(account.deviceId);
|
|
||||||
worker->addExtra("lastNumbers", account.lastNumbers);
|
|
||||||
worker->addExtra("transactionId", transaction.id);
|
|
||||||
worker->setPayload(QJsonDocument(obj).toJson());
|
|
||||||
worker->moveToThread(thread);
|
|
||||||
connect(thread, &QThread::started, worker, &NetworkService::insertTransactionData);
|
|
||||||
connect(worker, &NetworkService::finished, thread, &QThread::quit);
|
|
||||||
connect(worker, &NetworkService::finished, worker, &QObject::deleteLater);
|
|
||||||
connect(thread, &QThread::finished, thread, &QThread::deleteLater);
|
|
||||||
thread->start();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CommonScript::updateTransactionData(
|
|
||||||
const AccountInfo &account,
|
|
||||||
const int transactionId,
|
|
||||||
const TransactionStatus status,
|
|
||||||
const QString &oldDesc,
|
|
||||||
const QString &newDesc
|
|
||||||
) {
|
|
||||||
auto *thread = new QThread;
|
|
||||||
auto *worker = new NetworkService;
|
|
||||||
|
|
||||||
QJsonObject obj;
|
|
||||||
obj["id"] = transactionId;
|
|
||||||
obj["status"] = transactionStatusToString(status);
|
|
||||||
obj["description"] = newDesc;
|
|
||||||
obj["updatedDescription"] = oldDesc;
|
|
||||||
|
|
||||||
// FIXME доставить десктоп ид из настроеек
|
|
||||||
worker->setDeviceId(account.deviceId);
|
|
||||||
worker->addExtra("lastNumbers", account.lastNumbers);
|
|
||||||
worker->setPayload(QJsonDocument(obj).toJson());
|
|
||||||
worker->moveToThread(thread);
|
|
||||||
connect(thread, &QThread::started, worker, &NetworkService::updateTransactionData);
|
|
||||||
connect(worker, &NetworkService::finished, thread, &QThread::quit);
|
|
||||||
connect(worker, &NetworkService::finished, worker, &QObject::deleteLater);
|
|
||||||
connect(thread, &QThread::finished, thread, &QThread::deleteLater);
|
|
||||||
thread->start();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CommonScript::stop() {
|
|
||||||
m_running = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Rshb
|
|
||||||
@ -1,78 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <QObject>
|
|
||||||
#include "ScreenXmlParser.h"
|
|
||||||
|
|
||||||
namespace Rshb {
|
|
||||||
|
|
||||||
class CommonScript : public QObject {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit CommonScript(QObject *parent = nullptr);
|
|
||||||
|
|
||||||
~CommonScript() override;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual void doStart() = 0;
|
|
||||||
|
|
||||||
// static method
|
|
||||||
static bool inputPinCode(const QString &deviceId, const QList<Node> &pincode);
|
|
||||||
|
|
||||||
bool goToAllProducts(
|
|
||||||
const QString &deviceId,
|
|
||||||
int width,
|
|
||||||
int height
|
|
||||||
);
|
|
||||||
|
|
||||||
bool findAndTapOnAccount(const QString &deviceId, const QString &accountNumbers);
|
|
||||||
|
|
||||||
void postAccountsData(const QList<QPair<AccountInfo, Node> > &accounts);
|
|
||||||
|
|
||||||
void postNewTransactionData(const AccountInfo &account, const TransactionInfo &transaction);
|
|
||||||
|
|
||||||
void updateTransactionData(
|
|
||||||
const AccountInfo &account,
|
|
||||||
int transactionId,
|
|
||||||
TransactionStatus status,
|
|
||||||
const QString &oldDesc,
|
|
||||||
const QString &newDesc
|
|
||||||
);
|
|
||||||
|
|
||||||
Node swipeToButton(
|
|
||||||
const QString &deviceId,
|
|
||||||
const QString &text,
|
|
||||||
int &counter, int width, int height
|
|
||||||
);
|
|
||||||
|
|
||||||
bool runAppAndGoToHomeScreen(
|
|
||||||
const QString &deviceId,
|
|
||||||
const QString &packageName,
|
|
||||||
const QString &pinCode,
|
|
||||||
int width,
|
|
||||||
int height
|
|
||||||
);
|
|
||||||
|
|
||||||
bool tryToCloseAllBannersOnHomePage(
|
|
||||||
const QString &deviceId, int width, int height
|
|
||||||
);
|
|
||||||
|
|
||||||
bool m_running = true;
|
|
||||||
ScreenXmlParser xmlScreenParser;
|
|
||||||
int m_counter = 0;
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void finished();
|
|
||||||
|
|
||||||
void finishedWithResult(const QString &result);
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
virtual void start() final;
|
|
||||||
|
|
||||||
virtual void stop() final;
|
|
||||||
|
|
||||||
private:
|
|
||||||
Q_DISABLE_COPY(CommonScript);
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Rshb
|
|
||||||
@ -1,399 +0,0 @@
|
|||||||
#include "GetLastDaysHistoryScript.h"
|
|
||||||
|
|
||||||
#include <QJsonObject>
|
|
||||||
#include <QRandomGenerator>
|
|
||||||
#include <QThread>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
#include "DatabaseManager.h"
|
|
||||||
#include "adb/AdbUtils.h"
|
|
||||||
#include "dao/AccountDAO.h"
|
|
||||||
#include "dao/ApplicationDAO.h"
|
|
||||||
#include "dao/DeviceDAO.h"
|
|
||||||
#include "dao/TransactionDAO.h"
|
|
||||||
#include "db/DeviceInfo.h"
|
|
||||||
#include "net/NetworkService.h"
|
|
||||||
#include "time/DateUtils.h"
|
|
||||||
|
|
||||||
namespace Rshb {
|
|
||||||
|
|
||||||
GetLastDaysHistoryScript::GetLastDaysHistoryScript(
|
|
||||||
AccountInfo account,
|
|
||||||
QObject *parent
|
|
||||||
) : CommonScript(parent),
|
|
||||||
m_account(std::move(account)) {
|
|
||||||
}
|
|
||||||
|
|
||||||
GetLastDaysHistoryScript::~GetLastDaysHistoryScript() = default;
|
|
||||||
|
|
||||||
QList<TransactionInfo> findSavedTransaction(
|
|
||||||
const QList<TransactionInfo> &transactions,
|
|
||||||
const TransactionInfo &parsed
|
|
||||||
) {
|
|
||||||
QList<TransactionInfo> txs;
|
|
||||||
const QDateTime dateTime = QDateTime::fromString(parsed.bankTime, "dd.MM.yyyy"); // Московское время
|
|
||||||
|
|
||||||
for (const TransactionInfo &info: transactions) {
|
|
||||||
QDateTime timestamp = info.timestamp;
|
|
||||||
QString description = parsed.description;
|
|
||||||
// если тот же день
|
|
||||||
if (dateTime.date() == timestamp.date() && parsed.amount == info.amount) {
|
|
||||||
// Перевод Надежда Юрьевна К** в Альфа-Банк через СБП, по номеру телефона +79641815...
|
|
||||||
if (description.contains("Перевод")) {
|
|
||||||
if (description.contains(info.name)) {
|
|
||||||
txs.append(info);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Перевод по карте
|
|
||||||
if (description == info.description) {
|
|
||||||
txs.append(info);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return txs;
|
|
||||||
}
|
|
||||||
|
|
||||||
int countSimilar(const TransactionInfo &transaction, const QList<TransactionInfo> &transactions) {
|
|
||||||
int count = 0;
|
|
||||||
for (const TransactionInfo &info: transactions) {
|
|
||||||
if (info.amount == transaction.amount
|
|
||||||
&& info.description == transaction.description
|
|
||||||
&& info.bankTime == transaction.bankTime) {
|
|
||||||
++count;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString formatPrice(const double value) {
|
|
||||||
QString sign = value < 0 ? "Минус" : "Плюс";
|
|
||||||
const auto intValue = static_cast<qint64>(std::abs(value)); // округление до целого
|
|
||||||
|
|
||||||
QString number = QString::number(intValue);
|
|
||||||
QString formatted;
|
|
||||||
|
|
||||||
int count = 0;
|
|
||||||
for (int i = number.length() - 1; i >= 0; --i) {
|
|
||||||
formatted.prepend(number[i]);
|
|
||||||
++count;
|
|
||||||
if (count % 3 == 0 && i != 0) {
|
|
||||||
formatted.prepend(' ');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return QString("%1 %2").arg(sign, formatted);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GetLastDaysHistoryScript::saveAndPostNewTransactionData(
|
|
||||||
const AccountInfo &account,
|
|
||||||
const TransactionInfo &transaction,
|
|
||||||
const TransactionStatus &status
|
|
||||||
) {
|
|
||||||
TransactionInfo tr;
|
|
||||||
tr.accountId = account.id;
|
|
||||||
tr.description = transaction.description;
|
|
||||||
tr.bankTime = transaction.bankTime;
|
|
||||||
tr.bankName = transaction.bankName;
|
|
||||||
tr.amount = transaction.amount;
|
|
||||||
tr.phone = transaction.phone;
|
|
||||||
tr.updateTime = DateUtils::getUtcNow();
|
|
||||||
tr.fee = transaction.fee;
|
|
||||||
tr.name = transaction.name;
|
|
||||||
tr.bankTrExternalId = transaction.bankTrExternalId;
|
|
||||||
tr.status = status;
|
|
||||||
tr.type = transaction.description.startsWith("Перевод") ? TransactionType::Phone : TransactionType::Card;
|
|
||||||
tr.completeTime = DateUtils::getUtcNow();
|
|
||||||
tr.id = TransactionDAO::insertTransaction(tr);
|
|
||||||
|
|
||||||
if (tr.id == -1) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
postNewTransactionData(account, tr);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GetLastDaysHistoryScript::updateAndPostTransactionData(
|
|
||||||
const AccountInfo &account,
|
|
||||||
const int transactionId,
|
|
||||||
const TransactionStatus status,
|
|
||||||
const QString &oldDesc,
|
|
||||||
const QString &newDesc
|
|
||||||
) {
|
|
||||||
if (TransactionDAO::updateTransaction(transactionId, status, oldDesc, newDesc)) {
|
|
||||||
updateTransactionData(account, transactionId, status, oldDesc, newDesc);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GetLastDaysHistoryScript::doStart() {
|
|
||||||
// берем все транзакции из БД
|
|
||||||
const DeviceInfo device = DeviceDAO::getDeviceById(m_account.deviceId);
|
|
||||||
const ApplicationInfo app = ApplicationDAO::getApplication(m_account.deviceId, m_account.appCode);
|
|
||||||
|
|
||||||
if (!xmlScreenParser.isHomeScreen()) {
|
|
||||||
if (!runAppAndGoToHomeScreen(device.id, app.package, app.pinCode, device.screenWidth, device.screenHeight)) {
|
|
||||||
m_error = "Не смогли дойти до домашней страницы";
|
|
||||||
qCritical() << m_error;
|
|
||||||
emit finishedWithResult(m_error);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter));
|
|
||||||
Node closeBannerOrDialogNode = xmlScreenParser.tryToFindBannerOrDialog(device.screenWidth, device.screenHeight);
|
|
||||||
if (closeBannerOrDialogNode.x() != -1 && closeBannerOrDialogNode.y() != -1) {
|
|
||||||
AdbUtils::makeTap(device.id, closeBannerOrDialogNode.x(), closeBannerOrDialogNode.y());
|
|
||||||
QThread::msleep(500);
|
|
||||||
}
|
|
||||||
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter));
|
|
||||||
|
|
||||||
if (xmlScreenParser.isHomeScreen()) {
|
|
||||||
if (goToAllProducts(device.id, device.screenWidth, device.screenHeight)) {
|
|
||||||
QList<TransactionInfo> localTransactions = TransactionDAO::getTransactionsWithinHours(m_account.id, 48);
|
|
||||||
|
|
||||||
QList<QPair<AccountInfo, Node> > accounts = xmlScreenParser.parseAccountsInfo();
|
|
||||||
for (auto &[account, node]: accounts) {
|
|
||||||
account.deviceId = m_account.deviceId;
|
|
||||||
account.appCode = m_account.appCode;
|
|
||||||
if (!AccountDAO::upsertAccount(account)) {
|
|
||||||
qDebug() << "Not updated: " << account.lastNumbers;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
postAccountsData(accounts);
|
|
||||||
|
|
||||||
findAndTapOnAccount(device.id, m_account.lastNumbers);
|
|
||||||
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter));
|
|
||||||
Node actionBtn = xmlScreenParser.findButtonNode("Действия", false);
|
|
||||||
if (!actionBtn.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(m_account.deviceId, actionBtn.x(), actionBtn.y());
|
|
||||||
QThread::msleep(200);
|
|
||||||
} else {
|
|
||||||
m_error = "All action btn not found";
|
|
||||||
qCritical() << m_error;
|
|
||||||
emit finishedWithResult(m_error);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Node reportButton = swipeToButton(
|
|
||||||
m_account.deviceId,
|
|
||||||
"Выписка",
|
|
||||||
m_counter, device.screenWidth,
|
|
||||||
device.screenHeight
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!reportButton.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(m_account.deviceId, reportButton.x(), reportButton.y());
|
|
||||||
QThread::msleep(1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter));
|
|
||||||
|
|
||||||
Node reportTitle = xmlScreenParser.findTextNode("Выписка");
|
|
||||||
if (!reportTitle.isEmpty() && reportTitle.y() < 300) {
|
|
||||||
QDate beforeYesterday = DateUtils::getMoscowNow().date().addDays(-2);
|
|
||||||
QString beforeYesterdayTitle = beforeYesterday.toString("dd.MM.yyyy");
|
|
||||||
|
|
||||||
for (int i = 0; i < 5; ++i) {
|
|
||||||
Node byDayTitle = xmlScreenParser.findTextNode(beforeYesterdayTitle);
|
|
||||||
if (!byDayTitle.isEmpty()) {
|
|
||||||
qWarning() << "--- beforeYesterdayTitle found!";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
AdbUtils::makeSwipe(
|
|
||||||
m_account.deviceId,
|
|
||||||
device.screenWidth / 2, device.screenHeight / 4 * 3,
|
|
||||||
device.screenWidth / 2, device.screenHeight / 4
|
|
||||||
);
|
|
||||||
QThread::msleep(1000);
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
m_error = "All action - report title not found";
|
|
||||||
qCritical() << m_error;
|
|
||||||
emit finishedWithResult(m_error);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// все поддвержденные
|
|
||||||
QList<TransactionInfo> parsedTransactions = xmlScreenParser.parseTodayAndYesterdayReportHistory();
|
|
||||||
QSet<int> parsedTransactionIds;
|
|
||||||
for (const TransactionInfo &transaction: parsedTransactions) {
|
|
||||||
bool updated = false;
|
|
||||||
|
|
||||||
for (const TransactionInfo &saved: localTransactions) {
|
|
||||||
if (parsedTransactionIds.contains(saved.id)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
QDate sDate = QDateTime::fromString(saved.bankTime, "dd.MM.yyyy HH:mm:ss").date();
|
|
||||||
if (!sDate.isValid()) {
|
|
||||||
sDate = QDateTime::fromString(saved.bankTime, "dd.MM.yyyy").date();
|
|
||||||
}
|
|
||||||
QDate pDate = QDateTime::fromString(transaction.bankTime, "dd.MM.yyyy HH:mm:ss").date();
|
|
||||||
if (!pDate.isValid()) {
|
|
||||||
pDate = QDateTime::fromString(transaction.bankTime, "dd.MM.yyyy").date();
|
|
||||||
}
|
|
||||||
// Если сумма и дата совпадают
|
|
||||||
if (saved.amount == transaction.amount && sDate == pDate) {
|
|
||||||
if (transaction.description.startsWith("Перевод")) {
|
|
||||||
// Перевод по номеру
|
|
||||||
if (saved.bankName == transaction.bankName && saved.phone == transaction.phone) {
|
|
||||||
parsedTransactionIds.insert(saved.id);
|
|
||||||
updated = true;
|
|
||||||
if (saved.status != TransactionStatus::Complete || saved.description.isEmpty()) {
|
|
||||||
if (!TransactionDAO::updateTransaction(
|
|
||||||
saved.id,
|
|
||||||
TransactionStatus::Complete,
|
|
||||||
saved.description,
|
|
||||||
transaction.description
|
|
||||||
)) {
|
|
||||||
qDebug().noquote().nospace() << "--- updated+phone failed" <<
|
|
||||||
convertTransactionToString(transaction);;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// перевод по карте
|
|
||||||
// перезаписать saved.description -> updatedDescription если не равны
|
|
||||||
if (!saved.description.isEmpty()) {
|
|
||||||
if (saved.description == transaction.description) {
|
|
||||||
// описания совпадают
|
|
||||||
if (saved.status != TransactionStatus::Complete) {
|
|
||||||
if (!TransactionDAO::updateTransaction(
|
|
||||||
saved.id,
|
|
||||||
TransactionStatus::Complete,
|
|
||||||
saved.description,
|
|
||||||
transaction.description
|
|
||||||
)) {
|
|
||||||
qDebug().noquote().nospace() << "--- updated+card[description same] failed"
|
|
||||||
<<
|
|
||||||
convertTransactionToString(transaction);;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
parsedTransactionIds.insert(saved.id);
|
|
||||||
updated = true;
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
// описания не совпадают, то пробуем найти такое же, если не находим то это новая
|
|
||||||
bool findWithSameName = false;
|
|
||||||
for (const TransactionInfo &saved2: localTransactions) {
|
|
||||||
if (saved2.description == transaction.description && !parsedTransactionIds.
|
|
||||||
contains(
|
|
||||||
saved2.id)) {
|
|
||||||
// мы нашли с одинаковым описанием и еще не обработанную
|
|
||||||
if (saved2.status != TransactionStatus::Complete) {
|
|
||||||
if (!TransactionDAO::updateTransaction(
|
|
||||||
saved2.id,
|
|
||||||
TransactionStatus::Complete,
|
|
||||||
saved2.description,
|
|
||||||
transaction.description
|
|
||||||
)) {
|
|
||||||
qDebug().noquote().nospace() <<
|
|
||||||
"--- updated+card2[description same] failed"
|
|
||||||
<<
|
|
||||||
convertTransactionToString(transaction);;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
parsedTransactionIds.insert(saved2.id);
|
|
||||||
updated = true;
|
|
||||||
findWithSameName = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!findWithSameName) {
|
|
||||||
// обновляем описание
|
|
||||||
if (!TransactionDAO::updateTransaction(
|
|
||||||
saved.id,
|
|
||||||
TransactionStatus::Complete,
|
|
||||||
saved.description,
|
|
||||||
transaction.description
|
|
||||||
)) {
|
|
||||||
qDebug().noquote().nospace() <<
|
|
||||||
"--- updated+card2+new desc[description same] failed" <<
|
|
||||||
convertTransactionToString(transaction);;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
parsedTransactionIds.insert(saved.id);
|
|
||||||
updated = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// пустой описание
|
|
||||||
if (!TransactionDAO::updateTransaction(
|
|
||||||
saved.id,
|
|
||||||
TransactionStatus::Complete,
|
|
||||||
saved.description,
|
|
||||||
transaction.description
|
|
||||||
)) {
|
|
||||||
qDebug().noquote().nospace() <<
|
|
||||||
"--- updated+card[empty description]" <<
|
|
||||||
convertTransactionToString(transaction);;
|
|
||||||
}
|
|
||||||
parsedTransactionIds.insert(saved.id);
|
|
||||||
updated = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!updated) {
|
|
||||||
if (!saveAndPostNewTransactionData(m_account, transaction, TransactionStatus::Complete)) {
|
|
||||||
qDebug() << "--- saveAndPostNewTransactionData failed";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Если это перевод
|
|
||||||
// Если совпадает по сумме + телефон + банк дата (без времени) + банк
|
|
||||||
|
|
||||||
// Если по карте, мы знаем ток дату + сумма
|
|
||||||
}
|
|
||||||
Node waitTab = xmlScreenParser.findButtonNode("Ожидающие обработки", true);
|
|
||||||
if (!waitTab.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(m_account.deviceId, waitTab.x(), waitTab.y());
|
|
||||||
QThread::msleep(1000);
|
|
||||||
|
|
||||||
QList<TransactionInfo> parsedWaitTransactions = xmlScreenParser.parseTodayAndYesterdayReportHistory();
|
|
||||||
for (const TransactionInfo &transaction: parsedWaitTransactions) {
|
|
||||||
QList<TransactionInfo> localActualTransactions = TransactionDAO::getTransactionsWithinHours(
|
|
||||||
m_account.id, 48
|
|
||||||
);
|
|
||||||
for (const TransactionInfo &saved: localActualTransactions) {
|
|
||||||
if (saved.status != TransactionStatus::Wait) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
QDate sDate = QDateTime::fromString(saved.bankTime, "dd.MM.yyyy HH:mm:ss").date();
|
|
||||||
if (!sDate.isValid()) {
|
|
||||||
sDate = QDateTime::fromString(saved.bankTime, "dd.MM.yyyy").date();
|
|
||||||
}
|
|
||||||
QDate pDate = QDateTime::fromString(transaction.bankTime, "dd.MM.yyyy HH:mm:ss").date();
|
|
||||||
if (!pDate.isValid()) {
|
|
||||||
pDate = QDateTime::fromString(transaction.bankTime, "dd.MM.yyyy").date();
|
|
||||||
}
|
|
||||||
if (saved.amount == transaction.amount && sDate == pDate) {
|
|
||||||
// одно и тоже
|
|
||||||
} else {
|
|
||||||
if (!saveAndPostNewTransactionData(m_account, transaction, TransactionStatus::Wait)) {
|
|
||||||
qDebug() << "--- saveAndPostNewTransactionData - Wait failed";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
m_error = "GetLastDaysHistoryScript - home screen not found";
|
|
||||||
qWarning() << m_error;
|
|
||||||
emit finishedWithResult(m_error);
|
|
||||||
}
|
|
||||||
AdbUtils::goBack(m_account.deviceId);
|
|
||||||
AdbUtils::goBack(m_account.deviceId);
|
|
||||||
AdbUtils::goBack(m_account.deviceId);
|
|
||||||
emit finishedWithResult(m_error);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Rshb
|
|
||||||
@ -1,39 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include "CommonScript.h"
|
|
||||||
|
|
||||||
namespace Rshb {
|
|
||||||
|
|
||||||
class GetLastDaysHistoryScript final : public CommonScript {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
~GetLastDaysHistoryScript() override;
|
|
||||||
|
|
||||||
explicit GetLastDaysHistoryScript(
|
|
||||||
AccountInfo account,
|
|
||||||
QObject *parent = nullptr
|
|
||||||
);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void doStart() override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
const AccountInfo m_account;
|
|
||||||
QString m_error;
|
|
||||||
|
|
||||||
bool saveAndPostNewTransactionData(
|
|
||||||
const AccountInfo &account,
|
|
||||||
const TransactionInfo &transaction,
|
|
||||||
const TransactionStatus &status
|
|
||||||
);
|
|
||||||
|
|
||||||
bool updateAndPostTransactionData(
|
|
||||||
const AccountInfo &account,
|
|
||||||
int transactionId,
|
|
||||||
TransactionStatus status,
|
|
||||||
const QString &oldDesc,
|
|
||||||
const QString &newDesc
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Rshb
|
|
||||||
@ -1,513 +0,0 @@
|
|||||||
#include "HomeScreenScript.h"
|
|
||||||
|
|
||||||
#include <QThread>
|
|
||||||
#include <QDebug>
|
|
||||||
#include <QProcess>
|
|
||||||
#include <QRandomGenerator>
|
|
||||||
|
|
||||||
#include "ScreenXmlParser.h"
|
|
||||||
#include "adb/AdbUtils.h"
|
|
||||||
|
|
||||||
namespace Rshb {
|
|
||||||
|
|
||||||
|
|
||||||
HomeScreenScript::HomeScreenScript(QObject *parent)
|
|
||||||
: QObject(parent) {
|
|
||||||
}
|
|
||||||
|
|
||||||
HomeScreenScript::~HomeScreenScript() = default;
|
|
||||||
|
|
||||||
bool HomeScreenScript::goToHomeScreen(
|
|
||||||
const QString &deviceId,
|
|
||||||
const QString &packageName,
|
|
||||||
const QString &pinCode,
|
|
||||||
const int width,
|
|
||||||
const int height
|
|
||||||
) {
|
|
||||||
// Запустить устройство
|
|
||||||
if (const QString pid = AdbUtils::tryToGetRunningAppPid(deviceId, packageName); !pid.isEmpty()) {
|
|
||||||
qDebug() << "Process already running, pid: " << pid;
|
|
||||||
AdbUtils::getScreenDumpAsXml(deviceId, 1000);
|
|
||||||
AdbUtils::tryToKillApplication(deviceId, packageName);
|
|
||||||
}
|
|
||||||
if (!AdbUtils::tryToStartApplication(deviceId, packageName)) {
|
|
||||||
qWarning() << "Process has not started";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
xmlScreenParser.parseAndSaveXml(
|
|
||||||
AdbUtils::getScreenDumpAsXml(deviceId, 0)
|
|
||||||
);
|
|
||||||
|
|
||||||
// Даем минимальное время на запуск
|
|
||||||
QThread::msleep(4500);
|
|
||||||
int counter = 0;
|
|
||||||
int restarted = 0;
|
|
||||||
int totalCounter = 0;
|
|
||||||
bool findAndInputPincode = false;
|
|
||||||
while (true) {
|
|
||||||
counter++;
|
|
||||||
totalCounter++;
|
|
||||||
|
|
||||||
// 3 раза уже перезапускали приложение, завершаем попытки
|
|
||||||
if (restarted > 2) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Если более 30 секунд мы пытаемся перейти на домашнюю, перезапускаем
|
|
||||||
if (counter > 30) {
|
|
||||||
AdbUtils::tryToKillApplication(deviceId, packageName);
|
|
||||||
QThread::msleep(4500);
|
|
||||||
++restarted;
|
|
||||||
counter = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
const QString xml = AdbUtils::getScreenDumpAsXml(deviceId, totalCounter + 1);
|
|
||||||
xmlScreenParser.parseAndSaveXml(xml);
|
|
||||||
qDebug() << "Created xml+screenshot, idx: " << (totalCounter + 1);
|
|
||||||
|
|
||||||
if (xmlScreenParser.isHomeScreen()) {
|
|
||||||
qDebug() << "isHomeScreen!!!!!!!";
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Проверяем на банеры после пин-кодом
|
|
||||||
Node closeBannerOrDialogNode = xmlScreenParser.tryToFindBannerOrDialog(width, height);
|
|
||||||
if (closeBannerOrDialogNode.x() != -1 && closeBannerOrDialogNode.y() != -1) {
|
|
||||||
qDebug() << "--- tryToFindBannerOrDialog";
|
|
||||||
AdbUtils::makeTap(deviceId, closeBannerOrDialogNode.x(), closeBannerOrDialogNode.y());
|
|
||||||
QThread::msleep(1000);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Проверяем на банеры перед пин-кодом
|
|
||||||
Node closeBannerNode = xmlScreenParser.tryToFindSecurityBanner();
|
|
||||||
if (!closeBannerNode.isEmpty()) {
|
|
||||||
qDebug() << "--- tryToFindSecurityBanner";
|
|
||||||
AdbUtils::makeTap(deviceId, closeBannerNode.x(), closeBannerNode.y());
|
|
||||||
QThread::msleep(1000);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Проверяем, что это экран ввода пин-кода
|
|
||||||
if (!findAndInputPincode) {
|
|
||||||
if (const QList<Node> pincode = xmlScreenParser.tryToFindPinCode(pinCode, "Введите ПИН");
|
|
||||||
pincode.size() == 4) {
|
|
||||||
qDebug() << "--- tryToFindPinCode";
|
|
||||||
// делаем 4 тапа и ждем секунду и продолжаем
|
|
||||||
for (const Node &node: pincode) {
|
|
||||||
AdbUtils::makeTap(deviceId, node.x(), node.y());
|
|
||||||
QThread::msleep(QRandomGenerator::global()->bounded(200, 901));
|
|
||||||
}
|
|
||||||
// После ввода пин-код нужно сделать задержку, пока подгрузка идет, чтобы снова не спарсить
|
|
||||||
findAndInputPincode = true;
|
|
||||||
QThread::msleep(3000);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QThread::msleep(1000);
|
|
||||||
|
|
||||||
// Если что-то пойдет не по плану...
|
|
||||||
if (totalCounter > 100) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QString getPriceAsString(const double value) {
|
|
||||||
QString sign = value < 0 ? "Минус" : "Плюс";
|
|
||||||
const auto intValue = static_cast<qint64>(std::abs(value)); // округление до целого
|
|
||||||
|
|
||||||
QString number = QString::number(intValue);
|
|
||||||
QString formatted;
|
|
||||||
|
|
||||||
int count = 0;
|
|
||||||
for (int i = number.length() - 1; i >= 0; --i) {
|
|
||||||
formatted.prepend(number[i]);
|
|
||||||
++count;
|
|
||||||
if (count % 3 == 0 && i != 0) {
|
|
||||||
formatted.prepend(' ');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return QString("%1 %2").arg(sign, formatted);
|
|
||||||
}
|
|
||||||
|
|
||||||
Node swipeToButton(
|
|
||||||
ScreenXmlParser &xmlScreenParser, const QString &deviceId,
|
|
||||||
const QString &text, int &counter, const int width, const int height
|
|
||||||
) {
|
|
||||||
for (int i = 0; i < 10; ++i) {
|
|
||||||
if (Node button = xmlScreenParser.findButtonNode(text, true); button.x() > 0 && button.y() > 0) {
|
|
||||||
return button;
|
|
||||||
}
|
|
||||||
const int x = width / 2;
|
|
||||||
const int offset = height / 4;
|
|
||||||
AdbUtils::makeSwipe(deviceId, x, height - offset, x, offset);
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++counter));
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
void HomeScreenScript::start() {
|
|
||||||
// Достаем данные из БД по ИД транзакции, перед тем как запустить мы кладем в БД все данные
|
|
||||||
const QString deviceId = "6edc4a47";
|
|
||||||
const QString packageName = "ru.rshb.dbo";
|
|
||||||
const QString pinCode = "1102";
|
|
||||||
const int width = 720;
|
|
||||||
const int height = 1600;
|
|
||||||
|
|
||||||
const QString cardNumber = "7 1 8 3";
|
|
||||||
// В том числе и данные на каком устройстве это делать
|
|
||||||
// TODO тут код работы с БД
|
|
||||||
|
|
||||||
// +7 (964) 181-51-46
|
|
||||||
const QString phoneNumber = "+79641815146";
|
|
||||||
const QString bankName = "Альфа-Банк";
|
|
||||||
const QString paySum = "10";
|
|
||||||
|
|
||||||
int index = 0;
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++index));
|
|
||||||
|
|
||||||
// xmlScreenParser.test();
|
|
||||||
// тут просто получаем инфу которую спарсил
|
|
||||||
// == 1. Входящий (TransactionType::Phone)
|
|
||||||
// Перевод через СБП от Егор Иванович Ж (+7(000)-000-00-87) из Озон Банк (Ozon) на 40817810328000022077 .
|
|
||||||
// Идентификатор операции в СБП С2С B5121111443333300170011491301 , Дата операции 01.05.2025 14:14:41 Статус перевода Исполнен
|
|
||||||
// == 2. Исходящий (TransactionType::Phone)
|
|
||||||
// Перевод Надежда Иванкина К** в Сбербанк через СБП, по номеру телефона +79000810046, ID перевода 445900141, дата 03.05.2025
|
|
||||||
|
|
||||||
// (TransactionType::Card) -> T-BANK CARD2CARD
|
|
||||||
// TransactionInfo trInfo = xmlScreenParser.parseTransactionInfoHistory(width, height);
|
|
||||||
// qDebug().noquote().nospace() << convertTransactionToString(trInfo);
|
|
||||||
|
|
||||||
// Если начинается с ЕСПП - то не кликаем еще, ждет обработку
|
|
||||||
// А все переводы по карте - они не начинаются со слова "Перевод" ->
|
|
||||||
// .. пробуем кликать, но если не кликается ???
|
|
||||||
QList<TransactionInfo> transactions = xmlScreenParser.parseTodayAndYesterdayHistory();
|
|
||||||
for (const TransactionInfo &info: transactions) {
|
|
||||||
QString text = QString("%1 %2").arg(info.description, getPriceAsString(info.amount));
|
|
||||||
qDebug().noquote().nospace() << convertTransactionToString(info);
|
|
||||||
|
|
||||||
// Node trButton = xmlScreenParser.findButtonNode(text, true);
|
|
||||||
Node trButton = swipeToButton(xmlScreenParser, deviceId, text, index, width, height);
|
|
||||||
if (!trButton.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(deviceId, trButton.x(), trButton.y());
|
|
||||||
QThread::msleep(500);
|
|
||||||
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++index));
|
|
||||||
|
|
||||||
Node moreDetailBtn = xmlScreenParser.findButtonNode("Детали операции", false);
|
|
||||||
if (!moreDetailBtn.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(deviceId, moreDetailBtn.x(), moreDetailBtn.y());
|
|
||||||
QThread::msleep(200);
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++index));
|
|
||||||
TransactionInfo info = xmlScreenParser.parseTransactionInfoHistory(width, height);
|
|
||||||
qDebug().noquote().nospace() << convertTransactionToString(info);
|
|
||||||
}
|
|
||||||
|
|
||||||
AdbUtils::goBack(deviceId);
|
|
||||||
} else {
|
|
||||||
qWarning() << "--- trButton not found..........";
|
|
||||||
}
|
|
||||||
// Перевод ВЛАДИСЛАВ НИКОЛАЕВИЧ К** в Т-Банк через СБП, по номеру телефона +7985553... Минус 10 рублей 0 копеек
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
|
|
||||||
int payCounter = 0;
|
|
||||||
|
|
||||||
if (false) {
|
|
||||||
// Оплата со страницы карты
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++payCounter));
|
|
||||||
Node payBtn = xmlScreenParser.findButtonNode("Оплатить", false);
|
|
||||||
if (!payBtn.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(deviceId, payBtn.x(), payBtn.y());
|
|
||||||
QThread::msleep(1000);
|
|
||||||
} else {
|
|
||||||
qWarning() << "--- payBtn not found";
|
|
||||||
}
|
|
||||||
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++payCounter));
|
|
||||||
// TODO - По номеру карты В РСХБ и другие банки
|
|
||||||
Node payTitle = xmlScreenParser.findTextNode("Платежи и переводы");
|
|
||||||
if (!payTitle.isEmpty() && payTitle.y() < 300) {
|
|
||||||
Node payByPhoneBtn = xmlScreenParser.findButtonNode("По номеру телефона В РСХБ и через", false);
|
|
||||||
if (!payByPhoneBtn.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(deviceId, payByPhoneBtn.x(), payByPhoneBtn.y());
|
|
||||||
QThread::msleep(1000);
|
|
||||||
} else {
|
|
||||||
qWarning() << "--- payByPhoneBtn not found";
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
qWarning() << "--- payTitle not found";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++payCounter));
|
|
||||||
Node payByPhoneTitle = xmlScreenParser.findTextNode("Перевод по телефону");
|
|
||||||
Node continueBtn = xmlScreenParser.findButtonNode("Продолжить", false);
|
|
||||||
if (!payByPhoneTitle.isEmpty() && payByPhoneTitle.y() < 300 && continueBtn.isEmpty()) {
|
|
||||||
Node inputPhone = xmlScreenParser.findFirstEditText();
|
|
||||||
AdbUtils::makeTap(deviceId, inputPhone.x(), inputPhone.y());
|
|
||||||
QThread::msleep(500);
|
|
||||||
AdbUtils::inputText(deviceId, phoneNumber);
|
|
||||||
QThread::msleep(1000);
|
|
||||||
} else {
|
|
||||||
qWarning() << "--- payByPhoneTitle not found (no continueBtn)";
|
|
||||||
}
|
|
||||||
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++payCounter));
|
|
||||||
QString payBankName;
|
|
||||||
payBankName = bankName == "Россельхозбанк" ? "Россельхозбанк" : "Другой банк через СБП";
|
|
||||||
Node payOtherBankBtn = xmlScreenParser.findButtonNode(payBankName, false);
|
|
||||||
if (!payOtherBankBtn.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(deviceId, payOtherBankBtn.x(), payOtherBankBtn.y());
|
|
||||||
QThread::msleep(1000);
|
|
||||||
} else {
|
|
||||||
qWarning() << "--- payOtherBankBtn not found";
|
|
||||||
}
|
|
||||||
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++payCounter));
|
|
||||||
for (int i = 0; i < 5; ++i) {
|
|
||||||
Node allBanksTitle = xmlScreenParser.findTextNode("Банки участники");
|
|
||||||
if (!allBanksTitle.isEmpty() && allBanksTitle.y() < 300) {
|
|
||||||
Node inputBankName = xmlScreenParser.findFirstEditText();
|
|
||||||
AdbUtils::makeTap(deviceId, inputBankName.x(), inputBankName.y());
|
|
||||||
QThread::msleep(500);
|
|
||||||
AdbUtils::enableAdbIMEKeyboard(deviceId);
|
|
||||||
AdbUtils::inputAdbIMEText(deviceId, bankName);
|
|
||||||
AdbUtils::disableAdbIMEKeyboard(deviceId);
|
|
||||||
QThread::msleep(1000);
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
qWarning() << "--- allBanksTitle not found, i: " << i;
|
|
||||||
}
|
|
||||||
QThread::msleep(1000);
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++payCounter));
|
|
||||||
}
|
|
||||||
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++payCounter));
|
|
||||||
for (int i = 0; i < 5; ++i) {
|
|
||||||
Node bankNameListItem = xmlScreenParser.findTextNode(bankName);
|
|
||||||
if (!bankNameListItem.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(deviceId, bankNameListItem.x(), bankNameListItem.y());
|
|
||||||
QThread::msleep(1000);
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
qWarning() << "--- bankNameListItem not found, i: " << i;
|
|
||||||
}
|
|
||||||
QThread::msleep(1000);
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++payCounter));
|
|
||||||
}
|
|
||||||
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++payCounter));
|
|
||||||
|
|
||||||
Node payByPhoneScreenTitle = xmlScreenParser.findTextNode("Перевод по телефону");
|
|
||||||
Node continuePayBtn = xmlScreenParser.findButtonNode("Продолжить", false);
|
|
||||||
if (!payByPhoneScreenTitle.isEmpty() && payByPhoneScreenTitle.y() < 300 && !continuePayBtn.isEmpty()) {
|
|
||||||
Node sumBtn = xmlScreenParser.findButtonNode("0", false);
|
|
||||||
if (!sumBtn.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(deviceId, sumBtn.x(), sumBtn.y());
|
|
||||||
QThread::msleep(500);
|
|
||||||
AdbUtils::inputText(deviceId, paySum);
|
|
||||||
QThread::msleep(500);
|
|
||||||
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++payCounter));
|
|
||||||
Node readyBtn = xmlScreenParser.findTextNode("Готово");
|
|
||||||
if (!readyBtn.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(deviceId, readyBtn.x(), readyBtn.y());
|
|
||||||
QThread::msleep(500);
|
|
||||||
AdbUtils::makeTap(deviceId, continuePayBtn.x(), continuePayBtn.y());
|
|
||||||
QThread::msleep(1000);
|
|
||||||
} else {
|
|
||||||
qWarning() << "--- readyBtn not found";
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
qWarning() << "--- sumBtn not found";
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
qWarning() << "--- payByPhoneScreenTitle not found";
|
|
||||||
}
|
|
||||||
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++payCounter));
|
|
||||||
for (int i = 0; i < 5; ++i) {
|
|
||||||
// TODO кнопка содержит "Перевести 10 ₽" если будет от 1000 то скорее всвего будет "Перевести 1 000 ₽",
|
|
||||||
// TODO не ясно как форматирование будет, поэтому пока на начало зашьем
|
|
||||||
Node makePayBtn = xmlScreenParser.findButtonNode("Перевести ", true);
|
|
||||||
if (!makePayBtn.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(deviceId, makePayBtn.x(), makePayBtn.y());
|
|
||||||
QThread::msleep(500);
|
|
||||||
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++payCounter));
|
|
||||||
if (const QList<Node> pincode = xmlScreenParser.tryToFindPinCode(pinCode, "Введите код доступа");
|
|
||||||
pincode.size() == 4) {
|
|
||||||
// FIXME вынести в отдельный метод
|
|
||||||
// делаем 4 тапа и ждем секунду и продолжаем
|
|
||||||
for (const Node &node: pincode) {
|
|
||||||
AdbUtils::makeTap(deviceId, node.x(), node.y());
|
|
||||||
QThread::msleep(QRandomGenerator::global()->bounded(200, 901));
|
|
||||||
}
|
|
||||||
|
|
||||||
// После ввода пин-кода, ждем 3с
|
|
||||||
QThread::msleep(3000);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
qWarning() << "--- makePayBtn not found, i: " << i;
|
|
||||||
}
|
|
||||||
QThread::msleep(1000);
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++payCounter));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++payCounter));
|
|
||||||
|
|
||||||
for (int i = 0; i < 5; ++i) {
|
|
||||||
Node moreDetailBtn = xmlScreenParser.findButtonNode("Детали операции", false);
|
|
||||||
if (!moreDetailBtn.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(deviceId, moreDetailBtn.x(), moreDetailBtn.y());
|
|
||||||
QThread::msleep(200);
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++payCounter));
|
|
||||||
|
|
||||||
Node paymentCompleted = xmlScreenParser.findTextNode("Исполнен", 0, 0, width, height / 2);
|
|
||||||
Node paymentInProgress = xmlScreenParser.findTextNode("Выполняется", 0, 0, width, height / 2);
|
|
||||||
|
|
||||||
if (!paymentCompleted.isEmpty()) {
|
|
||||||
// Если вдруг исполнен
|
|
||||||
} else if (!paymentInProgress.isEmpty()) {
|
|
||||||
// Если все еще в ожидании
|
|
||||||
} else {
|
|
||||||
qWarning() << "--- paymentCompleted or paymentInProgress not found...";
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
qWarning() << "--- moreDetailBtn not found, i: " << i;
|
|
||||||
}
|
|
||||||
|
|
||||||
QThread::msleep(1000);
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++payCounter));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return;
|
|
||||||
|
|
||||||
int counter = 0;
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, counter));
|
|
||||||
Node closeBannerOrDialogNode = xmlScreenParser.tryToFindBannerOrDialog(width, height);
|
|
||||||
if (closeBannerOrDialogNode.x() != -1 && closeBannerOrDialogNode.y() != -1) {
|
|
||||||
qDebug() << "--- tryToFindBannerOrDialog";
|
|
||||||
AdbUtils::makeTap(deviceId, closeBannerOrDialogNode.x(), closeBannerOrDialogNode.y());
|
|
||||||
QThread::msleep(1000);
|
|
||||||
}
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++counter));
|
|
||||||
if (xmlScreenParser.isHomeScreen()) {
|
|
||||||
qDebug() << "--- isHomeScreen";
|
|
||||||
if (Node allCardTitle = xmlScreenParser.findTextNode("Счета и карты"); !allCardTitle.isEmpty()) {
|
|
||||||
// 1. Если нет кнопки видимой, свайпаем. Кликаем на "Все продукты"
|
|
||||||
for (int i = 0; i < 5; ++i) {
|
|
||||||
Node allProductsBtn = xmlScreenParser.findButtonNode("Все продукты", false);
|
|
||||||
// Node allProductsBtn = xmlScreenParser.findTextNode("Курсы валют и металлов"); для теста
|
|
||||||
if (allProductsBtn.x() > 0 && allProductsBtn.y() > 0) {
|
|
||||||
qDebug() << "--- All Product in focus";
|
|
||||||
AdbUtils::makeTap(deviceId, allProductsBtn.x(), allProductsBtn.y());
|
|
||||||
QThread::msleep(1000);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
AdbUtils::makeSwipe(deviceId,
|
|
||||||
allCardTitle.x(), allCardTitle.y(),
|
|
||||||
allCardTitle.x(), allCardTitle.y() - 200);
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++counter));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < 5; ++i) {
|
|
||||||
Node allProductsTitle = xmlScreenParser.findTextNode("Все продукты");
|
|
||||||
// Проверяем что вверху заголовок
|
|
||||||
if (!allProductsTitle.isEmpty() && allProductsTitle.y() < 300) {
|
|
||||||
qDebug() << "--- All Product screen";
|
|
||||||
|
|
||||||
// TODO тут делаем синхронизацию данных все карт
|
|
||||||
|
|
||||||
Node cardNumberBtn = xmlScreenParser.findButtonNode(cardNumber, true);
|
|
||||||
AdbUtils::makeTap(deviceId, cardNumberBtn.x(), cardNumberBtn.y());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
QThread::msleep(1000);
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++counter));
|
|
||||||
}
|
|
||||||
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++counter));
|
|
||||||
Node filterBtn = xmlScreenParser.findButtonNode("РСХБ Онлайн", false);
|
|
||||||
if (!filterBtn.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(deviceId, filterBtn.x(), filterBtn.y());
|
|
||||||
QThread::msleep(1000);
|
|
||||||
} else {
|
|
||||||
qWarning() << "--- filterBtn not found";
|
|
||||||
}
|
|
||||||
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++counter));
|
|
||||||
Node allTransactionFilerBtn = xmlScreenParser.findButtonNode("Все операции", false);
|
|
||||||
if (!allTransactionFilerBtn.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(deviceId, allTransactionFilerBtn.x(), allTransactionFilerBtn.y());
|
|
||||||
QThread::msleep(1000);
|
|
||||||
} else {
|
|
||||||
qWarning() << "--- allTransactionFilerBtn not found";
|
|
||||||
}
|
|
||||||
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++counter));
|
|
||||||
for (int i = 0; i < 5; ++i) {
|
|
||||||
QList<Node> transactions = xmlScreenParser.getLast2DaysTransactions();
|
|
||||||
if (!transactions.empty()) {
|
|
||||||
for (const Node &transaction: transactions) {
|
|
||||||
qDebug() << transaction.text;
|
|
||||||
// TODO вот мы дошли до списка транзакций
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
QThread::msleep(1000);
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++counter));
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
} else {
|
|
||||||
// пишем в БД, что не дошли до домашней страницы, и завершаемся
|
|
||||||
// сохраняем скрин приложения
|
|
||||||
// дделаем алерт
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// пишем в БД, что не дошли до домашней страницы, и завершаемся
|
|
||||||
// сохраняем скрин приложения
|
|
||||||
// дделаем алерт
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
|
|
||||||
// 1. Идем на домашнюю страницу
|
|
||||||
if (goToHomeScreen(deviceId, packageName, pinCode, width, height)) {
|
|
||||||
// мы на главном
|
|
||||||
// перед тем как юзать снова проверить на банеры
|
|
||||||
// Проверяем на банеры после пин-кодом
|
|
||||||
|
|
||||||
|
|
||||||
// Это уже для шага дальше
|
|
||||||
// если нулевые координаты, свайпаем вверх, чтобы текст "Счета и карты" был у верхнего края
|
|
||||||
} else {
|
|
||||||
// пишем в БД, что не дошли до домашней страницы, и завершаемся
|
|
||||||
// сохраняем скрин приложения
|
|
||||||
// дделаем алерт
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2. Идем дальше
|
|
||||||
|
|
||||||
emit finished();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void HomeScreenScript::stop() {
|
|
||||||
m_running = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Rshb
|
|
||||||
@ -1,39 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <QObject>
|
|
||||||
#include <QPair>
|
|
||||||
|
|
||||||
#include "ScreenXmlParser.h"
|
|
||||||
|
|
||||||
namespace Rshb {
|
|
||||||
|
|
||||||
class HomeScreenScript final : public QObject {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit HomeScreenScript(QObject *parent = nullptr);
|
|
||||||
|
|
||||||
~HomeScreenScript() override;
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
void start();
|
|
||||||
|
|
||||||
void stop();
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void finished();
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool m_running = true;
|
|
||||||
ScreenXmlParser xmlScreenParser;
|
|
||||||
|
|
||||||
bool goToHomeScreen(
|
|
||||||
const QString &deviceId,
|
|
||||||
const QString &packageName,
|
|
||||||
const QString &pinCode,
|
|
||||||
int width,
|
|
||||||
int height
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Rshb
|
|
||||||
@ -1,69 +0,0 @@
|
|||||||
#include "LoginAndCheckAccountsScript.h"
|
|
||||||
|
|
||||||
#include "adb/AdbUtils.h"
|
|
||||||
#include "dao/AccountDAO.h"
|
|
||||||
#include "dao/ApplicationDAO.h"
|
|
||||||
#include "dao/DeviceDAO.h"
|
|
||||||
|
|
||||||
namespace Rshb {
|
|
||||||
|
|
||||||
LoginAndCheckAccountsScript::LoginAndCheckAccountsScript(
|
|
||||||
QString deviceId,
|
|
||||||
QString appCode,
|
|
||||||
QObject *parent
|
|
||||||
) : CommonScript(parent),
|
|
||||||
m_deviceId(std::move(deviceId)), m_appCode(std::move(appCode)) {
|
|
||||||
}
|
|
||||||
|
|
||||||
LoginAndCheckAccountsScript::~LoginAndCheckAccountsScript() = default;
|
|
||||||
|
|
||||||
|
|
||||||
void LoginAndCheckAccountsScript::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 (!runAppAndGoToHomeScreen(device.id, app.package, app.pinCode, device.screenWidth, device.screenHeight)) {
|
|
||||||
m_error = "Cant open the home screen: " + m_deviceId + " " + m_appCode;
|
|
||||||
qWarning() << m_error;
|
|
||||||
if (!ApplicationDAO::updatePinCodeStatus(app.id, "no", "Не прошла проверка [дата]")) {
|
|
||||||
qWarning() << "Cant update the pincode: " << m_deviceId << " " << m_appCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
AdbUtils::tryToKillApplication(m_deviceId, app.package);
|
|
||||||
emit finishedWithResult(m_error);
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
if (!ApplicationDAO::updatePinCodeStatus(app.id, "yes", "")) {
|
|
||||||
qWarning() << "Cant update the pincode: " << m_deviceId << " " << m_appCode;
|
|
||||||
}
|
|
||||||
if (goToAllProducts(device.id, device.screenWidth, device.screenHeight)) {
|
|
||||||
QList<QPair<AccountInfo, Node> > accounts = xmlScreenParser.parseAccountsInfo();
|
|
||||||
for (auto &[account, node]: accounts) {
|
|
||||||
account.deviceId = m_deviceId;
|
|
||||||
account.appCode = m_appCode;
|
|
||||||
if (!AccountDAO::upsertAccount(account)) {
|
|
||||||
m_error = "Not updated: " + account.lastNumbers;
|
|
||||||
qCritical() << m_error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
postAccountsData(accounts);
|
|
||||||
} else {
|
|
||||||
qWarning() << "Cant go to all products: " << m_deviceId << " " << m_appCode;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
AdbUtils::tryToKillApplication(m_deviceId, app.package);
|
|
||||||
emit finishedWithResult(m_error);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Rshb
|
|
||||||
@ -1,27 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include "CommonScript.h"
|
|
||||||
|
|
||||||
namespace Rshb {
|
|
||||||
|
|
||||||
class LoginAndCheckAccountsScript final : public CommonScript {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
~LoginAndCheckAccountsScript() override;
|
|
||||||
|
|
||||||
explicit LoginAndCheckAccountsScript(
|
|
||||||
QString deviceId,
|
|
||||||
QString appCode,
|
|
||||||
QObject *parent = nullptr
|
|
||||||
);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void doStart() override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
const QString m_deviceId;
|
|
||||||
const QString m_appCode;
|
|
||||||
QString m_error;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Rshb
|
|
||||||
@ -1,340 +0,0 @@
|
|||||||
#include "PayByPhoneScript.h"
|
|
||||||
|
|
||||||
#include <QRandomGenerator>
|
|
||||||
#include <QThread>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
#include "DatabaseManager.h"
|
|
||||||
#include "adb/AdbUtils.h"
|
|
||||||
#include "dao/AccountDAO.h"
|
|
||||||
#include "dao/ApplicationDAO.h"
|
|
||||||
#include "dao/DeviceDAO.h"
|
|
||||||
#include "dao/TransactionDAO.h"
|
|
||||||
#include "db/ApplicationInfo.h"
|
|
||||||
#include "db/DeviceInfo.h"
|
|
||||||
|
|
||||||
namespace Rshb {
|
|
||||||
|
|
||||||
PayByPhoneScript::PayByPhoneScript(
|
|
||||||
AccountInfo account,
|
|
||||||
QString phone,
|
|
||||||
QString bankName,
|
|
||||||
const double amount,
|
|
||||||
QObject *parent
|
|
||||||
) : CommonScript(parent),
|
|
||||||
m_account(std::move(account)), m_phone(std::move(phone)),
|
|
||||||
m_bankName(std::move(bankName)), m_amount(amount) {
|
|
||||||
}
|
|
||||||
|
|
||||||
PayByPhoneScript::~PayByPhoneScript() = default;
|
|
||||||
|
|
||||||
|
|
||||||
void PayByPhoneScript::makePayment(
|
|
||||||
const QString &deviceId,
|
|
||||||
const QString &pinCode,
|
|
||||||
int width,
|
|
||||||
int height
|
|
||||||
) {
|
|
||||||
// Оплата со страницы карты
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
|
|
||||||
Node payBtn = xmlScreenParser.findButtonNode("Оплатить", false);
|
|
||||||
if (!payBtn.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(deviceId, payBtn.x(), payBtn.y());
|
|
||||||
QThread::msleep(1000);
|
|
||||||
} else {
|
|
||||||
AdbUtils::takeScreenshot(deviceId, "pay_by_phone_pay_btn_not_found");
|
|
||||||
m_error = "Кнопка 'Оплатить' не нашлась";
|
|
||||||
qDebug() << m_error;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
|
|
||||||
// TODO - По номеру карты В РСХБ и другие банки
|
|
||||||
Node payTitle = xmlScreenParser.findTextNode("Платежи и переводы");
|
|
||||||
if (!payTitle.isEmpty() && payTitle.y() < 300) {
|
|
||||||
Node payByPhoneBtn = xmlScreenParser.findButtonNode("По номеру телефона В РСХБ и через", false);
|
|
||||||
if (!payByPhoneBtn.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(deviceId, payByPhoneBtn.x(), payByPhoneBtn.y());
|
|
||||||
QThread::msleep(1000);
|
|
||||||
} else {
|
|
||||||
AdbUtils::takeScreenshot(deviceId, "pay_by_phone_not_found_pay_by_phone");
|
|
||||||
m_error = "Не смогли найти пункт 'По номеру телефона В РСХБ и через'";
|
|
||||||
qDebug() << m_error;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
AdbUtils::takeScreenshot(deviceId, "pay_by_phone_cant_go_to_payments");
|
|
||||||
m_error = "Не смогли перейти на экран 'Платежи и переводы'";
|
|
||||||
qDebug() << m_error;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
|
|
||||||
Node payByPhoneTitle = xmlScreenParser.findTextNode("Перевод по телефону");
|
|
||||||
Node continueBtn = xmlScreenParser.findButtonNode("Продолжить", false);
|
|
||||||
if (!payByPhoneTitle.isEmpty() && payByPhoneTitle.y() < 300 && continueBtn.isEmpty()) {
|
|
||||||
Node inputPhone = xmlScreenParser.findFirstEditText();
|
|
||||||
AdbUtils::makeTap(deviceId, inputPhone.x(), inputPhone.y());
|
|
||||||
QThread::msleep(500);
|
|
||||||
AdbUtils::inputText(deviceId, m_phone);
|
|
||||||
QThread::msleep(1000);
|
|
||||||
} else {
|
|
||||||
AdbUtils::takeScreenshot(deviceId, "pay_by_phone_cant_find_pay_by_phone");
|
|
||||||
m_error = "Не смогли найти пункт 'Перевод по телефону'";
|
|
||||||
qDebug() << m_error;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
|
|
||||||
QString payBankName = m_bankName == QStringLiteral("Россельхозбанк") ? "Россельхозбанк" : "Другой банк через СБП";
|
|
||||||
Node payOtherBankBtn = xmlScreenParser.findButtonNode(payBankName, false);
|
|
||||||
if (!payOtherBankBtn.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(deviceId, payOtherBankBtn.x(), payOtherBankBtn.y());
|
|
||||||
QThread::msleep(1000);
|
|
||||||
} else {
|
|
||||||
AdbUtils::takeScreenshot(deviceId, "pay_by_phone_cant_tap_on_bank");
|
|
||||||
m_error = "Не смогли нажать на первичный выбор банка";
|
|
||||||
qDebug() << m_error;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_bankName != QStringLiteral("Россельхозбанк")) {
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
|
|
||||||
for (int i = 0; i < 5; ++i) {
|
|
||||||
Node allBanksTitle = xmlScreenParser.findTextNode("Банки участники");
|
|
||||||
if (!allBanksTitle.isEmpty() && allBanksTitle.y() < 300) {
|
|
||||||
Node inputBankName = xmlScreenParser.findFirstEditText();
|
|
||||||
AdbUtils::makeTap(deviceId, inputBankName.x(), inputBankName.y());
|
|
||||||
QThread::msleep(500);
|
|
||||||
AdbUtils::enableAdbIMEKeyboard(deviceId);
|
|
||||||
AdbUtils::inputAdbIMEText(deviceId, m_bankName);
|
|
||||||
AdbUtils::disableAdbIMEKeyboard(deviceId);
|
|
||||||
QThread::msleep(1000);
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
qDebug() << "--- allBanksTitle not found, i: " << i;
|
|
||||||
}
|
|
||||||
QThread::msleep(1000);
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
|
|
||||||
}
|
|
||||||
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
|
|
||||||
for (int i = 0; i < 5; ++i) {
|
|
||||||
Node bankNameListItem = xmlScreenParser.findTextNode(m_bankName);
|
|
||||||
if (!bankNameListItem.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(deviceId, bankNameListItem.x(), bankNameListItem.y());
|
|
||||||
QThread::msleep(1000);
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
qDebug() << "--- bankNameListItem not found, i: " << i;
|
|
||||||
}
|
|
||||||
QThread::msleep(1000);
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
|
|
||||||
|
|
||||||
const bool isRshbBank = m_bankName == QStringLiteral("Россельхозбанк");
|
|
||||||
QString payByPhoneScreenTitleText = isRshbBank ? "Перевод клиенту РСХБ" : "Перевод по телефону";
|
|
||||||
Node payByPhoneScreenTitle = xmlScreenParser.findTextNode(payByPhoneScreenTitleText);
|
|
||||||
Node continuePayBtn = xmlScreenParser.findButtonNode("Продолжить", false);
|
|
||||||
|
|
||||||
if (isRshbBank ||
|
|
||||||
!payByPhoneScreenTitle.isEmpty() && payByPhoneScreenTitle.y() < 300 && !continuePayBtn.isEmpty()) {
|
|
||||||
Node sumBtn = xmlScreenParser.findButtonNode("0", false);
|
|
||||||
if (isRshbBank || !sumBtn.isEmpty()) {
|
|
||||||
if (!isRshbBank) {
|
|
||||||
AdbUtils::makeTap(deviceId, sumBtn.x(), sumBtn.y());
|
|
||||||
QThread::msleep(500);
|
|
||||||
}
|
|
||||||
AdbUtils::inputText(deviceId, QString::number(m_amount));
|
|
||||||
QThread::msleep(500);
|
|
||||||
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
|
|
||||||
Node readyBtn = xmlScreenParser.findTextNode("Готово");
|
|
||||||
if (!readyBtn.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(deviceId, readyBtn.x(), readyBtn.y());
|
|
||||||
QThread::msleep(500);
|
|
||||||
if (isRshbBank) {
|
|
||||||
QThread::msleep(1000);
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
|
|
||||||
continuePayBtn = xmlScreenParser.findButtonNode("Продолжить", false);
|
|
||||||
}
|
|
||||||
AdbUtils::makeTap(deviceId, continuePayBtn.x(), continuePayBtn.y());
|
|
||||||
QThread::msleep(1000);
|
|
||||||
} else {
|
|
||||||
AdbUtils::takeScreenshot(deviceId, "pay_by_phone_cant_tap_on_ready");
|
|
||||||
m_error = "Не смогли нажать 'Готово'";
|
|
||||||
qDebug() << m_error;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
AdbUtils::takeScreenshot(deviceId, "pay_by_phone_cant_tap_on_continue");
|
|
||||||
m_error = "Не смогли нажать 'Продолжить'";
|
|
||||||
qDebug() << m_error;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
AdbUtils::takeScreenshot(deviceId, "pay_by_phone_cant_find_bank_title");
|
|
||||||
m_error = "Не смогли найти заголовок: " + payByPhoneScreenTitleText;
|
|
||||||
qDebug() << m_error;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
|
|
||||||
bool inputedPinCode = false;
|
|
||||||
for (int i = 0; i < 5; ++i) {
|
|
||||||
// TODO кнопка содержит "Перевести 10 ₽" если будет от 1000 то скорее всвего будет "Перевести 1 000 ₽",
|
|
||||||
// TODO не ясно как форматирование будет, поэтому пока на начало зашьем
|
|
||||||
Node makePayBtn = xmlScreenParser.findButtonNode("Перевести ", true);
|
|
||||||
if (!makePayBtn.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(deviceId, makePayBtn.x(), makePayBtn.y());
|
|
||||||
QThread::msleep(500);
|
|
||||||
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
|
|
||||||
if (const QList<Node> pincode = xmlScreenParser.tryToFindPinCode(pinCode, "Введите код доступа");
|
|
||||||
pincode.size() == 4) {
|
|
||||||
inputPinCode(deviceId, pincode);
|
|
||||||
inputedPinCode = true;
|
|
||||||
// После ввода пин-кода, ждем 3с
|
|
||||||
QThread::msleep(3000);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
qWarning() << "--- makePayBtn not found, i: " << i;
|
|
||||||
}
|
|
||||||
QThread::msleep(1000);
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isRshbBank && !inputedPinCode) {
|
|
||||||
AdbUtils::takeScreenshot(deviceId, "pay_by_phone_cant_input_pin_code");
|
|
||||||
m_error = "Не смогли ввести пин-код!'";
|
|
||||||
qDebug() << m_error;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
|
|
||||||
|
|
||||||
for (int i = 0; i < 10; ++i) {
|
|
||||||
Node moreDetailBtn = xmlScreenParser.findButtonNode("Детали операции", false);
|
|
||||||
if (!moreDetailBtn.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(deviceId, moreDetailBtn.x(), moreDetailBtn.y());
|
|
||||||
QThread::msleep(200);
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
|
|
||||||
|
|
||||||
// TODO считываем все данные по переводу
|
|
||||||
TransactionInfo transaction = xmlScreenParser.parseTransactionInfo(width, height);
|
|
||||||
if (isRshbBank) {
|
|
||||||
transaction.bankName = m_bankName;
|
|
||||||
}
|
|
||||||
transaction.accountId = m_account.id;
|
|
||||||
transaction.amount = -m_amount;
|
|
||||||
transaction.type = TransactionType::Phone;
|
|
||||||
transaction.id = TransactionDAO::insertTransaction(transaction);
|
|
||||||
if (transaction.id == -1) {
|
|
||||||
// FIXME alert!!
|
|
||||||
qDebug() << "Transaction has not inserted...";
|
|
||||||
}
|
|
||||||
|
|
||||||
// ждем 10 секунд смену статуса
|
|
||||||
for (int k = 0; k < 10; ++k) {
|
|
||||||
Node paymentCompleted = xmlScreenParser.findTextNode("Исполнен", 0, 0, width, height / 2);
|
|
||||||
if (!paymentCompleted.isEmpty()) {
|
|
||||||
transaction.status = TransactionStatus::Complete;
|
|
||||||
if (!TransactionDAO::updateTransactionStatus(transaction.id, TransactionStatus::Complete)) {
|
|
||||||
qDebug() << "Not updated: " << transaction.id;
|
|
||||||
}
|
|
||||||
// TODO обновляем данные
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
QThread::msleep(1000);
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
|
|
||||||
}
|
|
||||||
|
|
||||||
postNewTransactionData(m_account, transaction);
|
|
||||||
|
|
||||||
AdbUtils::takeScreenshot(deviceId, "pay_by_phone_finish_transactions_" + transaction.id);
|
|
||||||
AdbUtils::takeXmlDump(deviceId, "pay_by_phone_finish_transactions_" + transaction.id);
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
qWarning() << "--- moreDetailBtn not found, i: " << i;
|
|
||||||
}
|
|
||||||
QThread::msleep(1000);
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
|
|
||||||
}
|
|
||||||
|
|
||||||
Node homeBtn = xmlScreenParser.findButtonNode("Вернуться на главную", false);
|
|
||||||
AdbUtils::makeTap(deviceId, homeBtn.x(), homeBtn.y());
|
|
||||||
QThread::msleep(1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PayByPhoneScript::doStart() {
|
|
||||||
const DeviceInfo device = DeviceDAO::getDeviceById(m_account.deviceId);
|
|
||||||
const ApplicationInfo app = ApplicationDAO::getApplication(m_account.deviceId, m_account.appCode);
|
|
||||||
|
|
||||||
if (device.id.isEmpty() || app.id == -1) {
|
|
||||||
m_error = "Device or app not found....";
|
|
||||||
qDebug() << m_error;
|
|
||||||
emit finishedWithResult(m_error);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter));
|
|
||||||
if (!xmlScreenParser.isHomeScreen()) {
|
|
||||||
if (!runAppAndGoToHomeScreen(device.id, app.package, app.pinCode, device.screenWidth, device.screenHeight)) {
|
|
||||||
m_error = "Не смогли дойти до домашней страницы";
|
|
||||||
qDebug() << m_error;
|
|
||||||
emit finishedWithResult(m_error);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (goToAllProducts(device.id, device.screenWidth, device.screenHeight)) {
|
|
||||||
QList<QPair<AccountInfo, Node> > accounts = xmlScreenParser.parseAccountsInfo();
|
|
||||||
for (auto &[account, node]: accounts) {
|
|
||||||
account.deviceId = m_account.deviceId;
|
|
||||||
account.appCode = m_account.appCode;
|
|
||||||
account.status = account.amount > 0 ? AccountStatus::Active : AccountStatus::Off;
|
|
||||||
if (!AccountDAO::upsertAccount(account)) {
|
|
||||||
qDebug() << "Not updated: " << account.lastNumbers;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
postAccountsData(accounts);
|
|
||||||
|
|
||||||
for (auto &[account, node]: accounts) {
|
|
||||||
// FIXME будем считать что числа последние везде уникальные
|
|
||||||
if (m_account.lastNumbers == account.lastNumbers) {
|
|
||||||
if (account.amount >= m_amount) {
|
|
||||||
AdbUtils::makeTap(device.id, node.x(), node.y());
|
|
||||||
QThread::msleep(1000);
|
|
||||||
} else {
|
|
||||||
AdbUtils::takeScreenshot(device.id, "pay_by_phone_not_enough_money_" + QString::number(m_account.id));
|
|
||||||
m_error = "Not enough money, id: " + QString::number(m_account.id)
|
|
||||||
+ ", amount: " + QString::number(account.amount)
|
|
||||||
+ ", trx amount: " + QString::number(m_amount);
|
|
||||||
qCritical() << m_error;
|
|
||||||
emit finishedWithResult(m_error);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
makePayment(device.id, app.pinCode, device.screenWidth, device.screenHeight);
|
|
||||||
// AdbUtils::tryToKillApplication(device.id, app.package); TODO - надо ли это???
|
|
||||||
} else {
|
|
||||||
AdbUtils::takeScreenshot(device.id, "pay_by_phone_cant_open_all_products_" + QString::number(m_account.id));
|
|
||||||
AdbUtils::tryToKillApplication(device.id, app.package);
|
|
||||||
m_error = "Не смогли открыть 'Все продукты'";
|
|
||||||
qDebug() << m_error;
|
|
||||||
}
|
|
||||||
|
|
||||||
emit finishedWithResult(m_error);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Rshb
|
|
||||||
@ -1,38 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include "CommonScript.h"
|
|
||||||
|
|
||||||
namespace Rshb {
|
|
||||||
|
|
||||||
class PayByPhoneScript final : public CommonScript {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
~PayByPhoneScript() override;
|
|
||||||
|
|
||||||
PayByPhoneScript(
|
|
||||||
AccountInfo account,
|
|
||||||
QString phone,
|
|
||||||
QString bankName,
|
|
||||||
double amount,
|
|
||||||
QObject *parent = nullptr
|
|
||||||
);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void doStart() override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
const AccountInfo m_account;
|
|
||||||
const QString m_phone;
|
|
||||||
const QString m_bankName;
|
|
||||||
const double m_amount;
|
|
||||||
QString m_error;
|
|
||||||
|
|
||||||
void makePayment(
|
|
||||||
const QString &deviceId,
|
|
||||||
const QString &pinCode,
|
|
||||||
int width,
|
|
||||||
int height
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Rshb
|
|
||||||
@ -1,980 +0,0 @@
|
|||||||
#include "ScreenXmlParser.h"
|
|
||||||
|
|
||||||
#include <QRegularExpression>
|
|
||||||
#include <QMap>
|
|
||||||
#include <QSet>
|
|
||||||
#include <QList>
|
|
||||||
#include <QXmlStreamReader>
|
|
||||||
#include <QDomDocument>
|
|
||||||
#include <QFile>
|
|
||||||
#include <QDateTime>
|
|
||||||
|
|
||||||
#include "adb/AdbUtils.h"
|
|
||||||
#include "android/xml/Node.h"
|
|
||||||
#include "db/AccountInfo.h"
|
|
||||||
#include "db/TransactionInfo.h"
|
|
||||||
#include "time/DateUtils.h"
|
|
||||||
|
|
||||||
namespace Rshb {
|
|
||||||
|
|
||||||
ScreenXmlParser::ScreenXmlParser(QObject *parent) : QObject(parent) {
|
|
||||||
}
|
|
||||||
|
|
||||||
ScreenXmlParser::~ScreenXmlParser() = default;
|
|
||||||
|
|
||||||
static const QRegularExpression boundsRegex(R"(\[([0-9]+),([0-9]+)\]\[([0-9]+),([0-9]+)\])");
|
|
||||||
static const QRegularExpression onlyDigitsRegex(R"([^0-9])");
|
|
||||||
static const QRegularExpression onlyDigitsAndDotRegex(R"([^0-9.])");
|
|
||||||
|
|
||||||
static const QRegularExpression rePhone(R"raw((\+7\(?\d{3}\)?[- ]?\d{3}[- ]?\d{2}[- ]?\d{2}))raw");
|
|
||||||
static const QRegularExpression reFromBank(R"raw(из (.+?) на)raw");
|
|
||||||
static const QRegularExpression reToBank(R"raw(в (.+?) через)raw");
|
|
||||||
static const QRegularExpression reSbpId(R"(СБП(?: С2С)? ([A-Z0-9]{30,}))");
|
|
||||||
static const QRegularExpression reIdAlt(R"(ID перевода (\d+))");
|
|
||||||
static const QRegularExpression reDate(R"((?:Дата операции|дата) (\d{2}\.\d{2}\.\d{4}(?: \d{2}:\d{2}:\d{2})?))");
|
|
||||||
static const QRegularExpression reSender(R"(от ([^\(]+))");
|
|
||||||
static const QRegularExpression reNameAlt(R"(Перевод ([А-Яа-яЁё\s\*]+) в)");
|
|
||||||
|
|
||||||
static const QRegularExpression reCardData(R"(цифрами\s+(\d\s\d\s\d\s\d).*?Сумма:\s([\d\s]+)\sруб)");
|
|
||||||
|
|
||||||
Node ScreenXmlParser::tryToFindBannerOrDialog(const int width, const int height) {
|
|
||||||
// 1. Ищем push banner - он перекрывает весь экран
|
|
||||||
Node first = m_nodes[0];
|
|
||||||
for (const Node &node: m_nodes) {
|
|
||||||
// Если это однозначно, что пуш-баннер
|
|
||||||
if (node.resourceId == "aft-popup-pushNotification-iconClose" && node.className == "android.widget.Button") {
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
// Если есть кнопка "Позже"
|
|
||||||
if (node.text.trimmed() == "Позже" && node.className == "android.widget.Button") {
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
// Если нашли пустую кнпоку
|
|
||||||
if (node.className == "android.widget.Button" && node.clickable
|
|
||||||
&& node.text.isEmpty() && node.contentDesc.isEmpty()) {
|
|
||||||
// <node class="android.widget.Button" package="ru.rshb.dbo" clickable="true" bounds="[630,142][691,205]"/>
|
|
||||||
if (node.x() > width / 2 && node.y() < width / 2) {
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Смотрим что есть текс "Мы заботимся о вашей безопасности" и
|
|
||||||
* кнопка "Отложить"
|
|
||||||
* @return координаты кнопки для закрытия
|
|
||||||
*/
|
|
||||||
Node ScreenXmlParser::tryToFindSecurityBanner() {
|
|
||||||
Node text;
|
|
||||||
Node closeBtn;
|
|
||||||
for (const Node &node: m_nodes) {
|
|
||||||
if (node.text.trimmed() == "Мы заботимся о вашей безопасности" && node.className == "android.app.Dialog") {
|
|
||||||
text = node;
|
|
||||||
}
|
|
||||||
if (node.text.trimmed() == "Отложить" && node.className == "android.widget.Button") {
|
|
||||||
closeBtn = node;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Не нужно проверять все, если хотя бы одна координата есть
|
|
||||||
if (!text.isEmpty() && !closeBtn.isEmpty()) {
|
|
||||||
return closeBtn;
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
Node ScreenXmlParser::tryToFindSelectBottomSheet() {
|
|
||||||
Node closeBtn;
|
|
||||||
for (const Node &node: m_nodes) {
|
|
||||||
if ((node.text.trimmed() == "Отмена" || node.text.trimmed() == "Отложить") && node.className ==
|
|
||||||
"android.widget.Button") {
|
|
||||||
closeBtn = node;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Не нужно проверять все, если хотя бы одна координата есть
|
|
||||||
if (!closeBtn.isEmpty()) {
|
|
||||||
return closeBtn;
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
Node ScreenXmlParser::findTextNode(const QString &text) {
|
|
||||||
for (const Node &node: m_nodes) {
|
|
||||||
if (node.className == "android.widget.TextView" && node.text.trimmed() == text) {
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
Node ScreenXmlParser::findTextNode(const QString &text, const int x1, const int y1, const int x2, const int y2) {
|
|
||||||
for (const Node &node: m_nodes) {
|
|
||||||
if (node.className == "android.widget.TextView" && node.text.trimmed() == text
|
|
||||||
&& node.x() >= x1 && node.x() <= x2 && node.y() >= y1 && node.y() <= y2) {
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
Node ScreenXmlParser::findFirstEditText() {
|
|
||||||
for (const Node &node: m_nodes) {
|
|
||||||
if (node.className == "android.widget.EditText" && node.focusable) {
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
Node ScreenXmlParser::findButtonNode(const QString &text, const bool contains) {
|
|
||||||
for (const Node &node: m_nodes) {
|
|
||||||
if (contains) {
|
|
||||||
if (node.className == "android.widget.Button" && node.text.contains(text)) {
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (node.className == "android.widget.Button" && node.text.trimmed() == text) {
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ScreenXmlParser::isHomeScreen() {
|
|
||||||
// Есть заголовок "Счета и карты" и кнопка "Все продукты"
|
|
||||||
Node text;
|
|
||||||
Node allProductBtn;
|
|
||||||
for (const Node &node: m_nodes) {
|
|
||||||
if (node.text.trimmed() == "Счета и карты" && node.className == "android.widget.TextView") {
|
|
||||||
text = node;
|
|
||||||
}
|
|
||||||
if (node.text.trimmed() == "Все продукты" && node.className == "android.widget.Button") {
|
|
||||||
allProductBtn = node;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return !text.isEmpty() && !allProductBtn.isEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<Node> ScreenXmlParser::findPinCodeNodes(const QString &pinCode) {
|
|
||||||
QMap<QString, Node> buttons;
|
|
||||||
const QSet<QString> numberSet = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"};
|
|
||||||
|
|
||||||
for (const Node &node: m_nodes) {
|
|
||||||
const QString &text = node.text.trimmed();
|
|
||||||
if (node.className == "android.widget.Button" && numberSet.contains(text)) {
|
|
||||||
buttons[text] = node;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<Node> nodes;
|
|
||||||
for (int i = 0; i < pinCode.length(); ++i) {
|
|
||||||
nodes.append(buttons[QString(pinCode.at(i))]);
|
|
||||||
}
|
|
||||||
return nodes;
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<Node> ScreenXmlParser::tryToFindPinCode(const QString &pinCode, const QString &title) {
|
|
||||||
for (const Node &node: m_nodes) {
|
|
||||||
// если там есть такая кнопка значит банер есть, и пин-код не прожать
|
|
||||||
if (node.text.trimmed() == "Отложить" && node.className == "android.widget.Button") {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (const Node &node: m_nodes) {
|
|
||||||
// FIXME определение пин-кода лучше сделать
|
|
||||||
if (node.text.trimmed() == title) {
|
|
||||||
return findPinCodeNodes(pinCode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<Node> ScreenXmlParser::getLast2DaysTransactions() {
|
|
||||||
QList<Node> nodes;
|
|
||||||
for (const Node &node: m_nodes) {
|
|
||||||
if (node.className == "android.widget.Button" && node.text.contains("рубл")
|
|
||||||
&& (node.text.contains("Минус") || node.text.contains("Плюс"))) {
|
|
||||||
nodes.append(node);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nodes;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <node NAF="true" index="1" text="" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[952,159][1039,248]"/>
|
|
||||||
*/
|
|
||||||
void ScreenXmlParser::parseAndSaveXml(const QString &xml) {
|
|
||||||
QDomDocument doc;
|
|
||||||
doc.setContent(xml);
|
|
||||||
m_xml = doc.documentElement();
|
|
||||||
m_nodes.clear();
|
|
||||||
|
|
||||||
QXmlStreamReader reader(xml);
|
|
||||||
while (!reader.atEnd()) {
|
|
||||||
reader.readNext();
|
|
||||||
if (reader.isStartElement() && reader.name() == "node") {
|
|
||||||
Node node = Node();
|
|
||||||
if (reader.attributes().hasAttribute("bounds")) {
|
|
||||||
QString bounds = reader.attributes().value("bounds").toString();
|
|
||||||
if (QRegularExpressionMatch match = boundsRegex.match(bounds); match.hasMatch()) {
|
|
||||||
node.setBounds(
|
|
||||||
match.captured(1).toInt(),
|
|
||||||
match.captured(2).toInt(),
|
|
||||||
match.captured(3).toInt(),
|
|
||||||
match.captured(4).toInt()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (reader.attributes().hasAttribute("text")) {
|
|
||||||
node.text = reader.attributes().value("text").toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (reader.attributes().hasAttribute("content-desc")) {
|
|
||||||
node.contentDesc = reader.attributes().value("content-desc").toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (reader.attributes().hasAttribute("class")) {
|
|
||||||
node.className = reader.attributes().value("class").toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (reader.attributes().hasAttribute("clickable")) {
|
|
||||||
node.clickable = reader.attributes().value("clickable").toString() == "true";
|
|
||||||
}
|
|
||||||
if (reader.attributes().hasAttribute("focusable")) {
|
|
||||||
node.focusable = reader.attributes().value("focusable").toString() == "true";
|
|
||||||
}
|
|
||||||
if (reader.attributes().hasAttribute("resource-id")) {
|
|
||||||
node.resourceId = reader.attributes().value("resource-id").toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
m_nodes.append(node);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QString getDayOfWeekAsString(const int day_of_week) {
|
|
||||||
switch (day_of_week) {
|
|
||||||
case 1: return "понедельник";
|
|
||||||
case 2: return "вторник";
|
|
||||||
case 3: return "среда";
|
|
||||||
case 4: return "четверг";
|
|
||||||
case 5: return "пятница";
|
|
||||||
case 6: return "суббота";
|
|
||||||
case 7: return "воскресенье";
|
|
||||||
default: return "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QString getMonthAsString(const int month) {
|
|
||||||
switch (month) {
|
|
||||||
case 1: return "января";
|
|
||||||
case 2: return "февраля";
|
|
||||||
case 3: return "марта";
|
|
||||||
case 4: return "апреля";
|
|
||||||
case 5: return "мая";
|
|
||||||
case 6: return "июня";
|
|
||||||
case 7: return "июля";
|
|
||||||
case 8: return "августа";
|
|
||||||
case 9: return "сентября";
|
|
||||||
case 10: return "октября";
|
|
||||||
case 11: return "ноября";
|
|
||||||
case 12: return "декабря";
|
|
||||||
default: return "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QDomElement findSubElement(const QDomElement &elem, const QString &index) {
|
|
||||||
if (elem.hasChildNodes()) {
|
|
||||||
QDomNodeList subInfoList = elem.childNodes();
|
|
||||||
for (QDomNode subInfoNode: subInfoList) {
|
|
||||||
if (!subInfoNode.isElement()) continue;
|
|
||||||
QDomElement subInfo = subInfoNode.toElement();
|
|
||||||
if (subInfo.attribute("index") == index) {
|
|
||||||
return subInfo;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
QString findSubInfo(const QDomElement &elem, const QString &index) {
|
|
||||||
QDomElement subInfo = findSubElement(elem, index);
|
|
||||||
if (!subInfo.isNull()) {
|
|
||||||
return subInfo.attribute("text");
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
bool hasTimeComponent(const QString &datetimeStr) {
|
|
||||||
QDateTime dt = QDateTime::fromString(datetimeStr, "dd.MM.yyyy HH:mm:ss");
|
|
||||||
if (!dt.isValid()) {
|
|
||||||
return false; // Строка не соответствует формату даты и времени
|
|
||||||
}
|
|
||||||
return dt.time() != QTime(0, 0, 0); // Проверка, что время не равно 00:00:00
|
|
||||||
}
|
|
||||||
|
|
||||||
QString transformBankDateTime(const QString &date) {
|
|
||||||
QDateTime dt;
|
|
||||||
if (date.contains(",")) {
|
|
||||||
// 10.05.2025, 15:03
|
|
||||||
dt = QDateTime::fromString(date, "dd.MM.yyyy, HH:mm");
|
|
||||||
} else {
|
|
||||||
dt = QDateTime::fromString(date, "dd.MM.yyyy HH:mm:ss");
|
|
||||||
}
|
|
||||||
if (!dt.isValid()) {
|
|
||||||
dt = QDateTime::fromString(date, "dd.MM.yyyy HH:mm");
|
|
||||||
}
|
|
||||||
if (!dt.isValid()) {
|
|
||||||
return date; // не распарсили
|
|
||||||
}
|
|
||||||
return dt.toString("dd.MM.yyyy HH:mm:ss");
|
|
||||||
}
|
|
||||||
|
|
||||||
void parseTransferInfo(const QString &text, TransactionInfo &info) {
|
|
||||||
if (const auto m = reSender.match(text); m.hasMatch()) {
|
|
||||||
info.name = m.captured(1).trimmed();
|
|
||||||
} else if (const auto m1 = reNameAlt.match(text); m1.hasMatch()) {
|
|
||||||
info.name = m1.captured(1).trimmed();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (const auto m = rePhone.match(text); m.hasMatch()) {
|
|
||||||
info.phone = m.captured(1).trimmed().remove(onlyDigitsRegex);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (const auto m = reFromBank.match(text); m.hasMatch()) {
|
|
||||||
if (const QString bank = m.captured(1).trimmed(); !bank.isEmpty()) {
|
|
||||||
info.bankName = bank;
|
|
||||||
}
|
|
||||||
} else if (const auto m1 = reToBank.match(text); m1.hasMatch()) {
|
|
||||||
if (const QString bank = m1.captured(1).trimmed(); !bank.isEmpty()) {
|
|
||||||
info.bankName = bank;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (const auto m = reSbpId.match(text); m.hasMatch()) {
|
|
||||||
info.bankTrExternalId = m.captured(1);
|
|
||||||
} else if (const auto m1 = reIdAlt.match(text); m1.hasMatch()) {
|
|
||||||
info.bankTrExternalId = m1.captured(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (const auto m = reDate.match(text); m.hasMatch()) {
|
|
||||||
const QString date = m.captured(1);
|
|
||||||
// если не пустая и дата у нас с 00:00
|
|
||||||
// if (hasTimeComponent(date)) {
|
|
||||||
info.bankTime = transformBankDateTime(date);
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void traverseNodes(const QDomNode &node) {
|
|
||||||
if (node.isElement()) {
|
|
||||||
QDomElement elem = node.toElement();
|
|
||||||
|
|
||||||
if (node.isElement()) {
|
|
||||||
QDomElement elem = node.toElement();
|
|
||||||
|
|
||||||
if (elem.tagName() == "node" &&
|
|
||||||
elem.attribute("class") == "android.widget.Button" &&
|
|
||||||
elem.attribute("text") == "Детали операции") {
|
|
||||||
// Все что ниже деталей операции
|
|
||||||
QDomNodeList detailInfo = elem.parentNode().childNodes();
|
|
||||||
|
|
||||||
|
|
||||||
for (int j = 0; j < detailInfo.count(); ++j) {
|
|
||||||
QDomNode info = detailInfo.at(j);
|
|
||||||
if (!info.isElement()) continue;
|
|
||||||
QDomElement infoElement = info.toElement();
|
|
||||||
QString index = infoElement.attribute("index");
|
|
||||||
switch (index.toInt()) {
|
|
||||||
case 2:
|
|
||||||
qDebug() << "Дата операции:" << findSubInfo(infoElement, "1");
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
qDebug() << "Название:" << findSubInfo(infoElement, "1");
|
|
||||||
qDebug() << "-------------------------------------";
|
|
||||||
// parseTransfer(findSubInfo(infoElement));
|
|
||||||
break;
|
|
||||||
case 7:
|
|
||||||
qDebug() << "Комиссия:" << findSubInfo(infoElement, "1");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
qDebug() << "Прочее:" << findSubInfo(infoElement, "1");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Node: "2" ""
|
|
||||||
... Node: "0" "Дата операции"
|
|
||||||
... Node: "1" "30.04.2025 17:46:29"
|
|
||||||
Node: "5" ""
|
|
||||||
... Node: "0" "Название"
|
|
||||||
... Node: "1" "DBO TRANSFER RSHB INTERNET-BANK"
|
|
||||||
Node: "7" ""
|
|
||||||
... Node: "0" "Комиссия"
|
|
||||||
... Node: "1" "50 ₽"
|
|
||||||
*/
|
|
||||||
|
|
||||||
// if (sibElem.hasChildNodes()) {
|
|
||||||
// QDomNodeList sibChildren = sibElem.childNodes();
|
|
||||||
// for (int k = 0; k < sibChildren.count(); ++k) {
|
|
||||||
// QDomNode sibChild = sibChildren.at(k);
|
|
||||||
// if (!sibChild.isElement()) continue;
|
|
||||||
// QDomElement sibChildElem = sibChild.toElement();
|
|
||||||
// qDebug() << "... Node:"
|
|
||||||
// << sibChildElem.attribute("index")
|
|
||||||
// << sibChildElem.attribute("text");
|
|
||||||
// // << sibChildElem.attribute("class");
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// if (sibChildElem.hasChildNodes()) {
|
|
||||||
// QDomNodeList sibChildren2 = sibChildElem.childNodes();
|
|
||||||
// for (int k = 0; k < sibChildren2.count(); ++k) {
|
|
||||||
// QDomNode sibChild2 = sibChildren2.at(k);
|
|
||||||
// if (!sibChild2.isElement()) continue;
|
|
||||||
// QDomElement sibChildElem2 = sibChild2.toElement();
|
|
||||||
//
|
|
||||||
// qDebug() << "...... Node:"
|
|
||||||
// << sibChildElem2.attribute("index")
|
|
||||||
// << sibChildElem2.attribute("text");
|
|
||||||
// // << sibChildElem2.attribute("class");
|
|
||||||
//
|
|
||||||
// if (sibChildElem2.hasChildNodes()) {
|
|
||||||
// QDomNodeList sibChildren3 = sibChildElem2.childNodes();
|
|
||||||
// for (int k = 0; k < sibChildren3.count(); ++k) {
|
|
||||||
// QDomNode sibChild3 = sibChildren3.at(k);
|
|
||||||
// if (!sibChild3.isElement()) continue;
|
|
||||||
// QDomElement sibChildElem3 = sibChild3.toElement();
|
|
||||||
//
|
|
||||||
// qDebug() << "......... Node:"
|
|
||||||
// << sibChildElem3.attribute("index")
|
|
||||||
// << sibChildElem3.attribute("text");
|
|
||||||
// // << sibChildElem2.attribute("class");
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Рекурсивно обходим всех детей
|
|
||||||
QDomNode child = node.firstChild();
|
|
||||||
while (!child.isNull()) {
|
|
||||||
traverseNodes(child);
|
|
||||||
child = child.nextSibling();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QDomNode findNode(const QDomNode &node, const QString &text) {
|
|
||||||
if (node.isElement()) {
|
|
||||||
QString nodeText = node.toElement().attribute("text");
|
|
||||||
if (nodeText.toLower().startsWith(text)) {
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
QDomNode child = node.firstChild();
|
|
||||||
while (!child.isNull()) {
|
|
||||||
QDomNode result = findNode(child, text);
|
|
||||||
if (!result.isNull()) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
child = child.nextSibling();
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
float extractAmounts(const QString &text) {
|
|
||||||
// Разрешаем пробелы внутри чисел, захватываем "рубль", "рубля", "рублей" и т.д.
|
|
||||||
// QRegularExpression re(R"((Плюс|Минус)\s+([\d\s]+)\s+рубл\w*\s+(\d+)\s+копе\w*)");
|
|
||||||
QRegularExpression re(
|
|
||||||
R"((Плюс|Минус)\s+([\d\s]+)\s+рубл\w*\s+(\d+)\s+копе\w*)",
|
|
||||||
QRegularExpression::UseUnicodePropertiesOption
|
|
||||||
);
|
|
||||||
|
|
||||||
QRegularExpressionMatch match = re.match(text);
|
|
||||||
if (match.hasMatch()) {
|
|
||||||
QString signStr = match.captured(1); // "Плюс" или "Минус"
|
|
||||||
QString rublesStr = match.captured(2).remove(' '); // "1 000" → "1000"
|
|
||||||
int rubles = rublesStr.toInt();
|
|
||||||
int kopecks = match.captured(3).toInt();
|
|
||||||
|
|
||||||
int totalKopecks = rubles * 100 + kopecks;
|
|
||||||
if (signStr == "Минус") {
|
|
||||||
totalKopecks *= -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return totalKopecks / 100.0f;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString beforeAmount(const QString &text) {
|
|
||||||
int index = text.indexOf(QRegularExpression("Плюс|Минус"));
|
|
||||||
if (index != -1) {
|
|
||||||
return text.left(index).trimmed();
|
|
||||||
}
|
|
||||||
return text; // если не найдено — вернуть всю строку
|
|
||||||
}
|
|
||||||
|
|
||||||
double parseAmount(const QString &amountAsString) {
|
|
||||||
QString numberString = amountAsString;
|
|
||||||
numberString.remove(QRegularExpression(R"([^\dточка])"));
|
|
||||||
numberString.replace("точка", ".");
|
|
||||||
double amount = numberString.toDouble();
|
|
||||||
|
|
||||||
if (amountAsString.startsWith("-")) {
|
|
||||||
amount *= -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return amount;
|
|
||||||
}
|
|
||||||
|
|
||||||
QDomElement findElementWithListView(const QDomElement &parent) {
|
|
||||||
QDomElement element = parent.firstChildElement();
|
|
||||||
while (!element.isNull()) {
|
|
||||||
QDomElement child = element.firstChildElement();
|
|
||||||
while (!child.isNull()) {
|
|
||||||
if (child.hasAttribute("class") && child.attribute("class") == "android.widget.ListView") {
|
|
||||||
return child;
|
|
||||||
}
|
|
||||||
child = child.nextSiblingElement();
|
|
||||||
}
|
|
||||||
|
|
||||||
QDomElement found = findElementWithListView(element);
|
|
||||||
if (!found.isNull()) {
|
|
||||||
return found;
|
|
||||||
}
|
|
||||||
element = element.nextSiblingElement();
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<TransactionInfo> ScreenXmlParser::parseTodayAndYesterdayReportHistory() {
|
|
||||||
QList<TransactionInfo> transactions;
|
|
||||||
|
|
||||||
QDomElement child = findElementWithListView(m_xml);
|
|
||||||
QDomNodeList listView = findElementWithListView(m_xml).childNodes();
|
|
||||||
qDebug() << listView.count();
|
|
||||||
if (!listView.isEmpty()) {
|
|
||||||
QString date;
|
|
||||||
for (QDomNode node: listView) {
|
|
||||||
if (node.hasChildNodes()) {
|
|
||||||
QString text;
|
|
||||||
if (node.childNodes().count() > 1) {
|
|
||||||
date = node.firstChildElement().attribute("text");
|
|
||||||
text = node.lastChildElement().attribute("text");
|
|
||||||
} else if (node.childNodes().count() == 1) {
|
|
||||||
text = node.firstChildElement().attribute("text");
|
|
||||||
}
|
|
||||||
|
|
||||||
TransactionInfo transaction;
|
|
||||||
if (text.startsWith("Перевод")) {
|
|
||||||
QRegularExpression re(R"([+-] \d{1,3}(?: \d{3})* точка \d{2} Рубль$)");
|
|
||||||
QRegularExpressionMatch match = re.match(text);
|
|
||||||
if (match.hasMatch()) {
|
|
||||||
QString amount = match.captured(0);
|
|
||||||
transaction.amount = parseAmount(amount.trimmed());
|
|
||||||
text.chop(amount.length());
|
|
||||||
}
|
|
||||||
transaction.description = text.trimmed();
|
|
||||||
parseTransferInfo(text, transaction);
|
|
||||||
if (transaction.bankTime.isEmpty()) {
|
|
||||||
transaction.bankTime = transformBankDateTime(date);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// карта
|
|
||||||
if (text.contains("без учета комиссии")) {
|
|
||||||
QRegularExpression re(R"( без учета комиссии -\d{1,3}(?: \d{3})* точка \d{2} Рубль$)");
|
|
||||||
QRegularExpressionMatch match = re.match(text);
|
|
||||||
if (match.hasMatch()) {
|
|
||||||
QString fee = match.captured(0);
|
|
||||||
text.chop(fee.length());
|
|
||||||
transaction.fee = parseAmount(fee.replace("без учета комиссии", "").trimmed());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
QRegularExpression re(R"([+-] \d{1,3}(?: \d{3})* точка \d{2} Рубль$)");
|
|
||||||
QRegularExpressionMatch match = re.match(text);
|
|
||||||
if (match.hasMatch()) {
|
|
||||||
QString amount = match.captured(0);
|
|
||||||
transaction.amount = parseAmount(amount.trimmed());
|
|
||||||
text.chop(amount.length());
|
|
||||||
}
|
|
||||||
transaction.description = text.trimmed();
|
|
||||||
if (transaction.bankTime.isEmpty()) {
|
|
||||||
transaction.bankTime = transformBankDateTime(date);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
transactions.append(transaction);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
qDebug() << "ListView is empty";
|
|
||||||
}
|
|
||||||
return transactions;
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<TransactionInfo> ScreenXmlParser::parseTodayAndYesterdayHistory() {
|
|
||||||
QDate today = DateUtils::getMoscowNow().date();
|
|
||||||
QDate yesterday = today.addDays(-1);
|
|
||||||
QDate beforeYesterday = today.addDays(-2);
|
|
||||||
|
|
||||||
|
|
||||||
QString todayTitle = QString("сегодня, %1").arg(getDayOfWeekAsString(today.dayOfWeek()));
|
|
||||||
QString yesterdayTitle = QString("вчера, %1").arg(getDayOfWeekAsString(yesterday.dayOfWeek()));
|
|
||||||
QString beforeYesterdayTitle = QString("%1 %2, %3").arg(
|
|
||||||
QString::number(beforeYesterday.day()),
|
|
||||||
getMonthAsString(beforeYesterday.month()),
|
|
||||||
getDayOfWeekAsString(beforeYesterday.dayOfWeek())
|
|
||||||
);
|
|
||||||
|
|
||||||
QDomNode todayNode = findNode(m_xml, todayTitle);
|
|
||||||
QDomNode yesterdayNode = findNode(m_xml, yesterdayTitle);
|
|
||||||
|
|
||||||
QDomNode parentNode;
|
|
||||||
if (!yesterdayNode.isNull()) {
|
|
||||||
parentNode = yesterdayNode.parentNode();
|
|
||||||
} else if (!todayNode.isNull()) {
|
|
||||||
parentNode = todayNode.parentNode();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
QList<TransactionInfo> transactions;
|
|
||||||
if (!parentNode.isNull()) {
|
|
||||||
QDate date = {};
|
|
||||||
for (QDomNode transactionNode: parentNode.childNodes()) {
|
|
||||||
QString transactionShortText = transactionNode.toElement().attribute("text");
|
|
||||||
|
|
||||||
const QString titleLowerCase = transactionShortText.toLower();
|
|
||||||
if (titleLowerCase.startsWith(beforeYesterdayTitle)) {
|
|
||||||
// только сегодня и вчера парсим, позавчера не трогаем
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (titleLowerCase.startsWith(todayTitle)) {
|
|
||||||
date = today;
|
|
||||||
transactionShortText = transactionShortText.mid(todayTitle.length() + 1);
|
|
||||||
}
|
|
||||||
if (titleLowerCase.startsWith(yesterdayTitle)) {
|
|
||||||
date = yesterday;
|
|
||||||
transactionShortText = transactionShortText.mid(yesterdayTitle.length() + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (transactionShortText.contains("ЕСПП")) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
float amount = extractAmounts(transactionShortText);
|
|
||||||
QString shortDesc = beforeAmount(transactionShortText);
|
|
||||||
|
|
||||||
TransactionInfo info;
|
|
||||||
info.amount = amount;
|
|
||||||
info.bankTime = date.toString("dd.MM.yyyy");
|
|
||||||
info.description = shortDesc;
|
|
||||||
|
|
||||||
transactions.append(info);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return transactions;
|
|
||||||
}
|
|
||||||
|
|
||||||
void parse2daysHistory(const QDomNode &node) {
|
|
||||||
QDate today = DateUtils::getMoscowNow().date();
|
|
||||||
QDate tomorrow = today.addDays(-1);
|
|
||||||
QDate after2Days = today.addDays(-2);
|
|
||||||
|
|
||||||
QString todayTitle = QString("сегодня, %1").arg(getDayOfWeekAsString(today.dayOfWeek()));
|
|
||||||
QDomNode todayNode = findNode(node, todayTitle);
|
|
||||||
if (todayNode.isNull()) {
|
|
||||||
} else {
|
|
||||||
qDebug() << "todayNode: " << todayNode.toElement().attribute("text");
|
|
||||||
}
|
|
||||||
|
|
||||||
QString tomorrowTitle = QString("вчера, %1").arg(getDayOfWeekAsString(tomorrow.dayOfWeek()));
|
|
||||||
QDomNode tomorrowNode = findNode(node, tomorrowTitle);
|
|
||||||
if (tomorrowNode.isNull()) {
|
|
||||||
} else {
|
|
||||||
qDebug() << "tomorrowNode: " << tomorrowNode.toElement().attribute("text");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 30 апреля, Среда
|
|
||||||
QString after2DaysTitle = QString("%1 %2, %3").arg(
|
|
||||||
QString::number(after2Days.day()),
|
|
||||||
getMonthAsString(after2Days.month()),
|
|
||||||
getDayOfWeekAsString(after2Days.dayOfWeek()));
|
|
||||||
QDomNode after2DaysNode = findNode(node, after2DaysTitle);
|
|
||||||
if (after2DaysNode.isNull()) {
|
|
||||||
qDebug() << "No after2DaysNode";
|
|
||||||
} else {
|
|
||||||
qDebug() << "after2DaysNode: " << after2DaysNode.toElement().attribute("text");
|
|
||||||
}
|
|
||||||
|
|
||||||
QDomNode parentNode;
|
|
||||||
if (!todayNode.isNull() || !tomorrowNode.isNull() || !after2DaysNode.isNull()) {
|
|
||||||
if (!todayNode.isNull()) {
|
|
||||||
parentNode = todayNode.parentNode();
|
|
||||||
}
|
|
||||||
if (!tomorrowNode.isNull()) {
|
|
||||||
parentNode = tomorrowNode.parentNode();
|
|
||||||
}
|
|
||||||
if (!after2DaysNode.isNull()) {
|
|
||||||
parentNode = after2DaysNode.parentNode();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (!parentNode.isNull()) {
|
|
||||||
for (QDomNode child_node: parentNode.childNodes()) {
|
|
||||||
QString child_text = child_node.toElement().attribute("text");
|
|
||||||
if (child_text.toLower().startsWith(todayTitle)) {
|
|
||||||
qDebug() << "=== Today: " << todayTitle;
|
|
||||||
qDebug() << "node: " << beforeAmount(child_text.mid(todayTitle.length() + 1));
|
|
||||||
qDebug() << "--> sum: " << QString::number(extractAmounts(child_text), 'f', 2);
|
|
||||||
// qDebug() << "";
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (child_text.toLower().startsWith(tomorrowTitle)) {
|
|
||||||
qDebug() << "=== Yesterday: " << todayTitle;
|
|
||||||
qDebug() << "node: " << beforeAmount(child_text.mid(tomorrowTitle.length() + 1));
|
|
||||||
qDebug() << "--> sum: " << QString::number(extractAmounts(child_text), 'f', 2);
|
|
||||||
// qDebug() << "";
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (child_text.toLower().startsWith(after2DaysTitle)) {
|
|
||||||
qDebug() << "=== Before yesterday: " << todayTitle;
|
|
||||||
qDebug() << "node: " << beforeAmount(child_text.mid(after2DaysTitle.length() + 1));
|
|
||||||
qDebug() << "--> sum: " << QString::number(extractAmounts(child_text), 'f', 2);
|
|
||||||
// qDebug() << "";
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
qDebug() << "node: " << beforeAmount(child_node.toElement().attribute("text"));
|
|
||||||
qDebug() << "--> sum: " <<
|
|
||||||
QString::number(extractAmounts(child_node.toElement().attribute("text")), 'f', 2);
|
|
||||||
// qDebug() << "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// QString d = today.day() > 9 ? QString::number(today.day()) : "0" + QString::number(today.day());
|
|
||||||
// QString m = today.month() > 9 ? QString::number(today.month()) : "0" + QString::number(today.month());
|
|
||||||
// QString y = QString::number(today.year());
|
|
||||||
// QString w = getDayOfWeekAsString(today.dayOfWeek());
|
|
||||||
// QString mm = getMonthAsString(today.month());
|
|
||||||
// qDebug() << "Date:" << d << m << y << w << mm;
|
|
||||||
|
|
||||||
|
|
||||||
// QString d2 = after2Days.day() > 9 ? QString::number(after2Days.day()) : "0" + QString::number(after2Days.day());
|
|
||||||
// QString m2 = after2Days.month() > 9
|
|
||||||
// ? QString::number(after2Days.month())
|
|
||||||
// : "0" + QString::number(after2Days.month());
|
|
||||||
// QString y2 = QString::number(after2Days.year());
|
|
||||||
// QString w2 = getDayOfWeekAsString(after2Days.dayOfWeek());
|
|
||||||
// QString mm2 = getMonthAsString(after2Days.month());
|
|
||||||
// qDebug() << "Date:" << d2 << m2 << y2 << w2 << mm2;
|
|
||||||
}
|
|
||||||
|
|
||||||
TransactionInfo parseExpandedInfoHistory(const QDomElement &root) {
|
|
||||||
if (root.isElement()) {
|
|
||||||
QDomElement elem = root.toElement();
|
|
||||||
if (elem.tagName() == "node"
|
|
||||||
&& elem.attribute("class") == "android.widget.Button"
|
|
||||||
&& elem.attribute("text") == "Детали операции"
|
|
||||||
) {
|
|
||||||
TransactionInfo transaction;
|
|
||||||
// Все что ниже деталей операции
|
|
||||||
QDomNodeList detailInfo = elem.parentNode().childNodes();
|
|
||||||
|
|
||||||
for (int i = 0; i < detailInfo.count(); ++i) {
|
|
||||||
QDomNode info = detailInfo.at(i);
|
|
||||||
if (!info.isElement()) continue;
|
|
||||||
|
|
||||||
switch (QDomElement e = info.toElement(); e.attribute("index").toInt()) {
|
|
||||||
case 2:
|
|
||||||
// Дата операции
|
|
||||||
transaction.bankTime = transformBankDateTime(findSubInfo(e, "1"));
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
transaction.description = findSubInfo(e, "1");
|
|
||||||
parseTransferInfo(transaction.description, transaction);
|
|
||||||
break;
|
|
||||||
case 7:
|
|
||||||
// Комиссия
|
|
||||||
transaction.fee = findSubInfo(e, "1").remove(onlyDigitsRegex).toFloat();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
// qDebug() << "Прочее:" << findSubInfo(e);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return transaction;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Рекурсивно обходим всех детей
|
|
||||||
QDomNode child = root.firstChild();
|
|
||||||
while (!child.isNull()) {
|
|
||||||
if (TransactionInfo info = parseExpandedInfoHistory(child.toElement()); !info.bankTime.isEmpty()) {
|
|
||||||
return info;
|
|
||||||
}
|
|
||||||
child = child.nextSibling();
|
|
||||||
}
|
|
||||||
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
TransactionInfo ScreenXmlParser::parseTransactionInfoHistory(int screenWidth, int screenHeight) {
|
|
||||||
// 1. Распарсить описание транзакции
|
|
||||||
TransactionInfo transaction = parseExpandedInfoHistory(m_xml);
|
|
||||||
// 1. Найти статус: Исполнен | Операция исполнена
|
|
||||||
transaction.status = TransactionStatus::Wait;
|
|
||||||
Node status1 = findTextNode("Исполнен", 0, 0, screenWidth, screenHeight / 2);
|
|
||||||
Node status2 = findTextNode("Операция исполнена", 0, 0, screenWidth, screenHeight / 2);
|
|
||||||
if (!status1.isEmpty() || !status2.isEmpty()) {
|
|
||||||
transaction.status = TransactionStatus::Complete;
|
|
||||||
}
|
|
||||||
return transaction;
|
|
||||||
}
|
|
||||||
|
|
||||||
TransactionInfo parseExpandedInfo(const QDomElement &root) {
|
|
||||||
if (root.isElement()) {
|
|
||||||
QDomElement elem = root.toElement();
|
|
||||||
if (elem.tagName() == "node"
|
|
||||||
&& elem.attribute("class") == "android.widget.Button"
|
|
||||||
&& elem.attribute("text") == "Детали операции"
|
|
||||||
) {
|
|
||||||
TransactionInfo transaction;
|
|
||||||
// Все что ниже деталей операции
|
|
||||||
QDomNodeList detailInfo = elem.parentNode().childNodes();
|
|
||||||
|
|
||||||
for (int i = 0; i < detailInfo.count(); ++i) {
|
|
||||||
QDomNode info = detailInfo.at(i);
|
|
||||||
if (!info.isElement()) continue;
|
|
||||||
|
|
||||||
QDomElement infoElement = info.toElement();
|
|
||||||
QString index = infoElement.attribute("index");
|
|
||||||
QDomElement ee;
|
|
||||||
switch (index.toInt()) {
|
|
||||||
case 3:
|
|
||||||
transaction.bankTime = transformBankDateTime(findSubInfo(infoElement, "1"));
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
ee = findSubElement(infoElement, "0");
|
|
||||||
ee = findSubElement(ee, "1");
|
|
||||||
transaction.phone = findSubInfo(ee, "0").remove(onlyDigitsRegex);
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
transaction.name = findSubInfo(infoElement, "1");
|
|
||||||
break;
|
|
||||||
case 6:
|
|
||||||
transaction.bankName = findSubInfo(infoElement, "1");
|
|
||||||
break;
|
|
||||||
case 9:
|
|
||||||
transaction.fee = findSubInfo(infoElement, "1").remove(onlyDigitsAndDotRegex).toFloat();
|
|
||||||
break;
|
|
||||||
case 10:
|
|
||||||
ee = findSubElement(infoElement, "1");
|
|
||||||
transaction.bankTrExternalId = findSubInfo(ee, "1");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return transaction;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Рекурсивно обходим всех детей
|
|
||||||
QDomNode child = root.firstChild();
|
|
||||||
while (!child.isNull()) {
|
|
||||||
if (TransactionInfo info = parseExpandedInfo(child.toElement()); !info.bankTime.isEmpty()) {
|
|
||||||
return info;
|
|
||||||
}
|
|
||||||
child = child.nextSibling();
|
|
||||||
}
|
|
||||||
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
TransactionInfo ScreenXmlParser::parseTransactionInfo(int screenWidth, int screenHeight) {
|
|
||||||
// 1. Распарсить описание транзакции
|
|
||||||
TransactionInfo transaction = parseExpandedInfo(m_xml);
|
|
||||||
// 1. Найти статус: Исполнен | Операция исполнена
|
|
||||||
transaction.status = TransactionStatus::Wait;
|
|
||||||
Node status1 = findTextNode("Исполнен", 0, 0, screenWidth, screenHeight / 2);
|
|
||||||
Node status2 = findTextNode("Операция исполнена", 0, 0, screenWidth, screenHeight / 2);
|
|
||||||
if (!status1.isEmpty() || !status2.isEmpty()) {
|
|
||||||
transaction.status = TransactionStatus::Complete;
|
|
||||||
}
|
|
||||||
return transaction;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
QList<QPair<AccountInfo, Node> > ScreenXmlParser::parseAccountsInfo() {
|
|
||||||
QList<QPair<AccountInfo, Node> > accounts;
|
|
||||||
for (const Node &node: m_nodes) {
|
|
||||||
const QString text = node.text;
|
|
||||||
|
|
||||||
// Проверяем только нужные строки
|
|
||||||
if (!text.contains("Номер карты с последними цифрами")) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
QRegularExpressionMatch match = reCardData.match(text);
|
|
||||||
if (!match.hasMatch()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
AccountInfo info;
|
|
||||||
info.lastNumbers = match.captured(1).remove(" ");
|
|
||||||
info.amount = match.captured(2).remove(" ").toFloat();
|
|
||||||
info.description = text.mid(0, text.indexOf("Номер карты"));
|
|
||||||
info.updateTime = DateUtils::getUtcNow();
|
|
||||||
|
|
||||||
accounts.append(qMakePair(info, node));
|
|
||||||
}
|
|
||||||
|
|
||||||
return accounts;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ScreenXmlParser::test() {
|
|
||||||
// TransactionInfo info2 = parseExpandedInfo(m_xml);
|
|
||||||
// qDebug().noquote().nospace() << convertTransactionToString(info2);
|
|
||||||
// return;
|
|
||||||
|
|
||||||
QFile file("assets/rshb/all_products.xml");
|
|
||||||
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
|
||||||
qDebug() << "Cannot open file";
|
|
||||||
}
|
|
||||||
|
|
||||||
QDomDocument doc;
|
|
||||||
if (!doc.setContent(&file)) {
|
|
||||||
qDebug() << "Failed to parse XML";
|
|
||||||
}
|
|
||||||
file.close();
|
|
||||||
|
|
||||||
qDebug() << "Start parsing XML:";
|
|
||||||
|
|
||||||
// Номер карты с последними цифрами
|
|
||||||
QDomElement root = doc.documentElement();
|
|
||||||
parseAndSaveXml(doc.toString());
|
|
||||||
// for (const AccountInfo &info: parseAccountsInfo()) {
|
|
||||||
// qDebug().noquote().nospace() << convertAccountToString(info);
|
|
||||||
// }
|
|
||||||
// TransactionInfo info = parseExpandedInfo(root);
|
|
||||||
// qDebug().noquote().nospace() << convertTransactionToString(info);
|
|
||||||
// ЕСПП
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Rshb
|
|
||||||
@ -1,61 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <QObject>
|
|
||||||
#include <QDomElement>
|
|
||||||
#include "android/xml/Node.h"
|
|
||||||
#include "db/AccountInfo.h"
|
|
||||||
#include "db/TransactionInfo.h"
|
|
||||||
|
|
||||||
namespace Rshb {
|
|
||||||
|
|
||||||
class ScreenXmlParser final : public QObject {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit ScreenXmlParser(QObject *parent = nullptr);
|
|
||||||
|
|
||||||
~ScreenXmlParser() override;
|
|
||||||
|
|
||||||
Node tryToFindBannerOrDialog(int width, int height);
|
|
||||||
|
|
||||||
Node tryToFindSecurityBanner();
|
|
||||||
|
|
||||||
Node tryToFindSelectBottomSheet();
|
|
||||||
|
|
||||||
Node findTextNode(const QString &text);
|
|
||||||
|
|
||||||
Node findTextNode(const QString &text, int x1, int y1, int x2, int y2);
|
|
||||||
|
|
||||||
Node findFirstEditText();
|
|
||||||
|
|
||||||
Node findButtonNode(const QString &text, bool contains);
|
|
||||||
|
|
||||||
bool isHomeScreen();
|
|
||||||
|
|
||||||
|
|
||||||
QList<Node> tryToFindPinCode(const QString &pinCode, const QString &title);
|
|
||||||
|
|
||||||
QList<Node> getLast2DaysTransactions();
|
|
||||||
|
|
||||||
void parseAndSaveXml(const QString &xml);
|
|
||||||
|
|
||||||
TransactionInfo parseTransactionInfoHistory(int screenWidth, int screenHeight);
|
|
||||||
TransactionInfo parseTransactionInfo(int screenWidth, int screenHeight);
|
|
||||||
|
|
||||||
QList<TransactionInfo> parseTodayAndYesterdayReportHistory();
|
|
||||||
|
|
||||||
QList<TransactionInfo> parseTodayAndYesterdayHistory();
|
|
||||||
|
|
||||||
|
|
||||||
QList<QPair<AccountInfo, Node> > parseAccountsInfo();
|
|
||||||
|
|
||||||
void test();
|
|
||||||
|
|
||||||
private:
|
|
||||||
QList<Node> m_nodes;
|
|
||||||
QDomElement m_xml;
|
|
||||||
|
|
||||||
QList<Node> findPinCodeNodes(const QString &pinCode);
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Rshb
|
|
||||||
@ -1,19 +0,0 @@
|
|||||||
#include "SyncAccountDataScript.h"
|
|
||||||
|
|
||||||
namespace Rshb {
|
|
||||||
|
|
||||||
SyncAccountDataScript::SyncAccountDataScript(
|
|
||||||
QString deviceId,
|
|
||||||
QObject *parent
|
|
||||||
) : CommonScript(parent),
|
|
||||||
m_deviceId(std::move(deviceId)) {
|
|
||||||
}
|
|
||||||
|
|
||||||
SyncAccountDataScript::~SyncAccountDataScript() = default;
|
|
||||||
|
|
||||||
void SyncAccountDataScript::doStart() {
|
|
||||||
|
|
||||||
// 1.
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Rshb
|
|
||||||
@ -1,24 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include "CommonScript.h"
|
|
||||||
|
|
||||||
namespace Rshb {
|
|
||||||
|
|
||||||
class SyncAccountDataScript final : public CommonScript {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
~SyncAccountDataScript() override;
|
|
||||||
|
|
||||||
explicit SyncAccountDataScript(
|
|
||||||
QString deviceId,
|
|
||||||
QObject *parent = nullptr
|
|
||||||
);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void doStart() override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
const QString m_deviceId;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Rshb
|
|
||||||
@ -1,217 +0,0 @@
|
|||||||
#include "CommonTossScript.h"
|
|
||||||
|
|
||||||
#include <QJsonArray>
|
|
||||||
#include <QJsonObject>
|
|
||||||
#include <QRandomGenerator>
|
|
||||||
#include <QThread>
|
|
||||||
|
|
||||||
#include "adb/AdbUtils.h"
|
|
||||||
#include "net/NetworkService.h"
|
|
||||||
#include "time/DateUtils.h"
|
|
||||||
|
|
||||||
CommonTossScript::CommonTossScript(QObject *parent)
|
|
||||||
: QObject(parent) {
|
|
||||||
}
|
|
||||||
|
|
||||||
CommonTossScript::~CommonTossScript() = default;
|
|
||||||
|
|
||||||
void CommonTossScript::start() {
|
|
||||||
doStart();
|
|
||||||
emit finished();
|
|
||||||
}
|
|
||||||
|
|
||||||
Node CommonTossScript::swipeToButton(
|
|
||||||
const QString &deviceId,
|
|
||||||
const QString &text, int &counter, const int width, const int height
|
|
||||||
) {
|
|
||||||
for (int i = 0; i < 10; ++i) {
|
|
||||||
if (Node button = xmlScreenParser.findButtonNode(text, true); button.x() > 0 && button.y() > 0) {
|
|
||||||
return button;
|
|
||||||
}
|
|
||||||
const int x = width / 2;
|
|
||||||
const int offset = height / 4;
|
|
||||||
AdbUtils::makeSwipe(deviceId, x, height - offset, x, offset);
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++counter));
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CommonTossScript::runAppAndGoToHomeScreen(
|
|
||||||
const QString &deviceId,
|
|
||||||
const QString &packageName,
|
|
||||||
const QString &pinCode,
|
|
||||||
const int width,
|
|
||||||
const int height
|
|
||||||
) {
|
|
||||||
// Запустить устройство
|
|
||||||
if (const QString pid = AdbUtils::tryToGetRunningAppPid(deviceId, packageName); !pid.isEmpty()) {
|
|
||||||
qDebug() << "Process already running, pid: " << pid;
|
|
||||||
AdbUtils::getScreenDumpAsXml(deviceId, 1000);
|
|
||||||
AdbUtils::tryToKillApplication(deviceId, packageName);
|
|
||||||
}
|
|
||||||
if (!AdbUtils::tryToStartApplication(deviceId, packageName)) {
|
|
||||||
AdbUtils::takeScreenshot(deviceId, "run_app_error");
|
|
||||||
qWarning() << "Process has not started";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Даем минимальное время на запуск
|
|
||||||
QThread::msleep(2500);
|
|
||||||
int counter = 0;
|
|
||||||
bool findAndInputPincode = false;
|
|
||||||
|
|
||||||
while (true) {
|
|
||||||
counter++;
|
|
||||||
|
|
||||||
// Если более 10 раз мы пытаемся перейти на домашнюю
|
|
||||||
if (counter > 10) {
|
|
||||||
AdbUtils::takeScreenshot(deviceId, "too_many_attempts");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
|
|
||||||
|
|
||||||
// Node closeBannerNode = xmlScreenParser.findButtonNode("Maraqlı deyil", false);
|
|
||||||
// if (!closeBannerNode.isEmpty()) {
|
|
||||||
// AdbUtils::makeTap(deviceId, closeBannerNode.x(), closeBannerNode.y());
|
|
||||||
// QThread::msleep(1000);
|
|
||||||
// continue;
|
|
||||||
// }
|
|
||||||
|
|
||||||
if (xmlScreenParser.isHomeScreen()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Проверяем, что это экран ввода пин-кода
|
|
||||||
if (!findAndInputPincode) {
|
|
||||||
if (const QList<Node> pincode = xmlScreenParser.findPinCodeNodes(pinCode); pincode.size() == 6) {
|
|
||||||
for (const Node &node: pincode) {
|
|
||||||
AdbUtils::makeTap(deviceId, node.x(), node.y());
|
|
||||||
QThread::msleep(QRandomGenerator::global()->bounded(200, 901));
|
|
||||||
}
|
|
||||||
// После ввода пин-код нужно сделать задержку, пока подгрузка идет, чтобы снова не спарсить
|
|
||||||
findAndInputPincode = true;
|
|
||||||
QThread::msleep(3000);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QThread::msleep(1000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CommonTossScript::goToAllProducts(
|
|
||||||
const QString &deviceId,
|
|
||||||
const int width,
|
|
||||||
const int height
|
|
||||||
) {
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, m_counter));
|
|
||||||
Node closeBannerNode = xmlScreenParser.findButtonNode("Maraqlı deyil", false);
|
|
||||||
if (!closeBannerNode.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(deviceId, closeBannerNode.x(), closeBannerNode.y());
|
|
||||||
QThread::msleep(500);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (xmlScreenParser.isHomeScreen()) {
|
|
||||||
Node allMyAccountBtn = xmlScreenParser.findButtonNode("All My Accounts", false);
|
|
||||||
if (!allMyAccountBtn.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(deviceId, allMyAccountBtn.x(), allMyAccountBtn.y());
|
|
||||||
QThread::msleep(500);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CommonTossScript::postAccountsData(const QList<AccountInfo> &accounts) {
|
|
||||||
if (accounts.isEmpty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto *thread = new QThread;
|
|
||||||
auto *worker = new NetworkService;
|
|
||||||
|
|
||||||
QJsonArray list;
|
|
||||||
for (const AccountInfo &account: accounts) {
|
|
||||||
QJsonObject obj;
|
|
||||||
obj["appName"] = account.appCode;
|
|
||||||
obj["lastNumbers"] = account.lastNumbers;
|
|
||||||
obj["amount"] = account.amount;
|
|
||||||
obj["currency"] = account.currency;
|
|
||||||
obj["description"] = account.description;
|
|
||||||
obj["status"] = accountStatusToString(account.status);
|
|
||||||
|
|
||||||
list.append(obj);
|
|
||||||
}
|
|
||||||
// FIXME доставить десктоп ид из настроеек
|
|
||||||
worker->setDeviceId(accounts.first().deviceId);
|
|
||||||
worker->setPayload(QJsonDocument(list).toJson());
|
|
||||||
worker->moveToThread(thread);
|
|
||||||
connect(thread, &QThread::started, worker, &NetworkService::postAccountsData);
|
|
||||||
connect(worker, &NetworkService::finished, thread, &QThread::quit);
|
|
||||||
connect(worker, &NetworkService::finished, worker, &QObject::deleteLater);
|
|
||||||
connect(thread, &QThread::finished, thread, &QThread::deleteLater);
|
|
||||||
thread->start();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CommonTossScript::postNewTransactionData(const AccountInfo &account, const TransactionInfo &transaction) {
|
|
||||||
auto *thread = new QThread;
|
|
||||||
auto *worker = new NetworkService;
|
|
||||||
|
|
||||||
QJsonObject obj;
|
|
||||||
obj["id"] = transaction.id;
|
|
||||||
obj["amount"] = transaction.amount;
|
|
||||||
obj["name"] = transaction.name;
|
|
||||||
obj["fee"] = transaction.fee;
|
|
||||||
obj["status"] = transactionStatusToString(transaction.status);
|
|
||||||
obj["type"] = transactionTypeToString(transaction.type);
|
|
||||||
obj["phone"] = transaction.phone;
|
|
||||||
obj["description"] = transaction.description + " | " + transaction.bankTime;
|
|
||||||
obj["updatedDescription"] = transaction.updatedDescription;
|
|
||||||
obj["bankName"] = transaction.bankName;
|
|
||||||
obj["bankTime"] = DateUtils::toUtcString(transaction.completeTime);
|
|
||||||
obj["bankTransactionId"] = transaction.bankTrExternalId;
|
|
||||||
|
|
||||||
// FIXME доставить десктоп ид из настроеек
|
|
||||||
worker->setDeviceId(account.deviceId);
|
|
||||||
worker->addExtra("lastNumbers", account.lastNumbers);
|
|
||||||
worker->addExtra("transactionId", transaction.id);
|
|
||||||
worker->setPayload(QJsonDocument(obj).toJson());
|
|
||||||
worker->moveToThread(thread);
|
|
||||||
connect(thread, &QThread::started, worker, &NetworkService::insertTransactionData);
|
|
||||||
connect(worker, &NetworkService::finished, thread, &QThread::quit);
|
|
||||||
connect(worker, &NetworkService::finished, worker, &QObject::deleteLater);
|
|
||||||
connect(thread, &QThread::finished, thread, &QThread::deleteLater);
|
|
||||||
thread->start();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CommonTossScript::updateTransactionData(
|
|
||||||
const AccountInfo &account,
|
|
||||||
const int transactionId,
|
|
||||||
const TransactionStatus status,
|
|
||||||
const QString &oldDesc,
|
|
||||||
const QString &newDesc
|
|
||||||
) {
|
|
||||||
auto *thread = new QThread;
|
|
||||||
auto *worker = new NetworkService;
|
|
||||||
|
|
||||||
QJsonObject obj;
|
|
||||||
obj["id"] = transactionId;
|
|
||||||
obj["status"] = transactionStatusToString(status);
|
|
||||||
obj["description"] = newDesc;
|
|
||||||
obj["updatedDescription"] = oldDesc;
|
|
||||||
|
|
||||||
// FIXME доставить десктоп ид из настроеек
|
|
||||||
worker->setDeviceId(account.deviceId);
|
|
||||||
worker->addExtra("lastNumbers", account.lastNumbers);
|
|
||||||
worker->setPayload(QJsonDocument(obj).toJson());
|
|
||||||
worker->moveToThread(thread);
|
|
||||||
connect(thread, &QThread::started, worker, &NetworkService::updateTransactionData);
|
|
||||||
connect(worker, &NetworkService::finished, thread, &QThread::quit);
|
|
||||||
connect(worker, &NetworkService::finished, worker, &QObject::deleteLater);
|
|
||||||
connect(thread, &QThread::finished, thread, &QThread::deleteLater);
|
|
||||||
thread->start();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CommonTossScript::stop() {
|
|
||||||
m_running = false;
|
|
||||||
}
|
|
||||||
@ -1,68 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <QObject>
|
|
||||||
#include "ScreenXmlTossParser.h"
|
|
||||||
#include "android/xml/Node.h"
|
|
||||||
#include "db/AccountInfo.h"
|
|
||||||
#include "db/TransactionInfo.h"
|
|
||||||
|
|
||||||
class CommonTossScript : public QObject {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit CommonTossScript(QObject *parent = nullptr);
|
|
||||||
|
|
||||||
~CommonTossScript() override;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual void doStart() = 0;
|
|
||||||
|
|
||||||
bool goToAllProducts(
|
|
||||||
const QString &deviceId,
|
|
||||||
int width,
|
|
||||||
int height
|
|
||||||
);
|
|
||||||
|
|
||||||
void postAccountsData(const QList<AccountInfo> &accounts);
|
|
||||||
|
|
||||||
void postNewTransactionData(const AccountInfo &account, const TransactionInfo &transaction);
|
|
||||||
|
|
||||||
void updateTransactionData(
|
|
||||||
const AccountInfo &account,
|
|
||||||
int transactionId,
|
|
||||||
TransactionStatus status,
|
|
||||||
const QString &oldDesc,
|
|
||||||
const QString &newDesc
|
|
||||||
);
|
|
||||||
|
|
||||||
Node swipeToButton(
|
|
||||||
const QString &deviceId,
|
|
||||||
const QString &text,
|
|
||||||
int &counter, int width, int height
|
|
||||||
);
|
|
||||||
|
|
||||||
bool runAppAndGoToHomeScreen(
|
|
||||||
const QString &deviceId,
|
|
||||||
const QString &packageName,
|
|
||||||
const QString &pinCode,
|
|
||||||
int width,
|
|
||||||
int height
|
|
||||||
);
|
|
||||||
|
|
||||||
bool m_running = true;
|
|
||||||
ScreenXmlTossParser xmlScreenParser;
|
|
||||||
int m_counter = 0;
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void finished();
|
|
||||||
|
|
||||||
void finishedWithResult(const QString &result);
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
virtual void start() final;
|
|
||||||
|
|
||||||
virtual void stop() final;
|
|
||||||
|
|
||||||
private:
|
|
||||||
Q_DISABLE_COPY(CommonTossScript);
|
|
||||||
};
|
|
||||||
@ -1,160 +0,0 @@
|
|||||||
#include "GetLastDaysHistoryTossScript.h"
|
|
||||||
|
|
||||||
#include <QJsonObject>
|
|
||||||
#include <QRandomGenerator>
|
|
||||||
#include <QThread>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
#include "DatabaseManager.h"
|
|
||||||
#include "adb/AdbUtils.h"
|
|
||||||
#include "dao/AccountDAO.h"
|
|
||||||
#include "dao/ApplicationDAO.h"
|
|
||||||
#include "dao/DeviceDAO.h"
|
|
||||||
#include "dao/TransactionDAO.h"
|
|
||||||
#include "db/DeviceInfo.h"
|
|
||||||
#include "net/NetworkService.h"
|
|
||||||
#include "time/DateUtils.h"
|
|
||||||
|
|
||||||
GetLastDaysHistoryTossScript::GetLastDaysHistoryTossScript(
|
|
||||||
AccountInfo account,
|
|
||||||
QObject *parent
|
|
||||||
) : CommonTossScript(parent),
|
|
||||||
m_account(std::move(account)) {
|
|
||||||
}
|
|
||||||
|
|
||||||
GetLastDaysHistoryTossScript::~GetLastDaysHistoryTossScript() = default;
|
|
||||||
|
|
||||||
bool GetLastDaysHistoryTossScript::saveAndPostNewTransactionData(
|
|
||||||
const AccountInfo &account,
|
|
||||||
const TransactionInfo &transaction,
|
|
||||||
const TransactionStatus &status
|
|
||||||
) {
|
|
||||||
TransactionInfo tr;
|
|
||||||
tr.accountId = account.id;
|
|
||||||
tr.description = transaction.description;
|
|
||||||
tr.bankTime = transaction.bankTime;
|
|
||||||
tr.bankName = transaction.bankName;
|
|
||||||
tr.amount = transaction.amount;
|
|
||||||
tr.phone = transaction.phone;
|
|
||||||
tr.updateTime = DateUtils::getUtcNow();
|
|
||||||
tr.fee = transaction.fee;
|
|
||||||
tr.name = transaction.name;
|
|
||||||
tr.bankTrExternalId = transaction.bankTrExternalId;
|
|
||||||
tr.status = status;
|
|
||||||
tr.type = TransactionType::Card;
|
|
||||||
tr.completeTime = transaction.completeTime;
|
|
||||||
tr.id = TransactionDAO::insertTransaction(tr);
|
|
||||||
|
|
||||||
if (tr.id == -1) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
postNewTransactionData(account, tr);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GetLastDaysHistoryTossScript::updateAndPostTransactionData(
|
|
||||||
const AccountInfo &account,
|
|
||||||
const int transactionId,
|
|
||||||
const TransactionStatus status,
|
|
||||||
const QString &oldDesc,
|
|
||||||
const QString &newDesc
|
|
||||||
) {
|
|
||||||
if (TransactionDAO::updateTransaction(transactionId, status, oldDesc, newDesc)) {
|
|
||||||
updateTransactionData(account, transactionId, status, oldDesc, newDesc);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GetLastDaysHistoryTossScript::doStart() {
|
|
||||||
// берем все транзакции из БД
|
|
||||||
const DeviceInfo device = DeviceDAO::getDeviceById(m_account.deviceId);
|
|
||||||
const ApplicationInfo app = ApplicationDAO::getApplication(m_account.deviceId, m_account.appCode);
|
|
||||||
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter));
|
|
||||||
if (!xmlScreenParser.isHomeScreen()) {
|
|
||||||
if (!runAppAndGoToHomeScreen(device.id, app.package, app.pinCode, device.screenWidth, device.screenHeight)) {
|
|
||||||
m_error = "Не смогли дойти до домашней страницы";
|
|
||||||
qCritical() << m_error;
|
|
||||||
emit finishedWithResult(m_error);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter));
|
|
||||||
|
|
||||||
if (xmlScreenParser.isHomeScreen()) {
|
|
||||||
QList<AccountInfo> oldAccounts = AccountDAO::getAccounts(m_account.deviceId, m_account.appCode);
|
|
||||||
QMap<QString, AccountInfo> accountMap;
|
|
||||||
for (AccountInfo &oldAccount: oldAccounts) {
|
|
||||||
if (oldAccount.status == AccountStatus::Active) {
|
|
||||||
accountMap.insert(oldAccount.lastNumbers, oldAccount);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<AccountInfo> accounts = xmlScreenParser.parseAccountsInfo();
|
|
||||||
if (accounts.length() == 1 && accountMap.size() == 1) {
|
|
||||||
AccountInfo account = accounts[0];
|
|
||||||
account.deviceId = m_account.deviceId;
|
|
||||||
account.appCode = m_account.appCode;
|
|
||||||
account.lastNumbers = accountMap.first().lastNumbers;
|
|
||||||
account.description = accountMap.first().description;
|
|
||||||
account.currency = accountMap.first().currency;
|
|
||||||
account.description = accountMap.first().description;
|
|
||||||
account.status = AccountStatus::Active;
|
|
||||||
if (!AccountDAO::upsertAccount(account)) {
|
|
||||||
m_error = "Not updated: " + account.lastNumbers;
|
|
||||||
qCritical() << m_error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<AccountInfo> savedAccounts = AccountDAO::getAccounts(m_account.deviceId, m_account.appCode);
|
|
||||||
postAccountsData(savedAccounts);
|
|
||||||
|
|
||||||
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter));
|
|
||||||
Node transferText = xmlScreenParser.findFirstAccountLine();
|
|
||||||
if (!transferText.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(device.id, transferText.x(), transferText.y());
|
|
||||||
QThread::msleep(3000);
|
|
||||||
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter));
|
|
||||||
|
|
||||||
for (int i = 0; i < 5; ++i) {
|
|
||||||
Node myBankText = xmlScreenParser.findTextNode("My Toss Bank");
|
|
||||||
Node accountText = xmlScreenParser.findTextNode("Account");
|
|
||||||
|
|
||||||
if (!myBankText.isEmpty() && !accountText.isEmpty()) {
|
|
||||||
QList<TransactionInfo> transactions = xmlScreenParser.parsePositiveTransactions();
|
|
||||||
QList<TransactionInfo> savedTransactions = TransactionDAO::getTransactionsWithinHours(m_account.id, 48);
|
|
||||||
for (TransactionInfo &transaction: transactions) {
|
|
||||||
bool isSaved = false;
|
|
||||||
for (TransactionInfo &savedTransaction: savedTransactions) {
|
|
||||||
if (savedTransaction.amount == transaction.amount
|
|
||||||
&& savedTransaction.bankTime == transaction.bankTime) {
|
|
||||||
isSaved = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!isSaved) {
|
|
||||||
if (!saveAndPostNewTransactionData(m_account, transaction, TransactionStatus::Complete)) {
|
|
||||||
qDebug() << "--- saveAndPostNewTransactionData failed";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
QThread::msleep(1000);
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId , ++m_counter));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
m_error = "Card not found: " + m_account.deviceId + " " + m_account.lastNumbers;
|
|
||||||
qWarning() << m_error;
|
|
||||||
emit finishedWithResult(m_error);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
AdbUtils::goBack(m_account.deviceId);
|
|
||||||
emit finishedWithResult(m_error);
|
|
||||||
}
|
|
||||||
@ -1,35 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include "CommonTossScript.h"
|
|
||||||
|
|
||||||
class GetLastDaysHistoryTossScript final : public CommonTossScript {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
~GetLastDaysHistoryTossScript() override;
|
|
||||||
|
|
||||||
explicit GetLastDaysHistoryTossScript(
|
|
||||||
AccountInfo account,
|
|
||||||
QObject *parent = nullptr
|
|
||||||
);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void doStart() override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
const AccountInfo m_account;
|
|
||||||
QString m_error;
|
|
||||||
|
|
||||||
bool saveAndPostNewTransactionData(
|
|
||||||
const AccountInfo &account,
|
|
||||||
const TransactionInfo &transaction,
|
|
||||||
const TransactionStatus &status
|
|
||||||
);
|
|
||||||
|
|
||||||
bool updateAndPostTransactionData(
|
|
||||||
const AccountInfo &account,
|
|
||||||
int transactionId,
|
|
||||||
TransactionStatus status,
|
|
||||||
const QString &oldDesc,
|
|
||||||
const QString &newDesc
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@ -1,379 +0,0 @@
|
|||||||
#include "LoginAndCheckAccountsTossScript.h"
|
|
||||||
|
|
||||||
#include <QRandomGenerator>
|
|
||||||
#include <QThread>
|
|
||||||
|
|
||||||
#include "adb/AdbUtils.h"
|
|
||||||
#include "dao/AccountDAO.h"
|
|
||||||
#include "dao/ApplicationDAO.h"
|
|
||||||
#include "dao/DeviceDAO.h"
|
|
||||||
#include "dao/TransactionDAO.h"
|
|
||||||
#include "time/DateUtils.h"
|
|
||||||
|
|
||||||
LoginAndCheckAccountsTossScript::LoginAndCheckAccountsTossScript(
|
|
||||||
QString deviceId,
|
|
||||||
QString appCode,
|
|
||||||
QObject *parent
|
|
||||||
) : CommonTossScript(parent),
|
|
||||||
m_deviceId(std::move(deviceId)), m_appCode(std::move(appCode)) {
|
|
||||||
}
|
|
||||||
|
|
||||||
LoginAndCheckAccountsTossScript::~LoginAndCheckAccountsTossScript() = default;
|
|
||||||
|
|
||||||
/**
|
|
||||||
NongHyup
|
|
||||||
KakaoBank
|
|
||||||
Kookmin
|
|
||||||
Toss Bank
|
|
||||||
Shinhan
|
|
||||||
Woori
|
|
||||||
IBK
|
|
||||||
Hana
|
|
||||||
MG
|
|
||||||
Busan Bank
|
|
||||||
iM Bank(Daegu)
|
|
||||||
Kbank
|
|
||||||
Credit Union
|
|
||||||
Postal Sav.
|
|
||||||
SC
|
|
||||||
Kyongnam
|
|
||||||
Kwangju
|
|
||||||
Suhyup
|
|
||||||
Jeonbuk
|
|
||||||
Savings Banks
|
|
||||||
Jeju Bank
|
|
||||||
Jeonbuk
|
|
||||||
Savings Banks
|
|
||||||
Jeju Bank
|
|
||||||
Citibank
|
|
||||||
KDB
|
|
||||||
NFCF
|
|
||||||
SBI Sav.
|
|
||||||
BOA
|
|
||||||
Bank of China
|
|
||||||
HSBC
|
|
||||||
ICBC
|
|
||||||
Deutsche
|
|
||||||
JPMorgan
|
|
||||||
BNP Paribas
|
|
||||||
CCB
|
|
||||||
*/
|
|
||||||
void LoginAndCheckAccountsTossScript::doStart() {
|
|
||||||
const DeviceInfo device = DeviceDAO::getDeviceById(m_deviceId);
|
|
||||||
const ApplicationInfo app = ApplicationDAO::getApplication(m_deviceId, m_appCode);
|
|
||||||
|
|
||||||
|
|
||||||
if (true) {
|
|
||||||
|
|
||||||
if (true) {
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
|
|
||||||
auto accounts = xmlScreenParser.parseAccountsInfo();
|
|
||||||
if (!accounts.empty()) {
|
|
||||||
qDebug() << "--- Finish, amount: " << QString::number(accounts[0].amount);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
|
|
||||||
// находим первую кнопку Transfer
|
|
||||||
Node transferText = xmlScreenParser.findButtonNode("Transfer", false);
|
|
||||||
if (!transferText.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(m_deviceId, transferText.x(), transferText.y());
|
|
||||||
QThread::msleep(1000);
|
|
||||||
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
|
|
||||||
Node enterAmount = xmlScreenParser.findEditText("Enter account number");
|
|
||||||
if (!enterAmount.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(m_deviceId, enterAmount.x(), enterAmount.y());
|
|
||||||
QThread::msleep(200);
|
|
||||||
|
|
||||||
AdbUtils::inputText(m_deviceId, "51291082442507");
|
|
||||||
QThread::msleep(200);
|
|
||||||
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
|
|
||||||
Node inputBank = xmlScreenParser.findNodeByClassName("android.widget.Spinner");
|
|
||||||
if (!inputBank.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(m_deviceId, inputBank.x(), inputBank.y());
|
|
||||||
QThread::msleep(500);
|
|
||||||
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
|
|
||||||
|
|
||||||
bool foundBank = false;
|
|
||||||
for (int i = 0; i < 5; ++i) {
|
|
||||||
Node bank = xmlScreenParser.findTextNode("Hana");
|
|
||||||
if (!bank.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(m_deviceId, bank.x(), bank.y());
|
|
||||||
QThread::msleep(200);
|
|
||||||
foundBank = true;
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
AdbUtils::makeSwipe(
|
|
||||||
m_deviceId,
|
|
||||||
device.screenWidth / 2, device.screenHeight / 4 * 3,
|
|
||||||
device.screenWidth / 2, device.screenHeight / 2
|
|
||||||
);
|
|
||||||
QThread::msleep(500);
|
|
||||||
}
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!foundBank) {
|
|
||||||
m_error = "Bank not found: " + m_deviceId + " " + m_appCode;
|
|
||||||
qCritical() << m_error;
|
|
||||||
emit finishedWithResult(m_error);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
|
|
||||||
Node confirmTransfer = xmlScreenParser.findButtonNode("Confirm", false);
|
|
||||||
if (!confirmTransfer.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(m_deviceId, confirmTransfer.x(), confirmTransfer.y());
|
|
||||||
QThread::msleep(3000);
|
|
||||||
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
|
|
||||||
|
|
||||||
bool enterAmountFound = false;
|
|
||||||
for (int i = 0; i < 10; ++i) {
|
|
||||||
Node enterAmountText = xmlScreenParser.findTextNode("Enter amount");
|
|
||||||
if (!enterAmountText.isEmpty()) {
|
|
||||||
// AdbUtils::makeTap(m_deviceId, enterAmountText.x(), enterAmountText.y());
|
|
||||||
// QThread::msleep(500);
|
|
||||||
enterAmountFound = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
QThread::msleep(1000);
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!enterAmountFound) {
|
|
||||||
m_error = "Enter amount not found: " + m_deviceId + " " + m_appCode;
|
|
||||||
qCritical() << m_error;
|
|
||||||
emit finishedWithResult(m_error);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
|
|
||||||
Node closeBtn = xmlScreenParser.findButtonNode("확인", false);
|
|
||||||
if (!closeBtn.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(m_deviceId, closeBtn.x(), closeBtn.y());
|
|
||||||
QThread::msleep(200);
|
|
||||||
}
|
|
||||||
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
|
|
||||||
for (Node &number: xmlScreenParser.getNodeNumbers(4)) {
|
|
||||||
AdbUtils::makeTap(m_deviceId, number.x(), number.y());
|
|
||||||
QThread::msleep(QRandomGenerator::global()->bounded(200, 901));
|
|
||||||
}
|
|
||||||
|
|
||||||
// AdbUtils::inputText(m_deviceId, "2");
|
|
||||||
QThread::msleep(1000);
|
|
||||||
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
|
|
||||||
Node nextBtn = xmlScreenParser.findButtonNode("Next", false);
|
|
||||||
if (!nextBtn.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(m_deviceId, nextBtn.x(), nextBtn.y());
|
|
||||||
QThread::msleep(1000);
|
|
||||||
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
|
|
||||||
Node sendBtn = xmlScreenParser.findButtonNode("Send", false);
|
|
||||||
if (!sendBtn.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(m_deviceId, sendBtn.x(), sendBtn.y());
|
|
||||||
QThread::msleep(1000);
|
|
||||||
|
|
||||||
xmlScreenParser.parseAndSaveXml(
|
|
||||||
AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
|
|
||||||
Node sendAgainBtn = xmlScreenParser.findButtonNode("Send", false);
|
|
||||||
if (!sendAgainBtn.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(m_deviceId, sendAgainBtn.x(), sendAgainBtn.y());
|
|
||||||
QThread::msleep(1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool findAndInputPincode = false;
|
|
||||||
xmlScreenParser.parseAndSaveXml(
|
|
||||||
AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
|
|
||||||
if (const QList<Node> pincode = xmlScreenParser.findPinCodeNodes(app.pinCode);
|
|
||||||
pincode.size() == 6) {
|
|
||||||
for (const Node &node: pincode) {
|
|
||||||
AdbUtils::makeTap(m_deviceId, node.x(), node.y());
|
|
||||||
QThread::msleep(QRandomGenerator::global()->bounded(200, 901));
|
|
||||||
}
|
|
||||||
findAndInputPincode = true;
|
|
||||||
QThread::msleep(2000);
|
|
||||||
}
|
|
||||||
if (!findAndInputPincode) {
|
|
||||||
m_error = "Pincode not found: " + m_deviceId + " " + m_appCode;
|
|
||||||
qCritical() << m_error;
|
|
||||||
emit finishedWithResult(m_error);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
xmlScreenParser.parseAndSaveXml(
|
|
||||||
AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
|
|
||||||
bool foundConfirmBtn = false;
|
|
||||||
for (int i = 0; i < 5; ++i) {
|
|
||||||
Node confirmBtn = xmlScreenParser.findButtonNode("Confirm", false);
|
|
||||||
if (!confirmBtn.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(m_deviceId, confirmBtn.x(), confirmBtn.y());
|
|
||||||
foundConfirmBtn = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
QThread::msleep(1000);
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!foundConfirmBtn) {
|
|
||||||
m_error = "Last Confirm button not found: " + m_deviceId + " " + m_appCode;
|
|
||||||
qCritical() << m_error;
|
|
||||||
emit finishedWithResult(m_error);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
QThread::msleep(1000);
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
|
|
||||||
for (int i = 0; i < 10; ++i) {
|
|
||||||
Node lastBtn = xmlScreenParser.findTextNode("닫기");
|
|
||||||
Node lastBtn2 = xmlScreenParser.findTextNode("Close");
|
|
||||||
if (!lastBtn.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(m_deviceId, lastBtn.x(), lastBtn.y());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!lastBtn2.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(m_deviceId, lastBtn2.x(), lastBtn2.y());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
QThread::msleep(1000);
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
|
|
||||||
qDebug() << "--- Finish: " << xmlScreenParser.parseAccountAmount();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
m_error = "Next button not found: " + m_deviceId + " " + m_appCode;
|
|
||||||
qCritical() << m_error;
|
|
||||||
emit finishedWithResult(m_error);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
m_error = "Confirm transfer button not found: " + m_deviceId + " " + m_appCode;
|
|
||||||
qCritical() << m_error;
|
|
||||||
emit finishedWithResult(m_error);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
m_error = "Input bank not found: " + m_deviceId + " " + m_appCode;
|
|
||||||
qCritical() << m_error;
|
|
||||||
emit finishedWithResult(m_error);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
m_error = "Enter account number not found: " + m_deviceId + " " + m_appCode;
|
|
||||||
qCritical() << m_error;
|
|
||||||
emit finishedWithResult(m_error);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
m_error = "Transfer button not found: " + m_deviceId + " " + m_appCode;
|
|
||||||
qCritical() << m_error;
|
|
||||||
emit finishedWithResult(m_error);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// "Maraqlı deyil" - не интересно
|
|
||||||
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 (!runAppAndGoToHomeScreen(device.id, app.package, app.pinCode, device.screenWidth, device.screenHeight)) {
|
|
||||||
m_error = "Cant open the home screen: " + m_deviceId + " " + m_appCode;
|
|
||||||
qWarning() << m_error;
|
|
||||||
if (!ApplicationDAO::updatePinCodeStatus(app.id, "no", "Не прошла проверка [дата]")) {
|
|
||||||
qWarning() << "Cant update the pincode: " << m_deviceId << " " << m_appCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
AdbUtils::tryToKillApplication(m_deviceId, app.package);
|
|
||||||
emit finishedWithResult(m_error);
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
if (!ApplicationDAO::updatePinCodeStatus(app.id, "yes", "")) {
|
|
||||||
qWarning() << "Cant update the pincode: " << m_deviceId << " " << m_appCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
Node mainAccount = xmlScreenParser.findTextContainsNode("Main account");
|
|
||||||
if (!mainAccount.isEmpty()) {
|
|
||||||
// AdbUtils::makeTap(device.id, mainAccount.x(), mainAccount.y());
|
|
||||||
// QThread::msleep(1000);
|
|
||||||
// for (int i = 0; i < 5; ++i) {
|
|
||||||
// xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter));
|
|
||||||
// Node mainAccount = xmlScreenParser.findTextContainsNode("Main account");
|
|
||||||
// if (!byDayTitle.isEmpty()) {
|
|
||||||
// qWarning() << "--- beforeYesterdayTitle found!";
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
// AdbUtils::makeSwipe(
|
|
||||||
// m_account.deviceId,
|
|
||||||
// device.screenWidth / 2, device.screenHeight / 4 * 3,
|
|
||||||
// device.screenWidth / 2, device.screenHeight / 4
|
|
||||||
// );
|
|
||||||
// QThread::msleep(1000);
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
QThread::msleep(2000);
|
|
||||||
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
|
|
||||||
|
|
||||||
QList<AccountInfo> oldAccounts = AccountDAO::getAccounts(m_deviceId, m_appCode);
|
|
||||||
QMap<QString, AccountInfo> accountMap;
|
|
||||||
for (AccountInfo &oldAccount: oldAccounts) {
|
|
||||||
if (oldAccount.status == AccountStatus::Active) {
|
|
||||||
accountMap.insert(oldAccount.lastNumbers, oldAccount);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<AccountInfo> accounts = xmlScreenParser.parseAccountsInfo();
|
|
||||||
if (accounts.length() == 1 && accountMap.size() == 1) {
|
|
||||||
AccountInfo account = accounts[0];
|
|
||||||
account.deviceId = m_deviceId;
|
|
||||||
account.appCode = m_appCode;
|
|
||||||
account.lastNumbers = accountMap.first().lastNumbers;
|
|
||||||
account.description = accountMap.first().description;
|
|
||||||
account.currency = accountMap.first().currency;
|
|
||||||
account.description = accountMap.first().description;
|
|
||||||
account.status = AccountStatus::Active;
|
|
||||||
if (!AccountDAO::upsertAccount(account)) {
|
|
||||||
m_error = "Not updated: " + account.lastNumbers;
|
|
||||||
qCritical() << m_error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// for (auto account: accounts) {
|
|
||||||
// if (accountMap.contains(account.lastNumbers)) {
|
|
||||||
// account.deviceId = m_deviceId;
|
|
||||||
// account.appCode = m_appCode;
|
|
||||||
// account.currency = accountMap[account.lastNumbers].currency;
|
|
||||||
// account.description = accountMap[account.lastNumbers].description;
|
|
||||||
// account.status = AccountStatus::Active;
|
|
||||||
// if (!AccountDAO::upsertAccount(account)) {
|
|
||||||
// m_error = "Not updated: " + account.lastNumbers;
|
|
||||||
// qCritical() << m_error;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
QList<AccountInfo> savedAccounts = AccountDAO::getAccounts(m_deviceId, m_appCode);
|
|
||||||
postAccountsData(savedAccounts);
|
|
||||||
}
|
|
||||||
|
|
||||||
AdbUtils::tryToKillApplication(m_deviceId, app.package);
|
|
||||||
}
|
|
||||||
emit finishedWithResult(m_error);
|
|
||||||
}
|
|
||||||
@ -1,23 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include "CommonTossScript.h"
|
|
||||||
|
|
||||||
class LoginAndCheckAccountsTossScript final : public CommonTossScript {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
~LoginAndCheckAccountsTossScript() override;
|
|
||||||
|
|
||||||
explicit LoginAndCheckAccountsTossScript(
|
|
||||||
QString deviceId,
|
|
||||||
QString appCode,
|
|
||||||
QObject *parent = nullptr
|
|
||||||
);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void doStart() override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
const QString m_deviceId;
|
|
||||||
const QString m_appCode;
|
|
||||||
QString m_error;
|
|
||||||
};
|
|
||||||
@ -1,350 +0,0 @@
|
|||||||
#include "PayByCardTossScript.h"
|
|
||||||
|
|
||||||
#include <QRandomGenerator>
|
|
||||||
#include <QThread>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
#include "DatabaseManager.h"
|
|
||||||
#include "adb/AdbUtils.h"
|
|
||||||
#include "dao/AccountDAO.h"
|
|
||||||
#include "dao/ApplicationDAO.h"
|
|
||||||
#include "dao/DeviceDAO.h"
|
|
||||||
#include "dao/TransactionDAO.h"
|
|
||||||
#include "db/ApplicationInfo.h"
|
|
||||||
#include "db/DeviceInfo.h"
|
|
||||||
#include "time/DateUtils.h"
|
|
||||||
|
|
||||||
PayByCardTossScript::PayByCardTossScript(
|
|
||||||
AccountInfo account,
|
|
||||||
QString iban,
|
|
||||||
QString fullName,
|
|
||||||
const double amount,
|
|
||||||
QObject *parent
|
|
||||||
) : CommonTossScript(parent),
|
|
||||||
m_account(std::move(account)),
|
|
||||||
m_fullName(std::move(fullName)), m_amount(amount) {
|
|
||||||
}
|
|
||||||
|
|
||||||
PayByCardTossScript::~PayByCardTossScript() = default;
|
|
||||||
|
|
||||||
|
|
||||||
void PayByCardTossScript::makePayment(const DeviceInfo &device) {
|
|
||||||
// Оплата со страницы карты
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(device.id, ++m_counter));
|
|
||||||
Node editIbanEditText = xmlScreenParser.findEditTextByResourceId("com.Toss.Tossmobil:id/edit_iban");
|
|
||||||
Node fullNameEditText = xmlScreenParser.findEditTextByResourceId("com.Toss.Tossmobil:id/edit_full_name");
|
|
||||||
if (!editIbanEditText.isEmpty() && !fullNameEditText.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(device.id, editIbanEditText.x(), editIbanEditText.y());
|
|
||||||
QThread::msleep(500);
|
|
||||||
// AdbUtils::inputText(device.id, m_iban);
|
|
||||||
|
|
||||||
AdbUtils::makeTap(device.id, editIbanEditText.x(), editIbanEditText.y());
|
|
||||||
QThread::msleep(500);
|
|
||||||
AdbUtils::inputText(device.id, m_fullName);
|
|
||||||
|
|
||||||
Node nextBtn = xmlScreenParser.findButtonNode("NEXT", false);
|
|
||||||
AdbUtils::makeTap(device.id, nextBtn.x(), nextBtn.y());
|
|
||||||
|
|
||||||
bool findSenderAccount = false;
|
|
||||||
for (int i = 0; i < 5; ++i) {
|
|
||||||
QThread::msleep(1000);
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(device.id, ++m_counter));
|
|
||||||
|
|
||||||
Node senderAccount = xmlScreenParser.findTextNode("Sender Account");
|
|
||||||
if (!senderAccount.isEmpty()) {
|
|
||||||
// Node inputBankName = xmlScreenParser.findAccountButton(m_account.lastNumbers);
|
|
||||||
// if (!inputBankName.isEmpty()) {
|
|
||||||
// AdbUtils::makeTap(device.id, inputBankName.x(), inputBankName.y());
|
|
||||||
// QThread::msleep(500);
|
|
||||||
|
|
||||||
|
|
||||||
// // FXIME скорее всего придется нажать кнопку NEXT
|
|
||||||
// findSenderAccount = true;
|
|
||||||
// }
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!findSenderAccount) {
|
|
||||||
m_error = "Не нашли Sender Account";
|
|
||||||
qDebug() << m_error;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool findAmountDetermination = false;
|
|
||||||
for (int i = 0; i < 5; ++i) {
|
|
||||||
QThread::msleep(1000);
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(device.id, ++m_counter));
|
|
||||||
|
|
||||||
Node amountDetermination = xmlScreenParser.findTextNode("Amount Determination");
|
|
||||||
if (!amountDetermination.isEmpty()) {
|
|
||||||
Node integerEditText = xmlScreenParser.findEditTextByResourceId(
|
|
||||||
"com.Toss.Tossmobil:id/edit_text_integer");
|
|
||||||
Node decimalEditText = xmlScreenParser.findEditTextByResourceId(
|
|
||||||
"com.Toss.Tossmobil:id/edit_text_decimal");
|
|
||||||
if (!integerEditText.isEmpty() && !decimalEditText.isEmpty()) {
|
|
||||||
int integerPart = static_cast<int>(m_amount);
|
|
||||||
AdbUtils::makeTap(device.id, integerEditText.x(), integerEditText.y());
|
|
||||||
QThread::msleep(500);
|
|
||||||
AdbUtils::inputText(device.id, QString::number(integerPart));
|
|
||||||
|
|
||||||
int decimalPart = static_cast<int>((m_amount - integerPart) * 100);
|
|
||||||
AdbUtils::makeTap(device.id, decimalEditText.x(), decimalEditText.y());
|
|
||||||
QThread::msleep(500);
|
|
||||||
AdbUtils::inputText(device.id, QString::number(decimalPart));
|
|
||||||
|
|
||||||
findAmountDetermination = true;
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
m_error = "Не нашли поля ввода для ввода суммы перевода";
|
|
||||||
qDebug() << m_error;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!findAmountDetermination) {
|
|
||||||
m_error = "Не нашли Amount Determination";
|
|
||||||
qDebug() << m_error;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool findDetailDefinition = false;
|
|
||||||
for (int i = 0; i < 5; ++i) {
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(device.id, ++m_counter));
|
|
||||||
Node fastTransferBtn = xmlScreenParser.findButtonNode("FAST TRANSFER", false);
|
|
||||||
if (!fastTransferBtn.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(device.id, fastTransferBtn.x(), fastTransferBtn.y());
|
|
||||||
QThread::msleep(500);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
Node detailDefinitionTitle = xmlScreenParser.findTextNode("Detail Definition");
|
|
||||||
Node pleaseChooseBtn = xmlScreenParser.findButtonNode("Please choose", false);
|
|
||||||
if (!detailDefinitionTitle.isEmpty() && !pleaseChooseBtn.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(device.id, pleaseChooseBtn.x(), pleaseChooseBtn.y());
|
|
||||||
QThread::msleep(500);
|
|
||||||
|
|
||||||
Node searchEditText = xmlScreenParser.
|
|
||||||
findEditTextByResourceId("com.Toss.Tossmobil:id/input_search");
|
|
||||||
if (!searchEditText.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(device.id, searchEditText.x(), searchEditText.y());
|
|
||||||
QThread::msleep(500);
|
|
||||||
// FIXME "Individual Payment" или "Other Payments" если нет одного, то надо другой
|
|
||||||
AdbUtils::inputText(device.id, "Other Payments");
|
|
||||||
QThread::msleep(1000);
|
|
||||||
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(device.id, ++m_counter));
|
|
||||||
|
|
||||||
Node otherPaymentsText = xmlScreenParser.findTextNode("Other Payments");
|
|
||||||
if (!otherPaymentsText.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(device.id, otherPaymentsText.x(), otherPaymentsText.y());
|
|
||||||
QThread::msleep(500);
|
|
||||||
findDetailDefinition = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for (int i = 0; i < 5; ++i) {
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(device.id, ++m_counter));
|
|
||||||
Node otherPaymentsText = xmlScreenParser.findTextNode("Other Payments");
|
|
||||||
if (otherPaymentsText.isEmpty()) {
|
|
||||||
AdbUtils::makeSwipe(
|
|
||||||
m_account.deviceId,
|
|
||||||
device.screenWidth / 2, device.screenHeight / 4 * 3,
|
|
||||||
device.screenWidth / 2, device.screenHeight / 4
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
AdbUtils::makeTap(device.id, otherPaymentsText.x(), otherPaymentsText.y());
|
|
||||||
QThread::msleep(500);
|
|
||||||
findDetailDefinition = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
QThread::msleep(500);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!findDetailDefinition) {
|
|
||||||
m_error = "Не нашли Detail Definition";
|
|
||||||
qDebug() << m_error;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(device.id, ++m_counter));
|
|
||||||
Node nextBtn4 = xmlScreenParser.findButtonNode("NEXT", false);
|
|
||||||
AdbUtils::makeTap(device.id, nextBtn4.x(), nextBtn4.y());
|
|
||||||
QThread::msleep(500);
|
|
||||||
|
|
||||||
Node checkInfo = xmlScreenParser.findTextNode(
|
|
||||||
"Check the details of the transaction you shall realize and approve your transaction.");
|
|
||||||
if (!checkInfo.isEmpty()) {
|
|
||||||
for (int i = 0; i < 5; ++i) {
|
|
||||||
Node confirmBtn = xmlScreenParser.findButtonNode("CONFIRM", false);
|
|
||||||
if (confirmBtn.isEmpty()) {
|
|
||||||
AdbUtils::makeSwipe(
|
|
||||||
m_account.deviceId,
|
|
||||||
device.screenWidth / 2, device.screenHeight / 4 * 3,
|
|
||||||
device.screenWidth / 2, device.screenHeight / 4
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
AdbUtils::makeTap(device.id, confirmBtn.x(), confirmBtn.y());
|
|
||||||
QThread::msleep(500);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
QThread::msleep(500);
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(device.id, ++m_counter));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
QThread::msleep(1000);
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(device.id, ++m_counter));
|
|
||||||
Node successText = xmlScreenParser.findTextNode("Your transaction is successfully realized.");
|
|
||||||
if (!successText.isEmpty()) {
|
|
||||||
Node receiptBtn = xmlScreenParser.findButtonNode("RECEIPT", false);
|
|
||||||
if (!receiptBtn.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(device.id, receiptBtn.x(), receiptBtn.y());
|
|
||||||
QThread::msleep(500);
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(device.id, ++m_counter));
|
|
||||||
|
|
||||||
Node sendBtn = xmlScreenParser.findButtonNode("SEND E-MAIL", false);
|
|
||||||
if (!sendBtn.isEmpty()) {
|
|
||||||
AdbUtils::takeXmlDump(
|
|
||||||
device.id, "pay_by_iban_finish_transactions_" + QString::number(m_account.id)
|
|
||||||
);
|
|
||||||
// Успешная транзакция
|
|
||||||
// TODO считываем все данные по переводу
|
|
||||||
TransactionInfo transaction;
|
|
||||||
transaction.name = m_fullName;
|
|
||||||
transaction.accountId = m_account.id;
|
|
||||||
transaction.amount = -m_amount;
|
|
||||||
transaction.fee = 0;
|
|
||||||
transaction.status = TransactionStatus::Complete;
|
|
||||||
transaction.type = TransactionType::Iban;
|
|
||||||
transaction.updateTime = DateUtils::getUtcNow();
|
|
||||||
transaction.completeTime = DateUtils::getUtcNow();
|
|
||||||
transaction.timestamp = DateUtils::getUtcNow();
|
|
||||||
transaction.id = TransactionDAO::insertTransaction(transaction);
|
|
||||||
if (transaction.id == -1) {
|
|
||||||
// FIXME alert!!
|
|
||||||
qDebug() << "Transaction has not inserted...";
|
|
||||||
}
|
|
||||||
|
|
||||||
postNewTransactionData(m_account, transaction);
|
|
||||||
|
|
||||||
Node backBtn = xmlScreenParser.findButtonNode("BACK", false);
|
|
||||||
if (!backBtn.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(device.id, backBtn.x(), backBtn.y());
|
|
||||||
QThread::msleep(500);
|
|
||||||
|
|
||||||
Node returnBtn = xmlScreenParser.findButtonNode("RETURN TO HOME PAGE", false);
|
|
||||||
if (!returnBtn.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(device.id, returnBtn.x(), returnBtn.y());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
//FIXME не успешная транзакция
|
|
||||||
AdbUtils::takeXmlDump(
|
|
||||||
device.id, "pay_by_iban_fail_transactions_receipt_" + QString::number(m_account.id)
|
|
||||||
);
|
|
||||||
m_error = "Транзакция не успешна";
|
|
||||||
qDebug() << m_error;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
m_error = "Транзакция не успешна";
|
|
||||||
qDebug() << m_error;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
m_error = "Не нашли Check the details title info";
|
|
||||||
qDebug() << m_error;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
m_error = "Не нашли поля ввода для IBAN";
|
|
||||||
qDebug() << m_error;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void PayByCardTossScript::doStart() {
|
|
||||||
const DeviceInfo device = DeviceDAO::getDeviceById(m_account.deviceId);
|
|
||||||
const ApplicationInfo app = ApplicationDAO::getApplication(m_account.deviceId, m_account.appCode);
|
|
||||||
|
|
||||||
if (device.id.isEmpty() || app.id == -1) {
|
|
||||||
m_error = "Device or app not found.";
|
|
||||||
qDebug() << m_error;
|
|
||||||
emit finishedWithResult(m_error);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter));
|
|
||||||
if (!xmlScreenParser.isHomeScreen()) {
|
|
||||||
if (!runAppAndGoToHomeScreen(device.id, app.package, app.pinCode, device.screenWidth, device.screenHeight)) {
|
|
||||||
m_error = "Не смогли дойти до домашней страницы";
|
|
||||||
qDebug() << m_error;
|
|
||||||
emit finishedWithResult(m_error);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter));
|
|
||||||
Node allTransactionsNav = xmlScreenParser.findTextNode("Transactions");
|
|
||||||
if (!allTransactionsNav.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(device.id, allTransactionsNav.x(), allTransactionsNav.y());
|
|
||||||
QThread::msleep(1000);
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter));
|
|
||||||
|
|
||||||
// перешли на страницу транзакций
|
|
||||||
Node allTransactionsTitle = xmlScreenParser.findTextNode(
|
|
||||||
"Transactions", 0, 0, device.screenWidth, device.screenHeight / 2
|
|
||||||
);
|
|
||||||
Node moneyTransfersBtn = xmlScreenParser.findTextNode("Money Transfers");
|
|
||||||
if (!allTransactionsTitle.isEmpty() && !moneyTransfersBtn.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(device.id, moneyTransfersBtn.x(), moneyTransfersBtn.y());
|
|
||||||
QThread::msleep(1000);
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter));
|
|
||||||
|
|
||||||
// перешли на страницу переводов
|
|
||||||
Node moneyTransfersTitle = xmlScreenParser.findTextNode(
|
|
||||||
"Money Transfers", 0, 0, device.screenWidth, device.screenHeight / 2
|
|
||||||
);
|
|
||||||
Node transferToOtherAccountBtn = xmlScreenParser.findTextNode("Transfer to Other Account");
|
|
||||||
if (!moneyTransfersTitle.isEmpty() && !transferToOtherAccountBtn.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(device.id, transferToOtherAccountBtn.x(), transferToOtherAccountBtn.y());
|
|
||||||
QThread::msleep(1000);
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter));
|
|
||||||
|
|
||||||
Node transferToOtherAccountTitle = xmlScreenParser.findTextNode(
|
|
||||||
"Transfer to Other Account", 0, 0, device.screenWidth, device.screenHeight / 2
|
|
||||||
);
|
|
||||||
Node aNewRecipientBtn = xmlScreenParser.findTextNode("A New Recipient");
|
|
||||||
if (!transferToOtherAccountTitle.isEmpty() && !aNewRecipientBtn.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(device.id, aNewRecipientBtn.x(), aNewRecipientBtn.y());
|
|
||||||
QThread::msleep(1000);
|
|
||||||
|
|
||||||
makePayment(device);
|
|
||||||
} else {
|
|
||||||
m_error = "Не нашли кнопку 'A New Recipient'";
|
|
||||||
qDebug() << m_error;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
m_error = "Не нашли кнопку 'Transfer to Other Account'";
|
|
||||||
qDebug() << m_error;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
m_error = "Не нашли кнопку 'Money Transfers'";
|
|
||||||
qDebug() << m_error;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
m_error = "Не нашли пункт меню 'Transactions'";
|
|
||||||
qDebug() << m_error;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!m_error.isEmpty()) {
|
|
||||||
AdbUtils::takeXmlDump(device.id, "pay_by_iban_fail_transactions_" + QString::number(m_account.id));
|
|
||||||
}
|
|
||||||
|
|
||||||
emit finishedWithResult(m_error);
|
|
||||||
}
|
|
||||||
@ -1,30 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include "CommonTossScript.h"
|
|
||||||
#include "db/DeviceInfo.h"
|
|
||||||
|
|
||||||
class PayByCardTossScript final : public CommonTossScript {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
~PayByCardTossScript() override;
|
|
||||||
|
|
||||||
PayByCardTossScript(
|
|
||||||
AccountInfo account,
|
|
||||||
QString CardToss,
|
|
||||||
QString fullName,
|
|
||||||
double amount,
|
|
||||||
QObject *parent = nullptr
|
|
||||||
);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void doStart() override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
const AccountInfo m_account;
|
|
||||||
const QString m_CardToss;
|
|
||||||
const QString m_fullName;
|
|
||||||
const double m_amount;
|
|
||||||
QString m_error;
|
|
||||||
|
|
||||||
void makePayment(const DeviceInfo &device);
|
|
||||||
};
|
|
||||||
@ -1,537 +0,0 @@
|
|||||||
#include "ScreenXmlTossParser.h"
|
|
||||||
|
|
||||||
#include <QRegularExpression>
|
|
||||||
#include <QMap>
|
|
||||||
#include <QSet>
|
|
||||||
#include <QList>
|
|
||||||
#include <QXmlStreamReader>
|
|
||||||
#include <QDomDocument>
|
|
||||||
#include <QFile>
|
|
||||||
#include <QDateTime>
|
|
||||||
|
|
||||||
#include "adb/AdbUtils.h"
|
|
||||||
#include "android/xml/Node.h"
|
|
||||||
#include "db/AccountInfo.h"
|
|
||||||
#include "db/TransactionInfo.h"
|
|
||||||
#include "time/DateUtils.h"
|
|
||||||
|
|
||||||
ScreenXmlTossParser::ScreenXmlTossParser(QObject *parent) : QObject(parent) {
|
|
||||||
}
|
|
||||||
|
|
||||||
ScreenXmlTossParser::~ScreenXmlTossParser() = default;
|
|
||||||
|
|
||||||
static const QRegularExpression boundsRegex(R"(\[([0-9]+),([0-9]+)\]\[([0-9]+),([0-9]+)\])");
|
|
||||||
|
|
||||||
Node ScreenXmlTossParser::findTextNode(const QString &text) {
|
|
||||||
for (const Node &node: m_nodes) {
|
|
||||||
if (node.className == "android.widget.TextView" && node.text.trimmed() == text) {
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
Node ScreenXmlTossParser::findTextContainsNode(const QString &text) {
|
|
||||||
for (const Node &node: m_nodes) {
|
|
||||||
if (node.className == "android.widget.TextView" && node.text.contains(text)) {
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
Node ScreenXmlTossParser::findTextNode(const QString &text, const int x1, const int y1, const int x2, const int y2) {
|
|
||||||
for (const Node &node: m_nodes) {
|
|
||||||
if (node.className == "android.widget.TextView" && node.text.trimmed() == text
|
|
||||||
&& node.x() >= x1 && node.x() <= x2 && node.y() >= y1 && node.y() <= y2) {
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
Node ScreenXmlTossParser::findEditText(const QString &text) {
|
|
||||||
for (const Node &node: m_nodes) {
|
|
||||||
if (node.className == "android.widget.EditText" && node.text == text) {
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
Node ScreenXmlTossParser::findEditTextByResourceId(const QString &resourceId) {
|
|
||||||
for (const Node &node: m_nodes) {
|
|
||||||
if (node.className == "android.widget.EditText" && node.resourceId == resourceId) {
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
QList<Node> ScreenXmlTossParser::getNodeNumbers(double value) {
|
|
||||||
// Формат 'f' с precision = 0 — дробная часть отбрасывается
|
|
||||||
QString str = QString::number(value, 'f', 0);
|
|
||||||
// Разбиваем на отдельные символы
|
|
||||||
QList<Node> nodes;
|
|
||||||
for (QChar ch: str) {
|
|
||||||
QString num = QString(ch);
|
|
||||||
for (const Node &node: m_nodes) {
|
|
||||||
if (node.contentDesc == num && node.className == "android.widget.Button") {
|
|
||||||
nodes.append(node);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nodes;
|
|
||||||
}
|
|
||||||
|
|
||||||
Node ScreenXmlTossParser::findNodeByClassName(const QString &className) {
|
|
||||||
for (const Node &node: m_nodes) {
|
|
||||||
if (node.className == className) {
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
Node ScreenXmlTossParser::findButtonNode(const QString &text, const bool contains) {
|
|
||||||
for (const Node &node: m_nodes) {
|
|
||||||
if (contains) {
|
|
||||||
if (node.className == "android.widget.Button" && node.text.contains(text)) {
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (node.className == "android.widget.Button" && node.text.trimmed() == text) {
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ScreenXmlTossParser::isHomeScreen() {
|
|
||||||
Node activitiesBtn;
|
|
||||||
for (const Node &node: m_nodes) {
|
|
||||||
if (node.text.contains("Transfer") && node.resourceId == "viva.republica.toss:id/rightButton") {
|
|
||||||
activitiesBtn = node;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return !activitiesBtn.isEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<Node> ScreenXmlTossParser::findPinCodeNodes(const QString &pinCode) {
|
|
||||||
QMap<QString, Node> buttons;
|
|
||||||
const QSet<QString> numberSet = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"};
|
|
||||||
|
|
||||||
for (const Node &node: m_nodes) {
|
|
||||||
const QString &text = node.text.trimmed();
|
|
||||||
if (node.className == "android.widget.Button" && numberSet.contains(text)) {
|
|
||||||
buttons[text] = node;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<Node> nodes;
|
|
||||||
for (int i = 0; i < pinCode.length(); ++i) {
|
|
||||||
nodes.append(buttons[QString(pinCode.at(i))]);
|
|
||||||
}
|
|
||||||
return nodes;
|
|
||||||
}
|
|
||||||
|
|
||||||
Node convertTossDomElementToNode(const QDomElement &element) {
|
|
||||||
auto node = Node();
|
|
||||||
if (element.hasAttribute("bounds")) {
|
|
||||||
const QString bounds = element.attribute("bounds");
|
|
||||||
if (const QRegularExpressionMatch match = boundsRegex.match(bounds); match.hasMatch()) {
|
|
||||||
node.setBounds(
|
|
||||||
match.captured(1).toInt(),
|
|
||||||
match.captured(2).toInt(),
|
|
||||||
match.captured(3).toInt(),
|
|
||||||
match.captured(4).toInt()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (element.hasAttribute("text")) {
|
|
||||||
node.text = element.attribute("text");
|
|
||||||
}
|
|
||||||
if (element.hasAttribute("content-desc")) {
|
|
||||||
node.contentDesc = element.attribute("content-desc");
|
|
||||||
}
|
|
||||||
if (element.hasAttribute("class")) {
|
|
||||||
node.className = element.attribute("class");
|
|
||||||
}
|
|
||||||
if (element.hasAttribute("clickable")) {
|
|
||||||
node.clickable = element.attribute("clickable") == "true";
|
|
||||||
}
|
|
||||||
if (element.hasAttribute("focusable")) {
|
|
||||||
node.focusable = element.attribute("focusable") == "true";
|
|
||||||
}
|
|
||||||
if (element.hasAttribute("resource-id")) {
|
|
||||||
node.resourceId = element.attribute("resource-id");
|
|
||||||
}
|
|
||||||
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ScreenXmlTossParser::parseAndSaveXml(const QString &xml) {
|
|
||||||
QDomDocument doc;
|
|
||||||
doc.setContent(xml);
|
|
||||||
m_xml = doc.documentElement();
|
|
||||||
m_nodes.clear();
|
|
||||||
|
|
||||||
QXmlStreamReader reader(xml);
|
|
||||||
while (!reader.atEnd()) {
|
|
||||||
reader.readNext();
|
|
||||||
if (reader.isStartElement() && reader.name() == "node") {
|
|
||||||
Node node = Node();
|
|
||||||
if (reader.attributes().hasAttribute("bounds")) {
|
|
||||||
QString bounds = reader.attributes().value("bounds").toString();
|
|
||||||
if (QRegularExpressionMatch match = boundsRegex.match(bounds); match.hasMatch()) {
|
|
||||||
node.setBounds(
|
|
||||||
match.captured(1).toInt(),
|
|
||||||
match.captured(2).toInt(),
|
|
||||||
match.captured(3).toInt(),
|
|
||||||
match.captured(4).toInt()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (reader.attributes().hasAttribute("text")) {
|
|
||||||
node.text = reader.attributes().value("text").toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (reader.attributes().hasAttribute("content-desc")) {
|
|
||||||
node.contentDesc = reader.attributes().value("content-desc").toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (reader.attributes().hasAttribute("class")) {
|
|
||||||
node.className = reader.attributes().value("class").toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (reader.attributes().hasAttribute("clickable")) {
|
|
||||||
node.clickable = reader.attributes().value("clickable").toString() == "true";
|
|
||||||
}
|
|
||||||
if (reader.attributes().hasAttribute("focusable")) {
|
|
||||||
node.focusable = reader.attributes().value("focusable").toString() == "true";
|
|
||||||
}
|
|
||||||
if (reader.attributes().hasAttribute("resource-id")) {
|
|
||||||
node.resourceId = reader.attributes().value("resource-id").toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
m_nodes.append(node);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QDomElement findSubElementToss(const QDomElement &elem, const QString &index) {
|
|
||||||
if (elem.hasChildNodes()) {
|
|
||||||
QDomNodeList subInfoList = elem.childNodes();
|
|
||||||
for (QDomNode subInfoNode: subInfoList) {
|
|
||||||
if (!subInfoNode.isElement()) continue;
|
|
||||||
QDomElement subInfo = subInfoNode.toElement();
|
|
||||||
if (subInfo.attribute("index") == index) {
|
|
||||||
return subInfo;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
QString findSubInfoToss(const QDomElement &elem, const QString &index) {
|
|
||||||
QDomElement subInfo = findSubElementToss(elem, index);
|
|
||||||
if (!subInfo.isNull()) {
|
|
||||||
return subInfo.attribute("text");
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
QDomNode findNodeToss(const QDomNode &node, const QString &text) {
|
|
||||||
if (node.isElement()) {
|
|
||||||
QString nodeText = node.toElement().attribute("text");
|
|
||||||
if (nodeText.toLower().startsWith(text)) {
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QDomNode child = node.firstChild();
|
|
||||||
while (!child.isNull()) {
|
|
||||||
QDomNode result = findNodeToss(child, text);
|
|
||||||
if (!result.isNull()) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
child = child.nextSibling();
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<QDomElement> findElementsWithPaymentsToss(const QDomElement &parent, const QString &attribute,
|
|
||||||
const QString &value) {
|
|
||||||
QList<QDomElement> result;
|
|
||||||
|
|
||||||
QDomElement element = parent.firstChildElement();
|
|
||||||
while (!element.isNull()) {
|
|
||||||
// Проверка самого element
|
|
||||||
// if (element.hasAttribute(attribute) && element.attribute(attribute) == value) {
|
|
||||||
// result.append(element);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// Проверка его дочерних элементов
|
|
||||||
QDomElement child = element.firstChildElement();
|
|
||||||
while (!child.isNull()) {
|
|
||||||
if (child.hasAttribute(attribute) && child.attribute(attribute) == value) {
|
|
||||||
result.append(child);
|
|
||||||
}
|
|
||||||
child = child.nextSiblingElement();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Рекурсивный обход
|
|
||||||
result.append(findElementsWithPaymentsToss(element, attribute, value));
|
|
||||||
|
|
||||||
element = element.nextSiblingElement();
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
QDomElement findElementWithPaymentsToss(const QDomElement &parent, const QString &attribute, const QString &value) {
|
|
||||||
QDomElement element = parent.firstChildElement();
|
|
||||||
while (!element.isNull()) {
|
|
||||||
QDomElement child = element.firstChildElement();
|
|
||||||
while (!child.isNull()) {
|
|
||||||
if (child.hasAttribute(attribute) && child.attribute(attribute) == value) {
|
|
||||||
return child;
|
|
||||||
}
|
|
||||||
child = child.nextSiblingElement();
|
|
||||||
}
|
|
||||||
|
|
||||||
QDomElement found = findElementWithPaymentsToss(element, attribute, value);
|
|
||||||
if (!found.isNull()) {
|
|
||||||
return found;
|
|
||||||
}
|
|
||||||
element = element.nextSiblingElement();
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
QDateTime getUtcFromSeoulDate(const QString &date, const QString &time) {
|
|
||||||
int year = QDate::currentDate().year(); // или укажи вручную нужный год
|
|
||||||
QString withYear = QString("%1년 %2 %3").arg(year).arg(date).arg(time); // "2025년 7월 28일 17:54"
|
|
||||||
|
|
||||||
QLocale korean(QLocale::Korean, QLocale::SouthKorea);
|
|
||||||
QString format = "yyyy년 M월 d일 H:mm";
|
|
||||||
|
|
||||||
QDateTime dt = korean.toDateTime(withYear, format);
|
|
||||||
if (dt.isValid()) {
|
|
||||||
dt.setTimeZone(QTimeZone("Asia/Seoul"));
|
|
||||||
return dt.toTimeZone(QTimeZone::utc());
|
|
||||||
} else {
|
|
||||||
qWarning() << "Ошибка разбора даты:" << withYear;
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Node ScreenXmlTossParser::findFirstAccountLine() {
|
|
||||||
Node node;
|
|
||||||
auto elements = findElementsWithPaymentsToss(m_xml, "text", "Transfer");
|
|
||||||
if (elements.length() == 2) {
|
|
||||||
for (QDomElement &element: elements) {
|
|
||||||
qDebug() << "Found account: " << element.attribute("content-desc");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!elements.isEmpty()) {
|
|
||||||
node = convertTossDomElementToNode(elements[0].parentNode().toElement());
|
|
||||||
}
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
QList<TransactionInfo> ScreenXmlTossParser::parsePositiveTransactions() {
|
|
||||||
QList<TransactionInfo> transactions;
|
|
||||||
|
|
||||||
QDomElement child = findElementWithPaymentsToss(m_xml, "class", "android.widget.ListView");
|
|
||||||
QDomNodeList listView = child.childNodes();
|
|
||||||
qDebug() << listView.count();
|
|
||||||
if (!listView.isEmpty()) {
|
|
||||||
QString date = "";
|
|
||||||
|
|
||||||
for (QDomNode node: listView) {
|
|
||||||
QString title = node.toElement().attribute("text");
|
|
||||||
if (title == "전체" || title.startsWith("AD") || title.endsWith("AD")) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!title.isEmpty()) {
|
|
||||||
date = node.toElement().attribute("text");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (date.isEmpty()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const QDomNodeList trBoxGroup = node.childNodes();
|
|
||||||
if (trBoxGroup.count() > 0) {
|
|
||||||
TransactionInfo transaction;
|
|
||||||
for (QDomNode item: trBoxGroup) {
|
|
||||||
QDomElement groupItem = item.toElement();
|
|
||||||
QString line = groupItem.attribute("text");
|
|
||||||
if (line.contains("잔액") && line.contains("입금")) {
|
|
||||||
QString beforeBalance = line.split("잔액").first().trimmed();
|
|
||||||
|
|
||||||
QString time = beforeBalance.split("입금").first().trimmed().last(5);
|
|
||||||
QString desc = beforeBalance.split("입금").first().replace(time, "").trimmed();
|
|
||||||
QString amount = beforeBalance.split("입금").last().replace("원", "").replace(",", "").trimmed();
|
|
||||||
|
|
||||||
transaction.amount = amount.toDouble();
|
|
||||||
transaction.description = desc;
|
|
||||||
transaction.bankTime = date + " " + time;
|
|
||||||
transaction.completeTime = getUtcFromSeoulDate(date, time);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (transaction.amount > 0) {
|
|
||||||
transactions.append(transaction);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
qDebug() << "ListView is empty";
|
|
||||||
}
|
|
||||||
return transactions;
|
|
||||||
}
|
|
||||||
|
|
||||||
float extractKoreanWonFromText(const QString &input) {
|
|
||||||
QRegularExpression re(R"(₩([\d,]+))");
|
|
||||||
QRegularExpressionMatch match = re.match(input);
|
|
||||||
if (!match.hasMatch()) {
|
|
||||||
qWarning() << "Не удалось найти сумму в строке:" << input;
|
|
||||||
return 0.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString numberStr = match.captured(1);
|
|
||||||
numberStr.remove(','); // удаляем запятые
|
|
||||||
|
|
||||||
return numberStr.toFloat();
|
|
||||||
}
|
|
||||||
|
|
||||||
double parseKoreanNumber(const QString &input) {
|
|
||||||
// Карта корейских единиц в числовые множители
|
|
||||||
static const QMap<QString, double> unitMap = {
|
|
||||||
{QStringLiteral("조"), 1e12},
|
|
||||||
{QStringLiteral("억"), 1e8},
|
|
||||||
{QStringLiteral("만"), 1e4}
|
|
||||||
};
|
|
||||||
// Статические регулярки (Clazy: don't create temporaries)
|
|
||||||
static const QRegularExpression cleanRe(QStringLiteral("[^0-9.,만억조]"));
|
|
||||||
static const QRegularExpression segmentRe(QStringLiteral(R"(([\d,]+(?:\.\d+)?)(조|억|만))"));
|
|
||||||
|
|
||||||
QString s = input;
|
|
||||||
s.remove(cleanRe);
|
|
||||||
|
|
||||||
double total = 0.0;
|
|
||||||
auto it = segmentRe.globalMatch(s);
|
|
||||||
qsizetype pos = 0;
|
|
||||||
|
|
||||||
while (it.hasNext()) {
|
|
||||||
auto match = it.next();
|
|
||||||
QString numStr = match.captured(1);
|
|
||||||
QString unitStr = match.captured(2);
|
|
||||||
|
|
||||||
numStr.remove(',');
|
|
||||||
bool ok = false;
|
|
||||||
const double num = numStr.toDouble(&ok);
|
|
||||||
if (ok)
|
|
||||||
total += num * unitMap.value(unitStr);
|
|
||||||
|
|
||||||
pos = match.capturedEnd();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Обработка остатка (обычное число, возможно с дробной частью)
|
|
||||||
QString rem = s.mid(static_cast<int>(pos));
|
|
||||||
rem.remove(',');
|
|
||||||
if (!rem.isEmpty()) {
|
|
||||||
bool ok = false;
|
|
||||||
const double num = rem.toDouble(&ok);
|
|
||||||
if (ok) total += num;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return total;
|
|
||||||
}
|
|
||||||
|
|
||||||
double ScreenXmlTossParser::parseAccountAmount() {
|
|
||||||
const QDomNodeList nodes = m_xml.elementsByTagName("node");
|
|
||||||
|
|
||||||
for (int i = 0; i < nodes.count(); ++i) {
|
|
||||||
const QDomElement el = nodes.at(i).toElement();
|
|
||||||
|
|
||||||
// Аккаунтов может быть несколько, вот берем первый по списку
|
|
||||||
if (el.attribute("text") == "Top up" && el.attribute("class") == "android.widget.Button") {
|
|
||||||
for (QDomNode node: el.parentNode().childNodes()) {
|
|
||||||
const QDomElement child = node.toElement();
|
|
||||||
if (child.attribute("text").contains("만") || child.attribute("text").contains("원")) {
|
|
||||||
return parseKoreanNumber(child.attribute("text"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<AccountInfo> ScreenXmlTossParser::parseAccountsInfo() {
|
|
||||||
const QDomNodeList nodes = m_xml.elementsByTagName("node");
|
|
||||||
QList<AccountInfo> accounts;
|
|
||||||
|
|
||||||
for (int i = 0; i < nodes.count(); ++i) {
|
|
||||||
const QDomElement el = nodes.at(i).toElement();
|
|
||||||
|
|
||||||
|
|
||||||
// Аккаунтов может быть несколько, вот берем первый по списку
|
|
||||||
if (el.attribute("text") == "Transfer") {
|
|
||||||
for (QDomNode node: el.parentNode().parentNode().parentNode().childNodes()) {
|
|
||||||
const QDomElement child = node.toElement();
|
|
||||||
if (child.attribute("content-desc").contains("₩")) {
|
|
||||||
AccountInfo info;
|
|
||||||
info.amount = extractKoreanWonFromText(child.attribute("content-desc"));
|
|
||||||
info.updateTime = DateUtils::getUtcNow();
|
|
||||||
accounts.append(info);
|
|
||||||
return accounts;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// if (el.attribute("content-desc").contains("토스뱅크 통장") && el.attribute("content-desc").contains("₩")) {
|
|
||||||
// AccountInfo info;
|
|
||||||
// info.amount = extractKoreanWonFromText(el.attribute("content-desc"));
|
|
||||||
// info.updateTime = DateUtils::getUtcNow();
|
|
||||||
// accounts.append(info);
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
return accounts;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ScreenXmlTossParser::test() {
|
|
||||||
// TransactionInfo info2 = parseExpandedInfo(m_xml);
|
|
||||||
// qDebug().noquote().nospace() << convertTransactionToString(info2);
|
|
||||||
// return;
|
|
||||||
|
|
||||||
QFile file("assets/rshb/all_products.xml");
|
|
||||||
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
|
||||||
qDebug() << "Cannot open file";
|
|
||||||
}
|
|
||||||
|
|
||||||
QDomDocument doc;
|
|
||||||
if (!doc.setContent(&file)) {
|
|
||||||
qDebug() << "Failed to parse XML";
|
|
||||||
}
|
|
||||||
file.close();
|
|
||||||
|
|
||||||
qDebug() << "Start parsing XML:";
|
|
||||||
|
|
||||||
// Номер карты с последними цифрами
|
|
||||||
QDomElement root = doc.documentElement();
|
|
||||||
parseAndSaveXml(doc.toString());
|
|
||||||
// for (const AccountInfo &info: parseAccountsInfo()) {
|
|
||||||
// qDebug().noquote().nospace() << convertAccountToString(info);
|
|
||||||
// }
|
|
||||||
// TransactionInfo info = parseExpandedInfo(root);
|
|
||||||
// qDebug().noquote().nospace() << convertTransactionToString(info);
|
|
||||||
// ЕСПП
|
|
||||||
}
|
|
||||||
@ -1,52 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <QObject>
|
|
||||||
#include <QDomElement>
|
|
||||||
#include "android/xml/Node.h"
|
|
||||||
#include "db/AccountInfo.h"
|
|
||||||
#include "db/TransactionInfo.h"
|
|
||||||
|
|
||||||
class ScreenXmlTossParser final : public QObject {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit ScreenXmlTossParser(QObject *parent = nullptr);
|
|
||||||
|
|
||||||
~ScreenXmlTossParser() override;
|
|
||||||
|
|
||||||
Node findTextNode(const QString &text);
|
|
||||||
|
|
||||||
Node findTextContainsNode(const QString &text);
|
|
||||||
|
|
||||||
Node findFirstAccountLine();
|
|
||||||
|
|
||||||
Node findTextNode(const QString &text, int x1, int y1, int x2, int y2);
|
|
||||||
|
|
||||||
Node findEditText(const QString &text);
|
|
||||||
|
|
||||||
Node findEditTextByResourceId(const QString &resourceId);
|
|
||||||
|
|
||||||
Node findNodeByClassName(const QString &className);
|
|
||||||
|
|
||||||
Node findButtonNode(const QString &text, bool contains);
|
|
||||||
|
|
||||||
bool isHomeScreen();
|
|
||||||
|
|
||||||
void parseAndSaveXml(const QString &xml);
|
|
||||||
|
|
||||||
QList<TransactionInfo> parsePositiveTransactions();
|
|
||||||
|
|
||||||
QList<AccountInfo> parseAccountsInfo();
|
|
||||||
|
|
||||||
double parseAccountAmount();
|
|
||||||
|
|
||||||
QList<Node> findPinCodeNodes(const QString &pinCode);
|
|
||||||
|
|
||||||
QList<Node> getNodeNumbers(double value);
|
|
||||||
|
|
||||||
void test();
|
|
||||||
|
|
||||||
private:
|
|
||||||
QList<Node> m_nodes;
|
|
||||||
QDomElement m_xml;
|
|
||||||
};
|
|
||||||
@ -1,223 +0,0 @@
|
|||||||
#include "CommonZiraatScript.h"
|
|
||||||
|
|
||||||
#include <QJsonArray>
|
|
||||||
#include <QJsonObject>
|
|
||||||
#include <QRandomGenerator>
|
|
||||||
#include <QThread>
|
|
||||||
|
|
||||||
#include "adb/AdbUtils.h"
|
|
||||||
#include "net/NetworkService.h"
|
|
||||||
|
|
||||||
CommonZiraatScript::CommonZiraatScript(QObject *parent)
|
|
||||||
: QObject(parent) {
|
|
||||||
}
|
|
||||||
|
|
||||||
CommonZiraatScript::~CommonZiraatScript() = default;
|
|
||||||
|
|
||||||
void CommonZiraatScript::start() {
|
|
||||||
doStart();
|
|
||||||
emit finished();
|
|
||||||
}
|
|
||||||
|
|
||||||
Node CommonZiraatScript::swipeToButton(
|
|
||||||
const QString &deviceId,
|
|
||||||
const QString &text, int &counter, const int width, const int height
|
|
||||||
) {
|
|
||||||
for (int i = 0; i < 10; ++i) {
|
|
||||||
if (Node button = xmlScreenParser.findButtonNode(text, true); button.x() > 0 && button.y() > 0) {
|
|
||||||
return button;
|
|
||||||
}
|
|
||||||
const int x = width / 2;
|
|
||||||
const int offset = height / 4;
|
|
||||||
AdbUtils::makeSwipe(deviceId, x, height - offset, x, offset);
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++counter));
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CommonZiraatScript::runAppAndGoToHomeScreen(
|
|
||||||
const QString &deviceId,
|
|
||||||
const QString &packageName,
|
|
||||||
const QString &pinCode,
|
|
||||||
const int width,
|
|
||||||
const int height
|
|
||||||
) {
|
|
||||||
// Запустить устройство
|
|
||||||
if (const QString pid = AdbUtils::tryToGetRunningAppPid(deviceId, packageName); !pid.isEmpty()) {
|
|
||||||
qDebug() << "Process already running, pid: " << pid;
|
|
||||||
AdbUtils::getScreenDumpAsXml(deviceId, 1000);
|
|
||||||
AdbUtils::tryToKillApplication(deviceId, packageName);
|
|
||||||
}
|
|
||||||
if (!AdbUtils::tryToStartApplication(deviceId, packageName)) {
|
|
||||||
AdbUtils::takeScreenshot(deviceId, "run_app_error");
|
|
||||||
qWarning() << "Process has not started";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Даем минимальное время на запуск
|
|
||||||
QThread::msleep(4500);
|
|
||||||
int counter = 0;
|
|
||||||
bool findAndInputPassword = false;
|
|
||||||
|
|
||||||
while (true) {
|
|
||||||
counter++;
|
|
||||||
|
|
||||||
// Если более 10 раз мы пытаемся перейти на домашнюю
|
|
||||||
if (counter > 10) {
|
|
||||||
AdbUtils::takeScreenshot(deviceId, "too_many_attempts");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
|
|
||||||
|
|
||||||
Node closeBannerNode = xmlScreenParser.findButtonNode("HAYIR", false);
|
|
||||||
if (!closeBannerNode.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(deviceId, closeBannerNode.x(), closeBannerNode.y());
|
|
||||||
QThread::msleep(1000);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (xmlScreenParser.isHomeScreen()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Проверяем, что это экран ввода пин-кода
|
|
||||||
if (!findAndInputPassword) {
|
|
||||||
Node loginNode = xmlScreenParser.findButtonNode("Login", false);
|
|
||||||
if (!loginNode.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(deviceId, loginNode.x(), loginNode.y());
|
|
||||||
QThread::msleep(500);
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
|
|
||||||
|
|
||||||
Node passwordEditText = xmlScreenParser.findEditText("Password");
|
|
||||||
if (!passwordEditText.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(deviceId, passwordEditText.x(), passwordEditText.y());
|
|
||||||
QThread::msleep(500);
|
|
||||||
AdbUtils::inputText(deviceId, pinCode);
|
|
||||||
|
|
||||||
findAndInputPassword = true;
|
|
||||||
QThread::msleep(3000);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QThread::msleep(1000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CommonZiraatScript::goToAllProducts(
|
|
||||||
const QString &deviceId,
|
|
||||||
const int width,
|
|
||||||
const int height
|
|
||||||
) {
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, m_counter));
|
|
||||||
Node closeBannerNode = xmlScreenParser.findButtonNode("HAYIR", false);
|
|
||||||
if (!closeBannerNode.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(deviceId, closeBannerNode.x(), closeBannerNode.y());
|
|
||||||
QThread::msleep(500);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (xmlScreenParser.isHomeScreen()) {
|
|
||||||
Node allMyAccountBtn = xmlScreenParser.findButtonNode("All My Accounts", false);
|
|
||||||
if (!allMyAccountBtn.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(deviceId, allMyAccountBtn.x(), allMyAccountBtn.y());
|
|
||||||
QThread::msleep(500);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CommonZiraatScript::postAccountsData(const QList<AccountInfo> &accounts) {
|
|
||||||
if (accounts.isEmpty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto *thread = new QThread;
|
|
||||||
auto *worker = new NetworkService;
|
|
||||||
|
|
||||||
QJsonArray list;
|
|
||||||
for (const AccountInfo &account: accounts) {
|
|
||||||
QJsonObject obj;
|
|
||||||
obj["appName"] = account.appCode;
|
|
||||||
obj["lastNumbers"] = account.lastNumbers;
|
|
||||||
obj["amount"] = account.amount;
|
|
||||||
obj["currency"] = account.currency;
|
|
||||||
obj["description"] = account.description;
|
|
||||||
obj["status"] = accountStatusToString(account.status);
|
|
||||||
|
|
||||||
list.append(obj);
|
|
||||||
}
|
|
||||||
// FIXME доставить десктоп ид из настроеек
|
|
||||||
worker->setDeviceId(accounts.first().deviceId);
|
|
||||||
worker->setPayload(QJsonDocument(list).toJson());
|
|
||||||
worker->moveToThread(thread);
|
|
||||||
connect(thread, &QThread::started, worker, &NetworkService::postAccountsData);
|
|
||||||
connect(worker, &NetworkService::finished, thread, &QThread::quit);
|
|
||||||
connect(worker, &NetworkService::finished, worker, &QObject::deleteLater);
|
|
||||||
connect(thread, &QThread::finished, thread, &QThread::deleteLater);
|
|
||||||
thread->start();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CommonZiraatScript::postNewTransactionData(const AccountInfo &account, const TransactionInfo &transaction) {
|
|
||||||
auto *thread = new QThread;
|
|
||||||
auto *worker = new NetworkService;
|
|
||||||
|
|
||||||
QJsonObject obj;
|
|
||||||
obj["id"] = transaction.id;
|
|
||||||
obj["amount"] = transaction.amount;
|
|
||||||
obj["name"] = transaction.name;
|
|
||||||
obj["fee"] = transaction.fee;
|
|
||||||
obj["status"] = transactionStatusToString(transaction.status);
|
|
||||||
obj["type"] = transactionTypeToString(transaction.type);
|
|
||||||
obj["phone"] = transaction.phone;
|
|
||||||
obj["description"] = transaction.description;
|
|
||||||
obj["updatedDescription"] = transaction.updatedDescription;
|
|
||||||
obj["bankName"] = transaction.bankName;
|
|
||||||
obj["bankTime"] = transaction.bankTime;
|
|
||||||
obj["bankTransactionId"] = transaction.bankTrExternalId;
|
|
||||||
|
|
||||||
// FIXME доставить десктоп ид из настроеек
|
|
||||||
worker->setDeviceId(account.deviceId);
|
|
||||||
worker->addExtra("lastNumbers", account.lastNumbers);
|
|
||||||
worker->addExtra("transactionId", transaction.id);
|
|
||||||
worker->setPayload(QJsonDocument(obj).toJson());
|
|
||||||
worker->moveToThread(thread);
|
|
||||||
connect(thread, &QThread::started, worker, &NetworkService::insertTransactionData);
|
|
||||||
connect(worker, &NetworkService::finished, thread, &QThread::quit);
|
|
||||||
connect(worker, &NetworkService::finished, worker, &QObject::deleteLater);
|
|
||||||
connect(thread, &QThread::finished, thread, &QThread::deleteLater);
|
|
||||||
thread->start();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CommonZiraatScript::updateTransactionData(
|
|
||||||
const AccountInfo &account,
|
|
||||||
const int transactionId,
|
|
||||||
const TransactionStatus status,
|
|
||||||
const QString &oldDesc,
|
|
||||||
const QString &newDesc
|
|
||||||
) {
|
|
||||||
auto *thread = new QThread;
|
|
||||||
auto *worker = new NetworkService;
|
|
||||||
|
|
||||||
QJsonObject obj;
|
|
||||||
obj["id"] = transactionId;
|
|
||||||
obj["status"] = transactionStatusToString(status);
|
|
||||||
obj["description"] = newDesc;
|
|
||||||
obj["updatedDescription"] = oldDesc;
|
|
||||||
|
|
||||||
// FIXME доставить десктоп ид из настроеек
|
|
||||||
worker->setDeviceId(account.deviceId);
|
|
||||||
worker->addExtra("lastNumbers", account.lastNumbers);
|
|
||||||
worker->setPayload(QJsonDocument(obj).toJson());
|
|
||||||
worker->moveToThread(thread);
|
|
||||||
connect(thread, &QThread::started, worker, &NetworkService::updateTransactionData);
|
|
||||||
connect(worker, &NetworkService::finished, thread, &QThread::quit);
|
|
||||||
connect(worker, &NetworkService::finished, worker, &QObject::deleteLater);
|
|
||||||
connect(thread, &QThread::finished, thread, &QThread::deleteLater);
|
|
||||||
thread->start();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CommonZiraatScript::stop() {
|
|
||||||
m_running = false;
|
|
||||||
}
|
|
||||||
@ -1,65 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <QObject>
|
|
||||||
#include "ScreenXmlZiraatParser.h"
|
|
||||||
|
|
||||||
class CommonZiraatScript : public QObject {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit CommonZiraatScript(QObject *parent = nullptr);
|
|
||||||
|
|
||||||
~CommonZiraatScript() override;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual void doStart() = 0;
|
|
||||||
|
|
||||||
bool goToAllProducts(
|
|
||||||
const QString &deviceId,
|
|
||||||
int width,
|
|
||||||
int height
|
|
||||||
);
|
|
||||||
|
|
||||||
void postAccountsData(const QList<AccountInfo> &accounts);
|
|
||||||
|
|
||||||
void postNewTransactionData(const AccountInfo &account, const TransactionInfo &transaction);
|
|
||||||
|
|
||||||
void updateTransactionData(
|
|
||||||
const AccountInfo &account,
|
|
||||||
int transactionId,
|
|
||||||
TransactionStatus status,
|
|
||||||
const QString &oldDesc,
|
|
||||||
const QString &newDesc
|
|
||||||
);
|
|
||||||
|
|
||||||
Node swipeToButton(
|
|
||||||
const QString &deviceId,
|
|
||||||
const QString &text,
|
|
||||||
int &counter, int width, int height
|
|
||||||
);
|
|
||||||
|
|
||||||
bool runAppAndGoToHomeScreen(
|
|
||||||
const QString &deviceId,
|
|
||||||
const QString &packageName,
|
|
||||||
const QString &pinCode,
|
|
||||||
int width,
|
|
||||||
int height
|
|
||||||
);
|
|
||||||
|
|
||||||
bool m_running = true;
|
|
||||||
ScreenXmlZiraatParser xmlScreenParser;
|
|
||||||
int m_counter = 0;
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void finished();
|
|
||||||
|
|
||||||
void finishedWithResult(const QString &result);
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
virtual void start() final;
|
|
||||||
|
|
||||||
virtual void stop() final;
|
|
||||||
|
|
||||||
private:
|
|
||||||
Q_DISABLE_COPY(CommonZiraatScript);
|
|
||||||
};
|
|
||||||
@ -1,160 +0,0 @@
|
|||||||
#include "GetLastDaysHistoryZiraatScript.h"
|
|
||||||
|
|
||||||
#include <QJsonObject>
|
|
||||||
#include <QRandomGenerator>
|
|
||||||
#include <QThread>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
#include "DatabaseManager.h"
|
|
||||||
#include "adb/AdbUtils.h"
|
|
||||||
#include "dao/AccountDAO.h"
|
|
||||||
#include "dao/ApplicationDAO.h"
|
|
||||||
#include "dao/DeviceDAO.h"
|
|
||||||
#include "dao/TransactionDAO.h"
|
|
||||||
#include "db/DeviceInfo.h"
|
|
||||||
#include "net/NetworkService.h"
|
|
||||||
#include "time/DateUtils.h"
|
|
||||||
|
|
||||||
GetLastDaysHistoryZiraatScript::GetLastDaysHistoryZiraatScript(
|
|
||||||
AccountInfo account,
|
|
||||||
QObject *parent
|
|
||||||
) : CommonZiraatScript(parent),
|
|
||||||
m_account(std::move(account)) {
|
|
||||||
}
|
|
||||||
|
|
||||||
GetLastDaysHistoryZiraatScript::~GetLastDaysHistoryZiraatScript() = default;
|
|
||||||
|
|
||||||
bool GetLastDaysHistoryZiraatScript::saveAndPostNewTransactionData(
|
|
||||||
const AccountInfo &account,
|
|
||||||
const TransactionInfo &transaction,
|
|
||||||
const TransactionStatus &status
|
|
||||||
) {
|
|
||||||
TransactionInfo tr;
|
|
||||||
tr.accountId = account.id;
|
|
||||||
tr.description = transaction.description;
|
|
||||||
tr.bankTime = transaction.bankTime;
|
|
||||||
tr.bankName = transaction.bankName;
|
|
||||||
tr.amount = transaction.amount;
|
|
||||||
tr.phone = transaction.phone;
|
|
||||||
tr.updateTime = DateUtils::getUtcNow();
|
|
||||||
tr.fee = transaction.fee;
|
|
||||||
tr.name = transaction.name;
|
|
||||||
tr.bankTrExternalId = transaction.bankTrExternalId;
|
|
||||||
tr.status = status;
|
|
||||||
tr.type = transaction.description.startsWith("Перевод") ? TransactionType::Phone : TransactionType::Card;
|
|
||||||
tr.completeTime = DateUtils::getUtcNow();
|
|
||||||
tr.id = TransactionDAO::insertTransaction(tr);
|
|
||||||
|
|
||||||
if (tr.id == -1) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
postNewTransactionData(account, tr);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GetLastDaysHistoryZiraatScript::updateAndPostTransactionData(
|
|
||||||
const AccountInfo &account,
|
|
||||||
const int transactionId,
|
|
||||||
const TransactionStatus status,
|
|
||||||
const QString &oldDesc,
|
|
||||||
const QString &newDesc
|
|
||||||
) {
|
|
||||||
if (TransactionDAO::updateTransaction(transactionId, status, oldDesc, newDesc)) {
|
|
||||||
updateTransactionData(account, transactionId, status, oldDesc, newDesc);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GetLastDaysHistoryZiraatScript::doStart() {
|
|
||||||
// берем все транзакции из БД
|
|
||||||
const DeviceInfo device = DeviceDAO::getDeviceById(m_account.deviceId);
|
|
||||||
const ApplicationInfo app = ApplicationDAO::getApplication(m_account.deviceId, m_account.appCode);
|
|
||||||
|
|
||||||
if (!xmlScreenParser.isHomeScreen()) {
|
|
||||||
if (!runAppAndGoToHomeScreen(device.id, app.package, app.pinCode, device.screenWidth, device.screenHeight)) {
|
|
||||||
m_error = "Не смогли дойти до домашней страницы";
|
|
||||||
qCritical() << m_error;
|
|
||||||
emit finishedWithResult(m_error);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter));
|
|
||||||
|
|
||||||
Node closeBannerNode = xmlScreenParser.findButtonNode("HAYIR", false);
|
|
||||||
if (!closeBannerNode.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(device.id, closeBannerNode.x(), closeBannerNode.y());
|
|
||||||
QThread::msleep(1000);
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (xmlScreenParser.isHomeScreen()) {
|
|
||||||
if (goToAllProducts(device.id, device.screenWidth, device.screenHeight)) {
|
|
||||||
QList<TransactionInfo> localTransactions = TransactionDAO::getTransactionsWithinHours(m_account.id, 48);
|
|
||||||
|
|
||||||
QList<AccountInfo> accounts = xmlScreenParser.parseAccountsInfo();
|
|
||||||
for (auto &account: accounts) {
|
|
||||||
account.deviceId = m_account.deviceId;
|
|
||||||
account.appCode = m_account.appCode;
|
|
||||||
if (!AccountDAO::upsertAccount(account)) {
|
|
||||||
qDebug() << "Not updated: " << account.lastNumbers;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
postAccountsData(accounts);
|
|
||||||
AdbUtils::goBack(device.id);
|
|
||||||
QThread::msleep(500);
|
|
||||||
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter));
|
|
||||||
|
|
||||||
Node actionBtn = xmlScreenParser.findButtonNode("Account Activities", false);
|
|
||||||
if (!actionBtn.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(m_account.deviceId, actionBtn.x(), actionBtn.y());
|
|
||||||
QThread::msleep(1000);
|
|
||||||
} else {
|
|
||||||
m_error = "Account Activities btn not found";
|
|
||||||
qCritical() << m_error;
|
|
||||||
emit finishedWithResult(m_error);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// localTransactions
|
|
||||||
// FIXME доделать так, чтобы свайпать и брать больше чем 5 транзакций
|
|
||||||
for (int i = 0; i < 5; ++i) {
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter));
|
|
||||||
QList<TransactionInfo> transactions = xmlScreenParser.parseTodayAndYesterdayReportHistory();
|
|
||||||
if (!transactions.isEmpty()) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter));
|
|
||||||
// все подтвержденные
|
|
||||||
QList<TransactionInfo> parsedTransactions = xmlScreenParser.parseTodayAndYesterdayReportHistory();
|
|
||||||
|
|
||||||
QSet<int> parsedTransactionIds;
|
|
||||||
for (const TransactionInfo &transaction: parsedTransactions) {
|
|
||||||
for (const TransactionInfo &saved: localTransactions) {
|
|
||||||
if (parsedTransactionIds.contains(saved.id)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (transaction.bankTime == saved.bankTime && transaction.amount == saved.amount) {
|
|
||||||
parsedTransactionIds.insert(saved.id);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!saveAndPostNewTransactionData(m_account, transaction, TransactionStatus::Complete)) {
|
|
||||||
qDebug() << "--- saveAndPostNewTransactionData failed";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
m_error = "GetLastDaysHistoryZiraatScript - home screen not found";
|
|
||||||
qWarning() << m_error;
|
|
||||||
emit finishedWithResult(m_error);
|
|
||||||
}
|
|
||||||
AdbUtils::goBack(m_account.deviceId);
|
|
||||||
emit finishedWithResult(m_error);
|
|
||||||
}
|
|
||||||
@ -1,35 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include "CommonZiraatScript.h"
|
|
||||||
|
|
||||||
class GetLastDaysHistoryZiraatScript final : public CommonZiraatScript {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
~GetLastDaysHistoryZiraatScript() override;
|
|
||||||
|
|
||||||
explicit GetLastDaysHistoryZiraatScript(
|
|
||||||
AccountInfo account,
|
|
||||||
QObject *parent = nullptr
|
|
||||||
);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void doStart() override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
const AccountInfo m_account;
|
|
||||||
QString m_error;
|
|
||||||
|
|
||||||
bool saveAndPostNewTransactionData(
|
|
||||||
const AccountInfo &account,
|
|
||||||
const TransactionInfo &transaction,
|
|
||||||
const TransactionStatus &status
|
|
||||||
);
|
|
||||||
|
|
||||||
bool updateAndPostTransactionData(
|
|
||||||
const AccountInfo &account,
|
|
||||||
int transactionId,
|
|
||||||
TransactionStatus status,
|
|
||||||
const QString &oldDesc,
|
|
||||||
const QString &newDesc
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@ -1,69 +0,0 @@
|
|||||||
#include "LoginAndCheckAccountsZiraatScript.h"
|
|
||||||
|
|
||||||
#include "adb/AdbUtils.h"
|
|
||||||
#include "dao/AccountDAO.h"
|
|
||||||
#include "dao/ApplicationDAO.h"
|
|
||||||
#include "dao/DeviceDAO.h"
|
|
||||||
|
|
||||||
LoginAndCheckAccountsZiraatScript::LoginAndCheckAccountsZiraatScript(
|
|
||||||
QString deviceId,
|
|
||||||
QString appCode,
|
|
||||||
QObject *parent
|
|
||||||
) : CommonZiraatScript(parent),
|
|
||||||
m_deviceId(std::move(deviceId)), m_appCode(std::move(appCode)) {
|
|
||||||
}
|
|
||||||
|
|
||||||
LoginAndCheckAccountsZiraatScript::~LoginAndCheckAccountsZiraatScript() = default;
|
|
||||||
|
|
||||||
|
|
||||||
void LoginAndCheckAccountsZiraatScript::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 (!runAppAndGoToHomeScreen(device.id, app.package, app.pinCode, device.screenWidth, device.screenHeight)) {
|
|
||||||
m_error = "Cant open the home screen: " + m_deviceId + " " + m_appCode;
|
|
||||||
qWarning() << m_error;
|
|
||||||
if (!ApplicationDAO::updatePinCodeStatus(app.id, "no", "Не прошла проверка [дата]")) {
|
|
||||||
qWarning() << "Cant update the pincode: " << m_deviceId << " " << m_appCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
AdbUtils::tryToKillApplication(m_deviceId, app.package);
|
|
||||||
emit finishedWithResult(m_error);
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
if (!ApplicationDAO::updatePinCodeStatus(app.id, "yes", "")) {
|
|
||||||
qWarning() << "Cant update the pincode: " << m_deviceId << " " << m_appCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (goToAllProducts(device.id, device.screenWidth, device.screenHeight)) {
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
|
|
||||||
|
|
||||||
QList<AccountInfo> accounts = xmlScreenParser.parseAccountsInfo();
|
|
||||||
for (auto account: accounts) {
|
|
||||||
account.deviceId = m_deviceId;
|
|
||||||
account.appCode = m_appCode;
|
|
||||||
account.status = AccountStatus::Active;
|
|
||||||
if (!AccountDAO::upsertAccount(account)) {
|
|
||||||
m_error = "Not updated: " + account.lastNumbers;
|
|
||||||
qCritical() << m_error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
postAccountsData(accounts);
|
|
||||||
} else {
|
|
||||||
qWarning() << "Cant go to all products: " << m_deviceId << " " << m_appCode;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
AdbUtils::tryToKillApplication(m_deviceId, app.package);
|
|
||||||
emit finishedWithResult(m_error);
|
|
||||||
}
|
|
||||||
@ -1,23 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include "CommonZiraatScript.h"
|
|
||||||
|
|
||||||
class LoginAndCheckAccountsZiraatScript final : public CommonZiraatScript {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
~LoginAndCheckAccountsZiraatScript() override;
|
|
||||||
|
|
||||||
explicit LoginAndCheckAccountsZiraatScript(
|
|
||||||
QString deviceId,
|
|
||||||
QString appCode,
|
|
||||||
QObject *parent = nullptr
|
|
||||||
);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void doStart() override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
const QString m_deviceId;
|
|
||||||
const QString m_appCode;
|
|
||||||
QString m_error;
|
|
||||||
};
|
|
||||||
@ -1,350 +0,0 @@
|
|||||||
#include "PayByIbanScript.h"
|
|
||||||
|
|
||||||
#include <QRandomGenerator>
|
|
||||||
#include <QThread>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
#include "DatabaseManager.h"
|
|
||||||
#include "adb/AdbUtils.h"
|
|
||||||
#include "dao/AccountDAO.h"
|
|
||||||
#include "dao/ApplicationDAO.h"
|
|
||||||
#include "dao/DeviceDAO.h"
|
|
||||||
#include "dao/TransactionDAO.h"
|
|
||||||
#include "db/ApplicationInfo.h"
|
|
||||||
#include "db/DeviceInfo.h"
|
|
||||||
#include "time/DateUtils.h"
|
|
||||||
|
|
||||||
PayByIbanScript::PayByIbanScript(
|
|
||||||
AccountInfo account,
|
|
||||||
QString iban,
|
|
||||||
QString fullName,
|
|
||||||
const double amount,
|
|
||||||
QObject *parent
|
|
||||||
) : CommonZiraatScript(parent),
|
|
||||||
m_account(std::move(account)), m_iban(std::move(iban)),
|
|
||||||
m_fullName(std::move(fullName)), m_amount(amount) {
|
|
||||||
}
|
|
||||||
|
|
||||||
PayByIbanScript::~PayByIbanScript() = default;
|
|
||||||
|
|
||||||
|
|
||||||
void PayByIbanScript::makePayment(const DeviceInfo &device) {
|
|
||||||
// Оплата со страницы карты
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(device.id, ++m_counter));
|
|
||||||
Node editIbanEditText = xmlScreenParser.findEditTextByResourceId("com.ziraat.ziraatmobil:id/edit_iban");
|
|
||||||
Node fullNameEditText = xmlScreenParser.findEditTextByResourceId("com.ziraat.ziraatmobil:id/edit_full_name");
|
|
||||||
if (!editIbanEditText.isEmpty() && !fullNameEditText.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(device.id, editIbanEditText.x(), editIbanEditText.y());
|
|
||||||
QThread::msleep(500);
|
|
||||||
AdbUtils::inputText(device.id, m_iban);
|
|
||||||
|
|
||||||
AdbUtils::makeTap(device.id, editIbanEditText.x(), editIbanEditText.y());
|
|
||||||
QThread::msleep(500);
|
|
||||||
AdbUtils::inputText(device.id, m_fullName);
|
|
||||||
|
|
||||||
Node nextBtn = xmlScreenParser.findButtonNode("NEXT", false);
|
|
||||||
AdbUtils::makeTap(device.id, nextBtn.x(), nextBtn.y());
|
|
||||||
|
|
||||||
bool findSenderAccount = false;
|
|
||||||
for (int i = 0; i < 5; ++i) {
|
|
||||||
QThread::msleep(1000);
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(device.id, ++m_counter));
|
|
||||||
|
|
||||||
Node senderAccount = xmlScreenParser.findTextNode("Sender Account");
|
|
||||||
if (!senderAccount.isEmpty()) {
|
|
||||||
Node inputBankName = xmlScreenParser.findAccountButton(m_account.lastNumbers);
|
|
||||||
if (!inputBankName.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(device.id, inputBankName.x(), inputBankName.y());
|
|
||||||
QThread::msleep(500);
|
|
||||||
|
|
||||||
|
|
||||||
// FXIME скорее всего придется нажать кнопку NEXT
|
|
||||||
findSenderAccount = true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!findSenderAccount) {
|
|
||||||
m_error = "Не нашли Sender Account";
|
|
||||||
qDebug() << m_error;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool findAmountDetermination = false;
|
|
||||||
for (int i = 0; i < 5; ++i) {
|
|
||||||
QThread::msleep(1000);
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(device.id, ++m_counter));
|
|
||||||
|
|
||||||
Node amountDetermination = xmlScreenParser.findTextNode("Amount Determination");
|
|
||||||
if (!amountDetermination.isEmpty()) {
|
|
||||||
Node integerEditText = xmlScreenParser.findEditTextByResourceId(
|
|
||||||
"com.ziraat.ziraatmobil:id/edit_text_integer");
|
|
||||||
Node decimalEditText = xmlScreenParser.findEditTextByResourceId(
|
|
||||||
"com.ziraat.ziraatmobil:id/edit_text_decimal");
|
|
||||||
if (!integerEditText.isEmpty() && !decimalEditText.isEmpty()) {
|
|
||||||
int integerPart = static_cast<int>(m_amount);
|
|
||||||
AdbUtils::makeTap(device.id, integerEditText.x(), integerEditText.y());
|
|
||||||
QThread::msleep(500);
|
|
||||||
AdbUtils::inputText(device.id, QString::number(integerPart));
|
|
||||||
|
|
||||||
int decimalPart = static_cast<int>((m_amount - integerPart) * 100);
|
|
||||||
AdbUtils::makeTap(device.id, decimalEditText.x(), decimalEditText.y());
|
|
||||||
QThread::msleep(500);
|
|
||||||
AdbUtils::inputText(device.id, QString::number(decimalPart));
|
|
||||||
|
|
||||||
findAmountDetermination = true;
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
m_error = "Не нашли поля ввода для ввода суммы перевода";
|
|
||||||
qDebug() << m_error;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!findAmountDetermination) {
|
|
||||||
m_error = "Не нашли Amount Determination";
|
|
||||||
qDebug() << m_error;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool findDetailDefinition = false;
|
|
||||||
for (int i = 0; i < 5; ++i) {
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(device.id, ++m_counter));
|
|
||||||
Node fastTransferBtn = xmlScreenParser.findButtonNode("FAST TRANSFER", false);
|
|
||||||
if (!fastTransferBtn.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(device.id, fastTransferBtn.x(), fastTransferBtn.y());
|
|
||||||
QThread::msleep(500);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
Node detailDefinitionTitle = xmlScreenParser.findTextNode("Detail Definition");
|
|
||||||
Node pleaseChooseBtn = xmlScreenParser.findButtonNode("Please choose", false);
|
|
||||||
if (!detailDefinitionTitle.isEmpty() && !pleaseChooseBtn.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(device.id, pleaseChooseBtn.x(), pleaseChooseBtn.y());
|
|
||||||
QThread::msleep(500);
|
|
||||||
|
|
||||||
Node searchEditText = xmlScreenParser.
|
|
||||||
findEditTextByResourceId("com.ziraat.ziraatmobil:id/input_search");
|
|
||||||
if (!searchEditText.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(device.id, searchEditText.x(), searchEditText.y());
|
|
||||||
QThread::msleep(500);
|
|
||||||
// FIXME "Individual Payment" или "Other Payments" если нет одного, то надо другой
|
|
||||||
AdbUtils::inputText(device.id, "Other Payments");
|
|
||||||
QThread::msleep(1000);
|
|
||||||
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(device.id, ++m_counter));
|
|
||||||
|
|
||||||
Node otherPaymentsText = xmlScreenParser.findTextNode("Other Payments");
|
|
||||||
if (!otherPaymentsText.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(device.id, otherPaymentsText.x(), otherPaymentsText.y());
|
|
||||||
QThread::msleep(500);
|
|
||||||
findDetailDefinition = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for (int i = 0; i < 5; ++i) {
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(device.id, ++m_counter));
|
|
||||||
Node otherPaymentsText = xmlScreenParser.findTextNode("Other Payments");
|
|
||||||
if (otherPaymentsText.isEmpty()) {
|
|
||||||
AdbUtils::makeSwipe(
|
|
||||||
m_account.deviceId,
|
|
||||||
device.screenWidth / 2, device.screenHeight / 4 * 3,
|
|
||||||
device.screenWidth / 2, device.screenHeight / 4
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
AdbUtils::makeTap(device.id, otherPaymentsText.x(), otherPaymentsText.y());
|
|
||||||
QThread::msleep(500);
|
|
||||||
findDetailDefinition = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
QThread::msleep(500);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!findDetailDefinition) {
|
|
||||||
m_error = "Не нашли Detail Definition";
|
|
||||||
qDebug() << m_error;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(device.id, ++m_counter));
|
|
||||||
Node nextBtn4 = xmlScreenParser.findButtonNode("NEXT", false);
|
|
||||||
AdbUtils::makeTap(device.id, nextBtn4.x(), nextBtn4.y());
|
|
||||||
QThread::msleep(500);
|
|
||||||
|
|
||||||
Node checkInfo = xmlScreenParser.findTextNode(
|
|
||||||
"Check the details of the transaction you shall realize and approve your transaction.");
|
|
||||||
if (!checkInfo.isEmpty()) {
|
|
||||||
for (int i = 0; i < 5; ++i) {
|
|
||||||
Node confirmBtn = xmlScreenParser.findButtonNode("CONFIRM", false);
|
|
||||||
if (confirmBtn.isEmpty()) {
|
|
||||||
AdbUtils::makeSwipe(
|
|
||||||
m_account.deviceId,
|
|
||||||
device.screenWidth / 2, device.screenHeight / 4 * 3,
|
|
||||||
device.screenWidth / 2, device.screenHeight / 4
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
AdbUtils::makeTap(device.id, confirmBtn.x(), confirmBtn.y());
|
|
||||||
QThread::msleep(500);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
QThread::msleep(500);
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(device.id, ++m_counter));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
QThread::msleep(1000);
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(device.id, ++m_counter));
|
|
||||||
Node successText = xmlScreenParser.findTextNode("Your transaction is successfully realized.");
|
|
||||||
if (!successText.isEmpty()) {
|
|
||||||
Node receiptBtn = xmlScreenParser.findButtonNode("RECEIPT", false);
|
|
||||||
if (!receiptBtn.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(device.id, receiptBtn.x(), receiptBtn.y());
|
|
||||||
QThread::msleep(500);
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(device.id, ++m_counter));
|
|
||||||
|
|
||||||
Node sendBtn = xmlScreenParser.findButtonNode("SEND E-MAIL", false);
|
|
||||||
if (!sendBtn.isEmpty()) {
|
|
||||||
AdbUtils::takeXmlDump(
|
|
||||||
device.id, "pay_by_iban_finish_transactions_" + QString::number(m_account.id)
|
|
||||||
);
|
|
||||||
// Успешная транзакция
|
|
||||||
// TODO считываем все данные по переводу
|
|
||||||
TransactionInfo transaction;
|
|
||||||
transaction.name = m_fullName;
|
|
||||||
transaction.accountId = m_account.id;
|
|
||||||
transaction.amount = -m_amount;
|
|
||||||
transaction.fee = 0;
|
|
||||||
transaction.status = TransactionStatus::Complete;
|
|
||||||
transaction.type = TransactionType::Iban;
|
|
||||||
transaction.updateTime = DateUtils::getUtcNow();
|
|
||||||
transaction.completeTime = DateUtils::getUtcNow();
|
|
||||||
transaction.timestamp = DateUtils::getUtcNow();
|
|
||||||
transaction.id = TransactionDAO::insertTransaction(transaction);
|
|
||||||
if (transaction.id == -1) {
|
|
||||||
// FIXME alert!!
|
|
||||||
qDebug() << "Transaction has not inserted...";
|
|
||||||
}
|
|
||||||
|
|
||||||
postNewTransactionData(m_account, transaction);
|
|
||||||
|
|
||||||
Node backBtn = xmlScreenParser.findButtonNode("BACK", false);
|
|
||||||
if (!backBtn.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(device.id, backBtn.x(), backBtn.y());
|
|
||||||
QThread::msleep(500);
|
|
||||||
|
|
||||||
Node returnBtn = xmlScreenParser.findButtonNode("RETURN TO HOME PAGE", false);
|
|
||||||
if (!returnBtn.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(device.id, returnBtn.x(), returnBtn.y());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
//FIXME не успешная транзакция
|
|
||||||
AdbUtils::takeXmlDump(
|
|
||||||
device.id, "pay_by_iban_fail_transactions_receipt_" + QString::number(m_account.id)
|
|
||||||
);
|
|
||||||
m_error = "Транзакция не успешна";
|
|
||||||
qDebug() << m_error;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
m_error = "Транзакция не успешна";
|
|
||||||
qDebug() << m_error;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
m_error = "Не нашли Check the details title info";
|
|
||||||
qDebug() << m_error;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
m_error = "Не нашли поля ввода для IBAN";
|
|
||||||
qDebug() << m_error;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void PayByIbanScript::doStart() {
|
|
||||||
const DeviceInfo device = DeviceDAO::getDeviceById(m_account.deviceId);
|
|
||||||
const ApplicationInfo app = ApplicationDAO::getApplication(m_account.deviceId, m_account.appCode);
|
|
||||||
|
|
||||||
if (device.id.isEmpty() || app.id == -1) {
|
|
||||||
m_error = "Device or app not found.";
|
|
||||||
qDebug() << m_error;
|
|
||||||
emit finishedWithResult(m_error);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter));
|
|
||||||
if (!xmlScreenParser.isHomeScreen()) {
|
|
||||||
if (!runAppAndGoToHomeScreen(device.id, app.package, app.pinCode, device.screenWidth, device.screenHeight)) {
|
|
||||||
m_error = "Не смогли дойти до домашней страницы";
|
|
||||||
qDebug() << m_error;
|
|
||||||
emit finishedWithResult(m_error);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter));
|
|
||||||
Node allTransactionsNav = xmlScreenParser.findTextNode("Transactions");
|
|
||||||
if (!allTransactionsNav.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(device.id, allTransactionsNav.x(), allTransactionsNav.y());
|
|
||||||
QThread::msleep(1000);
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter));
|
|
||||||
|
|
||||||
// перешли на страницу транзакций
|
|
||||||
Node allTransactionsTitle = xmlScreenParser.findTextNode(
|
|
||||||
"Transactions", 0, 0, device.screenWidth, device.screenHeight / 2
|
|
||||||
);
|
|
||||||
Node moneyTransfersBtn = xmlScreenParser.findTextNode("Money Transfers");
|
|
||||||
if (!allTransactionsTitle.isEmpty() && !moneyTransfersBtn.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(device.id, moneyTransfersBtn.x(), moneyTransfersBtn.y());
|
|
||||||
QThread::msleep(1000);
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter));
|
|
||||||
|
|
||||||
// перешли на страницу переводов
|
|
||||||
Node moneyTransfersTitle = xmlScreenParser.findTextNode(
|
|
||||||
"Money Transfers", 0, 0, device.screenWidth, device.screenHeight / 2
|
|
||||||
);
|
|
||||||
Node transferToOtherAccountBtn = xmlScreenParser.findTextNode("Transfer to Other Account");
|
|
||||||
if (!moneyTransfersTitle.isEmpty() && !transferToOtherAccountBtn.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(device.id, transferToOtherAccountBtn.x(), transferToOtherAccountBtn.y());
|
|
||||||
QThread::msleep(1000);
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter));
|
|
||||||
|
|
||||||
Node transferToOtherAccountTitle = xmlScreenParser.findTextNode(
|
|
||||||
"Transfer to Other Account", 0, 0, device.screenWidth, device.screenHeight / 2
|
|
||||||
);
|
|
||||||
Node aNewRecipientBtn = xmlScreenParser.findTextNode("A New Recipient");
|
|
||||||
if (!transferToOtherAccountTitle.isEmpty() && !aNewRecipientBtn.isEmpty()) {
|
|
||||||
AdbUtils::makeTap(device.id, aNewRecipientBtn.x(), aNewRecipientBtn.y());
|
|
||||||
QThread::msleep(1000);
|
|
||||||
|
|
||||||
makePayment(device);
|
|
||||||
} else {
|
|
||||||
m_error = "Не нашли кнопку 'A New Recipient'";
|
|
||||||
qDebug() << m_error;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
m_error = "Не нашли кнопку 'Transfer to Other Account'";
|
|
||||||
qDebug() << m_error;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
m_error = "Не нашли кнопку 'Money Transfers'";
|
|
||||||
qDebug() << m_error;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
m_error = "Не нашли пункт меню 'Transactions'";
|
|
||||||
qDebug() << m_error;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!m_error.isEmpty()) {
|
|
||||||
AdbUtils::takeXmlDump(device.id, "pay_by_iban_fail_transactions_" + QString::number(m_account.id));
|
|
||||||
}
|
|
||||||
|
|
||||||
emit finishedWithResult(m_error);
|
|
||||||
}
|
|
||||||
@ -1,30 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include "CommonZiraatScript.h"
|
|
||||||
#include "db/DeviceInfo.h"
|
|
||||||
|
|
||||||
class PayByIbanScript final : public CommonZiraatScript {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
~PayByIbanScript() override;
|
|
||||||
|
|
||||||
PayByIbanScript(
|
|
||||||
AccountInfo account,
|
|
||||||
QString iban,
|
|
||||||
QString fullName,
|
|
||||||
double amount,
|
|
||||||
QObject *parent = nullptr
|
|
||||||
);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void doStart() override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
const AccountInfo m_account;
|
|
||||||
const QString m_iban;
|
|
||||||
const QString m_fullName;
|
|
||||||
const double m_amount;
|
|
||||||
QString m_error;
|
|
||||||
|
|
||||||
void makePayment(const DeviceInfo &device);
|
|
||||||
};
|
|
||||||
@ -1,797 +0,0 @@
|
|||||||
#include "ScreenXmlZiraatParser.h"
|
|
||||||
|
|
||||||
#include <QRegularExpression>
|
|
||||||
#include <QMap>
|
|
||||||
#include <QSet>
|
|
||||||
#include <QList>
|
|
||||||
#include <QXmlStreamReader>
|
|
||||||
#include <QDomDocument>
|
|
||||||
#include <QFile>
|
|
||||||
#include <QDateTime>
|
|
||||||
|
|
||||||
#include "adb/AdbUtils.h"
|
|
||||||
#include "android/xml/Node.h"
|
|
||||||
#include "db/AccountInfo.h"
|
|
||||||
#include "db/TransactionInfo.h"
|
|
||||||
#include "time/DateUtils.h"
|
|
||||||
|
|
||||||
ScreenXmlZiraatParser::ScreenXmlZiraatParser(QObject *parent) : QObject(parent) {
|
|
||||||
}
|
|
||||||
|
|
||||||
ScreenXmlZiraatParser::~ScreenXmlZiraatParser() = default;
|
|
||||||
|
|
||||||
static const QRegularExpression boundsRegex(R"(\[([0-9]+),([0-9]+)\]\[([0-9]+),([0-9]+)\])");
|
|
||||||
static const QRegularExpression onlyDigitsRegex(R"([^0-9])");
|
|
||||||
static const QRegularExpression onlyDigitsAndDotRegex(R"([^0-9.])");
|
|
||||||
|
|
||||||
static const QRegularExpression rePhone(R"raw((\+7\(?\d{3}\)?[- ]?\d{3}[- ]?\d{2}[- ]?\d{2}))raw");
|
|
||||||
static const QRegularExpression reFromBank(R"raw(из (.+?) на)raw");
|
|
||||||
static const QRegularExpression reToBank(R"raw(в (.+?) через)raw");
|
|
||||||
static const QRegularExpression reSbpId(R"(СБП(?: С2С)? ([A-Z0-9]{30,}))");
|
|
||||||
static const QRegularExpression reIdAlt(R"(ID перевода (\d+))");
|
|
||||||
static const QRegularExpression reDate(R"((?:Дата операции|дата) (\d{2}\.\d{2}\.\d{4}(?: \d{2}:\d{2}:\d{2})?))");
|
|
||||||
static const QRegularExpression reSender(R"(от ([^\(]+))");
|
|
||||||
static const QRegularExpression reNameAlt(R"(Перевод ([А-Яа-яЁё\s\*]+) в)");
|
|
||||||
|
|
||||||
static const QRegularExpression reCardData(R"(цифрами\s+(\d\s\d\s\d\s\d).*?Сумма:\s([\d\s]+)\sруб)");
|
|
||||||
|
|
||||||
Node ScreenXmlZiraatParser::tryToFindBannerOrDialog(const int width, const int height) {
|
|
||||||
// 1. Ищем push banner - он перекрывает весь экран
|
|
||||||
Node first = m_nodes[0];
|
|
||||||
for (const Node &node: m_nodes) {
|
|
||||||
// Если это однозначно, что пуш-баннер
|
|
||||||
if (node.resourceId == "aft-popup-pushNotification-iconClose" && node.className == "android.widget.Button") {
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
// Если есть кнопка "Позже"
|
|
||||||
if (node.text.trimmed() == "Позже" && node.className == "android.widget.Button") {
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
// Если нашли пустую кнпоку
|
|
||||||
if (node.className == "android.widget.Button" && node.clickable
|
|
||||||
&& node.text.isEmpty() && node.contentDesc.isEmpty()) {
|
|
||||||
// <node class="android.widget.Button" package="ru.rshb.dbo" clickable="true" bounds="[630,142][691,205]"/>
|
|
||||||
if (node.x() > width / 2 && node.y() < width / 2) {
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
Node ScreenXmlZiraatParser::findAccountButton(const QString &numbers) {
|
|
||||||
// TODO возможно это не так, надо уточнять
|
|
||||||
return findTextNode(QString("LEVENT - %1").arg(numbers));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Смотрим что есть текс "Мы заботимся о вашей безопасности" и
|
|
||||||
* кнопка "Отложить"
|
|
||||||
* @return координаты кнопки для закрытия
|
|
||||||
*/
|
|
||||||
Node ScreenXmlZiraatParser::tryToFindSecurityBanner() {
|
|
||||||
Node text;
|
|
||||||
Node closeBtn;
|
|
||||||
for (const Node &node: m_nodes) {
|
|
||||||
if (node.text.trimmed() == "Мы заботимся о вашей безопасности" && node.className == "android.app.Dialog") {
|
|
||||||
text = node;
|
|
||||||
}
|
|
||||||
if (node.text.trimmed() == "Отложить" && node.className == "android.widget.Button") {
|
|
||||||
closeBtn = node;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Не нужно проверять все, если хотя бы одна координата есть
|
|
||||||
if (!text.isEmpty() && !closeBtn.isEmpty()) {
|
|
||||||
return closeBtn;
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
Node ScreenXmlZiraatParser::tryToFindSelectBottomSheet() {
|
|
||||||
Node closeBtn;
|
|
||||||
for (const Node &node: m_nodes) {
|
|
||||||
if ((node.text.trimmed() == "Отмена" || node.text.trimmed() == "Отложить") && node.className ==
|
|
||||||
"android.widget.Button") {
|
|
||||||
closeBtn = node;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Не нужно проверять все, если хотя бы одна координата есть
|
|
||||||
if (!closeBtn.isEmpty()) {
|
|
||||||
return closeBtn;
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
Node ScreenXmlZiraatParser::findTextNode(const QString &text) {
|
|
||||||
for (const Node &node: m_nodes) {
|
|
||||||
if (node.className == "android.widget.TextView" && node.text.trimmed() == text) {
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
Node ScreenXmlZiraatParser::findTextNode(const QString &text, const int x1, const int y1, const int x2, const int y2) {
|
|
||||||
for (const Node &node: m_nodes) {
|
|
||||||
if (node.className == "android.widget.TextView" && node.text.trimmed() == text
|
|
||||||
&& node.x() >= x1 && node.x() <= x2 && node.y() >= y1 && node.y() <= y2) {
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
Node ScreenXmlZiraatParser::findEditText(const QString &text) {
|
|
||||||
for (const Node &node: m_nodes) {
|
|
||||||
if (node.className == "android.widget.EditText" && node.text == text) {
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
Node ScreenXmlZiraatParser::findEditTextByResourceId(const QString &resourceId) {
|
|
||||||
for (const Node &node: m_nodes) {
|
|
||||||
if (node.className == "android.widget.EditText" && node.resourceId == resourceId) {
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
Node ScreenXmlZiraatParser::findButtonNode(const QString &text, const bool contains) {
|
|
||||||
for (const Node &node: m_nodes) {
|
|
||||||
if (contains) {
|
|
||||||
if (node.className == "android.widget.Button" && node.text.contains(text)) {
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (node.className == "android.widget.Button" && node.text.trimmed() == text) {
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ScreenXmlZiraatParser::isHomeScreen() {
|
|
||||||
Node activitiesBtn;
|
|
||||||
Node allProductBtn;
|
|
||||||
for (const Node &node: m_nodes) {
|
|
||||||
if (node.text.trimmed() == "Account Activities" && node.className == "android.widget.Button") {
|
|
||||||
activitiesBtn = node;
|
|
||||||
}
|
|
||||||
if (node.text.trimmed() == "All My Accounts" && node.className == "android.widget.Button") {
|
|
||||||
allProductBtn = node;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return !activitiesBtn.isEmpty() && !allProductBtn.isEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<Node> ScreenXmlZiraatParser::findPinCodeNodes(const QString &pinCode) {
|
|
||||||
QMap<QString, Node> buttons;
|
|
||||||
const QSet<QString> numberSet = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"};
|
|
||||||
|
|
||||||
for (const Node &node: m_nodes) {
|
|
||||||
const QString &text = node.text.trimmed();
|
|
||||||
if (node.className == "android.widget.Button" && numberSet.contains(text)) {
|
|
||||||
buttons[text] = node;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<Node> nodes;
|
|
||||||
for (int i = 0; i < pinCode.length(); ++i) {
|
|
||||||
nodes.append(buttons[QString(pinCode.at(i))]);
|
|
||||||
}
|
|
||||||
return nodes;
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<Node> ScreenXmlZiraatParser::getLast2DaysTransactions() {
|
|
||||||
QList<Node> nodes;
|
|
||||||
for (const Node &node: m_nodes) {
|
|
||||||
if (node.className == "android.widget.Button" && node.text.contains("рубл")
|
|
||||||
&& (node.text.contains("Минус") || node.text.contains("Плюс"))) {
|
|
||||||
nodes.append(node);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nodes;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <node NAF="true" index="1" text="" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[952,159][1039,248]"/>
|
|
||||||
*/
|
|
||||||
void ScreenXmlZiraatParser::parseAndSaveXml(const QString &xml) {
|
|
||||||
QDomDocument doc;
|
|
||||||
doc.setContent(xml);
|
|
||||||
m_xml = doc.documentElement();
|
|
||||||
m_nodes.clear();
|
|
||||||
|
|
||||||
QXmlStreamReader reader(xml);
|
|
||||||
while (!reader.atEnd()) {
|
|
||||||
reader.readNext();
|
|
||||||
if (reader.isStartElement() && reader.name() == "node") {
|
|
||||||
Node node = Node();
|
|
||||||
if (reader.attributes().hasAttribute("bounds")) {
|
|
||||||
QString bounds = reader.attributes().value("bounds").toString();
|
|
||||||
if (QRegularExpressionMatch match = boundsRegex.match(bounds); match.hasMatch()) {
|
|
||||||
node.setBounds(
|
|
||||||
match.captured(1).toInt(),
|
|
||||||
match.captured(2).toInt(),
|
|
||||||
match.captured(3).toInt(),
|
|
||||||
match.captured(4).toInt()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (reader.attributes().hasAttribute("text")) {
|
|
||||||
node.text = reader.attributes().value("text").toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (reader.attributes().hasAttribute("content-desc")) {
|
|
||||||
node.contentDesc = reader.attributes().value("content-desc").toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (reader.attributes().hasAttribute("class")) {
|
|
||||||
node.className = reader.attributes().value("class").toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (reader.attributes().hasAttribute("clickable")) {
|
|
||||||
node.clickable = reader.attributes().value("clickable").toString() == "true";
|
|
||||||
}
|
|
||||||
if (reader.attributes().hasAttribute("focusable")) {
|
|
||||||
node.focusable = reader.attributes().value("focusable").toString() == "true";
|
|
||||||
}
|
|
||||||
if (reader.attributes().hasAttribute("resource-id")) {
|
|
||||||
node.resourceId = reader.attributes().value("resource-id").toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
m_nodes.append(node);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QDomElement findSubElement2(const QDomElement &elem, const QString &index) {
|
|
||||||
if (elem.hasChildNodes()) {
|
|
||||||
QDomNodeList subInfoList = elem.childNodes();
|
|
||||||
for (QDomNode subInfoNode: subInfoList) {
|
|
||||||
if (!subInfoNode.isElement()) continue;
|
|
||||||
QDomElement subInfo = subInfoNode.toElement();
|
|
||||||
if (subInfo.attribute("index") == index) {
|
|
||||||
return subInfo;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
QString findSubInfo2(const QDomElement &elem, const QString &index) {
|
|
||||||
QDomElement subInfo = findSubElement2(elem, index);
|
|
||||||
if (!subInfo.isNull()) {
|
|
||||||
return subInfo.attribute("text");
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
bool hasTimeComponent2(const QString &datetimeStr) {
|
|
||||||
QDateTime dt = QDateTime::fromString(datetimeStr, "dd.MM.yyyy HH:mm:ss");
|
|
||||||
if (!dt.isValid()) {
|
|
||||||
return false; // Строка не соответствует формату даты и времени
|
|
||||||
}
|
|
||||||
return dt.time() != QTime(0, 0, 0); // Проверка, что время не равно 00:00:00
|
|
||||||
}
|
|
||||||
|
|
||||||
QString transformBankDateTime2(const QString &date) {
|
|
||||||
QDateTime dt;
|
|
||||||
if (date.contains(",")) {
|
|
||||||
// 10.05.2025, 15:03
|
|
||||||
dt = QDateTime::fromString(date, "dd.MM.yyyy, HH:mm");
|
|
||||||
} else {
|
|
||||||
dt = QDateTime::fromString(date, "dd.MM.yyyy HH:mm:ss");
|
|
||||||
}
|
|
||||||
if (!dt.isValid()) {
|
|
||||||
dt = QDateTime::fromString(date, "dd.MM.yyyy HH:mm");
|
|
||||||
}
|
|
||||||
if (!dt.isValid()) {
|
|
||||||
return date; // не распарсили
|
|
||||||
}
|
|
||||||
return dt.toString("dd.MM.yyyy HH:mm:ss");
|
|
||||||
}
|
|
||||||
|
|
||||||
void parseTransferInfo2(const QString &text, TransactionInfo &info) {
|
|
||||||
if (const auto m = reSender.match(text); m.hasMatch()) {
|
|
||||||
info.name = m.captured(1).trimmed();
|
|
||||||
} else if (const auto m1 = reNameAlt.match(text); m1.hasMatch()) {
|
|
||||||
info.name = m1.captured(1).trimmed();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (const auto m = rePhone.match(text); m.hasMatch()) {
|
|
||||||
info.phone = m.captured(1).trimmed().remove(onlyDigitsRegex);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (const auto m = reFromBank.match(text); m.hasMatch()) {
|
|
||||||
if (const QString bank = m.captured(1).trimmed(); !bank.isEmpty()) {
|
|
||||||
info.bankName = bank;
|
|
||||||
}
|
|
||||||
} else if (const auto m1 = reToBank.match(text); m1.hasMatch()) {
|
|
||||||
if (const QString bank = m1.captured(1).trimmed(); !bank.isEmpty()) {
|
|
||||||
info.bankName = bank;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (const auto m = reSbpId.match(text); m.hasMatch()) {
|
|
||||||
info.bankTrExternalId = m.captured(1);
|
|
||||||
} else if (const auto m1 = reIdAlt.match(text); m1.hasMatch()) {
|
|
||||||
info.bankTrExternalId = m1.captured(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (const auto m = reDate.match(text); m.hasMatch()) {
|
|
||||||
const QString date = m.captured(1);
|
|
||||||
// если не пустая и дата у нас с 00:00
|
|
||||||
// if (hasTimeComponent2(date)) {
|
|
||||||
info.bankTime = transformBankDateTime2(date);
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void traverseNodes2(const QDomNode &node) {
|
|
||||||
if (node.isElement()) {
|
|
||||||
QDomElement elem = node.toElement();
|
|
||||||
|
|
||||||
if (node.isElement()) {
|
|
||||||
QDomElement elem = node.toElement();
|
|
||||||
|
|
||||||
if (elem.tagName() == "node" &&
|
|
||||||
elem.attribute("class") == "android.widget.Button" &&
|
|
||||||
elem.attribute("text") == "Детали операции") {
|
|
||||||
// Все что ниже деталей операции
|
|
||||||
QDomNodeList detailInfo = elem.parentNode().childNodes();
|
|
||||||
|
|
||||||
|
|
||||||
for (int j = 0; j < detailInfo.count(); ++j) {
|
|
||||||
QDomNode info = detailInfo.at(j);
|
|
||||||
if (!info.isElement()) continue;
|
|
||||||
QDomElement infoElement = info.toElement();
|
|
||||||
QString index = infoElement.attribute("index");
|
|
||||||
switch (index.toInt()) {
|
|
||||||
case 2:
|
|
||||||
qDebug() << "Дата операции:" << findSubInfo2(infoElement, "1");
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
qDebug() << "Название:" << findSubInfo2(infoElement, "1");
|
|
||||||
qDebug() << "-------------------------------------";
|
|
||||||
// parseTransfer(findSubInfo2(infoElement));
|
|
||||||
break;
|
|
||||||
case 7:
|
|
||||||
qDebug() << "Комиссия:" << findSubInfo2(infoElement, "1");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
qDebug() << "Прочее:" << findSubInfo2(infoElement, "1");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Node: "2" ""
|
|
||||||
... Node: "0" "Дата операции"
|
|
||||||
... Node: "1" "30.04.2025 17:46:29"
|
|
||||||
Node: "5" ""
|
|
||||||
... Node: "0" "Название"
|
|
||||||
... Node: "1" "DBO TRANSFER RSHB INTERNET-BANK"
|
|
||||||
Node: "7" ""
|
|
||||||
... Node: "0" "Комиссия"
|
|
||||||
... Node: "1" "50 ₽"
|
|
||||||
*/
|
|
||||||
|
|
||||||
// if (sibElem.hasChildNodes()) {
|
|
||||||
// QDomNodeList sibChildren = sibElem.childNodes();
|
|
||||||
// for (int k = 0; k < sibChildren.count(); ++k) {
|
|
||||||
// QDomNode sibChild = sibChildren.at(k);
|
|
||||||
// if (!sibChild.isElement()) continue;
|
|
||||||
// QDomElement sibChildElem = sibChild.toElement();
|
|
||||||
// qDebug() << "... Node:"
|
|
||||||
// << sibChildElem.attribute("index")
|
|
||||||
// << sibChildElem.attribute("text");
|
|
||||||
// // << sibChildElem.attribute("class");
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// if (sibChildElem.hasChildNodes()) {
|
|
||||||
// QDomNodeList sibChildren2 = sibChildElem.childNodes();
|
|
||||||
// for (int k = 0; k < sibChildren2.count(); ++k) {
|
|
||||||
// QDomNode sibChild2 = sibChildren2.at(k);
|
|
||||||
// if (!sibChild2.isElement()) continue;
|
|
||||||
// QDomElement sibChildElem2 = sibChild2.toElement();
|
|
||||||
//
|
|
||||||
// qDebug() << "...... Node:"
|
|
||||||
// << sibChildElem2.attribute("index")
|
|
||||||
// << sibChildElem2.attribute("text");
|
|
||||||
// // << sibChildElem2.attribute("class");
|
|
||||||
//
|
|
||||||
// if (sibChildElem2.hasChildNodes()) {
|
|
||||||
// QDomNodeList sibChildren3 = sibChildElem2.childNodes();
|
|
||||||
// for (int k = 0; k < sibChildren3.count(); ++k) {
|
|
||||||
// QDomNode sibChild3 = sibChildren3.at(k);
|
|
||||||
// if (!sibChild3.isElement()) continue;
|
|
||||||
// QDomElement sibChildElem3 = sibChild3.toElement();
|
|
||||||
//
|
|
||||||
// qDebug() << "......... Node:"
|
|
||||||
// << sibChildElem3.attribute("index")
|
|
||||||
// << sibChildElem3.attribute("text");
|
|
||||||
// // << sibChildElem2.attribute("class");
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Рекурсивно обходим всех детей
|
|
||||||
QDomNode child = node.firstChild();
|
|
||||||
while (!child.isNull()) {
|
|
||||||
traverseNodes2(child);
|
|
||||||
child = child.nextSibling();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QDomNode findNode2(const QDomNode &node, const QString &text) {
|
|
||||||
if (node.isElement()) {
|
|
||||||
QString nodeText = node.toElement().attribute("text");
|
|
||||||
if (nodeText.toLower().startsWith(text)) {
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
QDomNode child = node.firstChild();
|
|
||||||
while (!child.isNull()) {
|
|
||||||
QDomNode result = findNode2(child, text);
|
|
||||||
if (!result.isNull()) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
child = child.nextSibling();
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
float extractAmounts2(const QString &text) {
|
|
||||||
// Разрешаем пробелы внутри чисел, захватываем "рубль", "рубля", "рублей" и т.д.
|
|
||||||
// QRegularExpression re(R"((Плюс|Минус)\s+([\d\s]+)\s+рубл\w*\s+(\d+)\s+копе\w*)");
|
|
||||||
QRegularExpression re(
|
|
||||||
R"((Плюс|Минус)\s+([\d\s]+)\s+рубл\w*\s+(\d+)\s+копе\w*)",
|
|
||||||
QRegularExpression::UseUnicodePropertiesOption
|
|
||||||
);
|
|
||||||
|
|
||||||
QRegularExpressionMatch match = re.match(text);
|
|
||||||
if (match.hasMatch()) {
|
|
||||||
QString signStr = match.captured(1); // "Плюс" или "Минус"
|
|
||||||
QString rublesStr = match.captured(2).remove(' '); // "1 000" → "1000"
|
|
||||||
int rubles = rublesStr.toInt();
|
|
||||||
int kopecks = match.captured(3).toInt();
|
|
||||||
|
|
||||||
int totalKopecks = rubles * 100 + kopecks;
|
|
||||||
if (signStr == "Минус") {
|
|
||||||
totalKopecks *= -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return totalKopecks / 100.0f;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString beforeAmount2(const QString &text) {
|
|
||||||
int index = text.indexOf(QRegularExpression("Плюс|Минус"));
|
|
||||||
if (index != -1) {
|
|
||||||
return text.left(index).trimmed();
|
|
||||||
}
|
|
||||||
return text; // если не найдено — вернуть всю строку
|
|
||||||
}
|
|
||||||
|
|
||||||
double parseAmount2(const QString &amountAsString) {
|
|
||||||
QString numberString = amountAsString;
|
|
||||||
numberString.remove(QRegularExpression(R"([^\dточка])"));
|
|
||||||
numberString.replace("точка", ".");
|
|
||||||
double amount = numberString.toDouble();
|
|
||||||
|
|
||||||
if (amountAsString.startsWith("-")) {
|
|
||||||
amount *= -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return amount;
|
|
||||||
}
|
|
||||||
|
|
||||||
QDomElement findElementWithListView2(const QDomElement &parent) {
|
|
||||||
QDomElement element = parent.firstChildElement();
|
|
||||||
while (!element.isNull()) {
|
|
||||||
QDomElement child = element.firstChildElement();
|
|
||||||
while (!child.isNull()) {
|
|
||||||
if (child.hasAttribute("class") && child.attribute("class") ==
|
|
||||||
"androidx.recyclerview.widget.RecyclerView") {
|
|
||||||
return child;
|
|
||||||
}
|
|
||||||
child = child.nextSiblingElement();
|
|
||||||
}
|
|
||||||
|
|
||||||
QDomElement found = findElementWithListView2(element);
|
|
||||||
if (!found.isNull()) {
|
|
||||||
return found;
|
|
||||||
}
|
|
||||||
element = element.nextSiblingElement();
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
QDateTime getUtcFromTurkey(const QString &d, const QString &m, const QString &t) {
|
|
||||||
const QMap<QString, int> monthMap = {
|
|
||||||
{"JAN", 1}, {"FEB", 2}, {"MAR", 3}, {"APR", 4},
|
|
||||||
{"MAY", 5}, {"JUN", 6}, {"JUL", 7}, {"AUG", 8},
|
|
||||||
{"SEP", 9}, {"OCT", 10}, {"NOV", 11}, {"DEC", 12}
|
|
||||||
};
|
|
||||||
|
|
||||||
const int day = d.toInt();
|
|
||||||
const int month = monthMap.value(m.toUpper(), 0);
|
|
||||||
const int year = QDate::currentDate().year();
|
|
||||||
|
|
||||||
const QDate date(year, month, day);
|
|
||||||
const QTime time = QTime::fromString(t, "HH:mm");
|
|
||||||
|
|
||||||
const QTimeZone tz("Europe/Istanbul"); // TRT (UTC+3, без перехода на зимнее время)
|
|
||||||
const QDateTime dtLocal(date, time, tz);
|
|
||||||
|
|
||||||
const QDateTime dtUtc = dtLocal.toTimeZone(QTimeZone::utc());
|
|
||||||
return dtUtc;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
QList<TransactionInfo> ScreenXmlZiraatParser::parseTodayAndYesterdayReportHistory() {
|
|
||||||
QList<TransactionInfo> transactions;
|
|
||||||
|
|
||||||
QDomElement child = findElementWithListView2(m_xml);
|
|
||||||
QDomNodeList listView = child.childNodes();
|
|
||||||
qDebug() << listView.count();
|
|
||||||
if (!listView.isEmpty()) {
|
|
||||||
for (QDomNode node: listView) {
|
|
||||||
const QDomNodeList trBoxGroup = node.childNodes();
|
|
||||||
if (trBoxGroup.count() > 0) {
|
|
||||||
for (QDomNode item: trBoxGroup) {
|
|
||||||
TransactionInfo transaction;
|
|
||||||
QDomElement groupItem = item.toElement();
|
|
||||||
if (groupItem.attribute("index") == "0") {
|
|
||||||
for (QDomNode subDate: groupItem.childNodes()) {
|
|
||||||
QDomElement dateItem = subDate.toElement();
|
|
||||||
QString date;
|
|
||||||
QString month;
|
|
||||||
QString time;
|
|
||||||
if (dateItem.attribute("index") == "0") {
|
|
||||||
date = dateItem.attribute("text");
|
|
||||||
} else if (groupItem.attribute("index") == "1") {
|
|
||||||
month = groupItem.attribute("text");
|
|
||||||
} else if (groupItem.attribute("index") == "2") {
|
|
||||||
time = groupItem.attribute("text");
|
|
||||||
}
|
|
||||||
transaction.bankTime = date + " " + month + " " + time;
|
|
||||||
transaction.completeTime = getUtcFromTurkey(date, month, time);
|
|
||||||
transaction.timestamp = DateUtils::getUtcNow();
|
|
||||||
}
|
|
||||||
} else if (groupItem.attribute("index") == "2") {
|
|
||||||
transaction.description = groupItem.attribute("text");
|
|
||||||
} else if (groupItem.attribute("index") == "3") {
|
|
||||||
transaction.amount = groupItem.attribute("text").replace("TL", "").trimmed().toFloat();
|
|
||||||
}
|
|
||||||
transactions.append(transaction);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
qDebug() << "ListView is empty";
|
|
||||||
}
|
|
||||||
return transactions;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
TransactionInfo parseExpandedInfoHistory2(const QDomElement &root) {
|
|
||||||
if (root.isElement()) {
|
|
||||||
QDomElement elem = root.toElement();
|
|
||||||
if (elem.tagName() == "node"
|
|
||||||
&& elem.attribute("class") == "android.widget.Button"
|
|
||||||
&& elem.attribute("text") == "Детали операции"
|
|
||||||
) {
|
|
||||||
TransactionInfo transaction;
|
|
||||||
// Все что ниже деталей операции
|
|
||||||
QDomNodeList detailInfo = elem.parentNode().childNodes();
|
|
||||||
|
|
||||||
for (int i = 0; i < detailInfo.count(); ++i) {
|
|
||||||
QDomNode info = detailInfo.at(i);
|
|
||||||
if (!info.isElement()) continue;
|
|
||||||
|
|
||||||
switch (QDomElement e = info.toElement(); e.attribute("index").toInt()) {
|
|
||||||
case 2:
|
|
||||||
// Дата операции
|
|
||||||
transaction.bankTime = transformBankDateTime2(findSubInfo2(e, "1"));
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
transaction.description = findSubInfo2(e, "1");
|
|
||||||
parseTransferInfo2(transaction.description, transaction);
|
|
||||||
break;
|
|
||||||
case 7:
|
|
||||||
// Комиссия
|
|
||||||
transaction.fee = findSubInfo2(e, "1").remove(onlyDigitsRegex).toFloat();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
// qDebug() << "Прочее:" << findSubInfo2(e);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return transaction;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Рекурсивно обходим всех детей
|
|
||||||
QDomNode child = root.firstChild();
|
|
||||||
while (!child.isNull()) {
|
|
||||||
if (TransactionInfo info = parseExpandedInfoHistory2(child.toElement()); !info.bankTime.isEmpty()) {
|
|
||||||
return info;
|
|
||||||
}
|
|
||||||
child = child.nextSibling();
|
|
||||||
}
|
|
||||||
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
TransactionInfo ScreenXmlZiraatParser::parseTransactionInfoHistory(int screenWidth, int screenHeight) {
|
|
||||||
// 1. Распарсить описание транзакции
|
|
||||||
TransactionInfo transaction = parseExpandedInfoHistory2(m_xml);
|
|
||||||
// 1. Найти статус: Исполнен | Операция исполнена
|
|
||||||
transaction.status = TransactionStatus::Wait;
|
|
||||||
Node status1 = findTextNode("Исполнен", 0, 0, screenWidth, screenHeight / 2);
|
|
||||||
Node status2 = findTextNode("Операция исполнена", 0, 0, screenWidth, screenHeight / 2);
|
|
||||||
if (!status1.isEmpty() || !status2.isEmpty()) {
|
|
||||||
transaction.status = TransactionStatus::Complete;
|
|
||||||
}
|
|
||||||
return transaction;
|
|
||||||
}
|
|
||||||
|
|
||||||
TransactionInfo parseExpandedInfo2(const QDomElement &root) {
|
|
||||||
if (root.isElement()) {
|
|
||||||
QDomElement elem = root.toElement();
|
|
||||||
if (elem.tagName() == "node"
|
|
||||||
&& elem.attribute("class") == "android.widget.Button"
|
|
||||||
&& elem.attribute("text") == "Детали операции"
|
|
||||||
) {
|
|
||||||
TransactionInfo transaction;
|
|
||||||
// Все что ниже деталей операции
|
|
||||||
QDomNodeList detailInfo = elem.parentNode().childNodes();
|
|
||||||
|
|
||||||
for (int i = 0; i < detailInfo.count(); ++i) {
|
|
||||||
QDomNode info = detailInfo.at(i);
|
|
||||||
if (!info.isElement()) continue;
|
|
||||||
|
|
||||||
QDomElement infoElement = info.toElement();
|
|
||||||
QString index = infoElement.attribute("index");
|
|
||||||
QDomElement ee;
|
|
||||||
switch (index.toInt()) {
|
|
||||||
case 3:
|
|
||||||
transaction.bankTime = transformBankDateTime2(findSubInfo2(infoElement, "1"));
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
ee = findSubElement2(infoElement, "0");
|
|
||||||
ee = findSubElement2(ee, "1");
|
|
||||||
transaction.phone = findSubInfo2(ee, "0").remove(onlyDigitsRegex);
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
transaction.name = findSubInfo2(infoElement, "1");
|
|
||||||
break;
|
|
||||||
case 6:
|
|
||||||
transaction.bankName = findSubInfo2(infoElement, "1");
|
|
||||||
break;
|
|
||||||
case 9:
|
|
||||||
transaction.fee = findSubInfo2(infoElement, "1").remove(onlyDigitsAndDotRegex).toFloat();
|
|
||||||
break;
|
|
||||||
case 10:
|
|
||||||
ee = findSubElement2(infoElement, "1");
|
|
||||||
transaction.bankTrExternalId = findSubInfo2(ee, "1");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return transaction;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Рекурсивно обходим всех детей
|
|
||||||
QDomNode child = root.firstChild();
|
|
||||||
while (!child.isNull()) {
|
|
||||||
if (TransactionInfo info = parseExpandedInfo2(child.toElement()); !info.bankTime.isEmpty()) {
|
|
||||||
return info;
|
|
||||||
}
|
|
||||||
child = child.nextSibling();
|
|
||||||
}
|
|
||||||
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
TransactionInfo ScreenXmlZiraatParser::parseTransactionInfo(int screenWidth, int screenHeight) {
|
|
||||||
// 1. Распарсить описание транзакции
|
|
||||||
TransactionInfo transaction = parseExpandedInfo2(m_xml);
|
|
||||||
// 1. Найти статус: Исполнен | Операция исполнена
|
|
||||||
transaction.status = TransactionStatus::Wait;
|
|
||||||
Node status1 = findTextNode("Исполнен", 0, 0, screenWidth, screenHeight / 2);
|
|
||||||
Node status2 = findTextNode("Операция исполнена", 0, 0, screenWidth, screenHeight / 2);
|
|
||||||
if (!status1.isEmpty() || !status2.isEmpty()) {
|
|
||||||
transaction.status = TransactionStatus::Complete;
|
|
||||||
}
|
|
||||||
return transaction;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
QList<AccountInfo> ScreenXmlZiraatParser::parseAccountsInfo() {
|
|
||||||
const QDomNodeList nodes = m_xml.elementsByTagName("node");
|
|
||||||
QList<AccountInfo> accounts;
|
|
||||||
|
|
||||||
for (int i = 0; i < nodes.count(); ++i) {
|
|
||||||
const QDomElement el = nodes.at(i).toElement();
|
|
||||||
if (el.attribute("resource-id") == "com.ziraat.ziraatmobil:id/text_account_or_bank_name") {
|
|
||||||
// Нашли нужный аккаунт
|
|
||||||
const QDomElement parent = el.parentNode().toElement(); // account_name_layout
|
|
||||||
const QDomElement balanceFrame = parent.parentNode().parentNode().lastChildElement("node");
|
|
||||||
// Перебираем потомков в поисках суммы
|
|
||||||
QDomNode n = balanceFrame;
|
|
||||||
while (!n.isNull()) {
|
|
||||||
const QDomElement e = n.toElement();
|
|
||||||
if (e.attribute("resource-id") == "com.ziraat.ziraatmobil:id/text_value") {
|
|
||||||
QString amount = e.attribute("text");
|
|
||||||
QString account = el.attribute("text");
|
|
||||||
|
|
||||||
AccountInfo info;
|
|
||||||
info.lastNumbers = account;
|
|
||||||
info.amount = amount.toFloat();
|
|
||||||
info.description = account;
|
|
||||||
info.updateTime = DateUtils::getUtcNow();
|
|
||||||
|
|
||||||
accounts.append(info);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
n = n.nextSibling();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return accounts;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ScreenXmlZiraatParser::test() {
|
|
||||||
// TransactionInfo info2 = parseExpandedInfo(m_xml);
|
|
||||||
// qDebug().noquote().nospace() << convertTransactionToString(info2);
|
|
||||||
// return;
|
|
||||||
|
|
||||||
QFile file("assets/rshb/all_products.xml");
|
|
||||||
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
|
||||||
qDebug() << "Cannot open file";
|
|
||||||
}
|
|
||||||
|
|
||||||
QDomDocument doc;
|
|
||||||
if (!doc.setContent(&file)) {
|
|
||||||
qDebug() << "Failed to parse XML";
|
|
||||||
}
|
|
||||||
file.close();
|
|
||||||
|
|
||||||
qDebug() << "Start parsing XML:";
|
|
||||||
|
|
||||||
// Номер карты с последними цифрами
|
|
||||||
QDomElement root = doc.documentElement();
|
|
||||||
parseAndSaveXml(doc.toString());
|
|
||||||
// for (const AccountInfo &info: parseAccountsInfo()) {
|
|
||||||
// qDebug().noquote().nospace() << convertAccountToString(info);
|
|
||||||
// }
|
|
||||||
// TransactionInfo info = parseExpandedInfo(root);
|
|
||||||
// qDebug().noquote().nospace() << convertTransactionToString(info);
|
|
||||||
// ЕСПП
|
|
||||||
}
|
|
||||||
@ -1,56 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <QObject>
|
|
||||||
#include <QDomElement>
|
|
||||||
#include "android/xml/Node.h"
|
|
||||||
#include "db/AccountInfo.h"
|
|
||||||
#include "db/TransactionInfo.h"
|
|
||||||
|
|
||||||
class ScreenXmlZiraatParser final : public QObject {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit ScreenXmlZiraatParser(QObject *parent = nullptr);
|
|
||||||
|
|
||||||
~ScreenXmlZiraatParser() override;
|
|
||||||
|
|
||||||
Node tryToFindBannerOrDialog(int width, int height);
|
|
||||||
|
|
||||||
Node tryToFindSecurityBanner();
|
|
||||||
|
|
||||||
Node tryToFindSelectBottomSheet();
|
|
||||||
|
|
||||||
Node findAccountButton(const QString &numbers);
|
|
||||||
|
|
||||||
Node findTextNode(const QString &text);
|
|
||||||
|
|
||||||
Node findTextNode(const QString &text, int x1, int y1, int x2, int y2);
|
|
||||||
|
|
||||||
Node findEditText(const QString &text);
|
|
||||||
|
|
||||||
Node findEditTextByResourceId(const QString &resourceId);
|
|
||||||
|
|
||||||
Node findButtonNode(const QString &text, bool contains);
|
|
||||||
|
|
||||||
bool isHomeScreen();
|
|
||||||
|
|
||||||
QList<Node> getLast2DaysTransactions();
|
|
||||||
|
|
||||||
void parseAndSaveXml(const QString &xml);
|
|
||||||
|
|
||||||
TransactionInfo parseTransactionInfoHistory(int screenWidth, int screenHeight);
|
|
||||||
|
|
||||||
TransactionInfo parseTransactionInfo(int screenWidth, int screenHeight);
|
|
||||||
|
|
||||||
QList<TransactionInfo> parseTodayAndYesterdayReportHistory();
|
|
||||||
|
|
||||||
QList<AccountInfo> parseAccountsInfo();
|
|
||||||
|
|
||||||
void test();
|
|
||||||
|
|
||||||
private:
|
|
||||||
QList<Node> m_nodes;
|
|
||||||
QDomElement m_xml;
|
|
||||||
|
|
||||||
QList<Node> findPinCodeNodes(const QString &pinCode);
|
|
||||||
};
|
|
||||||
|
Before Width: | Height: | Size: 96 KiB |
|
Before Width: | Height: | Size: 697 KiB |
@ -1,124 +0,0 @@
|
|||||||
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
|
|
||||||
<hierarchy rotation="0">
|
|
||||||
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,136][1080,2337]" drawing-order="0" hint="">
|
|
||||||
<node index="0" text="" resource-id="" class="android.widget.LinearLayout" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,136][1080,2337]" drawing-order="1" hint="">
|
|
||||||
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,136][1080,2337]" drawing-order="2" hint="">
|
|
||||||
<node index="0" text="" resource-id="az.kapitalbank.mbanking:id/action_bar_root"
|
|
||||||
class="android.widget.FrameLayout" package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,136][1080,2337]" drawing-order="1" hint="">
|
|
||||||
<node index="0" text="" resource-id="android:id/content" class="android.widget.FrameLayout"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false" bounds="[0,136][1080,2337]"
|
|
||||||
drawing-order="1" hint="">
|
|
||||||
<node index="0" text="" resource-id="az.kapitalbank.mbanking:id/container"
|
|
||||||
class="android.widget.FrameLayout" package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,136][1080,2337]" drawing-order="1" hint="">
|
|
||||||
<node index="0" text="" resource-id="az.kapitalbank.mbanking:id/coordinator"
|
|
||||||
class="android.view.ViewGroup" package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,136][1080,2337]" drawing-order="1" hint="">
|
|
||||||
<node NAF="true" index="0" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/touch_outside" class="android.view.View"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="true" enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,136][1080,2337]" drawing-order="1" hint=""/>
|
|
||||||
<node index="1" text="" resource-id="az.kapitalbank.mbanking:id/design_bottom_sheet"
|
|
||||||
class="android.widget.FrameLayout" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,777][1080,2337]" drawing-order="2"
|
|
||||||
hint="">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.ViewGroup"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,777][1080,2337]" drawing-order="1" hint="">
|
|
||||||
<node index="0" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/popupImagesViewPager"
|
|
||||||
class="androidx.viewpager.widget.ViewPager"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true" focusable="true"
|
|
||||||
focused="false" scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,777][1080,1512]" drawing-order="1" hint="">
|
|
||||||
<node index="0" text="" resource-id="az.kapitalbank.mbanking:id/imageView"
|
|
||||||
class="android.widget.ImageView" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,777][1080,1512]" drawing-order="1" hint=""/>
|
|
||||||
</node>
|
|
||||||
<node index="1" text="" resource-id="az.kapitalbank.mbanking:id/vDrag"
|
|
||||||
class="android.view.View" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[488,814][593,825]" drawing-order="2" hint=""/>
|
|
||||||
<node index="2" text="Sizə xidmət göstərən filiallarımız 🗓️"
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/tvTitle"
|
|
||||||
class="android.widget.TextView" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[42,1554][1038,1741]" drawing-order="4" hint=""/>
|
|
||||||
<node index="3" text="" resource-id="" class="android.widget.ScrollView"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true" focusable="true"
|
|
||||||
focused="false" scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,1762][1080,1959]" drawing-order="5" hint="">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.ViewGroup"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,1762][1080,1959]"
|
|
||||||
drawing-order="1" hint="">
|
|
||||||
<node index="0"
|
|
||||||
text="26-27 iyul tarixlərində bankımızın müəyyən filialları saat 10:00-dan 21:45-dək öz fəaliyyətini davam etdirəcək."
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/tvDescription"
|
|
||||||
class="android.widget.TextView" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[42,1762][1038,1917]" drawing-order="2"
|
|
||||||
hint=""/>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
<node index="4" text="Ünvanların siyahısı"
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/btnPrimary"
|
|
||||||
class="android.widget.Button" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="true"
|
|
||||||
enabled="true" focusable="true" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[42,2001][1038,2148]" drawing-order="6" hint=""/>
|
|
||||||
<node index="5" text="Maraqlı deyil"
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/btnSecondary"
|
|
||||||
class="android.widget.Button" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="true"
|
|
||||||
enabled="true" focusable="true" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[42,2148][1038,2295]" drawing-order="7" hint=""/>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</hierarchy>
|
|
||||||
|
Before Width: | Height: | Size: 328 KiB |
|
Before Width: | Height: | Size: 17 KiB |
@ -1,798 +0,0 @@
|
|||||||
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
|
|
||||||
<hierarchy rotation="0">
|
|
||||||
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,0][1080,2400]" drawing-order="0" hint="">
|
|
||||||
<node index="0" text="" resource-id="" class="android.widget.LinearLayout" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,0][1080,2337]" drawing-order="1" hint="">
|
|
||||||
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,0][1080,2337]" drawing-order="2" hint="">
|
|
||||||
<node index="0" text="" resource-id="az.kapitalbank.mbanking:id/action_bar_root"
|
|
||||||
class="android.widget.LinearLayout" package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,0][1080,2337]" drawing-order="1" hint="">
|
|
||||||
<node index="0" text="" resource-id="android:id/content" class="android.widget.FrameLayout"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false" bounds="[0,0][1080,2337]"
|
|
||||||
drawing-order="2" hint="">
|
|
||||||
<node index="0" text="" resource-id="az.kapitalbank.mbanking:id/activity_drawer"
|
|
||||||
class="android.view.ViewGroup" package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,0][1080,2337]" drawing-order="1" hint="">
|
|
||||||
<node index="0" text="" resource-id="az.kapitalbank.mbanking:id/activity_screen_container"
|
|
||||||
class="android.widget.FrameLayout" package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,0][1080,2337]" drawing-order="1" hint="">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.ViewGroup"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,0][1080,2337]" drawing-order="1" hint="">
|
|
||||||
<node index="0" text="" resource-id="az.kapitalbank.mbanking:id/header"
|
|
||||||
class="android.widget.LinearLayout" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,136][1080,283]" drawing-order="2" hint="">
|
|
||||||
<node index="0" text="" resource-id="az.kapitalbank.mbanking:id/vToolbar"
|
|
||||||
class="android.view.ViewGroup" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,136][1080,283]" drawing-order="1" hint="">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.ViewGroup"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,157][1080,262]"
|
|
||||||
drawing-order="1" hint="">
|
|
||||||
<node index="0" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/ivCenteredHeaderBack"
|
|
||||||
class="android.widget.ImageView" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="Back" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="true" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[42,178][131,241]" drawing-order="1"
|
|
||||||
hint=""/>
|
|
||||||
<node index="1" text="" resource-id="az.kapitalbank.mbanking:id/ivHide"
|
|
||||||
class="android.widget.FrameLayout"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[142,157][268,262]" drawing-order="2" hint="">
|
|
||||||
<node NAF="true" index="0" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/ivHideAmounts"
|
|
||||||
class="android.widget.CheckBox"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="true" checked="false" clickable="true"
|
|
||||||
enabled="true" focusable="true" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[173,178][236,241]" drawing-order="1"
|
|
||||||
hint=""/>
|
|
||||||
</node>
|
|
||||||
<node index="2" text="" resource-id="az.kapitalbank.mbanking:id/flTitle"
|
|
||||||
class="android.widget.FrameLayout"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[370,162][711,257]" drawing-order="3" hint="">
|
|
||||||
<node index="0" text="Birbank Cashback"
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/tvTitleCentered_Header"
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[370,181][711,238]" drawing-order="2"
|
|
||||||
hint=""/>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
<node NAF="true" index="1" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/ivButtonRight"
|
|
||||||
class="android.widget.ImageView" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="true"
|
|
||||||
enabled="true" focusable="true" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[933,136][1080,283]" drawing-order="2" hint=""/>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
<node index="1" text="" resource-id="az.kapitalbank.mbanking:id/root_progress_panel"
|
|
||||||
class="android.widget.FrameLayout" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,283][1080,2337]" drawing-order="1" hint="">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.ViewGroup"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,283][1080,2337]" drawing-order="1" hint="">
|
|
||||||
<node index="0" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/refresh_layout"
|
|
||||||
class="android.view.ViewGroup" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,283][1080,2337]" drawing-order="1" hint="">
|
|
||||||
<node index="0" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/scroll_view_root"
|
|
||||||
class="android.widget.ScrollView"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="true" focused="false" scrollable="true"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,283][1080,2337]" drawing-order="1" hint="">
|
|
||||||
<node index="0" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/view_motion"
|
|
||||||
class="android.widget.LinearLayout"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,283][1080,2337]" drawing-order="1"
|
|
||||||
hint="">
|
|
||||||
<node index="0" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/cards_pager"
|
|
||||||
class="androidx.viewpager.widget.ViewPager"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="true" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,283][1080,807]"
|
|
||||||
drawing-order="9" hint="">
|
|
||||||
<node index="0" text="" resource-id=""
|
|
||||||
class="androidx.recyclerview.widget.RecyclerView"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="true" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[0,283][1080,807]" drawing-order="1" hint="">
|
|
||||||
<node index="0" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/card_motion_layout"
|
|
||||||
class="android.view.ViewGroup"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="true"
|
|
||||||
enabled="true" focusable="true" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[0,283][1080,807]" drawing-order="1"
|
|
||||||
hint="">
|
|
||||||
<node index="0" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/card_front"
|
|
||||||
class="android.view.ViewGroup"
|
|
||||||
package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="true"
|
|
||||||
enabled="true" focusable="true"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[356,364][724,594]"
|
|
||||||
drawing-order="2" hint="">
|
|
||||||
<node index="0" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/iv_lens_front"
|
|
||||||
class="android.widget.ImageView"
|
|
||||||
package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[356,364][724,594]"
|
|
||||||
drawing-order="2" hint=""/>
|
|
||||||
<node index="1" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/iv_pan_dot"
|
|
||||||
class="android.widget.ImageView"
|
|
||||||
package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[377,406][382,411]"
|
|
||||||
drawing-order="3" hint=""/>
|
|
||||||
<node index="2" text="2480"
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/tv_pan"
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[393,385][640,427]"
|
|
||||||
drawing-order="4" hint=""/>
|
|
||||||
<node index="3" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/iv_provider_type"
|
|
||||||
class="android.widget.ImageView"
|
|
||||||
package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[640,375][703,438]"
|
|
||||||
drawing-order="6" hint=""/>
|
|
||||||
<node index="4" text="Данные карты"
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/tv_card_details"
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[377,530][595,573]"
|
|
||||||
drawing-order="5" hint=""/>
|
|
||||||
<node index="5" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/card_rectangle"
|
|
||||||
class="android.widget.ImageView"
|
|
||||||
package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[409,416][672,542]"
|
|
||||||
drawing-order="8" hint=""/>
|
|
||||||
<node index="6" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/iv_more_dots"
|
|
||||||
class="android.widget.ImageView"
|
|
||||||
package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[661,531][703,573]"
|
|
||||||
drawing-order="7" hint=""/>
|
|
||||||
</node>
|
|
||||||
<node index="2" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/ll_shadow"
|
|
||||||
class="android.widget.ImageView"
|
|
||||||
package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[356,542][724,647]"
|
|
||||||
drawing-order="1" hint=""/>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
<node index="1" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/ll_balance_details"
|
|
||||||
class="android.view.ViewGroup"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[459,677][620,813]"
|
|
||||||
drawing-order="1" hint="">
|
|
||||||
<node index="0" text="0 ₼"
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/tv_balance"
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[491,713][588,813]" drawing-order="2"
|
|
||||||
hint=""/>
|
|
||||||
</node>
|
|
||||||
<node index="3" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/ll_actions"
|
|
||||||
class="android.widget.LinearLayout"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,970][1080,1263]"
|
|
||||||
drawing-order="3" hint="">
|
|
||||||
<node index="0" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/ll_action"
|
|
||||||
class="android.widget.LinearLayout"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="true"
|
|
||||||
enabled="true" focusable="true" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[42,991][360,1221]" drawing-order="1" hint="">
|
|
||||||
<node index="0" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/iv_action_icon"
|
|
||||||
class="android.widget.ImageView"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[169,1023][232,1086]"
|
|
||||||
drawing-order="1" hint=""/>
|
|
||||||
<node index="1" text="Перевести"
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/tv_action_name"
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[120,1097][281,1189]"
|
|
||||||
drawing-order="2" hint=""/>
|
|
||||||
</node>
|
|
||||||
<node index="1" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/ll_action"
|
|
||||||
class="android.widget.LinearLayout"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="true"
|
|
||||||
enabled="true" focusable="true" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[381,991][699,1221]" drawing-order="2"
|
|
||||||
hint="">
|
|
||||||
<node index="0" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/iv_action_icon"
|
|
||||||
class="android.widget.ImageView"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[508,1023][571,1086]"
|
|
||||||
drawing-order="1" hint=""/>
|
|
||||||
<node index="1" text="Платежи"
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/tv_action_name"
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[473,1097][607,1189]"
|
|
||||||
drawing-order="2" hint=""/>
|
|
||||||
</node>
|
|
||||||
<node index="2" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/ll_action"
|
|
||||||
class="android.widget.LinearLayout"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="true"
|
|
||||||
enabled="true" focusable="true" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[720,991][1038,1221]" drawing-order="3"
|
|
||||||
hint="">
|
|
||||||
<node index="0" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/iv_action_icon"
|
|
||||||
class="android.widget.ImageView"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[847,1023][910,1086]"
|
|
||||||
drawing-order="1" hint=""/>
|
|
||||||
<node index="1" text="Пополнить"
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/tv_action_name"
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[796,1097][961,1189]"
|
|
||||||
drawing-order="2" hint=""/>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
<node index="4" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/ll_pfm_widget"
|
|
||||||
class="android.view.ViewGroup"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[42,1300][1038,2290]"
|
|
||||||
drawing-order="12" hint="">
|
|
||||||
<node index="0" text="В июле потрачено: "
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/tv_pfm_title"
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[84,1342][522,1407]" drawing-order="1"
|
|
||||||
hint=""/>
|
|
||||||
<node index="1" text="16 ₼"
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/tv_pfm_title_amount"
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[522,1342][611,1407]" drawing-order="2"
|
|
||||||
hint=""/>
|
|
||||||
<node index="2" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/ll_pfm_content"
|
|
||||||
class="android.view.ViewGroup"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[42,1407][1038,2114]" drawing-order="3"
|
|
||||||
hint="">
|
|
||||||
<node index="0" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/rv_pfm_operations"
|
|
||||||
class="androidx.recyclerview.widget.RecyclerView"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="true"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[42,1428][1038,2114]"
|
|
||||||
drawing-order="2" hint="">
|
|
||||||
<node index="0" text="" resource-id=""
|
|
||||||
class="android.view.ViewGroup"
|
|
||||||
package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[84,1428][1038,1498]"
|
|
||||||
drawing-order="1" hint="">
|
|
||||||
<node index="0" text="24 июля"
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/tv_date"
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[84,1439][561,1482]"
|
|
||||||
drawing-order="2" hint=""/>
|
|
||||||
</node>
|
|
||||||
<node index="1" text="" resource-id=""
|
|
||||||
class="android.view.ViewGroup"
|
|
||||||
package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="true"
|
|
||||||
enabled="true" focusable="true"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[42,1503][1038,1671]"
|
|
||||||
drawing-order="2" hint="">
|
|
||||||
<node index="0" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/transaction_logo_bg"
|
|
||||||
class="android.widget.ImageView"
|
|
||||||
package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[84,1529][200,1645]"
|
|
||||||
drawing-order="1" hint=""/>
|
|
||||||
<node index="1" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/transaction_logo_icon"
|
|
||||||
class="android.widget.ImageView"
|
|
||||||
package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[100,1545][184,1629]"
|
|
||||||
drawing-order="2" hint=""/>
|
|
||||||
<node index="2" text="Nar・+994703262002"
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/transaction_title"
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[232,1529][834,1591]"
|
|
||||||
drawing-order="5" hint=""/>
|
|
||||||
<node index="3" text="15 ₼"
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/transaction_amount"
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[918,1529][996,1586]"
|
|
||||||
drawing-order="8" hint=""/>
|
|
||||||
<node index="4" text="0:35"
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/transaction_time"
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[232,1596][294,1639]"
|
|
||||||
drawing-order="6" hint=""/>
|
|
||||||
<node index="5" text="・Связь"
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/transaction_category"
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[294,1594][996,1642]"
|
|
||||||
drawing-order="7" hint=""/>
|
|
||||||
</node>
|
|
||||||
<node index="2" text="" resource-id=""
|
|
||||||
class="android.view.ViewGroup"
|
|
||||||
package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="true"
|
|
||||||
enabled="true" focusable="true"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[42,1681][1038,1890]"
|
|
||||||
drawing-order="3" hint="">
|
|
||||||
<node index="0" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/transaction_logo_bg"
|
|
||||||
class="android.widget.ImageView"
|
|
||||||
package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[84,1707][200,1823]"
|
|
||||||
drawing-order="1" hint=""/>
|
|
||||||
<node index="1" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/transaction_logo_icon"
|
|
||||||
class="android.widget.ImageView"
|
|
||||||
package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[100,1723][184,1807]"
|
|
||||||
drawing-order="2" hint=""/>
|
|
||||||
<node index="2"
|
|
||||||
text="Проверка привязки карты в Birbank"
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/transaction_title"
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[232,1707][737,1816]"
|
|
||||||
drawing-order="5" hint=""/>
|
|
||||||
<node index="3" text="+0,05 ₼"
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/transaction_amount"
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[821,1707][996,1764]"
|
|
||||||
drawing-order="8" hint=""/>
|
|
||||||
<node index="4" text="Bозврат"
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/transaction_cashback"
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[874,1769][996,1812]"
|
|
||||||
drawing-order="10" hint=""/>
|
|
||||||
<node index="5" text="0:31"
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/transaction_time"
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[232,1821][294,1864]"
|
|
||||||
drawing-order="6" hint=""/>
|
|
||||||
<node index="6" text="・Коммуналка"
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/transaction_category"
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[294,1819][874,1867]"
|
|
||||||
drawing-order="7" hint=""/>
|
|
||||||
</node>
|
|
||||||
<node index="3" text="" resource-id=""
|
|
||||||
class="android.view.ViewGroup"
|
|
||||||
package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="true"
|
|
||||||
enabled="true" focusable="true"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[42,1900][1038,2109]"
|
|
||||||
drawing-order="4" hint="">
|
|
||||||
<node index="0" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/transaction_logo_bg"
|
|
||||||
class="android.widget.ImageView"
|
|
||||||
package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[84,1926][200,2042]"
|
|
||||||
drawing-order="1" hint=""/>
|
|
||||||
<node index="1" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/transaction_logo_icon"
|
|
||||||
class="android.widget.ImageView"
|
|
||||||
package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[100,1942][184,2026]"
|
|
||||||
drawing-order="2" hint=""/>
|
|
||||||
<node index="2"
|
|
||||||
text="Проверка привязки карты в Birbank"
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/transaction_title"
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[232,1926][813,2035]"
|
|
||||||
drawing-order="5" hint=""/>
|
|
||||||
<node index="3" text="0,05 ₼"
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/transaction_amount"
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[897,1926][996,1983]"
|
|
||||||
drawing-order="8" hint=""/>
|
|
||||||
<node index="4" text="0:31"
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/transaction_time"
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[232,2040][294,2083]"
|
|
||||||
drawing-order="6" hint=""/>
|
|
||||||
<node index="5" text="・Коммуналка"
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/transaction_category"
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[294,2038][996,2086]"
|
|
||||||
drawing-order="7" hint=""/>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
<node index="3" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/spr_tv_pfm_operation_history"
|
|
||||||
class="android.view.View"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[84,2140][996,2143]" drawing-order="4"
|
|
||||||
hint=""/>
|
|
||||||
<node index="4" text="История платежей"
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/tv_pfm_operation_history"
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="true"
|
|
||||||
enabled="true" focusable="true" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[42,2143][1038,2290]" drawing-order="5"
|
|
||||||
hint=""/>
|
|
||||||
</node>
|
|
||||||
<node index="5" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/pager_actions"
|
|
||||||
class="androidx.recyclerview.widget.RecyclerView"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="true" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,2311][1080,2337]"
|
|
||||||
drawing-order="8" hint="">
|
|
||||||
<node index="0" text="" resource-id=""
|
|
||||||
class="android.widget.FrameLayout"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="true"
|
|
||||||
enabled="true" focusable="true" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[0,2311][1080,2337]" drawing-order="1"
|
|
||||||
hint=""/>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
<node index="1" text="" resource-id="android:id/navigationBarBackground" class="android.view.View"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc="" checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,2337][1080,2400]" drawing-order="2" hint=""/>
|
|
||||||
</node>
|
|
||||||
</hierarchy>
|
|
||||||
|
Before Width: | Height: | Size: 220 KiB |
|
Before Width: | Height: | Size: 65 KiB |
@ -1,188 +0,0 @@
|
|||||||
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
|
|
||||||
<hierarchy rotation="0">
|
|
||||||
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,0][1080,2400]" drawing-order="0" hint="">
|
|
||||||
<node index="0" text="" resource-id="" class="android.widget.LinearLayout" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,0][1080,2337]" drawing-order="1" hint="">
|
|
||||||
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,0][1080,2337]" drawing-order="2" hint="">
|
|
||||||
<node index="0" text="" resource-id="az.kapitalbank.mbanking:id/action_bar_root"
|
|
||||||
class="android.widget.LinearLayout" package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,0][1080,2337]" drawing-order="1" hint="">
|
|
||||||
<node index="0" text="" resource-id="android:id/content" class="android.widget.FrameLayout"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false" bounds="[0,0][1080,2337]"
|
|
||||||
drawing-order="2" hint="">
|
|
||||||
<node index="0" text="" resource-id="az.kapitalbank.mbanking:id/lyCord"
|
|
||||||
class="android.view.ViewGroup" package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,0][1080,2337]" drawing-order="1" hint="">
|
|
||||||
<node index="0" text="" resource-id="az.kapitalbank.mbanking:id/rootView"
|
|
||||||
class="android.view.ViewGroup" package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,136][1080,2337]" drawing-order="1" hint="">
|
|
||||||
<node index="0" text="" resource-id="az.kapitalbank.mbanking:id/authContainer"
|
|
||||||
class="android.widget.FrameLayout" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,136][1080,2337]" drawing-order="2"
|
|
||||||
hint="">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.ViewGroup"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,136][1080,2337]" drawing-order="1" hint="">
|
|
||||||
<node index="0" text="" resource-id="az.kapitalbank.mbanking:id/ivLogo"
|
|
||||||
class="android.widget.ImageView" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[387,273][694,386]" drawing-order="1" hint=""/>
|
|
||||||
<node index="1" text="" resource-id="az.kapitalbank.mbanking:id/ivAvatar"
|
|
||||||
class="android.widget.ImageView" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[467,470][614,617]" drawing-order="2" hint=""/>
|
|
||||||
<node index="2" text="Добрый день"
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/tvGreeting"
|
|
||||||
class="android.widget.TextView" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,659][1080,716]" drawing-order="3" hint=""/>
|
|
||||||
<node index="3" text="Nicat Cəlilov"
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/tvUsername"
|
|
||||||
class="android.widget.TextView" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,721][1080,792]" drawing-order="4" hint=""/>
|
|
||||||
<node index="4" text="" resource-id="az.kapitalbank.mbanking:id/dsPasscodeInput"
|
|
||||||
class="android.view.ViewGroup" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[42,1042][1038,1097]" drawing-order="5" hint="">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.ViewGroup"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[42,1042][1038,1097]"
|
|
||||||
drawing-order="1" hint="">
|
|
||||||
<node index="0" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/passcode_first"
|
|
||||||
class="android.view.View" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[42,1042][1038,1097]" drawing-order="2"
|
|
||||||
hint=""/>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
<node index="5" text="" resource-id="az.kapitalbank.mbanking:id/dsNumpad"
|
|
||||||
class="android.view.ViewGroup" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,1347][1080,2190]" drawing-order="10" hint="">
|
|
||||||
<node index="0" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/dsNumpadRecycler"
|
|
||||||
class="android.widget.GridView" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="true" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[42,1559][1038,2190]" drawing-order="1" hint="">
|
|
||||||
<node index="0" text="1" resource-id="" class="android.widget.TextView"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="true" enabled="true"
|
|
||||||
focusable="true" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[42,1559][353,1701]" drawing-order="1" hint=""/>
|
|
||||||
<node index="1" text="2" resource-id="" class="android.widget.TextView"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="true" enabled="true"
|
|
||||||
focusable="true" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[395,1559][685,1701]" drawing-order="2" hint=""/>
|
|
||||||
<node index="2" text="3" resource-id="" class="android.widget.TextView"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="true" enabled="true"
|
|
||||||
focusable="true" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[727,1559][1038,1701]" drawing-order="3" hint=""/>
|
|
||||||
<node index="3" text="4" resource-id="" class="android.widget.TextView"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="true" enabled="true"
|
|
||||||
focusable="true" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[42,1721][353,1863]" drawing-order="4" hint=""/>
|
|
||||||
<node index="4" text="5" resource-id="" class="android.widget.TextView"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="true" enabled="true"
|
|
||||||
focusable="true" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[395,1721][685,1863]" drawing-order="5" hint=""/>
|
|
||||||
<node index="5" text="6" resource-id="" class="android.widget.TextView"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="true" enabled="true"
|
|
||||||
focusable="true" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[727,1721][1038,1863]" drawing-order="6" hint=""/>
|
|
||||||
<node index="6" text="7" resource-id="" class="android.widget.TextView"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="true" enabled="true"
|
|
||||||
focusable="true" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[42,1883][353,2025]" drawing-order="7" hint=""/>
|
|
||||||
<node index="7" text="8" resource-id="" class="android.widget.TextView"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="true" enabled="true"
|
|
||||||
focusable="true" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[395,1883][685,2025]" drawing-order="8" hint=""/>
|
|
||||||
<node index="8" text="9" resource-id="" class="android.widget.TextView"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="true" enabled="true"
|
|
||||||
focusable="true" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[727,1883][1038,2025]" drawing-order="9" hint=""/>
|
|
||||||
<node index="9" text="Не удается войти" resource-id=""
|
|
||||||
class="android.widget.TextView" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="true"
|
|
||||||
enabled="true" focusable="true" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[42,2045][353,2187]" drawing-order="10" hint=""/>
|
|
||||||
<node index="10" text="0" resource-id="" class="android.widget.TextView"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="true" enabled="true"
|
|
||||||
focusable="true" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[395,2045][685,2187]" drawing-order="11" hint=""/>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
<node index="1" text="" resource-id="android:id/navigationBarBackground" class="android.view.View"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc="" checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,2337][1080,2400]" drawing-order="2" hint=""/>
|
|
||||||
</node>
|
|
||||||
</hierarchy>
|
|
||||||
|
Before Width: | Height: | Size: 16 KiB |
@ -1,800 +0,0 @@
|
|||||||
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
|
|
||||||
<hierarchy rotation="0">
|
|
||||||
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,0][1080,2400]" drawing-order="0" hint="">
|
|
||||||
<node index="0" text="" resource-id="" class="android.widget.LinearLayout" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,0][1080,2400]" drawing-order="1" hint="">
|
|
||||||
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,0][1080,2400]" drawing-order="2" hint="">
|
|
||||||
<node index="0" text="" resource-id="az.kapitalbank.mbanking:id/action_bar_root"
|
|
||||||
class="android.widget.LinearLayout" package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,0][1080,2400]" drawing-order="1" hint="">
|
|
||||||
<node index="0" text="" resource-id="android:id/content" class="android.widget.FrameLayout"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false" bounds="[0,0][1080,2400]"
|
|
||||||
drawing-order="2" hint="">
|
|
||||||
<node index="0" text="" resource-id="az.kapitalbank.mbanking:id/activity_drawer"
|
|
||||||
class="android.view.ViewGroup" package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,0][1080,2400]" drawing-order="1" hint="">
|
|
||||||
<node index="0" text="" resource-id="az.kapitalbank.mbanking:id/activity_screen_container"
|
|
||||||
class="android.widget.FrameLayout" package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,0][1080,2337]" drawing-order="1" hint="">
|
|
||||||
<node index="0" text="" resource-id="az.kapitalbank.mbanking:id/root_progress_panel"
|
|
||||||
class="android.widget.FrameLayout" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,0][1080,2337]" drawing-order="1"
|
|
||||||
hint="">
|
|
||||||
<node index="0" text="" resource-id="az.kapitalbank.mbanking:id/transfers"
|
|
||||||
class="android.view.ViewGroup" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,0][1080,2337]" drawing-order="1" hint="">
|
|
||||||
<node index="0" text="" resource-id="az.kapitalbank.mbanking:id/header"
|
|
||||||
class="android.widget.LinearLayout" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="true"
|
|
||||||
enabled="true" focusable="true" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,0][1080,347]" drawing-order="1" hint="">
|
|
||||||
<node index="0" text="" resource-id="az.kapitalbank.mbanking:id/back_layout"
|
|
||||||
class="android.view.ViewGroup" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,0][1080,226]" drawing-order="1" hint="">
|
|
||||||
<node index="0" text="" resource-id=""
|
|
||||||
class="android.widget.LinearLayout"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,79][1080,226]" drawing-order="1" hint="">
|
|
||||||
<node index="0" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/header_back"
|
|
||||||
class="android.widget.ImageView"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc="Back"
|
|
||||||
checkable="false" checked="false" clickable="true"
|
|
||||||
enabled="true" focusable="true" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,79][147,226]" drawing-order="1"
|
|
||||||
hint=""/>
|
|
||||||
<node index="1" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/header_right"
|
|
||||||
class="android.widget.ImageView"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc="Back"
|
|
||||||
checkable="false" checked="false" clickable="true"
|
|
||||||
enabled="true" focusable="true" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[933,79][1080,226]" drawing-order="6"
|
|
||||||
hint=""/>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
<node index="1" text="На карту любого банка"
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/title"
|
|
||||||
class="android.widget.TextView" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[42,226][851,326]" drawing-order="2" hint=""/>
|
|
||||||
</node>
|
|
||||||
<node index="1" text="" resource-id="az.kapitalbank.mbanking:id/body"
|
|
||||||
class="android.widget.ScrollView" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="true" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,347][1080,2122]" drawing-order="2" hint="">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.ViewGroup"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,347][1080,2038]"
|
|
||||||
drawing-order="1" hint="">
|
|
||||||
<node index="1" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/group_details"
|
|
||||||
class="android.view.View" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,347][1080,2038]" drawing-order="7"
|
|
||||||
hint=""/>
|
|
||||||
<node index="2" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/source_container"
|
|
||||||
class="android.widget.FrameLayout"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,368][1080,716]" drawing-order="3" hint="">
|
|
||||||
<node index="0" text="" resource-id=""
|
|
||||||
class="android.widget.FrameLayout"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,368][1080,716]" drawing-order="1"
|
|
||||||
hint="">
|
|
||||||
<node index="0" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/product_view"
|
|
||||||
class="android.view.ViewGroup"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="true"
|
|
||||||
enabled="true" focusable="true" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,368][1080,716]"
|
|
||||||
drawing-order="1" hint="">
|
|
||||||
<node index="0" text="" resource-id=""
|
|
||||||
class="android.view.ViewGroup"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[0,368][1080,716]" drawing-order="1" hint="">
|
|
||||||
<node index="0" text="Оплатить с"
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/title"
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[42,411][248,464]"
|
|
||||||
drawing-order="1" hint=""/>
|
|
||||||
<node index="1" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/container_product"
|
|
||||||
class="android.widget.FrameLayout"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[42,506][1038,674]"
|
|
||||||
drawing-order="3" hint="">
|
|
||||||
<node index="0" text="" resource-id=""
|
|
||||||
class="androidx.cardview.widget.CardView"
|
|
||||||
package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[42,506][1038,674]"
|
|
||||||
drawing-order="1" hint="">
|
|
||||||
<node index="0" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/clContainer"
|
|
||||||
class="android.view.ViewGroup"
|
|
||||||
package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[42,506][1038,674]"
|
|
||||||
drawing-order="1" hint="">
|
|
||||||
<node index="0" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/card"
|
|
||||||
class="android.view.ViewGroup"
|
|
||||||
package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[74,546][210,635]"
|
|
||||||
drawing-order="1" hint="">
|
|
||||||
<node index="1" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/iv_card"
|
|
||||||
class="android.widget.ImageView"
|
|
||||||
package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="TODO"
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false"
|
|
||||||
scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[74,546][210,635]"
|
|
||||||
drawing-order="2" hint=""/>
|
|
||||||
<node index="2" text="• 2480"
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/card_text"
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[139,598][199,627]"
|
|
||||||
drawing-order="4" hint=""/>
|
|
||||||
</node>
|
|
||||||
<node index="1" text="Birbank Cashback"
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/tv_card_name"
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[242,538][932,581]"
|
|
||||||
drawing-order="2" hint=""/>
|
|
||||||
<node index="2" text="50.00 AZN"
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/tv_card_balance"
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[242,591][932,642]"
|
|
||||||
drawing-order="4" hint=""/>
|
|
||||||
<node index="3" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/iv_selection"
|
|
||||||
class="android.widget.ImageView"
|
|
||||||
package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[964,569][1006,611]"
|
|
||||||
drawing-order="7" hint=""/>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
<node index="3" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/destination_container"
|
|
||||||
class="android.widget.FrameLayout"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,716][1080,996]" drawing-order="4" hint="">
|
|
||||||
<node index="0" text="" resource-id=""
|
|
||||||
class="android.view.ViewGroup"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,716][1080,996]" drawing-order="1"
|
|
||||||
hint="">
|
|
||||||
<node index="0" text="Зачислить на"
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/title"
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[42,758][289,822]"
|
|
||||||
drawing-order="1" hint=""/>
|
|
||||||
<node NAF="true" index="1" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/flow_suggestion"
|
|
||||||
class="android.view.View"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="true"
|
|
||||||
enabled="true" focusable="true" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[598,737][1038,821]"
|
|
||||||
drawing-order="3" hint=""/>
|
|
||||||
<node index="2" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/iv_suggestion"
|
|
||||||
class="android.widget.ImageView"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc="TODO"
|
|
||||||
checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[630,758][672,800]"
|
|
||||||
drawing-order="4" hint=""/>
|
|
||||||
<node index="3" text="Выбрать получателя"
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/tv_suggestion"
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[693,758][1006,801]"
|
|
||||||
drawing-order="5" hint=""/>
|
|
||||||
<node index="4" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/card_view"
|
|
||||||
class="android.widget.LinearLayout"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,822][1080,996]"
|
|
||||||
drawing-order="2" hint="">
|
|
||||||
<node index="0" text="" resource-id=""
|
|
||||||
class="android.widget.LinearLayout"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[0,822][1080,996]" drawing-order="1" hint="">
|
|
||||||
<node index="0" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/card_number"
|
|
||||||
class="android.widget.LinearLayout"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,822][1080,996]"
|
|
||||||
drawing-order="2" hint="">
|
|
||||||
<node index="0" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/root"
|
|
||||||
class="android.widget.LinearLayout"
|
|
||||||
package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[42,822][1038,996]"
|
|
||||||
drawing-order="1" hint="">
|
|
||||||
<node index="0" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/card"
|
|
||||||
class="androidx.cardview.widget.CardView"
|
|
||||||
package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[42,833][1038,985]"
|
|
||||||
drawing-order="3" hint="">
|
|
||||||
<node index="0" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/input_container"
|
|
||||||
class="android.widget.LinearLayout"
|
|
||||||
package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[42,833][1038,985]"
|
|
||||||
drawing-order="1" hint="">
|
|
||||||
<node index="0" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/input_layout"
|
|
||||||
class="android.widget.LinearLayout"
|
|
||||||
package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[42,833][1038,985]"
|
|
||||||
drawing-order="2" hint="">
|
|
||||||
<node index="0" text=""
|
|
||||||
resource-id=""
|
|
||||||
class="android.widget.FrameLayout"
|
|
||||||
package="az.kapitalbank.mbanking"
|
|
||||||
content-desc=""
|
|
||||||
checkable="false"
|
|
||||||
checked="false"
|
|
||||||
clickable="false"
|
|
||||||
enabled="true"
|
|
||||||
focusable="false"
|
|
||||||
focused="false"
|
|
||||||
scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[42,833][1038,985]"
|
|
||||||
drawing-order="1" hint="">
|
|
||||||
<node index="0"
|
|
||||||
text="Номер карты"
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/value"
|
|
||||||
class="android.widget.EditText"
|
|
||||||
package="az.kapitalbank.mbanking"
|
|
||||||
content-desc=""
|
|
||||||
checkable="false"
|
|
||||||
checked="false"
|
|
||||||
clickable="true"
|
|
||||||
enabled="true"
|
|
||||||
focusable="true"
|
|
||||||
focused="false"
|
|
||||||
scrollable="false"
|
|
||||||
long-clickable="true"
|
|
||||||
password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[42,833][1038,985]"
|
|
||||||
drawing-order="1"
|
|
||||||
hint="Номер карты"/>
|
|
||||||
<node index="1" text=""
|
|
||||||
resource-id=""
|
|
||||||
class="android.widget.LinearLayout"
|
|
||||||
package="az.kapitalbank.mbanking"
|
|
||||||
content-desc=""
|
|
||||||
checkable="false"
|
|
||||||
checked="false"
|
|
||||||
clickable="false"
|
|
||||||
enabled="true"
|
|
||||||
focusable="false"
|
|
||||||
focused="false"
|
|
||||||
scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[901,833][1038,985]"
|
|
||||||
drawing-order="3" hint="">
|
|
||||||
<node index="0" text=""
|
|
||||||
resource-id=""
|
|
||||||
class="android.widget.FrameLayout"
|
|
||||||
package="az.kapitalbank.mbanking"
|
|
||||||
content-desc=""
|
|
||||||
checkable="false"
|
|
||||||
checked="false"
|
|
||||||
clickable="false"
|
|
||||||
enabled="true"
|
|
||||||
focusable="false"
|
|
||||||
focused="false"
|
|
||||||
scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[901,833][1038,985]"
|
|
||||||
drawing-order="2"
|
|
||||||
hint="">
|
|
||||||
<node NAF="true"
|
|
||||||
index="0" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/text_input_end_icon"
|
|
||||||
class="android.widget.ImageButton"
|
|
||||||
package="az.kapitalbank.mbanking"
|
|
||||||
content-desc=""
|
|
||||||
checkable="false"
|
|
||||||
checked="false"
|
|
||||||
clickable="true"
|
|
||||||
enabled="true"
|
|
||||||
focusable="true"
|
|
||||||
focused="false"
|
|
||||||
scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[912,846][1038,972]"
|
|
||||||
drawing-order="1"
|
|
||||||
hint=""/>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
<node index="4" text="Детали перевода"
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/details_title"
|
|
||||||
class="android.widget.TextView" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[42,1038][363,1091]" drawing-order="8"
|
|
||||||
hint=""/>
|
|
||||||
<node index="5" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/amount_view"
|
|
||||||
class="android.widget.LinearLayout"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,1102][1080,1535]" drawing-order="10" hint="">
|
|
||||||
<node index="0" text="" resource-id=""
|
|
||||||
class="android.view.ViewGroup"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,1102][1080,1535]"
|
|
||||||
drawing-order="1" hint="">
|
|
||||||
<node index="0" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/amount"
|
|
||||||
class="android.widget.LinearLayout"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="true"
|
|
||||||
enabled="true" focusable="true" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,1102][739,1330]"
|
|
||||||
drawing-order="4" hint="">
|
|
||||||
<node index="0" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/root"
|
|
||||||
class="android.widget.LinearLayout"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[42,1102][718,1330]" drawing-order="1"
|
|
||||||
hint="">
|
|
||||||
<node index="0" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/card"
|
|
||||||
class="androidx.cardview.widget.CardView"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[42,1113][718,1265]"
|
|
||||||
drawing-order="3" hint="">
|
|
||||||
<node index="0" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/input_container"
|
|
||||||
class="android.widget.LinearLayout"
|
|
||||||
package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[42,1113][718,1265]"
|
|
||||||
drawing-order="1" hint="">
|
|
||||||
<node index="0" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/input_layout"
|
|
||||||
class="android.widget.LinearLayout"
|
|
||||||
package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[42,1113][718,1265]"
|
|
||||||
drawing-order="2" hint="">
|
|
||||||
<node index="0" text="" resource-id=""
|
|
||||||
class="android.widget.FrameLayout"
|
|
||||||
package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[42,1113][718,1265]"
|
|
||||||
drawing-order="1" hint="">
|
|
||||||
<node index="0" text="Сумма"
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/value"
|
|
||||||
class="android.widget.EditText"
|
|
||||||
package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="true"
|
|
||||||
enabled="true" focusable="true"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="true"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[42,1113][718,1265]"
|
|
||||||
drawing-order="1" hint="Сумма"/>
|
|
||||||
<node index="1" text="" resource-id=""
|
|
||||||
class="android.widget.LinearLayout"
|
|
||||||
package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[581,1113][718,1265]"
|
|
||||||
drawing-order="3" hint="">
|
|
||||||
<node index="0" text=""
|
|
||||||
resource-id=""
|
|
||||||
class="android.widget.FrameLayout"
|
|
||||||
package="az.kapitalbank.mbanking"
|
|
||||||
content-desc=""
|
|
||||||
checkable="false"
|
|
||||||
checked="false"
|
|
||||||
clickable="false"
|
|
||||||
enabled="true"
|
|
||||||
focusable="false"
|
|
||||||
focused="false"
|
|
||||||
scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[581,1113][718,1265]"
|
|
||||||
drawing-order="2" hint="">
|
|
||||||
<node index="0" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/text_input_end_icon"
|
|
||||||
class="android.widget.ImageButton"
|
|
||||||
package="az.kapitalbank.mbanking"
|
|
||||||
content-desc=""
|
|
||||||
checkable="false"
|
|
||||||
checked="false"
|
|
||||||
clickable="false"
|
|
||||||
enabled="true"
|
|
||||||
focusable="false"
|
|
||||||
focused="false"
|
|
||||||
scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[592,1126][718,1252]"
|
|
||||||
drawing-order="1"
|
|
||||||
hint=""/>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
<node index="1" text="Mин: 0.01AZN, Макс: 50.00AZN"
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/helper"
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[47,1276][557,1319]"
|
|
||||||
drawing-order="1" hint=""/>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
<node index="1" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/currency_view"
|
|
||||||
class="android.widget.FrameLayout"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="true"
|
|
||||||
enabled="true" focusable="true" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[739,1113][1038,1265]"
|
|
||||||
drawing-order="6" hint="">
|
|
||||||
<node index="0" text="" resource-id=""
|
|
||||||
class="android.view.ViewGroup"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[739,1113][1038,1265]" drawing-order="1"
|
|
||||||
hint="">
|
|
||||||
<node index="0" text="" resource-id=""
|
|
||||||
class="android.widget.LinearLayout"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[781,1139][954,1240]"
|
|
||||||
drawing-order="1" hint="">
|
|
||||||
<node index="0" text="Валюта"
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/title_view"
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[781,1139][895,1182]"
|
|
||||||
drawing-order="1" hint=""/>
|
|
||||||
<node index="1" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/spinner"
|
|
||||||
class="android.widget.Spinner"
|
|
||||||
package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="true"
|
|
||||||
enabled="true" focusable="true"
|
|
||||||
focused="false" scrollable="true"
|
|
||||||
long-clickable="true" password="false"
|
|
||||||
selected="false" bounds="[781,1187][954,1240]"
|
|
||||||
drawing-order="3" hint="">
|
|
||||||
<node index="0" text="AZN"
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/text"
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[781,1187][954,1240]"
|
|
||||||
drawing-order="1" hint=""/>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
<node index="1" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/dropdown_icon"
|
|
||||||
class="android.widget.ImageView"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[954,1168][996,1210]"
|
|
||||||
drawing-order="2" hint=""/>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
<node index="2" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/fixed_buttons"
|
|
||||||
class="android.widget.LinearLayout"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,1330][1080,1519]"
|
|
||||||
drawing-order="5" hint="">
|
|
||||||
<node index="0" text="10"
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/pay_button"
|
|
||||||
class="android.widget.Button"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="true"
|
|
||||||
enabled="true" focusable="true" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[42,1351][346,1498]" drawing-order="1"
|
|
||||||
hint=""/>
|
|
||||||
<node index="1" text="20"
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/pay_button"
|
|
||||||
class="android.widget.Button"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="true"
|
|
||||||
enabled="true" focusable="true" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[388,1351][692,1498]" drawing-order="2"
|
|
||||||
hint=""/>
|
|
||||||
<node index="2" text="50"
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/pay_button"
|
|
||||||
class="android.widget.Button"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="true"
|
|
||||||
enabled="true" focusable="true" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[734,1351][1038,1498]" drawing-order="3"
|
|
||||||
hint=""/>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
<node index="2" text="" resource-id="" class="android.widget.ImageView"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,2059][1080,2143]" drawing-order="3" hint=""/>
|
|
||||||
<node index="3" text="Продолжить" resource-id="az.kapitalbank.mbanking:id/next"
|
|
||||||
class="android.widget.Button" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="true"
|
|
||||||
enabled="false" focusable="true" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[42,2143][1038,2295]" drawing-order="6" hint=""/>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</hierarchy>
|
|
||||||
|
Before Width: | Height: | Size: 100 KiB |
@ -1,719 +0,0 @@
|
|||||||
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
|
|
||||||
<hierarchy rotation="0">
|
|
||||||
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,0][1080,2400]" drawing-order="0" hint="">
|
|
||||||
<node index="0" text="" resource-id="" class="android.widget.LinearLayout" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,0][1080,2400]" drawing-order="1" hint="">
|
|
||||||
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,0][1080,2400]" drawing-order="2" hint="">
|
|
||||||
<node index="0" text="" resource-id="az.kapitalbank.mbanking:id/action_bar_root"
|
|
||||||
class="android.widget.LinearLayout" package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,0][1080,2400]" drawing-order="1" hint="">
|
|
||||||
<node index="0" text="" resource-id="android:id/content" class="android.widget.FrameLayout"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false" bounds="[0,0][1080,2400]"
|
|
||||||
drawing-order="2" hint="">
|
|
||||||
<node index="0" text="" resource-id="az.kapitalbank.mbanking:id/activity_drawer"
|
|
||||||
class="android.view.ViewGroup" package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,0][1080,2400]" drawing-order="1" hint="">
|
|
||||||
<node index="0" text="" resource-id="az.kapitalbank.mbanking:id/activity_screen_container"
|
|
||||||
class="android.widget.FrameLayout" package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,0][1080,2158]" drawing-order="1" hint="">
|
|
||||||
<node index="0" text="" resource-id="az.kapitalbank.mbanking:id/root_progress_panel"
|
|
||||||
class="android.widget.FrameLayout" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,0][1080,2158]" drawing-order="1"
|
|
||||||
hint="">
|
|
||||||
<node index="0" text="" resource-id="" class="android.widget.LinearLayout"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,0][1080,2158]" drawing-order="1" hint="">
|
|
||||||
<node index="0" text="" resource-id="az.kapitalbank.mbanking:id/header"
|
|
||||||
class="android.view.ViewGroup" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,0][1080,226]" drawing-order="1" hint="">
|
|
||||||
<node index="0" text="" resource-id="" class="android.widget.LinearLayout"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,79][1080,226]"
|
|
||||||
drawing-order="1" hint="">
|
|
||||||
<node index="0" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/header_back"
|
|
||||||
class="android.widget.ImageView" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="Back" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="true" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,79][147,226]" drawing-order="1"
|
|
||||||
hint=""/>
|
|
||||||
<node index="1" text="Переводы"
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/header_text"
|
|
||||||
class="android.widget.TextView" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[147,79][918,226]" drawing-order="4"
|
|
||||||
hint=""/>
|
|
||||||
<node index="2" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/header_text_one"
|
|
||||||
class="android.widget.TextView" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[918,79][995,226]" drawing-order="5"
|
|
||||||
hint=""/>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
<node index="1" text="" resource-id="az.kapitalbank.mbanking:id/rvCategories"
|
|
||||||
class="androidx.recyclerview.widget.RecyclerView"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true" focusable="true"
|
|
||||||
focused="false" scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,247][1080,1087]" drawing-order="2" hint="">
|
|
||||||
<node index="0" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/cellCategory"
|
|
||||||
class="android.view.ViewGroup" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="true"
|
|
||||||
enabled="true" focusable="true" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,247][1080,415]" drawing-order="1" hint="">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.ViewGroup"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,247][1080,415]" drawing-order="1" hint="">
|
|
||||||
<node index="0" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/flow_start_images"
|
|
||||||
class="android.view.View" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[42,268][200,394]"
|
|
||||||
drawing-order="3" hint=""/>
|
|
||||||
<node index="1" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/iv_start_icon_field_l"
|
|
||||||
class="android.widget.FrameLayout"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[42,268][168,394]" drawing-order="1"
|
|
||||||
hint="">
|
|
||||||
<node index="0" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/iv_start_icon_l"
|
|
||||||
class="android.widget.ImageView"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[42,268][167,393]"
|
|
||||||
drawing-order="1" hint=""/>
|
|
||||||
</node>
|
|
||||||
<node index="2" text="Между моими картами и счетами"
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/tv_header"
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[200,307][922,356]" drawing-order="4"
|
|
||||||
hint=""/>
|
|
||||||
<node index="3" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/flow_center_text"
|
|
||||||
class="android.view.View" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[200,307][922,356]"
|
|
||||||
drawing-order="6" hint=""/>
|
|
||||||
<node index="4" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/iv_end_icon"
|
|
||||||
class="android.widget.ImageView"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[933,279][1017,384]"
|
|
||||||
drawing-order="10" hint=""/>
|
|
||||||
<node index="5" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/flow_end_items"
|
|
||||||
class="android.view.View" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[933,279][1017,384]"
|
|
||||||
drawing-order="13" hint=""/>
|
|
||||||
<node index="6" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/separator"
|
|
||||||
class="android.view.View" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[168,412][1038,415]"
|
|
||||||
drawing-order="14" hint=""/>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
<node index="1" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/cellCategory"
|
|
||||||
class="android.view.ViewGroup" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="true"
|
|
||||||
enabled="true" focusable="true" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,415][1080,583]" drawing-order="2" hint="">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.ViewGroup"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,415][1080,583]" drawing-order="1" hint="">
|
|
||||||
<node index="0" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/flow_start_images"
|
|
||||||
class="android.view.View" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[42,436][200,562]"
|
|
||||||
drawing-order="3" hint=""/>
|
|
||||||
<node index="1" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/iv_start_icon_field_l"
|
|
||||||
class="android.widget.FrameLayout"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[42,436][168,562]" drawing-order="1"
|
|
||||||
hint="">
|
|
||||||
<node index="0" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/iv_start_icon_l"
|
|
||||||
class="android.widget.ImageView"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[42,436][167,561]"
|
|
||||||
drawing-order="1" hint=""/>
|
|
||||||
</node>
|
|
||||||
<node index="2" text="На карту любого банка"
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/tv_header"
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[200,475][922,524]" drawing-order="4"
|
|
||||||
hint=""/>
|
|
||||||
<node index="3" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/flow_center_text"
|
|
||||||
class="android.view.View" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[200,475][922,524]"
|
|
||||||
drawing-order="6" hint=""/>
|
|
||||||
<node index="4" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/iv_end_icon"
|
|
||||||
class="android.widget.ImageView"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[933,447][1017,552]"
|
|
||||||
drawing-order="10" hint=""/>
|
|
||||||
<node index="5" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/flow_end_items"
|
|
||||||
class="android.view.View" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[933,447][1017,552]"
|
|
||||||
drawing-order="13" hint=""/>
|
|
||||||
<node index="6" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/separator"
|
|
||||||
class="android.view.View" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[168,580][1038,583]"
|
|
||||||
drawing-order="14" hint=""/>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
<node index="2" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/cellCategory"
|
|
||||||
class="android.view.ViewGroup" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="true"
|
|
||||||
enabled="true" focusable="true" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,583][1080,751]" drawing-order="3" hint="">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.ViewGroup"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,583][1080,751]" drawing-order="1" hint="">
|
|
||||||
<node index="0" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/flow_start_images"
|
|
||||||
class="android.view.View" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[42,604][200,730]"
|
|
||||||
drawing-order="3" hint=""/>
|
|
||||||
<node index="1" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/iv_start_icon_field_l"
|
|
||||||
class="android.widget.FrameLayout"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[42,604][168,730]" drawing-order="1"
|
|
||||||
hint="">
|
|
||||||
<node index="0" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/iv_start_icon_l"
|
|
||||||
class="android.widget.ImageView"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[42,604][167,729]"
|
|
||||||
drawing-order="1" hint=""/>
|
|
||||||
</node>
|
|
||||||
<node index="2" text="Перевод другу"
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/tv_header"
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[200,643][922,692]" drawing-order="4"
|
|
||||||
hint=""/>
|
|
||||||
<node index="3" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/flow_center_text"
|
|
||||||
class="android.view.View" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[200,643][922,692]"
|
|
||||||
drawing-order="6" hint=""/>
|
|
||||||
<node index="4" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/iv_end_icon"
|
|
||||||
class="android.widget.ImageView"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[933,615][1017,720]"
|
|
||||||
drawing-order="10" hint=""/>
|
|
||||||
<node index="5" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/flow_end_items"
|
|
||||||
class="android.view.View" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[933,615][1017,720]"
|
|
||||||
drawing-order="13" hint=""/>
|
|
||||||
<node index="6" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/separator"
|
|
||||||
class="android.view.View" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[168,748][1038,751]"
|
|
||||||
drawing-order="14" hint=""/>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
<node index="3" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/cellCategory"
|
|
||||||
class="android.view.ViewGroup" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="true"
|
|
||||||
enabled="true" focusable="true" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,751][1080,919]" drawing-order="4" hint="">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.ViewGroup"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,751][1080,919]" drawing-order="1" hint="">
|
|
||||||
<node index="0" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/flow_start_images"
|
|
||||||
class="android.view.View" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[42,772][200,898]"
|
|
||||||
drawing-order="3" hint=""/>
|
|
||||||
<node index="1" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/iv_start_icon_field_l"
|
|
||||||
class="android.widget.FrameLayout"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[42,772][168,898]" drawing-order="1"
|
|
||||||
hint="">
|
|
||||||
<node index="0" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/iv_start_icon_l"
|
|
||||||
class="android.widget.ImageView"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[42,772][167,897]"
|
|
||||||
drawing-order="1" hint=""/>
|
|
||||||
</node>
|
|
||||||
<node index="2" text="Запрос средств у друзей"
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/tv_header"
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[200,811][922,860]" drawing-order="4"
|
|
||||||
hint=""/>
|
|
||||||
<node index="3" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/flow_center_text"
|
|
||||||
class="android.view.View" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[200,811][922,860]"
|
|
||||||
drawing-order="6" hint=""/>
|
|
||||||
<node index="4" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/iv_end_icon"
|
|
||||||
class="android.widget.ImageView"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[933,783][1017,888]"
|
|
||||||
drawing-order="10" hint=""/>
|
|
||||||
<node index="5" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/flow_end_items"
|
|
||||||
class="android.view.View" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[933,783][1017,888]"
|
|
||||||
drawing-order="13" hint=""/>
|
|
||||||
<node index="6" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/separator"
|
|
||||||
class="android.view.View" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[168,916][1038,919]"
|
|
||||||
drawing-order="14" hint=""/>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
<node index="4" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/cellCategory"
|
|
||||||
class="android.view.ViewGroup" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="true"
|
|
||||||
enabled="true" focusable="true" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,919][1080,1087]" drawing-order="5" hint="">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.ViewGroup"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,919][1080,1087]" drawing-order="1" hint="">
|
|
||||||
<node index="0" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/flow_start_images"
|
|
||||||
class="android.view.View" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[42,940][200,1066]"
|
|
||||||
drawing-order="3" hint=""/>
|
|
||||||
<node index="1" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/iv_start_icon_field_l"
|
|
||||||
class="android.widget.FrameLayout"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[42,940][168,1066]" drawing-order="1"
|
|
||||||
hint="">
|
|
||||||
<node index="0" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/iv_start_icon_l"
|
|
||||||
class="android.widget.ImageView"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[42,940][168,1066]"
|
|
||||||
drawing-order="1" hint=""/>
|
|
||||||
</node>
|
|
||||||
<node index="2" text="Перевод через AniPay"
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/tv_header"
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[200,979][922,1028]"
|
|
||||||
drawing-order="4" hint=""/>
|
|
||||||
<node index="3" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/flow_center_text"
|
|
||||||
class="android.view.View" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[200,979][922,1028]"
|
|
||||||
drawing-order="6" hint=""/>
|
|
||||||
<node index="4" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/iv_end_icon"
|
|
||||||
class="android.widget.ImageView"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[933,951][1017,1056]"
|
|
||||||
drawing-order="10" hint=""/>
|
|
||||||
<node index="5" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/flow_end_items"
|
|
||||||
class="android.view.View" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[933,951][1017,1056]" drawing-order="13" hint=""/>
|
|
||||||
<node index="6" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/separator"
|
|
||||||
class="android.view.View" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[168,1084][1038,1087]" drawing-order="14" hint=""/>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
<node index="1" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/bnv_activity_screen_navigation"
|
|
||||||
class="android.widget.FrameLayout" package="az.kapitalbank.mbanking" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,2158][1080,2400]" drawing-order="2" hint="">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.ViewGroup"
|
|
||||||
package="az.kapitalbank.mbanking" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,2158][1080,2305]" drawing-order="1" hint="">
|
|
||||||
<node index="0" text="" resource-id="az.kapitalbank.mbanking:id/tab_home"
|
|
||||||
class="android.widget.FrameLayout" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="Главная" checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="true" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="true"
|
|
||||||
bounds="[0,2158][216,2305]" drawing-order="1" hint="">
|
|
||||||
<node index="0" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/navigation_bar_item_labels_group"
|
|
||||||
class="android.view.ViewGroup" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="true"
|
|
||||||
bounds="[59,2236][157,2305]" drawing-order="2" hint="">
|
|
||||||
<node index="0" text="Главная"
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/navigation_bar_item_large_label_view"
|
|
||||||
class="android.widget.TextView" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="true"
|
|
||||||
bounds="[59,2236][157,2302]" drawing-order="2" hint=""/>
|
|
||||||
</node>
|
|
||||||
<node index="1" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/navigation_bar_item_icon_container"
|
|
||||||
class="android.widget.FrameLayout" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="true"
|
|
||||||
bounds="[76,2179][139,2242]" drawing-order="1" hint="">
|
|
||||||
<node index="0" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/navigation_bar_item_icon_view"
|
|
||||||
class="android.widget.ImageView" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="true"
|
|
||||||
bounds="[76,2179][139,2242]" drawing-order="2" hint=""/>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
<node index="1" text="" resource-id="az.kapitalbank.mbanking:id/tab_umico_market"
|
|
||||||
class="android.widget.FrameLayout" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="Выгода" checkable="false" checked="false" clickable="true"
|
|
||||||
enabled="true" focusable="true" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[216,2158][432,2305]" drawing-order="2" hint="">
|
|
||||||
<node index="0" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/navigation_bar_item_labels_group"
|
|
||||||
class="android.view.ViewGroup" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[278,2236][369,2305]" drawing-order="2" hint="">
|
|
||||||
<node index="0" text="Выгода"
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/navigation_bar_item_small_label_view"
|
|
||||||
class="android.widget.TextView" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[278,2236][369,2302]" drawing-order="1" hint=""/>
|
|
||||||
</node>
|
|
||||||
<node index="1" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/navigation_bar_item_icon_container"
|
|
||||||
class="android.widget.FrameLayout" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[292,2179][355,2242]" drawing-order="1" hint="">
|
|
||||||
<node index="0" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/navigation_bar_item_icon_view"
|
|
||||||
class="android.widget.ImageView" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[292,2179][355,2242]" drawing-order="2" hint=""/>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
<node index="2" text="" resource-id="az.kapitalbank.mbanking:id/tab_qr"
|
|
||||||
class="android.widget.FrameLayout" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="QR" checkable="false" checked="false" clickable="true"
|
|
||||||
enabled="true" focusable="true" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[432,2158][648,2305]" drawing-order="3" hint="">
|
|
||||||
<node index="0" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/navigation_bar_item_icon_container"
|
|
||||||
class="android.widget.FrameLayout" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[508,2179][571,2242]" drawing-order="1" hint="">
|
|
||||||
<node index="0" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/navigation_bar_item_icon_view"
|
|
||||||
class="android.widget.ImageView" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[508,2179][571,2242]" drawing-order="2" hint=""/>
|
|
||||||
</node>
|
|
||||||
<node index="1" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/navigation_bar_item_labels_group"
|
|
||||||
class="android.view.ViewGroup" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[522,2236][557,2305]" drawing-order="2" hint="">
|
|
||||||
<node index="0" text="QR"
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/navigation_bar_item_small_label_view"
|
|
||||||
class="android.widget.TextView" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[522,2236][556,2302]" drawing-order="1" hint=""/>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
<node index="3" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/tab_payments_and_transfers"
|
|
||||||
class="android.widget.FrameLayout" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="Платежи" checkable="false" checked="false" clickable="true"
|
|
||||||
enabled="true" focusable="true" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[648,2158][864,2305]" drawing-order="4" hint="">
|
|
||||||
<node index="0" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/navigation_bar_item_labels_group"
|
|
||||||
class="android.view.ViewGroup" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[701,2236][810,2305]" drawing-order="2" hint="">
|
|
||||||
<node index="0" text="Платежи"
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/navigation_bar_item_small_label_view"
|
|
||||||
class="android.widget.TextView" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[701,2236][810,2302]" drawing-order="1" hint=""/>
|
|
||||||
</node>
|
|
||||||
<node index="1" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/navigation_bar_item_icon_container"
|
|
||||||
class="android.widget.FrameLayout" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[724,2179][787,2242]" drawing-order="1" hint="">
|
|
||||||
<node index="0" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/navigation_bar_item_icon_view"
|
|
||||||
class="android.widget.ImageView" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[724,2179][787,2242]" drawing-order="2" hint=""/>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
<node index="4" text="" resource-id="az.kapitalbank.mbanking:id/tab_more"
|
|
||||||
class="android.widget.FrameLayout" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="Еще" checkable="false" checked="false" clickable="true"
|
|
||||||
enabled="true" focusable="true" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[864,2158][1080,2305]" drawing-order="5" hint="">
|
|
||||||
<node index="0" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/navigation_bar_item_icon_container"
|
|
||||||
class="android.widget.FrameLayout" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[940,2179][1003,2242]" drawing-order="1" hint="">
|
|
||||||
<node index="0" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/navigation_bar_item_icon_view"
|
|
||||||
class="android.widget.ImageView" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[940,2179][1003,2242]" drawing-order="2" hint=""/>
|
|
||||||
</node>
|
|
||||||
<node index="1" text=""
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/navigation_bar_item_labels_group"
|
|
||||||
class="android.view.ViewGroup" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[946,2236][998,2305]" drawing-order="2" hint="">
|
|
||||||
<node index="0" text="Еще"
|
|
||||||
resource-id="az.kapitalbank.mbanking:id/navigation_bar_item_small_label_view"
|
|
||||||
class="android.widget.TextView" package="az.kapitalbank.mbanking"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[946,2236][998,2302]" drawing-order="1" hint=""/>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</hierarchy>
|
|
||||||
|
Before Width: | Height: | Size: 107 KiB |
@ -1,297 +0,0 @@
|
|||||||
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
|
|
||||||
<hierarchy rotation="0">
|
|
||||||
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false" selected="false" bounds="[0,0][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.widget.LinearLayout" package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false" selected="false" bounds="[0,0][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="ru.rshb.dbo:id/action_bar_root" class="android.widget.LinearLayout"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="android:id/content" class="android.widget.FrameLayout"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.webkit.WebView" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.webkit.WebView" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="true" focused="true" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,82][720,166]">
|
|
||||||
<node index="0" text="" resource-id=""
|
|
||||||
class="android.view.View" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[7,89][78,157]">
|
|
||||||
<node index="0" text="Назад" resource-id=""
|
|
||||||
class="android.widget.Button"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="true"
|
|
||||||
enabled="true" focusable="true" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[7,89][69,157]"/>
|
|
||||||
</node>
|
|
||||||
<node index="1" text="Все продукты" resource-id=""
|
|
||||||
class="android.widget.TextView" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[86,89][339,173]"/>
|
|
||||||
<node index="2" text="" resource-id=""
|
|
||||||
class="android.widget.TextView" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[699,89][712,157]"/>
|
|
||||||
</node>
|
|
||||||
<node index="1" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,188][720,1379]">
|
|
||||||
<node index="0" text="" resource-id=""
|
|
||||||
class="android.view.View" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,188][720,1379]">
|
|
||||||
<node index="0" text="" resource-id=""
|
|
||||||
class="android.view.View" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,190][720,1379]">
|
|
||||||
<node index="0" text="" resource-id=""
|
|
||||||
class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[0,190][720,773]">
|
|
||||||
<node index="0"
|
|
||||||
text="Нажмите на сердечко для отображения на главной"
|
|
||||||
resource-id=""
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[30,226][690,256]"/>
|
|
||||||
<node index="1" text="Карты" resource-id=""
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[78,299][148,327]"/>
|
|
||||||
<node index="2"
|
|
||||||
text="Классическая карта МИР Моментального выпуска (Своя карта). Дебетовая. Номер карты с последними цифрами 5 2 6 4. Сумма: 160 рублей 0 копеек"
|
|
||||||
resource-id="aft-rsProduct"
|
|
||||||
class="android.widget.Button"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true"
|
|
||||||
focusable="true" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[30,370][690,442]"/>
|
|
||||||
<node index="3"
|
|
||||||
text="Классическая карта МИР. Дебетовая. Номер карты с последними цифрами 7 1 8 3. Сумма: 280 рублей 0 копеек"
|
|
||||||
resource-id="aft-rsProduct"
|
|
||||||
class="android.widget.Button"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true"
|
|
||||||
focusable="true" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[30,466][690,537]"/>
|
|
||||||
<node index="4"
|
|
||||||
text="Программа лояльности Подключить"
|
|
||||||
resource-id=""
|
|
||||||
class="android.widget.Button"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true"
|
|
||||||
focusable="true" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[30,563][690,698]"/>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
<node index="1" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,1377][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,1377][720,1439]">
|
|
||||||
<node index="0" text="Главная" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[1,1377][148,1439]"/>
|
|
||||||
<node index="1" text="История" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[144,1377][290,1439]"/>
|
|
||||||
<node index="2" text="Своё" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[286,1377][433,1439]"/>
|
|
||||||
<node index="3" text="Платежи" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[429,1377][575,1439]"/>
|
|
||||||
<node index="4" text="Ещё" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[571,1377][718,1439]"/>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
<node index="2" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,0][0,0]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,0][0,0]">
|
|
||||||
<node index="0" text="В банк" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,0][0,0]"/>
|
|
||||||
<node index="1" text="Кабинет" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,0][0,0]"/>
|
|
||||||
<node index="2" text="Продажи" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,0][0,0]"/>
|
|
||||||
<node index="3" text="Налоги" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,0][0,0]"/>
|
|
||||||
<node index="4" text="Профиль" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,0][0,0]"/>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
<node index="1" text="" resource-id="" class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,0][0,0]"/>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
<node index="1" text="" resource-id="android:id/statusBarBackground" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,0][720,82]"/>
|
|
||||||
<node index="2" text="" resource-id="android:id/navigationBarBackground" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,0][0,0]"/>
|
|
||||||
</node>
|
|
||||||
</hierarchy>
|
|
||||||
@ -1,205 +0,0 @@
|
|||||||
Сбербанк
|
|
||||||
Т-Банк
|
|
||||||
ВТБ
|
|
||||||
Альфа-Банк
|
|
||||||
Филиал Открытие БМ-Банк
|
|
||||||
Почта Банк
|
|
||||||
Райффайзен Банк
|
|
||||||
Газпромбанк
|
|
||||||
Совкомбанк
|
|
||||||
ПСБ
|
|
||||||
Ак Барс Банк
|
|
||||||
МКБ (Московский кредитный банк)
|
|
||||||
Банк Синара
|
|
||||||
МТС-Банк
|
|
||||||
Золотая Корона – Korona (РНКО Платежный Центр)
|
|
||||||
Банк Санкт-Петербург
|
|
||||||
Банк Русский Стандарт
|
|
||||||
VK Pay - ВК Платёжные решения
|
|
||||||
Wallet One (РНКО Единая касса)
|
|
||||||
Wildberries (Вайлдберриз Банк)
|
|
||||||
АБ РОССИЯ
|
|
||||||
АИКБ Енисейский объединенный банк
|
|
||||||
АКБ Держава
|
|
||||||
АКБ ЕВРОФИНАНС МОСНАРБАНК
|
|
||||||
АКБ Ланта Банк
|
|
||||||
АКБ НРБанк
|
|
||||||
АКБ СЛАВИЯ
|
|
||||||
АКБ Тендер Банк
|
|
||||||
АКИБАНК
|
|
||||||
Абсолют Банк
|
|
||||||
Авито Кошелек (Платежный конструктор)
|
|
||||||
Авто Финанс Банк
|
|
||||||
Автоторгбанк
|
|
||||||
Азиатско-Тихоокеанский Банк
|
|
||||||
Алеф-Банк
|
|
||||||
Алмазэргиэнбанк
|
|
||||||
БАНК МОСКВА СИТИ
|
|
||||||
БАНК ОРЕНБУРГ
|
|
||||||
БАНК СГБ
|
|
||||||
БАНК СНГБ
|
|
||||||
БАНК УРАЛСИБ
|
|
||||||
ББР Банк
|
|
||||||
БКС Банк
|
|
||||||
Банк АВАНГАРД
|
|
||||||
Банк АЛЕКСАНДРОВСКИЙ
|
|
||||||
Банк Аверс
|
|
||||||
Банк Агророс
|
|
||||||
Банк Акцепт
|
|
||||||
Банк БЖФ
|
|
||||||
Банк ВБРР
|
|
||||||
Банк Венец
|
|
||||||
Банк Вологжанин
|
|
||||||
Банк ДОМ.РФ
|
|
||||||
Банк ЗЕНИТ
|
|
||||||
Банк Заречье
|
|
||||||
Банк ИПБ
|
|
||||||
Банк ИТУРУП
|
|
||||||
Банк Интеза
|
|
||||||
Банк Йошкар-Ола
|
|
||||||
Банк Кремлевский
|
|
||||||
Банк Кузнецкий
|
|
||||||
Банк Левобережный
|
|
||||||
Банк МБА МОСКВА
|
|
||||||
Банк НОВИКОМ (НОВИКОМБАНК)
|
|
||||||
Банк Национальный стандарт
|
|
||||||
Банк Объединенный капитал
|
|
||||||
Банк Оранжевый
|
|
||||||
Банк ПСКБ
|
|
||||||
Банк Приморье
|
|
||||||
Банк РЕСО Кредит
|
|
||||||
Банк РСИ
|
|
||||||
Банк Развитие-Столица
|
|
||||||
Банк Саратов
|
|
||||||
Банк Снежинский
|
|
||||||
Банк Уралфинанс
|
|
||||||
Банк ФИНАМ
|
|
||||||
Банк Финсервис
|
|
||||||
Банк ЦентроКредит
|
|
||||||
Банк ЧБРР
|
|
||||||
Бланк банк
|
|
||||||
Братский АНКБ
|
|
||||||
БыстроБанк
|
|
||||||
ВЛАДБИЗНЕСБАНК
|
|
||||||
ВНЕШФИНБАНК
|
|
||||||
ВУЗ-банк
|
|
||||||
ГЕНБАНК
|
|
||||||
ГОРБАНК
|
|
||||||
ГУТА-БАНК
|
|
||||||
Газтрансбанк
|
|
||||||
Газэнергобанк
|
|
||||||
Далена Банк
|
|
||||||
Дальневосточный банк
|
|
||||||
Датабанк
|
|
||||||
Драйв Клик Банк
|
|
||||||
ЖИВАГО БАНК
|
|
||||||
Земский банк
|
|
||||||
ИК Банк
|
|
||||||
ИС Банк
|
|
||||||
ИШБАНК
|
|
||||||
Инбанк
|
|
||||||
Ингосстрах Банк
|
|
||||||
КБ РостФинанс
|
|
||||||
КБ АГРОПРОМКРЕДИТ
|
|
||||||
КБ АРЕСБАНК
|
|
||||||
КБ Долинск
|
|
||||||
КБ Крокус Банк
|
|
||||||
КБ ЛОКО-Банк
|
|
||||||
КБ Модульбанк
|
|
||||||
КБ Москоммерцбанк
|
|
||||||
КБ Пойдём
|
|
||||||
КБ Солидарность
|
|
||||||
КБ Стройлесбанк
|
|
||||||
КБ Хлынов
|
|
||||||
КБ ЭНЕРГОТРАНСБАНК
|
|
||||||
КБЭР Банк Казани
|
|
||||||
КОШЕЛЕВ-БАНК
|
|
||||||
Контур.Банк
|
|
||||||
Кошелек ЦУПИС (Мобильная карта)
|
|
||||||
Кредит Европа Банк (Россия)
|
|
||||||
Кредит Урал Банк
|
|
||||||
Кубань Кредит
|
|
||||||
Кубаньторгбанк
|
|
||||||
Кузнецкбизнесбанк
|
|
||||||
МБ Банк
|
|
||||||
МЕЖДУНАРОДНЫЙ ФИНАНСОВЫЙ КЛУБ
|
|
||||||
МЕТКОМБАНК
|
|
||||||
МОНЕТА
|
|
||||||
МОРСКОЙ БАНК
|
|
||||||
МОСКОМБАНК
|
|
||||||
МС Банк Рус
|
|
||||||
МТС Деньги (ЭКСИ Банк)
|
|
||||||
Металлинвестбанк
|
|
||||||
Мир Привилегий (МП Банк)
|
|
||||||
НБД-Банк
|
|
||||||
НИКО-БАНК
|
|
||||||
НК Банк
|
|
||||||
НКО МОБИ.Деньги
|
|
||||||
НКО Расчетные Решения
|
|
||||||
НОКССБАНК
|
|
||||||
НС Банк
|
|
||||||
Нацинвестпромбанк
|
|
||||||
Новобанк
|
|
||||||
Новый век
|
|
||||||
Норвик Банк
|
|
||||||
ОТП Банк
|
|
||||||
Озон Банк (Ozon)
|
|
||||||
ПЕРВОУРАЛЬСКБАНК
|
|
||||||
Первый Дортрансбанк
|
|
||||||
Первый Инвестиционный Банк
|
|
||||||
Прио-Внешторгбанк
|
|
||||||
ПроБанк
|
|
||||||
РНКБ Банк
|
|
||||||
РУСНАРБАНК
|
|
||||||
Реалист Банк
|
|
||||||
Ренессанс Банк (Ренессанс Кредит)
|
|
||||||
Рокетбанк
|
|
||||||
РосДорБанк
|
|
||||||
Роял Кредит Банк
|
|
||||||
Русьуниверсалбанк
|
|
||||||
СДМ-Банк
|
|
||||||
СИБСОЦБАНК
|
|
||||||
СИНКО-БАНК
|
|
||||||
СКБ Примсоцбанк
|
|
||||||
СОЦИУМ БАНК
|
|
||||||
Свой Банк
|
|
||||||
Северный Народный Банк
|
|
||||||
Солид Банк
|
|
||||||
Ставропольпромстройбанк
|
|
||||||
ТАТСОЦБАНК
|
|
||||||
ТРАНСКАПИТАЛБАНК
|
|
||||||
Таврический Банк
|
|
||||||
Тимер Банк
|
|
||||||
Тойота Банк
|
|
||||||
Тольяттихимбанк
|
|
||||||
Томскпромстройбанк
|
|
||||||
Точка Банк
|
|
||||||
Трансстройбанк
|
|
||||||
УБРиР
|
|
||||||
УКБ Белгородсоцбанк
|
|
||||||
УРАЛПРОМБАНК
|
|
||||||
Углеметбанк
|
|
||||||
Урал ФД
|
|
||||||
ФИНСТАР БАНК
|
|
||||||
ФОРА-БАНК
|
|
||||||
Форштадт
|
|
||||||
Хайс
|
|
||||||
Хакасский муниципальный банк
|
|
||||||
ЦМРБанк
|
|
||||||
Центр-инвест
|
|
||||||
Цифра банк
|
|
||||||
ЧЕЛИНДБАНК
|
|
||||||
ЧЕЛЯБИНВЕСТБАНК
|
|
||||||
ЭЛПЛАТ
|
|
||||||
Экономбанк
|
|
||||||
Экспобанк
|
|
||||||
Энергобанк
|
|
||||||
Эс-Би-Ай Банк
|
|
||||||
ЮГ-Инвестбанк
|
|
||||||
ЮМани
|
|
||||||
ЮНИСТРИМ БАНК
|
|
||||||
ЮниКредит Банк
|
|
||||||
ЯРИНТЕРБАНК
|
|
||||||
Яндекс
|
|
||||||
банк Раунд
|
|
||||||
банк Элита
|
|
||||||
|
Before Width: | Height: | Size: 215 KiB |
@ -1,430 +0,0 @@
|
|||||||
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
|
|
||||||
<hierarchy rotation="0">
|
|
||||||
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false" selected="false" bounds="[0,0][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.widget.LinearLayout" package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false" selected="false" bounds="[0,0][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="ru.rshb.dbo:id/action_bar_root" class="android.widget.LinearLayout"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="android:id/content" class="android.widget.FrameLayout"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.webkit.WebView" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.webkit.WebView" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="true" focused="true" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,82][720,166]">
|
|
||||||
<node index="0" text="" resource-id=""
|
|
||||||
class="android.view.View" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[7,89][78,157]">
|
|
||||||
<node index="0" text="Назад" resource-id=""
|
|
||||||
class="android.widget.Button"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="true"
|
|
||||||
enabled="true" focusable="true" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[7,89][69,157]"/>
|
|
||||||
</node>
|
|
||||||
<node index="1" text="Выписка" resource-id=""
|
|
||||||
class="android.widget.TextView" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[86,89][260,173]"/>
|
|
||||||
<node index="2" text="" resource-id=""
|
|
||||||
class="android.view.View" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[641,89][712,157]">
|
|
||||||
<node index="0"
|
|
||||||
text="Информирование о сроке отображения операций по счету"
|
|
||||||
resource-id="aft-rbtnClass-buttonIcon"
|
|
||||||
class="android.widget.Button"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="true"
|
|
||||||
enabled="true" focusable="true" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[650,89][712,157]"/>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
<node index="1" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,160][720,1379]">
|
|
||||||
<node index="0" text="" resource-id=""
|
|
||||||
class="android.view.View" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="true"
|
|
||||||
focused="false" scrollable="true"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,160][720,1379]">
|
|
||||||
<node index="0" text="" resource-id=""
|
|
||||||
class="android.view.View" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,162][720,1439]">
|
|
||||||
<node index="0" text="по счету 40817 .... 2077"
|
|
||||||
resource-id="" class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[206,205][513,258]"/>
|
|
||||||
<node index="1"
|
|
||||||
text="Период с 08.05.2025 по 10.05.2025 More"
|
|
||||||
resource-id="" class="android.widget.Button"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true"
|
|
||||||
focusable="true" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[0,295][720,391]"/>
|
|
||||||
<node index="2"
|
|
||||||
text="Подтвержденные Ожидающие обработки"
|
|
||||||
resource-id="" class="android.widget.Button"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true"
|
|
||||||
focusable="true" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[0,383][720,477]"/>
|
|
||||||
<node index="3" text="" resource-id=""
|
|
||||||
class="android.widget.ListView"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[0,473][720,1439]">
|
|
||||||
<node index="0" text="" resource-id=""
|
|
||||||
class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[0,473][720,798]">
|
|
||||||
<node index="0" text="09.05.2025"
|
|
||||||
resource-id=""
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false"
|
|
||||||
scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[28,473][691,517]"/>
|
|
||||||
<node index="1"
|
|
||||||
text="Перевод через СБП от Надежда Юрьевна К (+7(964)-181-51-46) из Сбербанк на 40817810328000022077 . Идентификатор операции в СБП С2С A5129141229250080000030011500701 , Дата операции 09.05.2025 17:12:29 Статус перевода Исполнен + 655 точка 00 Рубль"
|
|
||||||
resource-id=""
|
|
||||||
class="android.widget.Button"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true"
|
|
||||||
focusable="true" focused="false"
|
|
||||||
scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[28,533][691,779]"/>
|
|
||||||
</node>
|
|
||||||
<node index="1" text="" resource-id=""
|
|
||||||
class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[0,794][720,1017]">
|
|
||||||
<node index="0" text="08.05.2025"
|
|
||||||
resource-id=""
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false"
|
|
||||||
scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[28,794][691,837]"/>
|
|
||||||
<node index="1"
|
|
||||||
text="Перевод Надежда Юрьевна К** в Сбербанк через СБП, по номеру телефона +79641815146, ID перевода 448627512, дата 08.05.2025 - 250 точка 00 Рубль"
|
|
||||||
resource-id=""
|
|
||||||
class="android.widget.Button"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true"
|
|
||||||
focusable="true" focused="false"
|
|
||||||
scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[28,854][691,995]"/>
|
|
||||||
</node>
|
|
||||||
<node index="2" text="" resource-id=""
|
|
||||||
class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[0,1012][720,1193]">
|
|
||||||
<node index="0"
|
|
||||||
text="Перевод Надежда Юрьевна К** в Альфа-Банк через СБП, по номеру телефона +79641815146, ID перевода 448628517, дата 08.05.2025 - 305 точка 00 Рубль"
|
|
||||||
resource-id=""
|
|
||||||
class="android.widget.Button"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true"
|
|
||||||
focusable="true" focused="false"
|
|
||||||
scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[28,1030][691,1173]"/>
|
|
||||||
</node>
|
|
||||||
<node index="3" text="" resource-id=""
|
|
||||||
class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[0,1188][720,1370]">
|
|
||||||
<node index="0"
|
|
||||||
text="Перевод Надежда Юрьевна К** в Сбербанк через СБП, по номеру телефона +79641815146, ID перевода 448713642, дата 08.05.2025 - 405 точка 00 Рубль"
|
|
||||||
resource-id=""
|
|
||||||
class="android.widget.Button"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true"
|
|
||||||
focusable="true" focused="false"
|
|
||||||
scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[28,1208][691,1349]"/>
|
|
||||||
</node>
|
|
||||||
<node index="4" text="" resource-id=""
|
|
||||||
class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[0,1366][720,1439]">
|
|
||||||
<node index="0"
|
|
||||||
text="Перевод Надежда Юрьевна К** в Альфа-Банк через СБП, по номеру телефона +79641815146, ID перевода 448716504, дата 08.05.2025 - 310 точка 00 Рубль"
|
|
||||||
resource-id=""
|
|
||||||
class="android.widget.Button"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true"
|
|
||||||
focusable="true" focused="false"
|
|
||||||
scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[28,1385][691,1439]"/>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
<node index="2" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[575,1235][684,1343]">
|
|
||||||
<node index="0" text="Отправить" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="true"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[575,1235][684,1343]"/>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
<node index="1" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,1377][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,1377][720,1439]">
|
|
||||||
<node index="0" text="Главная" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[1,1377][148,1439]"/>
|
|
||||||
<node index="1" text="История" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[144,1377][290,1439]"/>
|
|
||||||
<node index="2" text="Своё" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[286,1377][433,1439]"/>
|
|
||||||
<node index="3" text="Платежи" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[429,1377][575,1439]"/>
|
|
||||||
<node index="4" text="Ещё" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[571,1377][718,1439]"/>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
<node index="2" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,0][0,0]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,0][0,0]">
|
|
||||||
<node index="0" text="В банк" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,0][0,0]"/>
|
|
||||||
<node index="1" text="Кабинет" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,0][0,0]"/>
|
|
||||||
<node index="2" text="Продажи" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,0][0,0]"/>
|
|
||||||
<node index="3" text="Налоги" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,0][0,0]"/>
|
|
||||||
<node index="4" text="Профиль" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,0][0,0]"/>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
<node index="1" text="" resource-id="" class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,0][0,0]"/>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
<node index="1" text="" resource-id="android:id/statusBarBackground" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,0][720,82]"/>
|
|
||||||
<node index="2" text="" resource-id="android:id/navigationBarBackground" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,0][0,0]"/>
|
|
||||||
</node>
|
|
||||||
</hierarchy>
|
|
||||||
|
Before Width: | Height: | Size: 248 KiB |
|
Before Width: | Height: | Size: 192 KiB |
|
Before Width: | Height: | Size: 185 KiB |
@ -1,869 +0,0 @@
|
|||||||
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
|
|
||||||
<hierarchy rotation="0">
|
|
||||||
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false" selected="false" bounds="[0,0][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.widget.LinearLayout" package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false" selected="false" bounds="[0,0][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="ru.rshb.dbo:id/action_bar_root" class="android.widget.LinearLayout"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="android:id/content" class="android.widget.FrameLayout"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.webkit.WebView" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.webkit.WebView" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="true" focused="true" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,82][720,166]">
|
|
||||||
<node index="0" text="" resource-id=""
|
|
||||||
class="android.view.View" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[7,89][78,157]">
|
|
||||||
<node index="0" text="Назад" resource-id=""
|
|
||||||
class="android.widget.Button"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="true"
|
|
||||||
enabled="true" focusable="true" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[7,89][69,157]"/>
|
|
||||||
</node>
|
|
||||||
<node index="1" text="Мои продукты" resource-id=""
|
|
||||||
class="android.widget.TextView" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[86,89][350,173]"/>
|
|
||||||
<node index="2" text="" resource-id=""
|
|
||||||
class="android.widget.TextView" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[699,89][712,157]"/>
|
|
||||||
</node>
|
|
||||||
<node index="1" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="true" focused="false" scrollable="true"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,160][720,1379]">
|
|
||||||
<node index="0" text="" resource-id=""
|
|
||||||
class="android.view.View" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,162][720,588]">
|
|
||||||
<node index="0" text="" resource-id=""
|
|
||||||
class="android.view.View" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,162][720,588]">
|
|
||||||
<node index="0" text="" resource-id=""
|
|
||||||
class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[0,0][0,0]">
|
|
||||||
<node index="0" text="" resource-id=""
|
|
||||||
class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[0,162][80,588]">
|
|
||||||
<node index="0" text="" resource-id=""
|
|
||||||
class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false"
|
|
||||||
scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[0,237][24,588]">
|
|
||||||
<node index="0" text="" resource-id=""
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[0,82][258,382]"/>
|
|
||||||
<node index="1" text="" resource-id=""
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[0,0][0,0]"/>
|
|
||||||
<node index="2" text="" resource-id=""
|
|
||||||
class="android.view.View"
|
|
||||||
package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[0,0][0,0]">
|
|
||||||
<node index="0" text=""
|
|
||||||
resource-id=""
|
|
||||||
class="android.view.View"
|
|
||||||
package="ru.rshb.dbo"
|
|
||||||
content-desc=""
|
|
||||||
checkable="false"
|
|
||||||
checked="false"
|
|
||||||
clickable="false"
|
|
||||||
enabled="true"
|
|
||||||
focusable="false"
|
|
||||||
focused="false"
|
|
||||||
scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[0,0][0,0]">
|
|
||||||
<node index="0" text="160"
|
|
||||||
resource-id="aft-operationHistory-money"
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo"
|
|
||||||
content-desc=""
|
|
||||||
checkable="false"
|
|
||||||
checked="false"
|
|
||||||
clickable="false"
|
|
||||||
enabled="true"
|
|
||||||
focusable="false"
|
|
||||||
focused="false"
|
|
||||||
scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[0,0][0,0]"/>
|
|
||||||
<node index="1" text="точка 00"
|
|
||||||
resource-id=""
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo"
|
|
||||||
content-desc=""
|
|
||||||
checkable="false"
|
|
||||||
checked="false"
|
|
||||||
clickable="false"
|
|
||||||
enabled="true"
|
|
||||||
focusable="false"
|
|
||||||
focused="false"
|
|
||||||
scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[0,0][0,0]"/>
|
|
||||||
<node index="2" text="Рубль"
|
|
||||||
resource-id=""
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo"
|
|
||||||
content-desc=""
|
|
||||||
checkable="false"
|
|
||||||
checked="false"
|
|
||||||
clickable="false"
|
|
||||||
enabled="true"
|
|
||||||
focusable="false"
|
|
||||||
focused="false"
|
|
||||||
scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[0,0][0,0]"/>
|
|
||||||
<node index="3" text=""
|
|
||||||
resource-id=""
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo"
|
|
||||||
content-desc=""
|
|
||||||
checkable="false"
|
|
||||||
checked="false"
|
|
||||||
clickable="false"
|
|
||||||
enabled="true"
|
|
||||||
focusable="false"
|
|
||||||
focused="false"
|
|
||||||
scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[0,0][0,0]"/>
|
|
||||||
</node>
|
|
||||||
<node index="1"
|
|
||||||
text="Классическая карта МИР Моментального выпуска (Своя карта)"
|
|
||||||
resource-id=""
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo"
|
|
||||||
content-desc=""
|
|
||||||
checkable="false"
|
|
||||||
checked="false"
|
|
||||||
clickable="false"
|
|
||||||
enabled="true"
|
|
||||||
focusable="false"
|
|
||||||
focused="false"
|
|
||||||
scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[0,0][0,0]"/>
|
|
||||||
<node index="2" text="дебетовая"
|
|
||||||
resource-id=""
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo"
|
|
||||||
content-desc=""
|
|
||||||
checkable="false"
|
|
||||||
checked="false"
|
|
||||||
clickable="false"
|
|
||||||
enabled="true"
|
|
||||||
focusable="false"
|
|
||||||
focused="false"
|
|
||||||
scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[0,0][0,0]"/>
|
|
||||||
<node index="3" text="** 5264"
|
|
||||||
resource-id=""
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo"
|
|
||||||
content-desc=""
|
|
||||||
checkable="false"
|
|
||||||
checked="false"
|
|
||||||
clickable="false"
|
|
||||||
enabled="true"
|
|
||||||
focusable="false"
|
|
||||||
focused="false"
|
|
||||||
scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[0,0][0,0]"/>
|
|
||||||
<node NAF="true" index="4" text=""
|
|
||||||
resource-id=""
|
|
||||||
class="android.widget.Button"
|
|
||||||
package="ru.rshb.dbo"
|
|
||||||
content-desc=""
|
|
||||||
checkable="false"
|
|
||||||
checked="false"
|
|
||||||
clickable="true"
|
|
||||||
enabled="true"
|
|
||||||
focusable="true"
|
|
||||||
focused="false"
|
|
||||||
scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[0,0][0,0]"/>
|
|
||||||
<node index="5" text=""
|
|
||||||
resource-id=""
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo"
|
|
||||||
content-desc=""
|
|
||||||
checkable="false"
|
|
||||||
checked="false"
|
|
||||||
clickable="false"
|
|
||||||
enabled="true"
|
|
||||||
focusable="false"
|
|
||||||
focused="false"
|
|
||||||
scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[0,0][0,0]"/>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
<node index="1" text="" resource-id=""
|
|
||||||
class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[0,162][720,588]">
|
|
||||||
<node index="0" text="" resource-id=""
|
|
||||||
class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false"
|
|
||||||
scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[54,237][665,588]">
|
|
||||||
<node index="0" text="" resource-id=""
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[296,82][720,382]"/>
|
|
||||||
<node index="1" text="" resource-id=""
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[0,443][423,860]"/>
|
|
||||||
<node index="2" text="" resource-id=""
|
|
||||||
class="android.view.View"
|
|
||||||
package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[99,277][620,550]">
|
|
||||||
<node index="0" text=""
|
|
||||||
resource-id=""
|
|
||||||
class="android.view.View"
|
|
||||||
package="ru.rshb.dbo"
|
|
||||||
content-desc=""
|
|
||||||
checkable="false"
|
|
||||||
checked="false"
|
|
||||||
clickable="false"
|
|
||||||
enabled="true"
|
|
||||||
focusable="false"
|
|
||||||
focused="false"
|
|
||||||
scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[99,312][620,368]">
|
|
||||||
<node index="0" text="2 095"
|
|
||||||
resource-id="aft-operationHistory-money"
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo"
|
|
||||||
content-desc=""
|
|
||||||
checkable="false"
|
|
||||||
checked="false"
|
|
||||||
clickable="false"
|
|
||||||
enabled="true"
|
|
||||||
focusable="false"
|
|
||||||
focused="false"
|
|
||||||
scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[99,312][215,367]"/>
|
|
||||||
<node index="1" text="точка 00"
|
|
||||||
resource-id=""
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo"
|
|
||||||
content-desc=""
|
|
||||||
checkable="false"
|
|
||||||
checked="false"
|
|
||||||
clickable="false"
|
|
||||||
enabled="true"
|
|
||||||
focusable="false"
|
|
||||||
focused="false"
|
|
||||||
scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[211,312][277,367]"/>
|
|
||||||
<node index="2" text="Рубль"
|
|
||||||
resource-id=""
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo"
|
|
||||||
content-desc=""
|
|
||||||
checkable="false"
|
|
||||||
checked="false"
|
|
||||||
clickable="false"
|
|
||||||
enabled="true"
|
|
||||||
focusable="false"
|
|
||||||
focused="false"
|
|
||||||
scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[286,312][315,367]"/>
|
|
||||||
<node index="3" text=""
|
|
||||||
resource-id=""
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo"
|
|
||||||
content-desc=""
|
|
||||||
checkable="false"
|
|
||||||
checked="false"
|
|
||||||
clickable="false"
|
|
||||||
enabled="true"
|
|
||||||
focusable="false"
|
|
||||||
focused="false"
|
|
||||||
scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[311,312][371,368]"/>
|
|
||||||
</node>
|
|
||||||
<node index="1"
|
|
||||||
text="Классическая карта МИР"
|
|
||||||
resource-id=""
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo"
|
|
||||||
content-desc=""
|
|
||||||
checkable="false"
|
|
||||||
checked="false"
|
|
||||||
clickable="false"
|
|
||||||
enabled="true"
|
|
||||||
focusable="false"
|
|
||||||
focused="false"
|
|
||||||
scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[99,380][620,421]"/>
|
|
||||||
<node index="2" text="дебетовая"
|
|
||||||
resource-id=""
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo"
|
|
||||||
content-desc=""
|
|
||||||
checkable="false"
|
|
||||||
checked="false"
|
|
||||||
clickable="false"
|
|
||||||
enabled="true"
|
|
||||||
focusable="false"
|
|
||||||
focused="false"
|
|
||||||
scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[99,419][620,458]"/>
|
|
||||||
<node index="3" text="** 7183"
|
|
||||||
resource-id=""
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo"
|
|
||||||
content-desc=""
|
|
||||||
checkable="false"
|
|
||||||
checked="false"
|
|
||||||
clickable="false"
|
|
||||||
enabled="true"
|
|
||||||
focusable="false"
|
|
||||||
focused="false"
|
|
||||||
scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[99,517][620,550]"/>
|
|
||||||
<node NAF="true" index="4" text=""
|
|
||||||
resource-id=""
|
|
||||||
class="android.widget.Button"
|
|
||||||
package="ru.rshb.dbo"
|
|
||||||
content-desc=""
|
|
||||||
checkable="false"
|
|
||||||
checked="false"
|
|
||||||
clickable="true"
|
|
||||||
enabled="true"
|
|
||||||
focusable="true"
|
|
||||||
focused="false"
|
|
||||||
scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[571,277][620,322]"/>
|
|
||||||
<node index="5" text=""
|
|
||||||
resource-id=""
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo"
|
|
||||||
content-desc=""
|
|
||||||
checkable="false"
|
|
||||||
checked="false"
|
|
||||||
clickable="false"
|
|
||||||
enabled="true"
|
|
||||||
focusable="false"
|
|
||||||
focused="false"
|
|
||||||
scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[541,524][639,550]"/>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
<node index="1" text="" resource-id=""
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[54,172][665,211]"/>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
<node index="1" text="Пополнить" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="true"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[78,622][268,773]"/>
|
|
||||||
<node index="2" text="Оплатить" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="true"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[264,622][455,773]"/>
|
|
||||||
<node index="3" text="Блокировка" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="true"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[451,622][641,773]"/>
|
|
||||||
<node index="4" text="История" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="true"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[30,788][352,880]"/>
|
|
||||||
<node index="5" text="Действия" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="true"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[367,788][691,880]"/>
|
|
||||||
<node index="6" text="" resource-id=""
|
|
||||||
class="android.view.View" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,880][720,1439]">
|
|
||||||
<node index="0" text="Настройки" resource-id=""
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[30,880][691,959]"/>
|
|
||||||
<node index="1" text="Новый ПИН-код" resource-id=""
|
|
||||||
class="android.widget.Button"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="true"
|
|
||||||
enabled="true" focusable="true" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[30,957][691,1072]"/>
|
|
||||||
<node index="2" text="Привязать платёжный аксессуар"
|
|
||||||
resource-id="" class="android.widget.Button"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="true"
|
|
||||||
enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[30,1070][691,1184]"/>
|
|
||||||
<node index="3" text="Лимиты и ограничения по карте"
|
|
||||||
resource-id="" class="android.widget.Button"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="true"
|
|
||||||
enabled="true" focusable="true" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[30,1180][691,1295]"/>
|
|
||||||
<node index="4" text="Переименовать" resource-id=""
|
|
||||||
class="android.widget.Button"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="true"
|
|
||||||
enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[30,1293][691,1409]"/>
|
|
||||||
<node index="5" text="Услуги" resource-id=""
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[30,1405][691,1439]"/>
|
|
||||||
<node index="6" text='Оформить овердрафт "До зарплаты"'
|
|
||||||
resource-id="" class="android.widget.Button"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="true"
|
|
||||||
enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[0,0][0,0]"/>
|
|
||||||
<node index="7" text="Снятие наличных по QR-коду"
|
|
||||||
resource-id="" class="android.widget.Button"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="true"
|
|
||||||
enabled="true" focusable="true" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[0,0][0,0]"/>
|
|
||||||
<node index="8" text="Подключить автопополнение"
|
|
||||||
resource-id="" class="android.widget.Button"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="true"
|
|
||||||
enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[0,0][0,0]"/>
|
|
||||||
<node index="9" text="Уведомления по счету"
|
|
||||||
resource-id="" class="android.widget.Button"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="true"
|
|
||||||
enabled="true" focusable="true" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[0,0][0,0]"/>
|
|
||||||
<node index="10" text="Выпустить карту" resource-id=""
|
|
||||||
class="android.widget.Button"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="true"
|
|
||||||
enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[0,0][0,0]"/>
|
|
||||||
<node index="11" text="Ссылка для пополнения карты"
|
|
||||||
resource-id="" class="android.widget.Button"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="true"
|
|
||||||
enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[0,0][0,0]"/>
|
|
||||||
<node index="12" text="Сформировать справку"
|
|
||||||
resource-id="" class="android.widget.Button"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="true"
|
|
||||||
enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[0,0][0,0]"/>
|
|
||||||
<node index="13" text="Информация" resource-id=""
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,0][0,0]"/>
|
|
||||||
<node index="14" text="Реквизиты карты" resource-id=""
|
|
||||||
class="android.widget.Button"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="true"
|
|
||||||
enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[0,0][0,0]"/>
|
|
||||||
<node index="15" text="Выписка" resource-id=""
|
|
||||||
class="android.widget.Button"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="true"
|
|
||||||
enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[0,0][0,0]"/>
|
|
||||||
<node index="16"
|
|
||||||
text="Подключенные программы страхования"
|
|
||||||
resource-id="" class="android.widget.Button"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="true"
|
|
||||||
enabled="true" focusable="true" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[0,0][0,0]"/>
|
|
||||||
<node index="17" text="Анализ финансов" resource-id=""
|
|
||||||
class="android.widget.Button"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="true"
|
|
||||||
enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[0,0][0,0]"/>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
<node index="1" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,1377][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,1377][720,1439]">
|
|
||||||
<node index="0" text="Главная" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[1,1377][148,1439]"/>
|
|
||||||
<node index="1" text="История" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[144,1377][290,1439]"/>
|
|
||||||
<node index="2" text="Своё" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[286,1377][433,1439]"/>
|
|
||||||
<node index="3" text="Платежи" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[429,1377][575,1439]"/>
|
|
||||||
<node index="4" text="Ещё" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[571,1377][718,1439]"/>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
<node index="2" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,0][0,0]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,0][0,0]">
|
|
||||||
<node index="0" text="В банк" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,0][0,0]"/>
|
|
||||||
<node index="1" text="Кабинет" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,0][0,0]"/>
|
|
||||||
<node index="2" text="Продажи" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,0][0,0]"/>
|
|
||||||
<node index="3" text="Налоги" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,0][0,0]"/>
|
|
||||||
<node index="4" text="Профиль" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,0][0,0]"/>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
<node index="1" text="" resource-id="" class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,0][0,0]"/>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
<node index="1" text="" resource-id="android:id/statusBarBackground" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,0][720,82]"/>
|
|
||||||
<node index="2" text="" resource-id="android:id/navigationBarBackground" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,0][0,0]"/>
|
|
||||||
</node>
|
|
||||||
</hierarchy>
|
|
||||||
|
Before Width: | Height: | Size: 189 KiB |
@ -1,898 +0,0 @@
|
|||||||
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
|
|
||||||
<hierarchy rotation="0">
|
|
||||||
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false" selected="false" bounds="[0,0][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.widget.LinearLayout" package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false" selected="false" bounds="[0,0][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="ru.rshb.dbo:id/action_bar_root" class="android.widget.LinearLayout"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="android:id/content" class="android.widget.FrameLayout"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.webkit.WebView" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.webkit.WebView" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="true" focused="true" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,82][720,166]">
|
|
||||||
<node index="0" text="" resource-id=""
|
|
||||||
class="android.view.View" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[7,89][78,157]">
|
|
||||||
<node index="0" text="Назад" resource-id=""
|
|
||||||
class="android.widget.Button"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="true"
|
|
||||||
enabled="true" focusable="true" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[7,89][69,157]"/>
|
|
||||||
</node>
|
|
||||||
<node index="1" text="Мои продукты" resource-id=""
|
|
||||||
class="android.widget.TextView" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[86,89][350,173]"/>
|
|
||||||
<node index="2" text="" resource-id=""
|
|
||||||
class="android.widget.TextView" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[699,89][712,157]"/>
|
|
||||||
</node>
|
|
||||||
<node index="1" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="true" focused="false" scrollable="true"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,160][720,1379]">
|
|
||||||
<node index="0" text="" resource-id=""
|
|
||||||
class="android.view.View" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,162][720,588]">
|
|
||||||
<node index="0" text="" resource-id=""
|
|
||||||
class="android.view.View" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,162][720,588]">
|
|
||||||
<node index="0" text="" resource-id=""
|
|
||||||
class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[0,0][0,0]">
|
|
||||||
<node index="0" text="" resource-id=""
|
|
||||||
class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[0,162][80,588]">
|
|
||||||
<node index="0" text="" resource-id=""
|
|
||||||
class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false"
|
|
||||||
scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[0,237][24,588]">
|
|
||||||
<node index="0" text="" resource-id=""
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[0,82][258,382]"/>
|
|
||||||
<node index="1" text="" resource-id=""
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[0,0][0,0]"/>
|
|
||||||
<node index="2" text="" resource-id=""
|
|
||||||
class="android.view.View"
|
|
||||||
package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[0,0][0,0]">
|
|
||||||
<node index="0" text=""
|
|
||||||
resource-id=""
|
|
||||||
class="android.view.View"
|
|
||||||
package="ru.rshb.dbo"
|
|
||||||
content-desc=""
|
|
||||||
checkable="false"
|
|
||||||
checked="false"
|
|
||||||
clickable="false"
|
|
||||||
enabled="true"
|
|
||||||
focusable="false"
|
|
||||||
focused="false"
|
|
||||||
scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[0,0][0,0]">
|
|
||||||
<node index="0" text="160"
|
|
||||||
resource-id="aft-operationHistory-money"
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo"
|
|
||||||
content-desc=""
|
|
||||||
checkable="false"
|
|
||||||
checked="false"
|
|
||||||
clickable="false"
|
|
||||||
enabled="true"
|
|
||||||
focusable="false"
|
|
||||||
focused="false"
|
|
||||||
scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[0,0][0,0]"/>
|
|
||||||
<node index="1" text="точка 00"
|
|
||||||
resource-id=""
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo"
|
|
||||||
content-desc=""
|
|
||||||
checkable="false"
|
|
||||||
checked="false"
|
|
||||||
clickable="false"
|
|
||||||
enabled="true"
|
|
||||||
focusable="false"
|
|
||||||
focused="false"
|
|
||||||
scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[0,0][0,0]"/>
|
|
||||||
<node index="2" text="Рубль"
|
|
||||||
resource-id=""
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo"
|
|
||||||
content-desc=""
|
|
||||||
checkable="false"
|
|
||||||
checked="false"
|
|
||||||
clickable="false"
|
|
||||||
enabled="true"
|
|
||||||
focusable="false"
|
|
||||||
focused="false"
|
|
||||||
scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[0,0][0,0]"/>
|
|
||||||
<node index="3" text=""
|
|
||||||
resource-id=""
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo"
|
|
||||||
content-desc=""
|
|
||||||
checkable="false"
|
|
||||||
checked="false"
|
|
||||||
clickable="false"
|
|
||||||
enabled="true"
|
|
||||||
focusable="false"
|
|
||||||
focused="false"
|
|
||||||
scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[0,0][0,0]"/>
|
|
||||||
</node>
|
|
||||||
<node index="1"
|
|
||||||
text="Классическая карта МИР Моментального выпуска (Своя карта)"
|
|
||||||
resource-id=""
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo"
|
|
||||||
content-desc=""
|
|
||||||
checkable="false"
|
|
||||||
checked="false"
|
|
||||||
clickable="false"
|
|
||||||
enabled="true"
|
|
||||||
focusable="false"
|
|
||||||
focused="false"
|
|
||||||
scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[0,0][0,0]"/>
|
|
||||||
<node index="2" text="дебетовая"
|
|
||||||
resource-id=""
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo"
|
|
||||||
content-desc=""
|
|
||||||
checkable="false"
|
|
||||||
checked="false"
|
|
||||||
clickable="false"
|
|
||||||
enabled="true"
|
|
||||||
focusable="false"
|
|
||||||
focused="false"
|
|
||||||
scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[0,0][0,0]"/>
|
|
||||||
<node index="3" text="** 5264"
|
|
||||||
resource-id=""
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo"
|
|
||||||
content-desc=""
|
|
||||||
checkable="false"
|
|
||||||
checked="false"
|
|
||||||
clickable="false"
|
|
||||||
enabled="true"
|
|
||||||
focusable="false"
|
|
||||||
focused="false"
|
|
||||||
scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[0,0][0,0]"/>
|
|
||||||
<node NAF="true" index="4" text=""
|
|
||||||
resource-id=""
|
|
||||||
class="android.widget.Button"
|
|
||||||
package="ru.rshb.dbo"
|
|
||||||
content-desc=""
|
|
||||||
checkable="false"
|
|
||||||
checked="false"
|
|
||||||
clickable="true"
|
|
||||||
enabled="true"
|
|
||||||
focusable="true"
|
|
||||||
focused="false"
|
|
||||||
scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[0,0][0,0]"/>
|
|
||||||
<node index="5" text=""
|
|
||||||
resource-id=""
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo"
|
|
||||||
content-desc=""
|
|
||||||
checkable="false"
|
|
||||||
checked="false"
|
|
||||||
clickable="false"
|
|
||||||
enabled="true"
|
|
||||||
focusable="false"
|
|
||||||
focused="false"
|
|
||||||
scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[0,0][0,0]"/>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
<node index="1" text="" resource-id=""
|
|
||||||
class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[0,162][720,588]">
|
|
||||||
<node index="0" text="" resource-id=""
|
|
||||||
class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false"
|
|
||||||
scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[54,237][665,588]">
|
|
||||||
<node index="0" text="" resource-id=""
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[296,82][720,382]"/>
|
|
||||||
<node index="1" text="" resource-id=""
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[0,443][423,860]"/>
|
|
||||||
<node index="2" text="" resource-id=""
|
|
||||||
class="android.view.View"
|
|
||||||
package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[99,277][620,550]">
|
|
||||||
<node index="0" text=""
|
|
||||||
resource-id=""
|
|
||||||
class="android.view.View"
|
|
||||||
package="ru.rshb.dbo"
|
|
||||||
content-desc=""
|
|
||||||
checkable="false"
|
|
||||||
checked="false"
|
|
||||||
clickable="false"
|
|
||||||
enabled="true"
|
|
||||||
focusable="false"
|
|
||||||
focused="false"
|
|
||||||
scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[99,312][620,368]">
|
|
||||||
<node index="0" text="280"
|
|
||||||
resource-id="aft-operationHistory-money"
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo"
|
|
||||||
content-desc=""
|
|
||||||
checkable="false"
|
|
||||||
checked="false"
|
|
||||||
clickable="false"
|
|
||||||
enabled="true"
|
|
||||||
focusable="false"
|
|
||||||
focused="false"
|
|
||||||
scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[99,312][178,367]"/>
|
|
||||||
<node index="1" text="точка 00"
|
|
||||||
resource-id=""
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo"
|
|
||||||
content-desc=""
|
|
||||||
checkable="false"
|
|
||||||
checked="false"
|
|
||||||
clickable="false"
|
|
||||||
enabled="true"
|
|
||||||
focusable="false"
|
|
||||||
focused="false"
|
|
||||||
scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[174,312][240,367]"/>
|
|
||||||
<node index="2" text="Рубль"
|
|
||||||
resource-id=""
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo"
|
|
||||||
content-desc=""
|
|
||||||
checkable="false"
|
|
||||||
checked="false"
|
|
||||||
clickable="false"
|
|
||||||
enabled="true"
|
|
||||||
focusable="false"
|
|
||||||
focused="false"
|
|
||||||
scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[249,312][277,367]"/>
|
|
||||||
<node index="3" text=""
|
|
||||||
resource-id=""
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo"
|
|
||||||
content-desc=""
|
|
||||||
checkable="false"
|
|
||||||
checked="false"
|
|
||||||
clickable="false"
|
|
||||||
enabled="true"
|
|
||||||
focusable="false"
|
|
||||||
focused="false"
|
|
||||||
scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[275,312][333,368]"/>
|
|
||||||
</node>
|
|
||||||
<node index="1"
|
|
||||||
text="Классическая карта МИР"
|
|
||||||
resource-id=""
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo"
|
|
||||||
content-desc=""
|
|
||||||
checkable="false"
|
|
||||||
checked="false"
|
|
||||||
clickable="false"
|
|
||||||
enabled="true"
|
|
||||||
focusable="false"
|
|
||||||
focused="false"
|
|
||||||
scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[99,380][620,421]"/>
|
|
||||||
<node index="2" text="дебетовая"
|
|
||||||
resource-id=""
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo"
|
|
||||||
content-desc=""
|
|
||||||
checkable="false"
|
|
||||||
checked="false"
|
|
||||||
clickable="false"
|
|
||||||
enabled="true"
|
|
||||||
focusable="false"
|
|
||||||
focused="false"
|
|
||||||
scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[99,419][620,458]"/>
|
|
||||||
<node index="3" text="** 7183"
|
|
||||||
resource-id=""
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo"
|
|
||||||
content-desc=""
|
|
||||||
checkable="false"
|
|
||||||
checked="false"
|
|
||||||
clickable="false"
|
|
||||||
enabled="true"
|
|
||||||
focusable="false"
|
|
||||||
focused="false"
|
|
||||||
scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[99,517][620,550]"/>
|
|
||||||
<node NAF="true" index="4" text=""
|
|
||||||
resource-id=""
|
|
||||||
class="android.widget.Button"
|
|
||||||
package="ru.rshb.dbo"
|
|
||||||
content-desc=""
|
|
||||||
checkable="false"
|
|
||||||
checked="false"
|
|
||||||
clickable="true"
|
|
||||||
enabled="true"
|
|
||||||
focusable="true"
|
|
||||||
focused="false"
|
|
||||||
scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[571,277][620,322]"/>
|
|
||||||
<node index="5" text=""
|
|
||||||
resource-id=""
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo"
|
|
||||||
content-desc=""
|
|
||||||
checkable="false"
|
|
||||||
checked="false"
|
|
||||||
clickable="false"
|
|
||||||
enabled="true"
|
|
||||||
focusable="false"
|
|
||||||
focused="false"
|
|
||||||
scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[541,524][639,550]"/>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
<node index="1" text="" resource-id=""
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[54,172][665,211]"/>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
<node index="1" text="Пополнить" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="true"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[78,622][268,773]"/>
|
|
||||||
<node index="2" text="Оплатить" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="true"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[264,622][455,773]"/>
|
|
||||||
<node index="3" text="Блокировка" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="true"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[451,622][641,773]"/>
|
|
||||||
<node index="4" text="История" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="true"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[30,788][352,880]"/>
|
|
||||||
<node index="5" text="Действия" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="true"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[367,788][691,880]"/>
|
|
||||||
<node index="6" text="" resource-id=""
|
|
||||||
class="android.view.View" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,880][720,1439]">
|
|
||||||
<node index="0" text="" resource-id=""
|
|
||||||
class="android.view.View" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,880][720,1439]">
|
|
||||||
<node index="0" text="" resource-id=""
|
|
||||||
class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[0,880][720,1439]">
|
|
||||||
<node index="0" text=""
|
|
||||||
resource-id="tab-content-12"
|
|
||||||
class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[0,0][0,0]"/>
|
|
||||||
<node index="1" text=""
|
|
||||||
resource-id="tab-content-13"
|
|
||||||
class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[0,880][720,1439]">
|
|
||||||
<node index="0" text="" resource-id=""
|
|
||||||
class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false"
|
|
||||||
scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[0,880][720,1439]">
|
|
||||||
<node index="0" text="" resource-id=""
|
|
||||||
class="android.view.View"
|
|
||||||
package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[0,880][720,1025]">
|
|
||||||
<node index="0"
|
|
||||||
text="27.04.25 29.04.25"
|
|
||||||
resource-id=""
|
|
||||||
class="android.widget.Button"
|
|
||||||
package="ru.rshb.dbo"
|
|
||||||
content-desc=""
|
|
||||||
checkable="false"
|
|
||||||
checked="false"
|
|
||||||
clickable="true"
|
|
||||||
enabled="true"
|
|
||||||
focusable="true"
|
|
||||||
focused="false"
|
|
||||||
scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[277,910][423,995]"/>
|
|
||||||
<node index="1" text=""
|
|
||||||
resource-id=""
|
|
||||||
class="android.view.View"
|
|
||||||
package="ru.rshb.dbo"
|
|
||||||
content-desc=""
|
|
||||||
checkable="false"
|
|
||||||
checked="false"
|
|
||||||
clickable="false"
|
|
||||||
enabled="true"
|
|
||||||
focusable="false"
|
|
||||||
focused="false"
|
|
||||||
scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[30,910][264,995]">
|
|
||||||
<node index="0"
|
|
||||||
text="Все операции "
|
|
||||||
resource-id=""
|
|
||||||
class="android.widget.Button"
|
|
||||||
package="ru.rshb.dbo"
|
|
||||||
content-desc=""
|
|
||||||
checkable="false"
|
|
||||||
checked="false"
|
|
||||||
clickable="true"
|
|
||||||
enabled="true"
|
|
||||||
focusable="true"
|
|
||||||
focused="false"
|
|
||||||
scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[50,937][241,968]"/>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
<node index="1" text="" resource-id=""
|
|
||||||
class="android.view.View"
|
|
||||||
package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[0,1023][720,1439]">
|
|
||||||
<node index="0"
|
|
||||||
text="Сегодня, Вторник Перевод ВЛАДИСЛАВ НИКОЛАЕВИЧ К** в Т-Банк через СБП, по номеру телефона +7985553... Минус 10 рублей 0 копеек"
|
|
||||||
resource-id=""
|
|
||||||
class="android.widget.Button"
|
|
||||||
package="ru.rshb.dbo"
|
|
||||||
content-desc=""
|
|
||||||
checkable="false"
|
|
||||||
checked="false"
|
|
||||||
clickable="true"
|
|
||||||
enabled="true"
|
|
||||||
focusable="true"
|
|
||||||
focused="false"
|
|
||||||
scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[0,1023][720,1349]"/>
|
|
||||||
<node index="1"
|
|
||||||
text="DBO TRANSFER RSHB INTERNET-BANK Минус 10 рублей 0 копеек"
|
|
||||||
resource-id=""
|
|
||||||
class="android.widget.Button"
|
|
||||||
package="ru.rshb.dbo"
|
|
||||||
content-desc=""
|
|
||||||
checkable="false"
|
|
||||||
checked="false"
|
|
||||||
clickable="true"
|
|
||||||
enabled="true"
|
|
||||||
focusable="true"
|
|
||||||
focused="false"
|
|
||||||
scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[0,1343][720,1439]"/>
|
|
||||||
<node index="2"
|
|
||||||
text="Вчера, Понедельник P2P DBO RSHB INTERNET-BANK Плюс 300 рублей 0 копеек"
|
|
||||||
resource-id=""
|
|
||||||
class="android.widget.Button"
|
|
||||||
package="ru.rshb.dbo"
|
|
||||||
content-desc=""
|
|
||||||
checkable="false"
|
|
||||||
checked="false"
|
|
||||||
clickable="true"
|
|
||||||
enabled="true"
|
|
||||||
focusable="true"
|
|
||||||
focused="false"
|
|
||||||
scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false"
|
|
||||||
selected="false"
|
|
||||||
bounds="[0,0][0,0]"/>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
<node index="1" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,1377][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,1377][720,1439]">
|
|
||||||
<node index="0" text="Главная" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[1,1377][148,1439]"/>
|
|
||||||
<node index="1" text="История" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[144,1377][290,1439]"/>
|
|
||||||
<node index="2" text="Своё" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[286,1377][433,1439]"/>
|
|
||||||
<node index="3" text="Платежи" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[429,1377][575,1439]"/>
|
|
||||||
<node index="4" text="Ещё" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[571,1377][718,1439]"/>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
<node index="2" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,0][0,0]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,0][0,0]">
|
|
||||||
<node index="0" text="В банк" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,0][0,0]"/>
|
|
||||||
<node index="1" text="Кабинет" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,0][0,0]"/>
|
|
||||||
<node index="2" text="Продажи" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,0][0,0]"/>
|
|
||||||
<node index="3" text="Налоги" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,0][0,0]"/>
|
|
||||||
<node index="4" text="Профиль" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,0][0,0]"/>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
<node index="1" text="" resource-id="" class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,0][0,0]"/>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
<node index="1" text="" resource-id="android:id/statusBarBackground" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,0][720,82]"/>
|
|
||||||
<node index="2" text="" resource-id="android:id/navigationBarBackground" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,0][0,0]"/>
|
|
||||||
</node>
|
|
||||||
</hierarchy>
|
|
||||||
|
Before Width: | Height: | Size: 142 KiB |
@ -1,111 +0,0 @@
|
|||||||
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
|
|
||||||
<hierarchy rotation="0">
|
|
||||||
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false" selected="false" bounds="[0,0][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.widget.LinearLayout" package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false" selected="false" bounds="[0,0][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="ru.rshb.dbo:id/action_bar_root" class="android.widget.LinearLayout"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="android:id/content" class="android.widget.FrameLayout"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.webkit.WebView" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.webkit.WebView" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="true" focused="true" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,0][0,0]"/>
|
|
||||||
<node index="1" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,82][720,1439]"/>
|
|
||||||
<node index="1" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,1126][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,1126][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,1186][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,1186][720,1439]">
|
|
||||||
<node index="0" text="РСХБ Онлайн" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="true"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[0,1186][720,1283]"/>
|
|
||||||
<node index="1" text="Зачисления" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="true"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[0,1278][720,1375]"/>
|
|
||||||
<node index="2" text="Все операции" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="true"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[0,1372][720,1439]"/>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
<node index="1" text="" resource-id="android:id/statusBarBackground" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,0][720,82]"/>
|
|
||||||
<node index="2" text="" resource-id="android:id/navigationBarBackground" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,0][0,0]"/>
|
|
||||||
</node>
|
|
||||||
</hierarchy>
|
|
||||||
|
Before Width: | Height: | Size: 106 KiB |
@ -1,89 +0,0 @@
|
|||||||
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
|
|
||||||
<hierarchy rotation="0">
|
|
||||||
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false" selected="false" bounds="[0,0][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.widget.LinearLayout" package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false" selected="false" bounds="[0,0][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="ru.rshb.dbo:id/action_bar_root" class="android.widget.LinearLayout"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="android:id/content" class="android.widget.FrameLayout"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.webkit.WebView" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.webkit.WebView" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="true" focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,82][720,1439]"/>
|
|
||||||
<node index="1" text="" resource-id="" class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,0][0,0]"/>
|
|
||||||
<node index="2" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="Ошибка" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="true" focused="true"
|
|
||||||
scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[95,627][624,965]">
|
|
||||||
<node index="0"
|
|
||||||
text="Невозможно зачислить сумму перевода на счет Получателя"
|
|
||||||
resource-id="" class="android.widget.TextView" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[140,751][579,830]"/>
|
|
||||||
<node index="1" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[95,865][624,965]">
|
|
||||||
<node index="0" text="Ок" resource-id="" class="android.widget.Button"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="true" enabled="true" focusable="true"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[485,880][609,950]"/>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
<node index="1" text="" resource-id="android:id/statusBarBackground" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,0][720,82]"/>
|
|
||||||
<node index="2" text="" resource-id="android:id/navigationBarBackground" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,0][0,0]"/>
|
|
||||||
</node>
|
|
||||||
</hierarchy>
|
|
||||||
|
Before Width: | Height: | Size: 106 KiB |
|
Before Width: | Height: | Size: 145 KiB |
@ -1,307 +0,0 @@
|
|||||||
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
|
|
||||||
<hierarchy rotation="0">
|
|
||||||
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false" selected="false" bounds="[0,0][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.widget.LinearLayout" package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false" selected="false" bounds="[0,0][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="ru.rshb.dbo:id/action_bar_root" class="android.widget.LinearLayout"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="android:id/content" class="android.widget.FrameLayout"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.webkit.WebView" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.webkit.WebView" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="true" focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id=""
|
|
||||||
class="android.view.View" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id=""
|
|
||||||
class="android.view.View" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id=""
|
|
||||||
class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[30,112][251,202]">
|
|
||||||
<node index="0" text="Меню" resource-id=""
|
|
||||||
class="android.widget.Button"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true"
|
|
||||||
focusable="true" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[30,112][88,202]"/>
|
|
||||||
</node>
|
|
||||||
<node index="1" text="Кю Ар сканер" resource-id=""
|
|
||||||
class="android.widget.Button"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true"
|
|
||||||
focusable="true" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[545,112][605,202]"/>
|
|
||||||
<node index="2"
|
|
||||||
text="Уведомления. Новых уведомлений нет"
|
|
||||||
resource-id="" class="android.widget.Button"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true"
|
|
||||||
focusable="true" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[631,112][691,202]"/>
|
|
||||||
<node index="3" text="Введите ПИН" resource-id=""
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true"
|
|
||||||
focusable="true" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[90,408][630,451]"/>
|
|
||||||
<node index="4" text="1" resource-id=""
|
|
||||||
class="android.widget.Button"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true"
|
|
||||||
focusable="true" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[108,547][253,689]"/>
|
|
||||||
<node index="5" text="2" resource-id=""
|
|
||||||
class="android.widget.Button"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true"
|
|
||||||
focusable="true" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[288,547][431,689]"/>
|
|
||||||
<node index="6" text="3" resource-id=""
|
|
||||||
class="android.widget.Button"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true"
|
|
||||||
focusable="true" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[466,547][611,689]"/>
|
|
||||||
<node index="7" text="4" resource-id=""
|
|
||||||
class="android.widget.Button"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true"
|
|
||||||
focusable="true" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[108,727][253,869]"/>
|
|
||||||
<node index="8" text="5" resource-id=""
|
|
||||||
class="android.widget.Button"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true"
|
|
||||||
focusable="true" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[288,727][431,869]"/>
|
|
||||||
<node index="9" text="6" resource-id=""
|
|
||||||
class="android.widget.Button"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true"
|
|
||||||
focusable="true" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[466,727][611,869]"/>
|
|
||||||
<node index="10" text="7" resource-id=""
|
|
||||||
class="android.widget.Button"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true"
|
|
||||||
focusable="true" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[108,905][253,1049]"/>
|
|
||||||
<node index="11" text="8" resource-id=""
|
|
||||||
class="android.widget.Button"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true"
|
|
||||||
focusable="true" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[288,905][431,1049]"/>
|
|
||||||
<node index="12" text="9" resource-id=""
|
|
||||||
class="android.widget.Button"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true"
|
|
||||||
focusable="true" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[466,905][611,1049]"/>
|
|
||||||
<node index="13" text="0" resource-id=""
|
|
||||||
class="android.widget.Button"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true"
|
|
||||||
focusable="true" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[288,1083][431,1227]"/>
|
|
||||||
<node index="14" text="Стереть" resource-id=""
|
|
||||||
class="android.widget.Button"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true"
|
|
||||||
focusable="true" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[466,1083][611,1227]"/>
|
|
||||||
<node index="15" text="Выйти" resource-id=""
|
|
||||||
class="android.widget.Button"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true"
|
|
||||||
focusable="true" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[90,1263][630,1302]"/>
|
|
||||||
<node index="16" text=""
|
|
||||||
resource-id="loginEnterResults"
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[88,1297][93,1302]"/>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
<node index="1" text="" resource-id="" class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,82][720,1439]"/>
|
|
||||||
<node index="2" text="" resource-id="" class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,0][0,0]"/>
|
|
||||||
<node index="3" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="Внимание" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="true" focused="true"
|
|
||||||
scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[95,644][624,946]">
|
|
||||||
<node index="0" text="Сессия завершена" resource-id=""
|
|
||||||
class="android.widget.TextView" package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[95,772][624,848]"/>
|
|
||||||
<node index="1" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[95,847][624,946]">
|
|
||||||
<node index="0" text="Ок" resource-id="" class="android.widget.Button"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="true" enabled="true" focusable="true"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[485,862][609,931]"/>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
<node index="1" text="" resource-id="android:id/statusBarBackground" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,0][720,82]"/>
|
|
||||||
<node index="2" text="" resource-id="android:id/navigationBarBackground" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,0][0,0]"/>
|
|
||||||
</node>
|
|
||||||
</hierarchy>
|
|
||||||
|
Before Width: | Height: | Size: 79 KiB |
@ -1,307 +0,0 @@
|
|||||||
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
|
|
||||||
<hierarchy rotation="0">
|
|
||||||
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false" selected="false" bounds="[0,0][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.widget.LinearLayout" package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false" selected="false" bounds="[0,0][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="ru.rshb.dbo:id/action_bar_root" class="android.widget.LinearLayout"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="android:id/content" class="android.widget.FrameLayout"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.webkit.WebView" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.webkit.WebView" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="true" focused="true" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,82][720,166]">
|
|
||||||
<node index="0" text="" resource-id=""
|
|
||||||
class="android.view.View" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[7,89][78,157]">
|
|
||||||
<node index="0" text="Назад" resource-id=""
|
|
||||||
class="android.widget.Button"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="true"
|
|
||||||
enabled="true" focusable="true" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[7,89][69,157]"/>
|
|
||||||
</node>
|
|
||||||
<node index="1" text="Выписка" resource-id=""
|
|
||||||
class="android.widget.TextView" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[86,89][260,173]"/>
|
|
||||||
<node index="2" text="" resource-id=""
|
|
||||||
class="android.view.View" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[641,89][712,157]">
|
|
||||||
<node index="0"
|
|
||||||
text="Информирование о сроке отображения операций по счету"
|
|
||||||
resource-id="aft-rbtnClass-buttonIcon"
|
|
||||||
class="android.widget.Button"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="true"
|
|
||||||
enabled="true" focusable="true" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[650,89][712,157]"/>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
<node index="1" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,160][720,1379]">
|
|
||||||
<node index="0" text="" resource-id=""
|
|
||||||
class="android.view.View" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,160][720,1379]">
|
|
||||||
<node index="0" text="" resource-id=""
|
|
||||||
class="android.view.View" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,162][720,571]">
|
|
||||||
<node index="0" text="по счету 40817 .... 2077"
|
|
||||||
resource-id="" class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[206,205][513,258]"/>
|
|
||||||
<node index="1"
|
|
||||||
text="Период с 02.06.2025 по 04.06.2025 More"
|
|
||||||
resource-id="" class="android.widget.Button"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true"
|
|
||||||
focusable="true" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[0,295][720,391]"/>
|
|
||||||
<node index="2"
|
|
||||||
text="Подтвержденные Ожидающие обработки"
|
|
||||||
resource-id="" class="android.widget.Button"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true"
|
|
||||||
focusable="true" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[0,383][720,477]"/>
|
|
||||||
<node index="3" text="" resource-id=""
|
|
||||||
class="android.widget.ListView"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[0,475][720,475]"/>
|
|
||||||
<node index="4"
|
|
||||||
text="Операции с 02.06.2025 по 04.06.2025 отсутствуют"
|
|
||||||
resource-id="" class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[0,475][720,569]"/>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
<node index="2" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[575,1235][684,1343]">
|
|
||||||
<node index="0" text="Отправить" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="true"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[575,1235][684,1343]"/>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
<node index="1" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,1377][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,1377][720,1439]">
|
|
||||||
<node index="0" text="Главная" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[1,1377][148,1439]"/>
|
|
||||||
<node index="1" text="История" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[144,1377][290,1439]"/>
|
|
||||||
<node index="2" text="Своё" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[286,1377][433,1439]"/>
|
|
||||||
<node index="3" text="Платежи" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[429,1377][575,1439]"/>
|
|
||||||
<node index="4" text="Ещё" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[571,1377][718,1439]"/>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
<node index="2" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,0][0,0]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,0][0,0]">
|
|
||||||
<node index="0" text="В банк" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,0][0,0]"/>
|
|
||||||
<node index="1" text="Кабинет" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,0][0,0]"/>
|
|
||||||
<node index="2" text="Продажи" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,0][0,0]"/>
|
|
||||||
<node index="3" text="Налоги" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,0][0,0]"/>
|
|
||||||
<node index="4" text="Профиль" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,0][0,0]"/>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
<node index="1" text="" resource-id="" class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,0][0,0]"/>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
<node index="1" text="" resource-id="android:id/statusBarBackground" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,0][720,82]"/>
|
|
||||||
<node index="2" text="" resource-id="android:id/navigationBarBackground" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,0][0,0]"/>
|
|
||||||
</node>
|
|
||||||
</hierarchy>
|
|
||||||
|
Before Width: | Height: | Size: 461 KiB |
@ -1,172 +0,0 @@
|
|||||||
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
|
|
||||||
<hierarchy rotation="0">
|
|
||||||
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false" selected="false" bounds="[0,0][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.widget.LinearLayout" package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false" selected="false" bounds="[0,0][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="ru.rshb.dbo:id/action_bar_root" class="android.widget.LinearLayout"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="android:id/content" class="android.widget.FrameLayout"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.webkit.WebView" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.webkit.WebView" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="true" focused="true" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,0][0,0]"/>
|
|
||||||
<node index="1" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,82][720,1439]"/>
|
|
||||||
<node index="1" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,284][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="aft-popup-pushNotification"
|
|
||||||
class="android.view.View" package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,284][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[15,299][706,803]">
|
|
||||||
<node index="0" text="Закрыть"
|
|
||||||
resource-id="aft-popup-pushNotification-iconClose"
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="true"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[615,329][676,393]"/>
|
|
||||||
</node>
|
|
||||||
<node index="1" text="Получайте новости с помощью push-уведомлений"
|
|
||||||
resource-id="" class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[45,742][676,893]"/>
|
|
||||||
<node index="2" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[45,892][676,1028]">
|
|
||||||
<node index="0" text="" resource-id=""
|
|
||||||
class="android.widget.TextView" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[75,940][120,987]"/>
|
|
||||||
<node index="1" text="Держите свои финансы под контролем"
|
|
||||||
resource-id="" class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[150,922][646,998]"/>
|
|
||||||
</node>
|
|
||||||
<node index="3" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[45,1028][676,1165]">
|
|
||||||
<node index="0" text="" resource-id=""
|
|
||||||
class="android.widget.TextView" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[75,1077][120,1124]"/>
|
|
||||||
<node index="1"
|
|
||||||
text="Не пропускайте специальные предложения и рекомендации"
|
|
||||||
resource-id="" class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[150,1058][646,1135]"/>
|
|
||||||
</node>
|
|
||||||
<node index="4" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[45,1165][676,1302]">
|
|
||||||
<node index="0" text="" resource-id=""
|
|
||||||
class="android.widget.TextView" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[75,1214][120,1261]"/>
|
|
||||||
<node index="1" text="Push-уведомления абсолютно бесплатны!"
|
|
||||||
resource-id="" class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[150,1195][646,1272]"/>
|
|
||||||
</node>
|
|
||||||
<node index="5" text="Позже"
|
|
||||||
resource-id="aft-popup-pushNotification-btnLater"
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="true"
|
|
||||||
enabled="true" focusable="true" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[45,1330][354,1418]"/>
|
|
||||||
<node index="6" text="Включить"
|
|
||||||
resource-id="aft-popup-pushNotification-btnEnable"
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="true"
|
|
||||||
enabled="true" focusable="true" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[365,1330][676,1418]"/>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
<node index="1" text="" resource-id="android:id/statusBarBackground" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,0][720,82]"/>
|
|
||||||
<node index="2" text="" resource-id="android:id/navigationBarBackground" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,0][0,0]"/>
|
|
||||||
</node>
|
|
||||||
</hierarchy>
|
|
||||||
|
Before Width: | Height: | Size: 372 KiB |
|
Before Width: | Height: | Size: 99 KiB |
|
Before Width: | Height: | Size: 86 KiB |
@ -1,333 +0,0 @@
|
|||||||
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
|
|
||||||
<hierarchy rotation="0">
|
|
||||||
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false" selected="false" bounds="[0,0][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.widget.LinearLayout" package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false" selected="false" bounds="[0,0][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="ru.rshb.dbo:id/action_bar_root" class="android.widget.LinearLayout"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="android:id/content" class="android.widget.FrameLayout"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.webkit.WebView" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.webkit.WebView" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="true" focused="true" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,82][720,166]">
|
|
||||||
<node index="0" text="" resource-id=""
|
|
||||||
class="android.view.View" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[7,89][78,157]">
|
|
||||||
<node index="0" text="Назад" resource-id=""
|
|
||||||
class="android.widget.Button"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="true"
|
|
||||||
enabled="true" focusable="true" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[7,89][69,157]"/>
|
|
||||||
</node>
|
|
||||||
<node index="1" text="Перевод по телефону" resource-id=""
|
|
||||||
class="android.widget.TextView" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[86,89][461,173]"/>
|
|
||||||
<node index="2" text="" resource-id=""
|
|
||||||
class="android.widget.TextView" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[699,89][712,157]"/>
|
|
||||||
</node>
|
|
||||||
<node index="1" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,162][720,290]">
|
|
||||||
<node index="0" text="" resource-id=""
|
|
||||||
class="android.view.View" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[26,160][693,239]">
|
|
||||||
<node NAF="true" index="0" text="" resource-id=""
|
|
||||||
class="android.widget.EditText"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="true"
|
|
||||||
enabled="true" focusable="true" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[58,179][663,220]"/>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
<node index="2" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,284][720,1379]">
|
|
||||||
<node index="0" text="" resource-id=""
|
|
||||||
class="android.view.View" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,284][720,1379]">
|
|
||||||
<node index="0" text="" resource-id=""
|
|
||||||
class="android.view.View" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,286][720,1379]">
|
|
||||||
<node index="0" text="" resource-id=""
|
|
||||||
class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[0,286][720,1379]">
|
|
||||||
<node index="0" text="" resource-id=""
|
|
||||||
class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[78,760][678,907]">
|
|
||||||
<node index="0"
|
|
||||||
text="Для перевода средств по номеру телефона предоставьте доступ к адресной книге в настройках смартфона"
|
|
||||||
resource-id=""
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false"
|
|
||||||
scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[86,760][671,869]"/>
|
|
||||||
<node index="1" text=" " resource-id=""
|
|
||||||
class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false"
|
|
||||||
scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[667,832][667,869]"/>
|
|
||||||
<node index="2" text="" resource-id=""
|
|
||||||
class="android.view.View"
|
|
||||||
package="ru.rshb.dbo"
|
|
||||||
content-desc="Перейти в настройки"
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true"
|
|
||||||
focusable="false" focused="false"
|
|
||||||
scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[226,867][530,905]">
|
|
||||||
<node index="0"
|
|
||||||
text="Перейти в настройки"
|
|
||||||
resource-id=""
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[226,867][530,905]"/>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
<node index="1" text=""
|
|
||||||
resource-id="phonebookSearchResult"
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[33,1373][39,1377]"/>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
<node index="1" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,1377][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,1377][720,1439]">
|
|
||||||
<node index="0" text="Главная" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[1,1377][148,1439]"/>
|
|
||||||
<node index="1" text="История" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[144,1377][290,1439]"/>
|
|
||||||
<node index="2" text="Своё" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[286,1377][433,1439]"/>
|
|
||||||
<node index="3" text="Платежи" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[429,1377][575,1439]"/>
|
|
||||||
<node index="4" text="Ещё" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[571,1377][718,1439]"/>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
<node index="2" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,0][0,0]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,0][0,0]">
|
|
||||||
<node index="0" text="В банк" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,0][0,0]"/>
|
|
||||||
<node index="1" text="Кабинет" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,0][0,0]"/>
|
|
||||||
<node index="2" text="Продажи" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,0][0,0]"/>
|
|
||||||
<node index="3" text="Налоги" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,0][0,0]"/>
|
|
||||||
<node index="4" text="Профиль" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,0][0,0]"/>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
<node index="1" text="" resource-id="" class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,0][0,0]"/>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
<node index="1" text="" resource-id="android:id/statusBarBackground" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,0][720,82]"/>
|
|
||||||
<node index="2" text="" resource-id="android:id/navigationBarBackground" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,0][0,0]"/>
|
|
||||||
</node>
|
|
||||||
</hierarchy>
|
|
||||||
|
Before Width: | Height: | Size: 97 KiB |
@ -1,305 +0,0 @@
|
|||||||
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
|
|
||||||
<hierarchy rotation="0">
|
|
||||||
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false" selected="false" bounds="[0,0][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.widget.LinearLayout" package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false" selected="false" bounds="[0,0][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,82][720,1031]">
|
|
||||||
<node index="0" text="" resource-id="ru.rshb.dbo:id/action_bar_root" class="android.widget.LinearLayout"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,82][720,1031]">
|
|
||||||
<node index="0" text="" resource-id="android:id/content" class="android.widget.FrameLayout"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,82][720,1031]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.webkit.WebView" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,82][720,1031]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.webkit.WebView" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="true" focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,82][720,1032]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,82][720,1032]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,82][720,1032]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,82][720,1032]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,82][720,1032]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,82][720,1032]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,82][720,1032]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,82][720,166]">
|
|
||||||
<node index="0" text="" resource-id=""
|
|
||||||
class="android.view.View" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[7,89][78,157]">
|
|
||||||
<node index="0" text="Назад" resource-id=""
|
|
||||||
class="android.widget.Button"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="true"
|
|
||||||
enabled="true" focusable="true" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[7,89][69,157]"/>
|
|
||||||
</node>
|
|
||||||
<node index="1" text="Перевод по телефону" resource-id=""
|
|
||||||
class="android.widget.TextView" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[86,89][461,173]"/>
|
|
||||||
<node index="2" text="" resource-id=""
|
|
||||||
class="android.widget.TextView" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[699,89][712,157]"/>
|
|
||||||
</node>
|
|
||||||
<node index="1" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,162][720,290]">
|
|
||||||
<node index="0" text="" resource-id=""
|
|
||||||
class="android.view.View" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[26,160][693,239]">
|
|
||||||
<node index="0" text="+7 964 181 51 46" resource-id=""
|
|
||||||
class="android.widget.EditText"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="true"
|
|
||||||
enabled="true" focusable="true" focused="true"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[58,179][605,220]"/>
|
|
||||||
<node index="1" text="Очистить" resource-id=""
|
|
||||||
class="android.widget.Button"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="true"
|
|
||||||
enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[622,170][682,230]"/>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
<node index="2" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,284][720,1032]">
|
|
||||||
<node index="0" text="" resource-id=""
|
|
||||||
class="android.view.View" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,284][720,1032]">
|
|
||||||
<node index="0" text="" resource-id=""
|
|
||||||
class="android.view.View" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,286][720,1032]">
|
|
||||||
<node index="0" text="" resource-id=""
|
|
||||||
class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[0,286][720,1032]">
|
|
||||||
<node index="0" text=" Россельхозбанк"
|
|
||||||
resource-id=""
|
|
||||||
class="android.widget.Button"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true"
|
|
||||||
focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[33,286][720,404]"/>
|
|
||||||
<node index="1" text=" Другой банк через СБП"
|
|
||||||
resource-id=""
|
|
||||||
class="android.widget.Button"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true"
|
|
||||||
focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[33,398][720,517]"/>
|
|
||||||
<node index="2" text=""
|
|
||||||
resource-id="phonebookSearchResult"
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[33,509][39,515]"/>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
<node index="1" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,1030][720,1030]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[575,1030][720,1030]">
|
|
||||||
<node index="0" text="Главная" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[31,989][112,1032]"/>
|
|
||||||
<node index="1" text="История" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[174,989][258,1032]"/>
|
|
||||||
<node index="2" text="Своё" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[290,987][429,1032]"/>
|
|
||||||
<node index="3" text="Платежи" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[459,989][547,1032]"/>
|
|
||||||
<node index="4" text="Ещё" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[624,989][671,1032]"/>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
<node index="2" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,0][0,0]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,0][0,0]">
|
|
||||||
<node index="0" text="В банк" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,0][0,0]"/>
|
|
||||||
<node index="1" text="Кабинет" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,0][0,0]"/>
|
|
||||||
<node index="2" text="Продажи" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,0][0,0]"/>
|
|
||||||
<node index="3" text="Налоги" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,0][0,0]"/>
|
|
||||||
<node index="4" text="Профиль" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,0][0,0]"/>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
<node index="1" text="" resource-id="" class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,0][0,0]"/>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
<node index="1" text="" resource-id="android:id/statusBarBackground" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,0][720,82]"/>
|
|
||||||
<node index="2" text="" resource-id="android:id/navigationBarBackground" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,0][0,0]"/>
|
|
||||||
</node>
|
|
||||||
</hierarchy>
|
|
||||||
|
Before Width: | Height: | Size: 97 KiB |
@ -1,292 +0,0 @@
|
|||||||
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
|
|
||||||
<hierarchy rotation="0">
|
|
||||||
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false" selected="false" bounds="[0,0][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.widget.LinearLayout" package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false" selected="false" bounds="[0,0][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="ru.rshb.dbo:id/action_bar_root" class="android.widget.LinearLayout"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="android:id/content" class="android.widget.FrameLayout"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.webkit.WebView" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.webkit.WebView" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="true" focused="true" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,82][720,1439]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,82][720,1377]">
|
|
||||||
<node index="0" text="" resource-id=""
|
|
||||||
class="android.view.View" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,82][720,796]">
|
|
||||||
<node index="0" text="Исполнен" resource-id=""
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[230,329][489,397]"/>
|
|
||||||
<node index="1"
|
|
||||||
text="Перевод по номеру телефона в другой банк Владислав Николаевич К."
|
|
||||||
resource-id="" class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[31,421][688,498]"/>
|
|
||||||
<node index="2" text="" resource-id=""
|
|
||||||
class="android.view.View" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[275,595][444,695]">
|
|
||||||
<node index="0" text="10"
|
|
||||||
resource-id="aft-operationHistory-money"
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[275,597][373,693]"/>
|
|
||||||
<node index="1" text="Рубль" resource-id=""
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[393,597][444,693]"/>
|
|
||||||
<node index="2" text="" resource-id=""
|
|
||||||
class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[440,595][500,633]"/>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
<node index="1" text="Детали операции" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,820][720,922]"/>
|
|
||||||
<node index="2"
|
|
||||||
text="Перевод через систему быстрых платежей"
|
|
||||||
resource-id="" class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="false"
|
|
||||||
enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[129,955][665,987]"/>
|
|
||||||
<node index="3" text="" resource-id=""
|
|
||||||
class="android.view.View" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,1027][720,1377]">
|
|
||||||
<node index="0" text="Добавить в избранное"
|
|
||||||
resource-id="saveTemplateButton"
|
|
||||||
class="android.widget.Button"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="true"
|
|
||||||
enabled="true" focusable="true" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[30,1057][691,1147]"/>
|
|
||||||
<node index="1" text="Сохранить или отправить чек"
|
|
||||||
resource-id="" class="android.widget.Button"
|
|
||||||
package="ru.rshb.dbo" content-desc=""
|
|
||||||
checkable="false" checked="false" clickable="true"
|
|
||||||
enabled="true" focusable="true" focused="false"
|
|
||||||
scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false"
|
|
||||||
bounds="[30,1165][691,1257]"/>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
<node index="1" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,1375][720,1439]">
|
|
||||||
<node index="0" text="Вернуться на главную" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="true"
|
|
||||||
focused="false" scrollable="false"
|
|
||||||
long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[30,1398][691,1439]"/>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
<node index="1" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,0][0,0]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,0][0,0]">
|
|
||||||
<node index="0" text="Главная" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,0][0,0]"/>
|
|
||||||
<node index="1" text="История" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,0][0,0]"/>
|
|
||||||
<node index="2" text="Своё" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,0][0,0]"/>
|
|
||||||
<node index="3" text="Платежи" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,0][0,0]"/>
|
|
||||||
<node index="4" text="Ещё" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,0][0,0]"/>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
<node index="2" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,0][0,0]">
|
|
||||||
<node index="0" text="" resource-id="" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false"
|
|
||||||
checked="false" clickable="false" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,0][0,0]">
|
|
||||||
<node index="0" text="В банк" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,0][0,0]"/>
|
|
||||||
<node index="1" text="Кабинет" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,0][0,0]"/>
|
|
||||||
<node index="2" text="Продажи" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,0][0,0]"/>
|
|
||||||
<node index="3" text="Налоги" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,0][0,0]"/>
|
|
||||||
<node index="4" text="Профиль" resource-id=""
|
|
||||||
class="android.widget.Button" package="ru.rshb.dbo"
|
|
||||||
content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="true" enabled="true" focusable="false"
|
|
||||||
focused="false" scrollable="false" long-clickable="false"
|
|
||||||
password="false" selected="false" bounds="[0,0][0,0]"/>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
<node index="1" text="" resource-id="" class="android.widget.TextView"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
|
|
||||||
clickable="false" enabled="true" focusable="false" focused="false"
|
|
||||||
scrollable="false" long-clickable="false" password="false" selected="false"
|
|
||||||
bounds="[0,0][0,0]"/>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
</node>
|
|
||||||
<node index="1" text="" resource-id="android:id/statusBarBackground" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,0][720,82]"/>
|
|
||||||
<node index="2" text="" resource-id="android:id/navigationBarBackground" class="android.view.View"
|
|
||||||
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
|
||||||
focusable="false" focused="false" scrollable="false" long-clickable="false" password="false"
|
|
||||||
selected="false" bounds="[0,0][0,0]"/>
|
|
||||||
</node>
|
|
||||||
</hierarchy>
|
|
||||||
|
Before Width: | Height: | Size: 101 KiB |