1
0
forked from BRT/arc

Daily commit

This commit is contained in:
slava 2025-07-27 21:01:13 +05:00
parent ee6de4fc5a
commit 6ded374ee8
24 changed files with 5708 additions and 30 deletions

View 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;
}

View 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);
};

View 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);
}

View 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
);
};

View 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);
}

View 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;
};

View 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"([^\очка])"));
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);
// ЕСПП
}

View 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;
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 697 KiB

View 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 &#128467;"
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>

Binary file not shown.

After

Width:  |  Height:  |  Size: 328 KiB

1950
assets/birbank/home_page.xml Normal file

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View 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>

Binary file not shown.

After

Width:  |  Height:  |  Size: 220 KiB

File diff suppressed because it is too large Load Diff

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
View 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>

View File

@ -10,6 +10,9 @@ currencies=USD, KRW, AZN, RUB
token=token1753605586797
version=0.0.1
[db]
dbPath=/Users/trnsmkot/CLionProjects/ARCDeskProject/ARCDeskProject/database/app_data.db
[net]
accountUpdate=http://localhost:9999/api/v1/account/update
appInfoUpdate=http://localhost:9999/api/v1/device/update

Binary file not shown.

View File

@ -16,6 +16,7 @@ bool AccountDAO::upsertAccount(const AccountInfo &info) {
DO UPDATE SET
amount = excluded.amount,
update_time = excluded.update_time,
last_numbers = excluded.last_numbers,
status = excluded.status,
description = excluded.description,
currency = excluded.currency
@ -50,12 +51,14 @@ bool AccountDAO::updateAccountById(
UPDATE accounts
SET status = :status,
description = :description,
last_numbers = :last_numbers,
currency = :currency
WHERE id = :id
)");
query.bindValue(":status", status);
query.bindValue(":description", description);
query.bindValue(":last_numbers", description.right(4));
query.bindValue(":currency", currency);
query.bindValue(":id", id);

View File

@ -167,6 +167,7 @@ int main(int argc, char *argv[]) {
registrationWindow->close();
startNetworkService(app);
startDeviceScreener(app);
startEventHandler(app);
}, Qt::QueuedConnection);
} else {
auto *loader = new LoaderWindow(token);
@ -183,6 +184,7 @@ int main(int argc, char *argv[]) {
mainWindow->show();
startNetworkService(app);
startDeviceScreener(app);
startEventHandler(app);
} else if (result == 0) {
auto *registrationWindow = new RegistrationWindow();
registrationWindow->show();
@ -195,6 +197,7 @@ int main(int argc, char *argv[]) {
registrationWindow->close();
startNetworkService(app);
startDeviceScreener(app);
startEventHandler(app);
}, Qt::QueuedConnection);
}
loader->close();
@ -202,8 +205,5 @@ int main(int argc, char *argv[]) {
// loader.show();
}
}
// startEventHandler(app);
return QApplication::exec();
}

View File

@ -11,6 +11,7 @@
#include "dao/EventDAO.h"
#include "db/ApplicationInfo.h"
#include "net/NetworkService.h"
#include "birbank/GetLastDaysHistoryBirbankScript.h"
#include "rshb/CommonScript.h"
#include "rshb/GetLastDaysHistoryScript.h"
#include "rshb/LoginAndCheckAccountsScript.h"
@ -123,36 +124,51 @@ void EventHandler::startThreadForKey(const QString &key) {
const auto thr = new QThread(this);
// qDebug() << "Start thread for key" << eventTypeToString(event.type);
if (event.type == EventType::Balance) {
auto *worker = new GetLastDaysHistoryScript(account);
worker->moveToThread(thr);
if (event.type == EventType::History) {
if ("birbank" == account.appCode) {
auto *worker = new GetLastDaysHistoryBirbankScript(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(thr, &QThread::started, worker, &GetLastDaysHistoryBirbankScript::start);
connect(worker, &GetLastDaysHistoryBirbankScript::finished, thr, &QThread::quit);
connect(worker, &GetLastDaysHistoryBirbankScript::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);
}
);
connect(worker, &GetLastDaysHistoryBirbankScript::finishedWithResult, this,
[this, key, event](const QString &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) {
auto *worker = new PayByPhoneScript(account, event.phone, event.bankName, event.amount);
worker->moveToThread(thr);
connect(thr, &QThread::started, worker, &PayByPhoneScript::start);
connect(worker, &PayByPhoneScript::finished, thr, &QThread::quit);
connect(worker, &PayByPhoneScript::finished, worker, &QObject::deleteLater);
connect(thr, &QThread::finished, thr, &QObject::deleteLater);
connect(worker, &PayByPhoneScript::finishedWithResult, this,
[this, key, event](const QString &result) {
updateEventThread(key, event, result);
}
);
// auto *worker = new PayByPhoneScript(account, event.phone, event.bankName, event.amount);
// worker->moveToThread(thr);
//
// connect(thr, &QThread::started, worker, &PayByPhoneScript::start);
// connect(worker, &PayByPhoneScript::finished, thr, &QThread::quit);
// connect(worker, &PayByPhoneScript::finished, worker, &QObject::deleteLater);
// connect(thr, &QThread::finished, thr, &QObject::deleteLater);
//
// connect(worker, &PayByPhoneScript::finishedWithResult, this,
// [this, key, event](const QString &result) {
// updateEventThread(key, event, result);
// }
// );
}
// Таймер на 5 минут — если не успел finish(), убить и перезапустить

View File

@ -11,6 +11,7 @@
#include <QJsonObject>
#include <QThread>
#include "birbank/LoginAndCheckAccountsBirbankScript.h"
#include "common/PaddedItemDelegate.h"
#include "dao/AccountDAO.h"
#include "dao/ApplicationDAO.h"
@ -120,8 +121,23 @@ AccountSettingsWindow::AccountSettingsWindow(
"background-color: orange;"
"color: white;"
);
QObject::connect(soloButton, &QPushButton::clicked, []() {
qDebug() << "Кнопка 3 нажата";
QObject::connect(soloButton, &QPushButton::clicked, [&, this]() {
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);
@ -158,6 +174,7 @@ AccountSettingsWindow::AccountSettingsWindow(
qDebug() << "Cant insert bank account data";
} else {
reloadContent(tableWidget);
tableWidget->resizeColumnsToContents();
updateAccountData(accountInfo);
}
}
@ -179,6 +196,17 @@ AccountSettingsWindow::AccountSettingsWindow(
}
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) {
@ -301,6 +329,7 @@ void AccountSettingsWindow::reloadContent(QTableWidget *tableWidget) {
accountInfo.currency = currency;
accountInfo.description = cardNumber;
accountInfo.amount = account.amount;
accountInfo.currency = currency;
accountInfo.appCode = m_applicationInfo.code;
accountInfo.deviceId = m_deviceId;
accountInfo.status = on ? AccountStatus::Active : AccountStatus::Off;