Daily commit
This commit is contained in:
parent
ee6de4fc5a
commit
6ded374ee8
216
android/birbank/CommonBirbankScript.cpp
Normal file
216
android/birbank/CommonBirbankScript.cpp
Normal file
@ -0,0 +1,216 @@
|
|||||||
|
#include "CommonBirbankScript.h"
|
||||||
|
|
||||||
|
#include <QJsonArray>
|
||||||
|
#include <QJsonObject>
|
||||||
|
#include <QRandomGenerator>
|
||||||
|
#include <QThread>
|
||||||
|
|
||||||
|
#include "adb/AdbUtils.h"
|
||||||
|
#include "net/NetworkService.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;
|
||||||
|
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 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;
|
||||||
|
}
|
||||||
68
android/birbank/CommonBirbankScript.h
Normal file
68
android/birbank/CommonBirbankScript.h
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
#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);
|
||||||
|
};
|
||||||
164
android/birbank/GetLastDaysHistoryBirbankScript.cpp
Normal file
164
android/birbank/GetLastDaysHistoryBirbankScript.cpp
Normal file
@ -0,0 +1,164 @@
|
|||||||
|
#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);
|
||||||
|
}
|
||||||
35
android/birbank/GetLastDaysHistoryBirbankScript.h
Normal file
35
android/birbank/GetLastDaysHistoryBirbankScript.h
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
#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
|
||||||
|
);
|
||||||
|
};
|
||||||
150
android/birbank/LoginAndCheckAccountsBirbankScript.cpp
Normal file
150
android/birbank/LoginAndCheckAccountsBirbankScript.cpp
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
#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 (false) {
|
||||||
|
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
|
||||||
|
Node cardText = xmlScreenParser.findTextNode("2480");
|
||||||
|
if (!cardText.isEmpty()) {
|
||||||
|
AdbUtils::makeTap(device.id, cardText.x(), cardText.y());
|
||||||
|
QThread::msleep(2000);
|
||||||
|
|
||||||
|
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
|
||||||
|
Node cardTitleText = xmlScreenParser.findTextNode("2480");
|
||||||
|
Node cardHistory = xmlScreenParser.findTextNode("История платежей");
|
||||||
|
if (!cardTitleText.isEmpty() && !cardHistory.isEmpty()) {
|
||||||
|
QList<TransactionInfo> transactions = xmlScreenParser.parsePositiveTransactions();
|
||||||
|
|
||||||
|
QList<TransactionInfo> savedTransactions = TransactionDAO::getTransactions(89);
|
||||||
|
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) {
|
||||||
|
TransactionInfo tr;
|
||||||
|
tr.accountId = 89;
|
||||||
|
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 = TransactionStatus::Complete;
|
||||||
|
tr.type = TransactionType::Card;
|
||||||
|
tr.completeTime = transaction.completeTime;
|
||||||
|
tr.id = TransactionDAO::insertTransaction(tr);
|
||||||
|
|
||||||
|
if (tr.id == -1) {
|
||||||
|
qDebug() << "--- saveAndPostNewTransactionData failed";
|
||||||
|
}
|
||||||
|
AccountInfo account = AccountDAO::getAccountById(89);
|
||||||
|
postNewTransactionData(account, tr);
|
||||||
|
|
||||||
|
// if (!saveAndPostNewTransactionData(m_account, transaction, TransactionStatus::Complete)) {
|
||||||
|
// qDebug() << "--- saveAndPostNewTransactionData failed";
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
m_error = "Card page not found: " + m_deviceId + " " + m_appCode;
|
||||||
|
qWarning() << m_error;
|
||||||
|
emit finishedWithResult(m_error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
m_error = "Card 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);
|
||||||
|
}
|
||||||
23
android/birbank/LoginAndCheckAccountsBirbankScript.h
Normal file
23
android/birbank/LoginAndCheckAccountsBirbankScript.h
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
#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;
|
||||||
|
};
|
||||||
732
android/birbank/ScreenXmlBirbankParser.cpp
Normal file
732
android/birbank/ScreenXmlBirbankParser.cpp
Normal file
@ -0,0 +1,732 @@
|
|||||||
|
#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) {
|
||||||
|
int year = QDate::currentDate().year(); // Или укажи вручную нужный год
|
||||||
|
QString combined = QString("%1 %2 %3").arg(date).arg(year).arg(time); // "24 июля 2025 0:31"
|
||||||
|
|
||||||
|
QLocale ruLocale(QLocale::Russian, QLocale::Russia);
|
||||||
|
QDateTime dt = ruLocale.toDateTime(combined, "d MMMM yyyy H:mm");
|
||||||
|
|
||||||
|
if (dt.isValid()) {
|
||||||
|
// Установка часового пояса Asia/Baku
|
||||||
|
dt.setTimeZone(QTimeZone("Asia/Baku"));
|
||||||
|
// Перевод в UTC
|
||||||
|
QDateTime utc = dt.toTimeZone(QTimeZone::utc());
|
||||||
|
return utc;
|
||||||
|
} else {
|
||||||
|
qWarning() << "Ошибка разбора даты/времени";
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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);
|
||||||
|
// ЕСПП
|
||||||
|
}
|
||||||
57
android/birbank/ScreenXmlBirbankParser.h
Normal file
57
android/birbank/ScreenXmlBirbankParser.h
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
#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;
|
||||||
|
|
||||||
|
};
|
||||||
BIN
assets/birbank/banner/home_banner.png
Normal file
BIN
assets/birbank/banner/home_banner.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 697 KiB |
124
assets/birbank/banner/home_banner.xml
Normal file
124
assets/birbank/banner/home_banner.xml
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
<?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>
|
||||||
BIN
assets/birbank/home_page.png
Normal file
BIN
assets/birbank/home_page.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 328 KiB |
1950
assets/birbank/home_page.xml
Normal file
1950
assets/birbank/home_page.xml
Normal file
File diff suppressed because it is too large
Load Diff
BIN
assets/birbank/payments_card.png
Normal file
BIN
assets/birbank/payments_card.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 17 KiB |
798
assets/birbank/payments_card.xml
Normal file
798
assets/birbank/payments_card.xml
Normal file
@ -0,0 +1,798 @@
|
|||||||
|
<?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>
|
||||||
BIN
assets/birbank/payments_history.png
Normal file
BIN
assets/birbank/payments_history.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 220 KiB |
1122
assets/birbank/payments_history.xml
Normal file
1122
assets/birbank/payments_history.xml
Normal file
File diff suppressed because it is too large
Load Diff
BIN
assets/birbank/pin_code.png
Normal file
BIN
assets/birbank/pin_code.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 65 KiB |
188
assets/birbank/pin_code.xml
Normal file
188
assets/birbank/pin_code.xml
Normal file
@ -0,0 +1,188 @@
|
|||||||
|
<?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>
|
||||||
@ -10,6 +10,9 @@ currencies=USD, KRW, AZN, RUB
|
|||||||
token=token1753605586797
|
token=token1753605586797
|
||||||
version=0.0.1
|
version=0.0.1
|
||||||
|
|
||||||
|
[db]
|
||||||
|
dbPath=/Users/trnsmkot/CLionProjects/ARCDeskProject/ARCDeskProject/database/app_data.db
|
||||||
|
|
||||||
[net]
|
[net]
|
||||||
accountUpdate=http://localhost:9999/api/v1/account/update
|
accountUpdate=http://localhost:9999/api/v1/account/update
|
||||||
appInfoUpdate=http://localhost:9999/api/v1/device/update
|
appInfoUpdate=http://localhost:9999/api/v1/device/update
|
||||||
|
|||||||
Binary file not shown.
@ -16,6 +16,7 @@ bool AccountDAO::upsertAccount(const AccountInfo &info) {
|
|||||||
DO UPDATE SET
|
DO UPDATE SET
|
||||||
amount = excluded.amount,
|
amount = excluded.amount,
|
||||||
update_time = excluded.update_time,
|
update_time = excluded.update_time,
|
||||||
|
last_numbers = excluded.last_numbers,
|
||||||
status = excluded.status,
|
status = excluded.status,
|
||||||
description = excluded.description,
|
description = excluded.description,
|
||||||
currency = excluded.currency
|
currency = excluded.currency
|
||||||
@ -50,12 +51,14 @@ bool AccountDAO::updateAccountById(
|
|||||||
UPDATE accounts
|
UPDATE accounts
|
||||||
SET status = :status,
|
SET status = :status,
|
||||||
description = :description,
|
description = :description,
|
||||||
|
last_numbers = :last_numbers,
|
||||||
currency = :currency
|
currency = :currency
|
||||||
WHERE id = :id
|
WHERE id = :id
|
||||||
)");
|
)");
|
||||||
|
|
||||||
query.bindValue(":status", status);
|
query.bindValue(":status", status);
|
||||||
query.bindValue(":description", description);
|
query.bindValue(":description", description);
|
||||||
|
query.bindValue(":last_numbers", description.right(4));
|
||||||
query.bindValue(":currency", currency);
|
query.bindValue(":currency", currency);
|
||||||
query.bindValue(":id", id);
|
query.bindValue(":id", id);
|
||||||
|
|
||||||
|
|||||||
6
main.cpp
6
main.cpp
@ -167,6 +167,7 @@ int main(int argc, char *argv[]) {
|
|||||||
registrationWindow->close();
|
registrationWindow->close();
|
||||||
startNetworkService(app);
|
startNetworkService(app);
|
||||||
startDeviceScreener(app);
|
startDeviceScreener(app);
|
||||||
|
startEventHandler(app);
|
||||||
}, Qt::QueuedConnection);
|
}, Qt::QueuedConnection);
|
||||||
} else {
|
} else {
|
||||||
auto *loader = new LoaderWindow(token);
|
auto *loader = new LoaderWindow(token);
|
||||||
@ -183,6 +184,7 @@ int main(int argc, char *argv[]) {
|
|||||||
mainWindow->show();
|
mainWindow->show();
|
||||||
startNetworkService(app);
|
startNetworkService(app);
|
||||||
startDeviceScreener(app);
|
startDeviceScreener(app);
|
||||||
|
startEventHandler(app);
|
||||||
} else if (result == 0) {
|
} else if (result == 0) {
|
||||||
auto *registrationWindow = new RegistrationWindow();
|
auto *registrationWindow = new RegistrationWindow();
|
||||||
registrationWindow->show();
|
registrationWindow->show();
|
||||||
@ -195,6 +197,7 @@ int main(int argc, char *argv[]) {
|
|||||||
registrationWindow->close();
|
registrationWindow->close();
|
||||||
startNetworkService(app);
|
startNetworkService(app);
|
||||||
startDeviceScreener(app);
|
startDeviceScreener(app);
|
||||||
|
startEventHandler(app);
|
||||||
}, Qt::QueuedConnection);
|
}, Qt::QueuedConnection);
|
||||||
}
|
}
|
||||||
loader->close();
|
loader->close();
|
||||||
@ -202,8 +205,5 @@ int main(int argc, char *argv[]) {
|
|||||||
// loader.show();
|
// loader.show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// startEventHandler(app);
|
|
||||||
return QApplication::exec();
|
return QApplication::exec();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,6 +11,7 @@
|
|||||||
#include "dao/EventDAO.h"
|
#include "dao/EventDAO.h"
|
||||||
#include "db/ApplicationInfo.h"
|
#include "db/ApplicationInfo.h"
|
||||||
#include "net/NetworkService.h"
|
#include "net/NetworkService.h"
|
||||||
|
#include "birbank/GetLastDaysHistoryBirbankScript.h"
|
||||||
#include "rshb/CommonScript.h"
|
#include "rshb/CommonScript.h"
|
||||||
#include "rshb/GetLastDaysHistoryScript.h"
|
#include "rshb/GetLastDaysHistoryScript.h"
|
||||||
#include "rshb/LoginAndCheckAccountsScript.h"
|
#include "rshb/LoginAndCheckAccountsScript.h"
|
||||||
@ -123,36 +124,51 @@ void EventHandler::startThreadForKey(const QString &key) {
|
|||||||
|
|
||||||
const auto thr = new QThread(this);
|
const auto thr = new QThread(this);
|
||||||
// qDebug() << "Start thread for key" << eventTypeToString(event.type);
|
// qDebug() << "Start thread for key" << eventTypeToString(event.type);
|
||||||
if (event.type == EventType::Balance) {
|
if (event.type == EventType::History) {
|
||||||
auto *worker = new GetLastDaysHistoryScript(account);
|
if ("birbank" == account.appCode) {
|
||||||
|
auto *worker = new GetLastDaysHistoryBirbankScript(account);
|
||||||
worker->moveToThread(thr);
|
worker->moveToThread(thr);
|
||||||
|
|
||||||
connect(thr, &QThread::started, worker, &GetLastDaysHistoryScript::start);
|
connect(thr, &QThread::started, worker, &GetLastDaysHistoryBirbankScript::start);
|
||||||
connect(worker, &GetLastDaysHistoryScript::finished, thr, &QThread::quit);
|
connect(worker, &GetLastDaysHistoryBirbankScript::finished, thr, &QThread::quit);
|
||||||
connect(worker, &GetLastDaysHistoryScript::finished, worker, &QObject::deleteLater);
|
connect(worker, &GetLastDaysHistoryBirbankScript::finished, worker, &QObject::deleteLater);
|
||||||
connect(thr, &QThread::finished, thr, &QObject::deleteLater);
|
connect(thr, &QThread::finished, thr, &QObject::deleteLater);
|
||||||
|
|
||||||
connect(worker, &GetLastDaysHistoryScript::finishedWithResult, this,
|
connect(worker, &GetLastDaysHistoryBirbankScript::finishedWithResult, this,
|
||||||
[this, key, event](const QString &result) {
|
[this, key, event](const QString &result) {
|
||||||
updateEventThread(key, event, result);
|
updateEventThread(key, event, result);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
// auto *worker = new GetLastDaysHistoryScript(account);
|
||||||
|
// worker->moveToThread(thr);
|
||||||
|
//
|
||||||
|
// connect(thr, &QThread::started, worker, &GetLastDaysHistoryScript::start);
|
||||||
|
// connect(worker, &GetLastDaysHistoryScript::finished, thr, &QThread::quit);
|
||||||
|
// connect(worker, &GetLastDaysHistoryScript::finished, worker, &QObject::deleteLater);
|
||||||
|
// connect(thr, &QThread::finished, thr, &QObject::deleteLater);
|
||||||
|
//
|
||||||
|
// connect(worker, &GetLastDaysHistoryScript::finishedWithResult, this,
|
||||||
|
// [this, key, event](const QString &result) {
|
||||||
|
// updateEventThread(key, event, result);
|
||||||
|
// }
|
||||||
|
// );
|
||||||
|
}
|
||||||
|
|
||||||
if (event.type == EventType::Phone) {
|
if (event.type == EventType::Phone) {
|
||||||
auto *worker = new PayByPhoneScript(account, event.phone, event.bankName, event.amount);
|
// auto *worker = new PayByPhoneScript(account, event.phone, event.bankName, event.amount);
|
||||||
worker->moveToThread(thr);
|
// worker->moveToThread(thr);
|
||||||
|
//
|
||||||
connect(thr, &QThread::started, worker, &PayByPhoneScript::start);
|
// connect(thr, &QThread::started, worker, &PayByPhoneScript::start);
|
||||||
connect(worker, &PayByPhoneScript::finished, thr, &QThread::quit);
|
// connect(worker, &PayByPhoneScript::finished, thr, &QThread::quit);
|
||||||
connect(worker, &PayByPhoneScript::finished, worker, &QObject::deleteLater);
|
// connect(worker, &PayByPhoneScript::finished, worker, &QObject::deleteLater);
|
||||||
connect(thr, &QThread::finished, thr, &QObject::deleteLater);
|
// connect(thr, &QThread::finished, thr, &QObject::deleteLater);
|
||||||
|
//
|
||||||
connect(worker, &PayByPhoneScript::finishedWithResult, this,
|
// connect(worker, &PayByPhoneScript::finishedWithResult, this,
|
||||||
[this, key, event](const QString &result) {
|
// [this, key, event](const QString &result) {
|
||||||
updateEventThread(key, event, result);
|
// updateEventThread(key, event, result);
|
||||||
}
|
// }
|
||||||
);
|
// );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Таймер на 5 минут — если не успел finish(), убить и перезапустить
|
// Таймер на 5 минут — если не успел finish(), убить и перезапустить
|
||||||
|
|||||||
@ -11,6 +11,7 @@
|
|||||||
#include <QJsonObject>
|
#include <QJsonObject>
|
||||||
#include <QThread>
|
#include <QThread>
|
||||||
|
|
||||||
|
#include "birbank/LoginAndCheckAccountsBirbankScript.h"
|
||||||
#include "common/PaddedItemDelegate.h"
|
#include "common/PaddedItemDelegate.h"
|
||||||
#include "dao/AccountDAO.h"
|
#include "dao/AccountDAO.h"
|
||||||
#include "dao/ApplicationDAO.h"
|
#include "dao/ApplicationDAO.h"
|
||||||
@ -120,8 +121,23 @@ AccountSettingsWindow::AccountSettingsWindow(
|
|||||||
"background-color: orange;"
|
"background-color: orange;"
|
||||||
"color: white;"
|
"color: white;"
|
||||||
);
|
);
|
||||||
QObject::connect(soloButton, &QPushButton::clicked, []() {
|
QObject::connect(soloButton, &QPushButton::clicked, [&, this]() {
|
||||||
qDebug() << "Кнопка 3 нажата";
|
if (!m_applicationInfo.pinCode.isEmpty()) {
|
||||||
|
QMessageBox msgBox(this);
|
||||||
|
msgBox.setWindowTitle(tr("Запустить проверку пин-кода?"));
|
||||||
|
msgBox.setText("Запуститься скрипт проверки входа в банк " + m_applicationInfo.name + " по пин-коду. Окно с настройками закроется.");
|
||||||
|
|
||||||
|
QPushButton *deleteBtn = msgBox.addButton(tr("Запустить"), QMessageBox::AcceptRole);
|
||||||
|
QPushButton *closeBtn = msgBox.addButton(tr("Отмена"), QMessageBox::RejectRole);
|
||||||
|
msgBox.setDefaultButton(closeBtn);
|
||||||
|
msgBox.setModal(true);
|
||||||
|
msgBox.exec();
|
||||||
|
|
||||||
|
if (msgBox.clickedButton() == deleteBtn) {
|
||||||
|
startCheckPinCode(m_applicationInfo.code);
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
layout->addWidget(soloButton);
|
layout->addWidget(soloButton);
|
||||||
|
|
||||||
@ -158,6 +174,7 @@ AccountSettingsWindow::AccountSettingsWindow(
|
|||||||
qDebug() << "Cant insert bank account data";
|
qDebug() << "Cant insert bank account data";
|
||||||
} else {
|
} else {
|
||||||
reloadContent(tableWidget);
|
reloadContent(tableWidget);
|
||||||
|
tableWidget->resizeColumnsToContents();
|
||||||
updateAccountData(accountInfo);
|
updateAccountData(accountInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -179,6 +196,17 @@ AccountSettingsWindow::AccountSettingsWindow(
|
|||||||
}
|
}
|
||||||
|
|
||||||
void AccountSettingsWindow::startCheckPinCode(const QString &appCode) {
|
void AccountSettingsWindow::startCheckPinCode(const QString &appCode) {
|
||||||
|
if (appCode == "birbank") {
|
||||||
|
const auto thread = new QThread(nullptr);
|
||||||
|
auto *worker = new LoginAndCheckAccountsBirbankScript(m_deviceId, appCode, nullptr);
|
||||||
|
worker->moveToThread(thread);
|
||||||
|
connect(thread, &QThread::started, worker, &LoginAndCheckAccountsBirbankScript::start);
|
||||||
|
connect(worker, &LoginAndCheckAccountsBirbankScript::finished, thread, &QThread::quit);
|
||||||
|
connect(worker, &LoginAndCheckAccountsBirbankScript::finished, worker, &QObject::deleteLater);
|
||||||
|
connect(thread, &QThread::finished, thread, &QObject::deleteLater);
|
||||||
|
thread->start();
|
||||||
|
} else if (appCode == "ziraat") {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AccountSettingsWindow::sendAppStatus(const QString &deviceId, const QString &code, const QString &status) {
|
void AccountSettingsWindow::sendAppStatus(const QString &deviceId, const QString &code, const QString &status) {
|
||||||
@ -301,6 +329,7 @@ void AccountSettingsWindow::reloadContent(QTableWidget *tableWidget) {
|
|||||||
accountInfo.currency = currency;
|
accountInfo.currency = currency;
|
||||||
accountInfo.description = cardNumber;
|
accountInfo.description = cardNumber;
|
||||||
accountInfo.amount = account.amount;
|
accountInfo.amount = account.amount;
|
||||||
|
accountInfo.currency = currency;
|
||||||
accountInfo.appCode = m_applicationInfo.code;
|
accountInfo.appCode = m_applicationInfo.code;
|
||||||
accountInfo.deviceId = m_deviceId;
|
accountInfo.deviceId = m_deviceId;
|
||||||
accountInfo.status = on ? AccountStatus::Active : AccountStatus::Off;
|
accountInfo.status = on ? AccountStatus::Active : AccountStatus::Off;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user