Add core scripts for Black app automation and XML parsing
Implemented `CommonScript` as a base class with reusable functionality for automation workflows, including PIN input, app navigation, and server communication. Added specialized scripts like `GetCardInfoScript`, `GetProfileInfoScript`, and `LoginAndCheckAccountsScript` for card retrieval, profile parsing, and login validation. Introduced `ScreenXmlParser` for efficient XML-based UI parsing and node detection.
232
android/black/CommonScript.cpp
Normal file
@ -0,0 +1,232 @@
|
||||
#include "CommonScript.h"
|
||||
|
||||
#include <QJsonArray>
|
||||
#include <QJsonObject>
|
||||
#include <QRandomGenerator>
|
||||
#include <QThread>
|
||||
|
||||
#include "adb/AdbUtils.h"
|
||||
#include "dao/ApplicationDAO.h"
|
||||
#include "net/NetworkService.h"
|
||||
|
||||
namespace Black {
|
||||
|
||||
CommonScript::CommonScript(QObject *parent)
|
||||
: QObject(parent) {
|
||||
}
|
||||
|
||||
CommonScript::~CommonScript() = default;
|
||||
|
||||
void CommonScript::start() {
|
||||
doStart();
|
||||
emit finished();
|
||||
}
|
||||
|
||||
Node CommonScript::swipeToButton(
|
||||
const QString &deviceId,
|
||||
const QString &text, int &counter, const int width, const int height
|
||||
) {
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
if (Node button = xmlScreenParser.findButtonNode(text, true); button.x() > 0 && button.y() > 0) {
|
||||
return button;
|
||||
}
|
||||
const int x = width / 2;
|
||||
const int offset = height / 4;
|
||||
AdbUtils::makeSwipe(deviceId, x, height - offset, x, offset);
|
||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++counter));
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
bool CommonScript::inputPinCode(const QString &deviceId, const QString &pinCode) {
|
||||
// BlackBanx использует EditText с password=true, а не кнопочную сетку
|
||||
Node editText = xmlScreenParser.findPinCodeEditText();
|
||||
if (editText.isEmpty()) {
|
||||
qWarning() << "[Black::inputPinCode] PIN EditText not found";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Тапаем по полю для фокуса
|
||||
AdbUtils::makeTap(deviceId, editText.x(), editText.y());
|
||||
QThread::msleep(500);
|
||||
|
||||
// Вводим PIN через текстовый ввод
|
||||
AdbUtils::inputText(deviceId, pinCode);
|
||||
QThread::msleep(500);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CommonScript::runAppAndGoToHomeScreen(
|
||||
const QString &deviceId,
|
||||
const QString &packageName,
|
||||
const QString &pinCode,
|
||||
const int width,
|
||||
const int height
|
||||
) {
|
||||
// Убить приложение если запущено
|
||||
if (const QString pid = AdbUtils::tryToGetRunningAppPid(deviceId, packageName); !pid.isEmpty()) {
|
||||
qDebug() << "[Black] 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() << "[Black] Process has not started";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Даем время на запуск
|
||||
QThread::msleep(4500);
|
||||
int counter = 0;
|
||||
bool findAndInputPincode = false;
|
||||
|
||||
while (true) {
|
||||
counter++;
|
||||
|
||||
if (counter > 10) {
|
||||
AdbUtils::takeScreenshot(deviceId, "too_many_attempts");
|
||||
return false;
|
||||
}
|
||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
|
||||
|
||||
if (xmlScreenParser.isHomeScreen()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Проверяем экран ввода PIN-кода
|
||||
if (!findAndInputPincode && xmlScreenParser.isPinCodeScreen()) {
|
||||
inputPinCode(deviceId, pinCode);
|
||||
findAndInputPincode = true;
|
||||
QThread::msleep(3000);
|
||||
continue;
|
||||
}
|
||||
|
||||
QThread::msleep(1000);
|
||||
}
|
||||
}
|
||||
|
||||
void CommonScript::postAccountsData(const QList<QPair<AccountInfo, Node>> &accounts) {
|
||||
if (accounts.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto *thread = new QThread;
|
||||
auto *worker = new NetworkService;
|
||||
|
||||
QJsonArray list;
|
||||
for (const QPair<AccountInfo, Node> &pair : accounts) {
|
||||
QJsonObject obj;
|
||||
AccountInfo account = pair.first;
|
||||
obj["appName"] = account.appCode;
|
||||
obj["lastNumbers"] = account.lastNumbers;
|
||||
obj["amount"] = account.amount;
|
||||
obj["description"] = account.description;
|
||||
obj["currency"] = account.currency;
|
||||
obj["status"] = accountStatusToString(account.status);
|
||||
list.append(obj);
|
||||
}
|
||||
|
||||
worker->setDeviceId(accounts.first().first.deviceId);
|
||||
worker->setPayload(QJsonDocument(list).toJson());
|
||||
worker->moveToThread(thread);
|
||||
connect(thread, &QThread::started, worker, &NetworkService::postAccountsData);
|
||||
connect(worker, &NetworkService::finished, thread, &QThread::quit);
|
||||
connect(worker, &NetworkService::finished, worker, &QObject::deleteLater);
|
||||
connect(thread, &QThread::finished, thread, &QThread::deleteLater);
|
||||
thread->start();
|
||||
}
|
||||
|
||||
void CommonScript::postNewTransactionData(const AccountInfo &account, const TransactionInfo &transaction) {
|
||||
auto *thread = new QThread;
|
||||
auto *worker = new NetworkService;
|
||||
|
||||
QJsonObject obj;
|
||||
obj["id"] = transaction.id;
|
||||
obj["amount"] = transaction.amount;
|
||||
obj["name"] = transaction.name;
|
||||
obj["fee"] = transaction.fee;
|
||||
obj["status"] = transactionStatusToString(transaction.status);
|
||||
obj["type"] = transactionTypeToString(transaction.type);
|
||||
obj["phone"] = transaction.phone;
|
||||
obj["description"] = transaction.description;
|
||||
obj["updatedDescription"] = transaction.updatedDescription;
|
||||
obj["bankName"] = transaction.bankName;
|
||||
obj["bankTime"] = transaction.bankTime;
|
||||
obj["bankTransactionId"] = transaction.bankTrExternalId;
|
||||
|
||||
worker->setDeviceId(account.deviceId);
|
||||
worker->addExtra("lastNumbers", account.lastNumbers);
|
||||
worker->addExtra("transactionId", transaction.id);
|
||||
worker->setPayload(QJsonDocument(obj).toJson());
|
||||
worker->moveToThread(thread);
|
||||
connect(thread, &QThread::started, worker, &NetworkService::insertTransactionData);
|
||||
connect(worker, &NetworkService::finished, thread, &QThread::quit);
|
||||
connect(worker, &NetworkService::finished, worker, &QObject::deleteLater);
|
||||
connect(thread, &QThread::finished, thread, &QThread::deleteLater);
|
||||
thread->start();
|
||||
}
|
||||
|
||||
void CommonScript::updateTransactionData(
|
||||
const AccountInfo &account,
|
||||
const int transactionId,
|
||||
const TransactionStatus status,
|
||||
const QString &oldDesc,
|
||||
const QString &newDesc
|
||||
) {
|
||||
auto *thread = new QThread;
|
||||
auto *worker = new NetworkService;
|
||||
|
||||
QJsonObject obj;
|
||||
obj["id"] = transactionId;
|
||||
obj["status"] = transactionStatusToString(status);
|
||||
obj["description"] = newDesc;
|
||||
obj["updatedDescription"] = oldDesc;
|
||||
|
||||
worker->setDeviceId(account.deviceId);
|
||||
worker->addExtra("lastNumbers", account.lastNumbers);
|
||||
worker->setPayload(QJsonDocument(obj).toJson());
|
||||
worker->moveToThread(thread);
|
||||
connect(thread, &QThread::started, worker, &NetworkService::updateTransactionData);
|
||||
connect(worker, &NetworkService::finished, thread, &QThread::quit);
|
||||
connect(worker, &NetworkService::finished, worker, &QObject::deleteLater);
|
||||
connect(thread, &QThread::finished, thread, &QThread::deleteLater);
|
||||
thread->start();
|
||||
}
|
||||
|
||||
void CommonScript::createBankProfileIfNeeded(const QString &deviceId, const QString &appCode) {
|
||||
const ApplicationInfo app = ApplicationDAO::getApplication(deviceId, appCode);
|
||||
if (!app.bankProfileId.isEmpty()) {
|
||||
qDebug() << "[Black] bankProfileId already exists:" << app.bankProfileId;
|
||||
return;
|
||||
}
|
||||
|
||||
const QMap<QString, int> currencyCodes = {
|
||||
{"RUB", 643}, {"USD", 840}, {"KRW", 410}, {"AZN", 944}
|
||||
};
|
||||
const int currencyCode = currencyCodes.value(app.currency.toUpper(), 840);
|
||||
const QStringList parts = app.fullName.split(' ', Qt::SkipEmptyParts);
|
||||
|
||||
QJsonObject profileBody;
|
||||
profileBody["first_name"] = parts.value(0);
|
||||
profileBody["middle_name"] = parts.size() >= 3 ? parts.value(1) : QString("");
|
||||
profileBody["last_name"] = parts.size() >= 3 ? parts.value(2) : parts.value(1);
|
||||
profileBody["bank_name"] = appCode;
|
||||
profileBody["phone_number"] = app.phone.simplified().remove(' ');
|
||||
profileBody["balance"] = QString::number(qRound64(app.amount * 100));
|
||||
profileBody["state"] = (app.status == "active") ? "enabled" : "disabled";
|
||||
profileBody["currency"] = currencyCode;
|
||||
|
||||
NetworkService ns;
|
||||
ns.setDeviceId(deviceId);
|
||||
ns.setPayload(QJsonDocument(profileBody).toJson());
|
||||
ns.addExtra("app_id", app.id);
|
||||
ns.postBankProfile();
|
||||
qDebug() << "[Black] createBankProfileIfNeeded: postBankProfile done";
|
||||
}
|
||||
|
||||
void CommonScript::stop() {
|
||||
m_running = false;
|
||||
}
|
||||
|
||||
} // namespace Black
|
||||
70
android/black/CommonScript.h
Normal file
@ -0,0 +1,70 @@
|
||||
#pragma once
|
||||
|
||||
#include <QObject>
|
||||
#include "ScreenXmlParser.h"
|
||||
#include "db/TransactionInfo.h"
|
||||
|
||||
namespace Black {
|
||||
|
||||
class CommonScript : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit CommonScript(QObject *parent = nullptr);
|
||||
|
||||
~CommonScript() override;
|
||||
|
||||
protected:
|
||||
virtual void doStart() = 0;
|
||||
|
||||
// Ввод PIN-кода через EditText (BlackBanx использует текстовое поле, а не кнопки)
|
||||
bool inputPinCode(const QString &deviceId, const QString &pinCode);
|
||||
|
||||
bool runAppAndGoToHomeScreen(
|
||||
const QString &deviceId,
|
||||
const QString &packageName,
|
||||
const QString &pinCode,
|
||||
int width,
|
||||
int height
|
||||
);
|
||||
|
||||
Node swipeToButton(
|
||||
const QString &deviceId,
|
||||
const QString &text,
|
||||
int &counter, int width, int height
|
||||
);
|
||||
|
||||
void postAccountsData(const QList<QPair<AccountInfo, Node>> &accounts);
|
||||
|
||||
void postNewTransactionData(const AccountInfo &account, const TransactionInfo &transaction);
|
||||
|
||||
void updateTransactionData(
|
||||
const AccountInfo &account,
|
||||
int transactionId,
|
||||
TransactionStatus status,
|
||||
const QString &oldDesc,
|
||||
const QString &newDesc
|
||||
);
|
||||
|
||||
// Создаёт bank_profile на сервере если ещё не создан
|
||||
void createBankProfileIfNeeded(const QString &deviceId, const QString &appCode);
|
||||
|
||||
bool m_running = true;
|
||||
ScreenXmlParser xmlScreenParser;
|
||||
int m_counter = 0;
|
||||
|
||||
signals:
|
||||
void finished();
|
||||
|
||||
void finishedWithResult(const QString &result);
|
||||
|
||||
public slots:
|
||||
virtual void start() final;
|
||||
|
||||
virtual void stop() final;
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(CommonScript);
|
||||
};
|
||||
|
||||
} // namespace Black
|
||||
132
android/black/GetCardInfoScript.cpp
Normal file
@ -0,0 +1,132 @@
|
||||
#include "GetCardInfoScript.h"
|
||||
|
||||
#include <QThread>
|
||||
|
||||
#include "adb/AdbUtils.h"
|
||||
#include "dao/AccountDAO.h"
|
||||
#include "dao/ApplicationDAO.h"
|
||||
#include "dao/DeviceDAO.h"
|
||||
|
||||
namespace Black {
|
||||
|
||||
GetCardInfoScript::GetCardInfoScript(
|
||||
QString deviceId,
|
||||
QString appCode,
|
||||
QObject *parent
|
||||
) : CommonScript(parent),
|
||||
m_deviceId(std::move(deviceId)),
|
||||
m_appCode(std::move(appCode)) {
|
||||
}
|
||||
|
||||
GetCardInfoScript::~GetCardInfoScript() = default;
|
||||
|
||||
void GetCardInfoScript::doStart() {
|
||||
const DeviceInfo device = DeviceDAO::getDeviceById(m_deviceId);
|
||||
const ApplicationInfo app = ApplicationDAO::getApplication(m_deviceId, m_appCode);
|
||||
|
||||
if (device.id.isEmpty() || app.id == -1) {
|
||||
m_error = "Device or app not found: " + m_deviceId + " " + m_appCode;
|
||||
qCritical() << m_error;
|
||||
emit finishedWithResult(m_error);
|
||||
return;
|
||||
}
|
||||
|
||||
// Читаем текущий экран
|
||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
|
||||
|
||||
// Если не на домашнем экране — перезапускаем
|
||||
if (!xmlScreenParser.isHomeScreen()) {
|
||||
qDebug() << "[Black::GetCardInfo] Not on home screen, restarting app...";
|
||||
if (!runAppAndGoToHomeScreen(device.id, app.package, app.pinCode,
|
||||
device.screenWidth, device.screenHeight)) {
|
||||
m_error = "Cannot reach home screen: " + m_deviceId + " " + m_appCode;
|
||||
qWarning() << m_error;
|
||||
AdbUtils::tryToKillApplication(m_deviceId, app.package);
|
||||
emit finishedWithResult(m_error);
|
||||
return;
|
||||
}
|
||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
|
||||
}
|
||||
|
||||
// 1. Парсим баланс с домашнего экрана
|
||||
const double balance = xmlScreenParser.parseBalanceFromHomeScreen();
|
||||
qDebug() << "[Black::GetCardInfo] balance from home:" << balance;
|
||||
ApplicationDAO::updateAmount(app.id, balance);
|
||||
|
||||
// 2. Нажимаем "Tu CVU" на домашнем экране
|
||||
Node cvuButton = xmlScreenParser.findButtonNode("Tu CVU", false);
|
||||
if (cvuButton.isEmpty()) {
|
||||
m_error = "Cannot find Tu CVU button: " + m_deviceId;
|
||||
qWarning() << m_error;
|
||||
AdbUtils::tryToKillApplication(m_deviceId, app.package);
|
||||
emit finishedWithResult(m_error);
|
||||
return;
|
||||
}
|
||||
|
||||
AdbUtils::makeTap(m_deviceId, cvuButton.x(), cvuButton.y());
|
||||
QThread::msleep(2000);
|
||||
|
||||
// 3. Ждём экран CVU
|
||||
bool cvuScreenFound = false;
|
||||
for (int attempt = 0; attempt < 5; ++attempt) {
|
||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
|
||||
if (xmlScreenParser.isCVUScreen()) {
|
||||
cvuScreenFound = true;
|
||||
break;
|
||||
}
|
||||
QThread::msleep(1000);
|
||||
}
|
||||
|
||||
if (!cvuScreenFound) {
|
||||
m_error = "CVU screen not detected: " + m_deviceId;
|
||||
qWarning() << m_error;
|
||||
AdbUtils::tryToKillApplication(m_deviceId, app.package);
|
||||
emit finishedWithResult(m_error);
|
||||
return;
|
||||
}
|
||||
|
||||
// 4. Парсим номер CVU
|
||||
const QString cvuNumber = xmlScreenParser.parseCVUNumber();
|
||||
qDebug() << "[Black::GetCardInfo] CVU number:" << cvuNumber;
|
||||
|
||||
if (cvuNumber.isEmpty()) {
|
||||
m_error = "Cannot parse CVU number: " + m_deviceId;
|
||||
qWarning() << m_error;
|
||||
AdbUtils::tryToKillApplication(m_deviceId, app.package);
|
||||
emit finishedWithResult(m_error);
|
||||
return;
|
||||
}
|
||||
|
||||
// 5. Сохраняем аккаунт в БД (lastNumbers = последние 4 цифры CVU)
|
||||
const QString lastNumbers = cvuNumber.right(4);
|
||||
|
||||
AccountInfo account;
|
||||
account.deviceId = m_deviceId;
|
||||
account.appCode = m_appCode;
|
||||
account.lastNumbers = lastNumbers;
|
||||
account.cardNumber = cvuNumber;
|
||||
account.amount = balance;
|
||||
account.currency = "USD";
|
||||
account.description = "CVU";
|
||||
account.status = AccountStatus::Active;
|
||||
account.updateTime = QDateTime::currentDateTimeUtc();
|
||||
|
||||
if (!AccountDAO::upsertAccount(account)) {
|
||||
qWarning() << "[Black::GetCardInfo] Failed to upsert account";
|
||||
}
|
||||
|
||||
// 6. Отправляем данные аккаунтов на сервер
|
||||
AccountInfo savedAccount = AccountDAO::findAppAccount(m_deviceId, m_appCode, lastNumbers);
|
||||
if (savedAccount.id != -1) {
|
||||
QList<QPair<AccountInfo, Node>> accounts;
|
||||
accounts.append({savedAccount, Node()});
|
||||
postAccountsData(accounts);
|
||||
}
|
||||
|
||||
qDebug() << "[Black::GetCardInfo] Done. CVU:" << cvuNumber << "balance:" << balance;
|
||||
|
||||
AdbUtils::tryToKillApplication(m_deviceId, app.package);
|
||||
emit finishedWithResult(m_error);
|
||||
}
|
||||
|
||||
} // namespace Black
|
||||
27
android/black/GetCardInfoScript.h
Normal file
@ -0,0 +1,27 @@
|
||||
#pragma once
|
||||
#include "CommonScript.h"
|
||||
|
||||
namespace Black {
|
||||
|
||||
class GetCardInfoScript final : public CommonScript {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit GetCardInfoScript(
|
||||
QString deviceId,
|
||||
QString appCode,
|
||||
QObject *parent = nullptr
|
||||
);
|
||||
|
||||
~GetCardInfoScript() override;
|
||||
|
||||
protected:
|
||||
void doStart() override;
|
||||
|
||||
private:
|
||||
const QString m_deviceId;
|
||||
const QString m_appCode;
|
||||
QString m_error;
|
||||
};
|
||||
|
||||
} // namespace Black
|
||||
168
android/black/GetProfileInfoScript.cpp
Normal file
@ -0,0 +1,168 @@
|
||||
#include "GetProfileInfoScript.h"
|
||||
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QThread>
|
||||
|
||||
#include "adb/AdbUtils.h"
|
||||
#include "dao/ApplicationDAO.h"
|
||||
#include "dao/DeviceDAO.h"
|
||||
#include "net/NetworkService.h"
|
||||
|
||||
namespace Black {
|
||||
|
||||
GetProfileInfoScript::GetProfileInfoScript(
|
||||
QString deviceId,
|
||||
QString appCode,
|
||||
QObject *parent
|
||||
) : CommonScript(parent),
|
||||
m_deviceId(std::move(deviceId)),
|
||||
m_appCode(std::move(appCode)) {
|
||||
}
|
||||
|
||||
GetProfileInfoScript::~GetProfileInfoScript() = default;
|
||||
|
||||
void GetProfileInfoScript::doStart() {
|
||||
const DeviceInfo device = DeviceDAO::getDeviceById(m_deviceId);
|
||||
const ApplicationInfo app = ApplicationDAO::getApplication(m_deviceId, m_appCode);
|
||||
|
||||
if (device.id.isEmpty() || app.id == -1) {
|
||||
m_error = "Device or app not found: " + m_deviceId + " " + m_appCode;
|
||||
qCritical() << m_error;
|
||||
emit finishedWithResult(m_error);
|
||||
return;
|
||||
}
|
||||
|
||||
// Читаем текущий экран
|
||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
|
||||
|
||||
// Если не на домашнем экране — перезапускаем
|
||||
if (!xmlScreenParser.isHomeScreen()) {
|
||||
qDebug() << "[Black::GetProfileInfo] Not on home screen, restarting app...";
|
||||
if (!runAppAndGoToHomeScreen(device.id, app.package, app.pinCode,
|
||||
device.screenWidth, device.screenHeight)) {
|
||||
m_error = "Cannot reach home screen: " + m_deviceId + " " + m_appCode;
|
||||
qWarning() << m_error;
|
||||
AdbUtils::tryToKillApplication(m_deviceId, app.package);
|
||||
emit finishedWithResult(m_error);
|
||||
return;
|
||||
}
|
||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
|
||||
}
|
||||
|
||||
// 1. Тапаем по кнопке "¡Hola!" (аватар с именем) на домашнем экране
|
||||
Node holaNode = xmlScreenParser.findHolaButton();
|
||||
if (holaNode.isEmpty()) {
|
||||
m_error = "Cannot find Hola button on home screen: " + m_deviceId;
|
||||
qWarning() << m_error;
|
||||
AdbUtils::tryToKillApplication(m_deviceId, app.package);
|
||||
emit finishedWithResult(m_error);
|
||||
return;
|
||||
}
|
||||
|
||||
// Парсим имя и баланс с домашнего экрана
|
||||
const QString fullName = xmlScreenParser.parseUserNameFromHomeScreen();
|
||||
const double balance = xmlScreenParser.parseBalanceFromHomeScreen();
|
||||
qDebug() << "[Black::GetProfileInfo] fullName from home:" << fullName << "balance:" << balance;
|
||||
|
||||
// Сохраняем баланс
|
||||
ApplicationDAO::updateAmount(app.id, balance);
|
||||
|
||||
AdbUtils::makeTap(m_deviceId, holaNode.x(), holaNode.y());
|
||||
QThread::msleep(2000);
|
||||
|
||||
// 2. Ждём боковое меню
|
||||
bool sideMenuFound = false;
|
||||
for (int attempt = 0; attempt < 5; ++attempt) {
|
||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
|
||||
if (xmlScreenParser.isSideMenu()) {
|
||||
sideMenuFound = true;
|
||||
break;
|
||||
}
|
||||
QThread::msleep(1000);
|
||||
}
|
||||
|
||||
if (!sideMenuFound) {
|
||||
m_error = "Side menu not detected: " + m_deviceId;
|
||||
qWarning() << m_error;
|
||||
AdbUtils::tryToKillApplication(m_deviceId, app.package);
|
||||
emit finishedWithResult(m_error);
|
||||
return;
|
||||
}
|
||||
|
||||
// 3. Тапаем "Tu Información"
|
||||
Node tuInfoNode = xmlScreenParser.findNodeByContentDesc(QString::fromUtf8("Tu Información"));
|
||||
if (tuInfoNode.isEmpty()) {
|
||||
m_error = "Cannot find Tu Información button: " + m_deviceId;
|
||||
qWarning() << m_error;
|
||||
AdbUtils::tryToKillApplication(m_deviceId, app.package);
|
||||
emit finishedWithResult(m_error);
|
||||
return;
|
||||
}
|
||||
|
||||
AdbUtils::makeTap(m_deviceId, tuInfoNode.x(), tuInfoNode.y());
|
||||
QThread::msleep(2500);
|
||||
|
||||
// 4. Ждём страницу профиля "Tu información"
|
||||
bool profileFound = false;
|
||||
for (int attempt = 0; attempt < 5; ++attempt) {
|
||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
|
||||
if (xmlScreenParser.isProfilePage()) {
|
||||
profileFound = true;
|
||||
break;
|
||||
}
|
||||
QThread::msleep(1000);
|
||||
}
|
||||
|
||||
if (!profileFound) {
|
||||
m_error = "Profile page not detected: " + m_deviceId;
|
||||
qWarning() << m_error;
|
||||
AdbUtils::tryToKillApplication(m_deviceId, app.package);
|
||||
emit finishedWithResult(m_error);
|
||||
return;
|
||||
}
|
||||
|
||||
// 5. Парсим данные профиля (первый экран: nombre, apellido, email)
|
||||
const QString nombre = xmlScreenParser.parseProfileNombre();
|
||||
const QString apellido = xmlScreenParser.parseProfileApellido();
|
||||
const QString email = xmlScreenParser.parseProfileEmail();
|
||||
|
||||
// 6. Скроллим вниз чтобы увидеть телефон
|
||||
const int x = device.screenWidth / 2;
|
||||
const int fromY = device.screenHeight * 3 / 4;
|
||||
const int toY = device.screenHeight / 4;
|
||||
AdbUtils::makeSwipe(m_deviceId, x, fromY, x, toY);
|
||||
QThread::msleep(1500);
|
||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
|
||||
|
||||
const QString phone = xmlScreenParser.parseProfilePhone();
|
||||
|
||||
// Собираем полное имя: "имя фамилия"
|
||||
QString parsedFullName;
|
||||
if (!nombre.isEmpty() && !apellido.isEmpty()) {
|
||||
parsedFullName = nombre + " " + apellido;
|
||||
} else if (!nombre.isEmpty()) {
|
||||
parsedFullName = nombre;
|
||||
} else {
|
||||
parsedFullName = fullName; // fallback с домашнего экрана
|
||||
}
|
||||
|
||||
qDebug() << "[Black::GetProfileInfo] nombre:" << nombre
|
||||
<< "apellido:" << apellido
|
||||
<< "email:" << email
|
||||
<< "phone:" << phone
|
||||
<< "fullName:" << parsedFullName;
|
||||
|
||||
// 7. Сохраняем в БД
|
||||
if (!ApplicationDAO::updateProfileInfo(app.id, parsedFullName, phone, email)) {
|
||||
qWarning() << "[Black::GetProfileInfo] Failed to save profile info to DB";
|
||||
}
|
||||
|
||||
// 7. Создаём bank profile если нет
|
||||
createBankProfileIfNeeded(m_deviceId, m_appCode);
|
||||
|
||||
AdbUtils::tryToKillApplication(m_deviceId, app.package);
|
||||
emit finishedWithResult(m_error);
|
||||
}
|
||||
|
||||
} // namespace Black
|
||||
27
android/black/GetProfileInfoScript.h
Normal file
@ -0,0 +1,27 @@
|
||||
#pragma once
|
||||
#include "CommonScript.h"
|
||||
|
||||
namespace Black {
|
||||
|
||||
class GetProfileInfoScript final : public CommonScript {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
~GetProfileInfoScript() override;
|
||||
|
||||
explicit GetProfileInfoScript(
|
||||
QString deviceId,
|
||||
QString appCode,
|
||||
QObject *parent = nullptr
|
||||
);
|
||||
|
||||
protected:
|
||||
void doStart() override;
|
||||
|
||||
private:
|
||||
const QString m_deviceId;
|
||||
const QString m_appCode;
|
||||
QString m_error;
|
||||
};
|
||||
|
||||
} // namespace Black
|
||||
64
android/black/LoginAndCheckAccountsScript.cpp
Normal file
@ -0,0 +1,64 @@
|
||||
#include "LoginAndCheckAccountsScript.h"
|
||||
|
||||
#include <QThread>
|
||||
|
||||
#include "adb/AdbUtils.h"
|
||||
#include "dao/ApplicationDAO.h"
|
||||
#include "dao/DeviceDAO.h"
|
||||
#include "AppLogger.h"
|
||||
#include "GetProfileInfoScript.h"
|
||||
|
||||
namespace Black {
|
||||
|
||||
LoginAndCheckAccountsScript::LoginAndCheckAccountsScript(
|
||||
QString deviceId,
|
||||
QString appCode,
|
||||
QObject *parent
|
||||
) : CommonScript(parent),
|
||||
m_deviceId(std::move(deviceId)),
|
||||
m_appCode(std::move(appCode)) {
|
||||
}
|
||||
|
||||
LoginAndCheckAccountsScript::~LoginAndCheckAccountsScript() = default;
|
||||
|
||||
void LoginAndCheckAccountsScript::doStart() {
|
||||
const DeviceInfo device = DeviceDAO::getDeviceById(m_deviceId);
|
||||
const ApplicationInfo app = ApplicationDAO::getApplication(m_deviceId, m_appCode);
|
||||
|
||||
if (device.id.isEmpty() || app.id == -1) {
|
||||
m_error = "Device or app not found: " + m_deviceId + " " + m_appCode;
|
||||
qCritical() << m_error;
|
||||
emit finishedWithResult(m_error);
|
||||
return;
|
||||
}
|
||||
|
||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
|
||||
|
||||
if (!runAppAndGoToHomeScreen(device.id, app.package, app.pinCode, device.screenWidth, device.screenHeight)) {
|
||||
m_error = "Cant open the home screen: " + m_deviceId + " " + m_appCode;
|
||||
qWarning() << m_error;
|
||||
AppLogger::log("black/LoginAndCheck", m_deviceId, m_error,
|
||||
AdbUtils::captureScreenshotBytes(m_deviceId),
|
||||
"FETCH_PROFILE");
|
||||
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;
|
||||
}
|
||||
|
||||
// PIN-код прошёл
|
||||
if (!ApplicationDAO::updatePinCodeStatus(app.id, "yes", "")) {
|
||||
qWarning() << "Cant update the pincode: " << m_deviceId << " " << m_appCode;
|
||||
}
|
||||
|
||||
// Проверяем профиль и аккаунты (приложение уже на home screen)
|
||||
GetProfileInfoScript profileScript(m_deviceId, m_appCode);
|
||||
profileScript.start();
|
||||
|
||||
emit finishedWithResult(m_error);
|
||||
}
|
||||
|
||||
} // namespace Black
|
||||
27
android/black/LoginAndCheckAccountsScript.h
Normal file
@ -0,0 +1,27 @@
|
||||
#pragma once
|
||||
#include "CommonScript.h"
|
||||
|
||||
namespace Black {
|
||||
|
||||
class LoginAndCheckAccountsScript final : public CommonScript {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
~LoginAndCheckAccountsScript() override;
|
||||
|
||||
explicit LoginAndCheckAccountsScript(
|
||||
QString deviceId,
|
||||
QString appCode,
|
||||
QObject *parent = nullptr
|
||||
);
|
||||
|
||||
protected:
|
||||
void doStart() override;
|
||||
|
||||
private:
|
||||
const QString m_deviceId;
|
||||
const QString m_appCode;
|
||||
QString m_error;
|
||||
};
|
||||
|
||||
} // namespace Black
|
||||
309
android/black/ScreenXmlParser.cpp
Normal file
@ -0,0 +1,309 @@
|
||||
#include "ScreenXmlParser.h"
|
||||
|
||||
#include <QRegularExpression>
|
||||
#include <QXmlStreamReader>
|
||||
#include <QDomDocument>
|
||||
|
||||
#include "android/xml/Node.h"
|
||||
|
||||
namespace Black {
|
||||
|
||||
static const QRegularExpression boundsRegex(R"(\[([0-9]+),([0-9]+)\]\[([0-9]+),([0-9]+)\])");
|
||||
|
||||
ScreenXmlParser::ScreenXmlParser(QObject *parent) : QObject(parent) {
|
||||
}
|
||||
|
||||
ScreenXmlParser::~ScreenXmlParser() = default;
|
||||
|
||||
void ScreenXmlParser::parseAndSaveXml(const QString &xml) {
|
||||
QDomDocument doc;
|
||||
doc.setContent(xml);
|
||||
m_xml = doc.documentElement();
|
||||
m_nodes.clear();
|
||||
|
||||
QXmlStreamReader reader(xml);
|
||||
while (!reader.atEnd()) {
|
||||
reader.readNext();
|
||||
if (reader.isStartElement() && reader.name() == u"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();
|
||||
}
|
||||
if (reader.attributes().hasAttribute("hint")) {
|
||||
node.hint = reader.attributes().value("hint").toString();
|
||||
}
|
||||
if (reader.attributes().hasAttribute("password")) {
|
||||
node.password = reader.attributes().value("password").toString() == "true";
|
||||
}
|
||||
m_nodes.append(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const QList<Node> &ScreenXmlParser::findAllNodes() const {
|
||||
return m_nodes;
|
||||
}
|
||||
|
||||
Node ScreenXmlParser::findTextNode(const QString &text) {
|
||||
for (const Node &node : m_nodes) {
|
||||
if (node.text.trimmed() == text) {
|
||||
return node;
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
Node ScreenXmlParser::findNodeByContentDesc(const QString &contentDesc) {
|
||||
for (const Node &node : m_nodes) {
|
||||
if (node.contentDesc == contentDesc) {
|
||||
return node;
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
Node ScreenXmlParser::findNodeByContentDesc(const QString &contentDesc, bool contains) {
|
||||
for (const Node &node : m_nodes) {
|
||||
if (contains) {
|
||||
if (node.contentDesc.contains(contentDesc)) {
|
||||
return node;
|
||||
}
|
||||
} else {
|
||||
if (node.contentDesc == contentDesc) {
|
||||
return node;
|
||||
}
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
Node ScreenXmlParser::findButtonNode(const QString &text, bool contains) {
|
||||
for (const Node &node : m_nodes) {
|
||||
if (!node.clickable) continue;
|
||||
if (contains) {
|
||||
if (node.text.contains(text) || node.contentDesc.contains(text)) {
|
||||
return node;
|
||||
}
|
||||
} else {
|
||||
if (node.text.trimmed() == text || node.contentDesc == text) {
|
||||
return node;
|
||||
}
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
Node ScreenXmlParser::findFirstEditText() {
|
||||
for (const Node &node : m_nodes) {
|
||||
if (node.className == "android.widget.EditText") {
|
||||
return node;
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
bool ScreenXmlParser::isPinCodeScreen() {
|
||||
for (const Node &node : m_nodes) {
|
||||
if (node.contentDesc.contains(QString::fromUtf8("¿Olvidaste tu PIN?"))) {
|
||||
return true;
|
||||
}
|
||||
if (node.contentDesc.contains(QString::fromUtf8("Ingresá tu PIN"))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Node ScreenXmlParser::findPinCodeEditText() {
|
||||
for (const Node &node : m_nodes) {
|
||||
if (node.className == "android.widget.EditText" && node.password) {
|
||||
return node;
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
bool ScreenXmlParser::isHomeScreen() {
|
||||
bool hasSaldo = false;
|
||||
bool hasInicio = false;
|
||||
for (const Node &node : m_nodes) {
|
||||
if (node.contentDesc == "Saldo disponible") {
|
||||
hasSaldo = true;
|
||||
}
|
||||
if (node.contentDesc == "Inicio") {
|
||||
hasInicio = true;
|
||||
}
|
||||
if (hasSaldo && hasInicio) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ScreenXmlParser::isSideMenu() {
|
||||
bool hasTuInfo = false;
|
||||
bool hasCerrar = false;
|
||||
for (const Node &node : m_nodes) {
|
||||
if (node.contentDesc == QString::fromUtf8("Tu Información")) {
|
||||
hasTuInfo = true;
|
||||
}
|
||||
if (node.contentDesc == QString::fromUtf8("Cerrar sesión")) {
|
||||
hasCerrar = true;
|
||||
}
|
||||
if (hasTuInfo && hasCerrar) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Node ScreenXmlParser::findHolaButton() {
|
||||
for (const Node &node : m_nodes) {
|
||||
if (node.clickable && node.contentDesc.startsWith(QString::fromUtf8("¡Hola!"))) {
|
||||
return node;
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
QString ScreenXmlParser::parseUserNameFromHomeScreen() {
|
||||
// content-desc: "¡Hola!\nveronica cintia heredia \nvc"
|
||||
for (const Node &node : m_nodes) {
|
||||
if (node.contentDesc.startsWith(QString::fromUtf8("¡Hola!"))) {
|
||||
QStringList lines = node.contentDesc.split('\n');
|
||||
if (lines.size() >= 2) {
|
||||
return lines[1].trimmed();
|
||||
}
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
double ScreenXmlParser::parseBalanceFromHomeScreen() {
|
||||
// Баланс идёт после "Saldo disponible", формат: "$1.857,00" или "$0,00"
|
||||
bool afterSaldo = false;
|
||||
for (const Node &node : m_nodes) {
|
||||
if (node.contentDesc == "Saldo disponible") {
|
||||
afterSaldo = true;
|
||||
continue;
|
||||
}
|
||||
if (afterSaldo && node.contentDesc.startsWith("$")) {
|
||||
// "$1.857,00" → "1857.00"
|
||||
QString raw = node.contentDesc.mid(1); // убираем "$"
|
||||
raw.remove('.'); // убираем разделитель тысяч
|
||||
raw.replace(',', '.'); // запятая → точка
|
||||
bool ok = false;
|
||||
double val = raw.toDouble(&ok);
|
||||
if (ok) return val;
|
||||
}
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
bool ScreenXmlParser::isProfilePage() {
|
||||
for (const Node &node : m_nodes) {
|
||||
if (node.contentDesc == QString::fromUtf8("Tu información")) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
QString ScreenXmlParser::parseProfileNombre() {
|
||||
for (const Node &node : m_nodes) {
|
||||
if (node.hint == "Nombre" && !node.text.isEmpty()) {
|
||||
return node.text.trimmed();
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
QString ScreenXmlParser::parseProfileApellido() {
|
||||
for (const Node &node : m_nodes) {
|
||||
if (node.hint == "Apellido" && !node.text.isEmpty()) {
|
||||
return node.text.trimmed();
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
QString ScreenXmlParser::parseProfileEmail() {
|
||||
for (const Node &node : m_nodes) {
|
||||
if (node.hint == "E-mail" && !node.text.isEmpty()) {
|
||||
return node.text.trimmed();
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
QString ScreenXmlParser::parseProfilePhone() {
|
||||
for (const Node &node : m_nodes) {
|
||||
if (node.hint == QString::fromUtf8("Teléfono celular") && !node.text.isEmpty()) {
|
||||
return node.text.trimmed();
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
bool ScreenXmlParser::isCVUScreen() {
|
||||
for (const Node &node : m_nodes) {
|
||||
if (node.contentDesc == "CVU") {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
QString ScreenXmlParser::parseCVUNumber() {
|
||||
// CVU номер идёт после content-desc="CVU", это 22-значный номер
|
||||
bool afterCVU = false;
|
||||
for (const Node &node : m_nodes) {
|
||||
if (node.contentDesc == "CVU") {
|
||||
afterCVU = true;
|
||||
continue;
|
||||
}
|
||||
if (afterCVU && !node.contentDesc.isEmpty()) {
|
||||
// Проверяем что это числовая строка (CVU — 22 цифры)
|
||||
QString cvu = node.contentDesc.trimmed();
|
||||
bool allDigits = true;
|
||||
for (const QChar &c : cvu) {
|
||||
if (!c.isDigit()) {
|
||||
allDigits = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (allDigits && !cvu.isEmpty()) {
|
||||
return cvu;
|
||||
}
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
} // namespace Black
|
||||
72
android/black/ScreenXmlParser.h
Normal file
@ -0,0 +1,72 @@
|
||||
#pragma once
|
||||
|
||||
#include <QObject>
|
||||
#include <QDomElement>
|
||||
#include "android/xml/Node.h"
|
||||
#include "db/AccountInfo.h"
|
||||
|
||||
namespace Black {
|
||||
|
||||
class ScreenXmlParser final : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ScreenXmlParser(QObject *parent = nullptr);
|
||||
|
||||
~ScreenXmlParser() override;
|
||||
|
||||
void parseAndSaveXml(const QString &xml);
|
||||
|
||||
const QList<Node> &findAllNodes() const;
|
||||
|
||||
Node findTextNode(const QString &text);
|
||||
|
||||
Node findNodeByContentDesc(const QString &contentDesc);
|
||||
|
||||
Node findNodeByContentDesc(const QString &contentDesc, bool contains);
|
||||
|
||||
Node findButtonNode(const QString &text, bool contains);
|
||||
|
||||
Node findFirstEditText();
|
||||
|
||||
// Определяет экран ввода PIN-кода по content-desc "¿Olvidaste tu PIN?"
|
||||
bool isPinCodeScreen();
|
||||
|
||||
// Находит EditText с password=true для ввода PIN
|
||||
Node findPinCodeEditText();
|
||||
|
||||
bool isHomeScreen();
|
||||
|
||||
// Определяет боковое меню по content-desc "Tu Información" + "Cerrar sesión"
|
||||
bool isSideMenu();
|
||||
|
||||
// Находит кнопку "¡Hola!" (аватар с именем) на домашнем экране
|
||||
Node findHolaButton();
|
||||
|
||||
// Парсит имя пользователя из content-desc "¡Hola!\nимя\nинициалы"
|
||||
QString parseUserNameFromHomeScreen();
|
||||
|
||||
// Парсит баланс с домашнего экрана (content-desc "$0,00" после "Saldo disponible")
|
||||
double parseBalanceFromHomeScreen();
|
||||
|
||||
// Определяет страницу профиля "Tu información"
|
||||
bool isProfilePage();
|
||||
|
||||
// Парсит данные профиля по hint полей
|
||||
QString parseProfileNombre(); // hint="Nombre"
|
||||
QString parseProfileApellido(); // hint="Apellido"
|
||||
QString parseProfileEmail(); // hint="E-mail"
|
||||
QString parseProfilePhone(); // hint="Teléfono celular"
|
||||
|
||||
// Определяет экран CVU (окно поверх домашнего экрана)
|
||||
bool isCVUScreen();
|
||||
|
||||
// Парсит номер CVU (22-значный номер после content-desc="CVU")
|
||||
QString parseCVUNumber();
|
||||
|
||||
private:
|
||||
QList<Node> m_nodes;
|
||||
QDomElement m_xml;
|
||||
};
|
||||
|
||||
} // namespace Black
|
||||
@ -6,6 +6,7 @@
|
||||
#include <QThread>
|
||||
|
||||
#include "adb/AdbUtils.h"
|
||||
#include "dao/ApplicationDAO.h"
|
||||
#include "net/NetworkService.h"
|
||||
|
||||
namespace Ozon {
|
||||
@ -289,6 +290,37 @@ void CommonScript::updateTransactionData(
|
||||
thread->start();
|
||||
}
|
||||
|
||||
void CommonScript::createBankProfileIfNeeded(const QString &deviceId, const QString &appCode) {
|
||||
const ApplicationInfo app = ApplicationDAO::getApplication(deviceId, appCode);
|
||||
if (!app.bankProfileId.isEmpty()) {
|
||||
qDebug() << "[Ozon] bankProfileId already exists:" << app.bankProfileId;
|
||||
return;
|
||||
}
|
||||
|
||||
const QMap<QString, int> currencyCodes = {
|
||||
{"RUB", 643}, {"USD", 840}, {"KRW", 410}, {"AZN", 944}
|
||||
};
|
||||
const int currencyCode = currencyCodes.value(app.currency.toUpper(), 643);
|
||||
const QStringList parts = app.fullName.split(' ', Qt::SkipEmptyParts);
|
||||
|
||||
QJsonObject profileBody;
|
||||
profileBody["first_name"] = parts.value(0);
|
||||
profileBody["middle_name"] = parts.size() >= 3 ? parts.value(1) : QString("");
|
||||
profileBody["last_name"] = parts.size() >= 3 ? parts.value(2) : parts.value(1);
|
||||
profileBody["bank_name"] = appCode;
|
||||
profileBody["phone_number"] = app.phone.simplified().remove(' ');
|
||||
profileBody["balance"] = QString::number(qRound64(app.amount * 100));
|
||||
profileBody["state"] = (app.status == "active") ? "enabled" : "disabled";
|
||||
profileBody["currency"] = currencyCode;
|
||||
|
||||
NetworkService ns;
|
||||
ns.setDeviceId(deviceId);
|
||||
ns.setPayload(QJsonDocument(profileBody).toJson());
|
||||
ns.addExtra("app_id", app.id);
|
||||
ns.postBankProfile();
|
||||
qDebug() << "[Ozon] createBankProfileIfNeeded: postBankProfile done";
|
||||
}
|
||||
|
||||
void CommonScript::stop() {
|
||||
m_running = false;
|
||||
}
|
||||
|
||||
@ -57,6 +57,9 @@ protected:
|
||||
const QString &deviceId, int width, int height
|
||||
);
|
||||
|
||||
// Создаёт bank_profile на сервере если ещё не создан
|
||||
void createBankProfileIfNeeded(const QString &deviceId, const QString &appCode);
|
||||
|
||||
bool m_running = true;
|
||||
ScreenXmlParser xmlScreenParser;
|
||||
int m_counter = 0;
|
||||
|
||||
@ -53,6 +53,10 @@ void LoginAndCheckAccountsScript::doStart() {
|
||||
if (!ApplicationDAO::updatePinCodeStatus(app.id, "yes", "")) {
|
||||
qWarning() << "Cant update the pincode: " << m_deviceId << " " << m_appCode;
|
||||
}
|
||||
|
||||
// Создаём bank profile если ещё не создан
|
||||
createBankProfileIfNeeded(m_deviceId, m_appCode);
|
||||
|
||||
if (goToAllProducts(device.id, device.screenWidth, device.screenHeight)) {
|
||||
QList<QPair<AccountInfo, Node> > accounts = xmlScreenParser.parseAccountsInfo();
|
||||
for (auto &[account, node]: accounts) {
|
||||
|
||||
BIN
assets/black/accounts.png
Normal file
|
After Width: | Height: | Size: 160 KiB |
123
assets/black/accounts.xml
Normal file
@ -0,0 +1,123 @@
|
||||
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
|
||||
<hierarchy rotation="0">
|
||||
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="app.blackwallet.ar"
|
||||
content-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="app.blackwallet.ar"
|
||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
|
||||
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
|
||||
bounds="[0,0][1080,2400]" drawing-order="1" hint="">
|
||||
<node index="0" text="" resource-id="android:id/content" class="android.widget.FrameLayout"
|
||||
package="app.blackwallet.ar" content-desc="" checkable="false" checked="false" clickable="false"
|
||||
enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false"
|
||||
password="false" selected="false" bounds="[0,0][1080,2400]" drawing-order="2" hint="">
|
||||
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="app.blackwallet.ar"
|
||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
||||
focusable="true" focused="true" scrollable="false" long-clickable="false" password="false"
|
||||
selected="false" bounds="[0,0][1080,2400]" drawing-order="1" hint="">
|
||||
<node index="0" text="" resource-id="" class="android.view.View" package="app.blackwallet.ar"
|
||||
content-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.view.View" package="app.blackwallet.ar"
|
||||
content-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.view.View"
|
||||
package="app.blackwallet.ar" content-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.view.View"
|
||||
package="app.blackwallet.ar" content-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.view.View"
|
||||
package="app.blackwallet.ar" content-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.view.View"
|
||||
package="app.blackwallet.ar" content-desc="" checkable="false"
|
||||
checked="false" clickable="false" enabled="true" focusable="false"
|
||||
focused="false" scrollable="false" long-clickable="false" password="false"
|
||||
selected="false" bounds="[26,1256][1054,2337]" drawing-order="0" hint="">
|
||||
<node index="0" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" content-desc="" checkable="false"
|
||||
checked="false" clickable="false" enabled="true" focusable="false"
|
||||
focused="false" scrollable="false" long-clickable="false"
|
||||
password="false" selected="false" bounds="[89,1309][991,2059]"
|
||||
drawing-order="0" hint="">
|
||||
<node NAF="true" index="0" text="" resource-id=""
|
||||
class="android.view.View" package="app.blackwallet.ar"
|
||||
content-desc="" checkable="false" checked="false" clickable="true"
|
||||
enabled="true" focusable="true" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false"
|
||||
bounds="[928,1309][991,1372]" drawing-order="0" hint=""/>
|
||||
<node index="1" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" content-desc="Datos de tu cuenta"
|
||||
checkable="false" checked="false" clickable="false" enabled="true"
|
||||
focusable="true" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false"
|
||||
bounds="[89,1372][478,1437]" drawing-order="0" hint=""/>
|
||||
<node index="2" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" content-desc="CVU" checkable="false"
|
||||
checked="false" clickable="false" enabled="true" focusable="true"
|
||||
focused="false" scrollable="false" long-clickable="false"
|
||||
password="false" selected="false" bounds="[89,1516][165,1571]"
|
||||
drawing-order="0" hint=""/>
|
||||
<node index="3" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" content-desc="0000177501057000175004"
|
||||
checkable="false" checked="false" clickable="false" enabled="true"
|
||||
focusable="true" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false"
|
||||
bounds="[89,1579][492,1626]" drawing-order="0" hint=""/>
|
||||
<node NAF="true" index="4" text="" resource-id=""
|
||||
class="android.widget.ImageView" package="app.blackwallet.ar"
|
||||
content-desc="" checkable="false" checked="false" clickable="true"
|
||||
enabled="true" focusable="true" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false"
|
||||
bounds="[938,1545][991,1598]" drawing-order="0" hint=""/>
|
||||
<node index="5" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" content-desc="Alias"
|
||||
checkable="false" checked="false" clickable="false" enabled="true"
|
||||
focusable="true" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false"
|
||||
bounds="[89,1653][173,1708]" drawing-order="0" hint=""/>
|
||||
<node index="6" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" content-desc="27335723320.black"
|
||||
checkable="false" checked="false" clickable="false" enabled="true"
|
||||
focusable="true" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false"
|
||||
bounds="[89,1716][378,1763]" drawing-order="0" hint=""/>
|
||||
<node NAF="true" index="7" text="" resource-id=""
|
||||
class="android.widget.ImageView" package="app.blackwallet.ar"
|
||||
content-desc="" checkable="false" checked="false" clickable="true"
|
||||
enabled="true" focusable="true" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false"
|
||||
bounds="[938,1682][991,1734]" drawing-order="0" hint=""/>
|
||||
</node>
|
||||
<node index="1" text="" resource-id="" class="android.widget.ImageView"
|
||||
package="app.blackwallet.ar" content-desc="Compartir datos"
|
||||
checkable="false" checked="false" clickable="true" enabled="true"
|
||||
focusable="true" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false"
|
||||
bounds="[47,2143][1033,2316]" drawing-order="0" hint=""/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node index="1" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" content-desc="Cerrar" checkable="false" checked="false"
|
||||
clickable="true" enabled="true" focusable="true" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false" bounds="[0,0][1080,2400]"
|
||||
drawing-order="0" hint=""/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</hierarchy>
|
||||
BIN
assets/black/home_screen.png
Normal file
|
After Width: | Height: | Size: 246 KiB |
248
assets/black/home_screen.xml
Normal file
@ -0,0 +1,248 @@
|
||||
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
|
||||
<hierarchy rotation="0">
|
||||
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="app.blackwallet.ar"
|
||||
content-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="app.blackwallet.ar"
|
||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
|
||||
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
|
||||
bounds="[0,0][1080,2400]" drawing-order="1" hint="">
|
||||
<node index="0" text="" resource-id="android:id/content" class="android.widget.FrameLayout"
|
||||
package="app.blackwallet.ar" content-desc="" checkable="false" checked="false" clickable="false"
|
||||
enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false"
|
||||
password="false" selected="false" bounds="[0,0][1080,2400]" drawing-order="2" hint="">
|
||||
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="app.blackwallet.ar"
|
||||
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,0][1080,2400]" drawing-order="1" hint="">
|
||||
<node index="0" text="" resource-id="" class="android.view.View" package="app.blackwallet.ar"
|
||||
content-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.view.View" package="app.blackwallet.ar"
|
||||
content-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.view.View"
|
||||
package="app.blackwallet.ar" content-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.view.View"
|
||||
package="app.blackwallet.ar" content-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.view.View"
|
||||
package="app.blackwallet.ar" content-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.view.View"
|
||||
package="app.blackwallet.ar" content-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.view.View"
|
||||
package="app.blackwallet.ar" content-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.ScrollView"
|
||||
package="app.blackwallet.ar" 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,0][1080,2400]"
|
||||
drawing-order="0" hint="">
|
||||
<node index="0" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar"
|
||||
content-desc="¡Hola! veronica cintia heredia vc"
|
||||
checkable="false" checked="false" clickable="true"
|
||||
enabled="true" focusable="true" focused="false"
|
||||
scrollable="false" long-clickable="false" password="false"
|
||||
selected="false" bounds="[0,158][1080,347]" drawing-order="0"
|
||||
hint=""/>
|
||||
<node index="1" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" content-desc="Tu wallet"
|
||||
checkable="false" checked="false" clickable="false"
|
||||
enabled="true" focusable="true" focused="false"
|
||||
scrollable="false" long-clickable="false" password="false"
|
||||
selected="false" bounds="[107,465][414,570]" drawing-order="0"
|
||||
hint=""/>
|
||||
<node index="2" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" content-desc="Saldo disponible"
|
||||
checkable="false" checked="false" clickable="false"
|
||||
enabled="true" focusable="true" focused="false"
|
||||
scrollable="false" long-clickable="false" password="false"
|
||||
selected="false" bounds="[107,596][370,643]" drawing-order="0"
|
||||
hint=""/>
|
||||
<node NAF="true" index="3" text="" resource-id=""
|
||||
class="android.view.View" package="app.blackwallet.ar"
|
||||
content-desc="" checkable="false" checked="false"
|
||||
clickable="true" enabled="true" focusable="true"
|
||||
focused="false" scrollable="false" long-clickable="false"
|
||||
password="false" selected="false" bounds="[440,495][484,539]"
|
||||
drawing-order="0" hint=""/>
|
||||
<node index="4" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" content-desc="Tu CVU"
|
||||
checkable="false" checked="false" clickable="true"
|
||||
enabled="true" focusable="true" focused="false"
|
||||
scrollable="false" long-clickable="false" password="false"
|
||||
selected="false" bounds="[783,484][974,597]" drawing-order="0"
|
||||
hint=""/>
|
||||
<node index="5" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" content-desc="$0,00"
|
||||
checkable="false" checked="false" clickable="false"
|
||||
enabled="true" focusable="true" focused="false"
|
||||
scrollable="false" long-clickable="false" password="false"
|
||||
selected="false" bounds="[107,643][316,761]" drawing-order="0"
|
||||
hint=""/>
|
||||
<node index="6" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" content-desc="Accesos rápidos"
|
||||
checkable="false" checked="false" clickable="false"
|
||||
enabled="true" focusable="true" focused="false"
|
||||
scrollable="false" long-clickable="false" password="false"
|
||||
selected="false" bounds="[53,1116][378,1179]"
|
||||
drawing-order="0" hint=""/>
|
||||
<node index="7" text="" resource-id=""
|
||||
class="android.widget.ImageView" package="app.blackwallet.ar"
|
||||
content-desc="QR Personal" checkable="false" checked="false"
|
||||
clickable="true" enabled="true" focusable="true"
|
||||
focused="false" scrollable="false" long-clickable="false"
|
||||
password="false" selected="false" bounds="[53,1218][315,1488]"
|
||||
drawing-order="0" hint=""/>
|
||||
<node index="8" text="" resource-id=""
|
||||
class="android.widget.ImageView" package="app.blackwallet.ar"
|
||||
content-desc="Enviar a CBU o alias" checkable="false"
|
||||
checked="false" clickable="true" enabled="true"
|
||||
focusable="true" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false"
|
||||
bounds="[409,1218][671,1536]" drawing-order="0" hint=""/>
|
||||
<node index="9" text="" resource-id=""
|
||||
class="android.widget.ImageView" package="app.blackwallet.ar"
|
||||
content-desc="Solicitar con link" checkable="false"
|
||||
checked="false" clickable="true" enabled="true"
|
||||
focusable="true" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false"
|
||||
bounds="[765,1218][1028,1536]" drawing-order="0" hint=""/>
|
||||
<node index="10" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" content-desc="Tu actividad"
|
||||
checkable="false" checked="false" clickable="false"
|
||||
enabled="true" focusable="true" focused="false"
|
||||
scrollable="false" long-clickable="false" password="false"
|
||||
selected="false" bounds="[53,1667][297,1730]"
|
||||
drawing-order="0" hint=""/>
|
||||
<node index="11" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" content-desc="Ver más"
|
||||
checkable="false" checked="false" clickable="true"
|
||||
enabled="true" focusable="true" focused="false"
|
||||
scrollable="false" long-clickable="false" password="false"
|
||||
selected="false" bounds="[802,1667][1028,1730]"
|
||||
drawing-order="0" hint=""/>
|
||||
<node index="12" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" content-desc="" checkable="false"
|
||||
checked="false" clickable="false" enabled="true"
|
||||
focusable="false" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false"
|
||||
bounds="[0,1756][1080,2229]" drawing-order="0" hint="">
|
||||
<node index="0" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" content-desc=""
|
||||
checkable="false" checked="false" clickable="false"
|
||||
enabled="true" focusable="false" focused="false"
|
||||
scrollable="false" long-clickable="false" password="false"
|
||||
selected="false" bounds="[0,1756][1080,2229]"
|
||||
drawing-order="0" hint="">
|
||||
<node index="0" text="" resource-id=""
|
||||
class="android.widget.ImageView"
|
||||
package="app.blackwallet.ar"
|
||||
content-desc="Transferencia 21 de febrero de 2026 - 09:39 $-1.857, 00"
|
||||
checkable="false" checked="false" clickable="true"
|
||||
enabled="true" focusable="true" focused="false"
|
||||
scrollable="false" long-clickable="false"
|
||||
password="false" selected="false"
|
||||
bounds="[0,1756][1080,1880]" drawing-order="0"
|
||||
hint=""/>
|
||||
<node index="1" text="" resource-id=""
|
||||
class="android.widget.ImageView"
|
||||
package="app.blackwallet.ar"
|
||||
content-desc="Transferencia 21 de febrero de 2026 - 09:38 $-123, 45"
|
||||
checkable="false" checked="false" clickable="true"
|
||||
enabled="true" focusable="true" focused="false"
|
||||
scrollable="false" long-clickable="false"
|
||||
password="false" selected="false"
|
||||
bounds="[0,1880][1080,2003]" drawing-order="0"
|
||||
hint=""/>
|
||||
<node index="2" text="" resource-id=""
|
||||
class="android.widget.ImageView"
|
||||
package="app.blackwallet.ar"
|
||||
content-desc="Transferencia externa de NOELIA ISABEL LEZCANO 21 de febrero de 2026 - 09:35 $123, 45"
|
||||
checkable="false" checked="false" clickable="true"
|
||||
enabled="true" focusable="true" focused="false"
|
||||
scrollable="false" long-clickable="false"
|
||||
password="false" selected="false"
|
||||
bounds="[0,2003][1080,2179]" drawing-order="0"
|
||||
hint=""/>
|
||||
</node>
|
||||
</node>
|
||||
<node index="13" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" content-desc="Tarjetas"
|
||||
checkable="false" checked="false" clickable="false"
|
||||
enabled="true" focusable="true" focused="false"
|
||||
scrollable="false" long-clickable="false" password="false"
|
||||
selected="false" bounds="[53,2255][215,2318]"
|
||||
drawing-order="0" hint=""/>
|
||||
<node index="14" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" content-desc="Ver más"
|
||||
checkable="false" checked="false" clickable="true"
|
||||
enabled="true" focusable="true" focused="false"
|
||||
scrollable="false" long-clickable="false" password="false"
|
||||
selected="false" bounds="[802,2255][1028,2318]"
|
||||
drawing-order="0" hint=""/>
|
||||
<node index="15" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar"
|
||||
content-desc="No hay tarjetas en tu billetera"
|
||||
checkable="false" checked="false" clickable="false"
|
||||
enabled="true" focusable="true" focused="false"
|
||||
scrollable="false" long-clickable="false" password="false"
|
||||
selected="false" bounds="[302,2344][778,2391]"
|
||||
drawing-order="0" hint=""/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node NAF="true" index="1" text="" resource-id="" class="android.widget.ImageView"
|
||||
package="app.blackwallet.ar" content-desc="" checkable="false" checked="false"
|
||||
clickable="true" enabled="true" focusable="true" focused="false"
|
||||
scrollable="false" long-clickable="false" password="false" selected="false"
|
||||
bounds="[456,2106][624,2274]" drawing-order="0" hint=""/>
|
||||
<node index="2" text="" resource-id="" class="android.widget.ImageView"
|
||||
package="app.blackwallet.ar" content-desc="Inicio" checkable="false"
|
||||
checked="false" clickable="true" enabled="true" focusable="true"
|
||||
focused="false" scrollable="false" long-clickable="false" password="false"
|
||||
selected="false" bounds="[88,2229][162,2350]" drawing-order="0" hint=""/>
|
||||
<node index="3" text="" resource-id="" class="android.widget.ImageView"
|
||||
package="app.blackwallet.ar" content-desc="Enviar" checkable="false"
|
||||
checked="false" clickable="true" enabled="true" focusable="true"
|
||||
focused="false" scrollable="false" long-clickable="false" password="false"
|
||||
selected="false" bounds="[251,2229][336,2350]" drawing-order="0" hint=""/>
|
||||
<node index="4" text="" resource-id="" class="android.widget.ImageView"
|
||||
package="app.blackwallet.ar" content-desc="Recibir" checkable="false"
|
||||
checked="false" clickable="true" enabled="true" focusable="true"
|
||||
focused="false" scrollable="false" long-clickable="false" password="false"
|
||||
selected="false" bounds="[729,2229][824,2350]" drawing-order="0" hint=""/>
|
||||
<node index="5" text="" resource-id="" class="android.widget.ImageView"
|
||||
package="app.blackwallet.ar" content-desc="Pagar" checkable="false"
|
||||
checked="false" clickable="true" enabled="true" focusable="true"
|
||||
focused="false" scrollable="false" long-clickable="false" password="false"
|
||||
selected="false" bounds="[913,2229][992,2350]" drawing-order="0" hint=""/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</hierarchy>
|
||||
BIN
assets/black/pin_code.png
Normal file
|
After Width: | Height: | Size: 127 KiB |
97
assets/black/pin_code.xml
Normal file
@ -0,0 +1,97 @@
|
||||
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
|
||||
<hierarchy rotation="0">
|
||||
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="app.blackwallet.ar"
|
||||
content-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="app.blackwallet.ar"
|
||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
|
||||
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
|
||||
bounds="[0,0][1080,2400]" drawing-order="1" hint="">
|
||||
<node index="0" text="" resource-id="android:id/content" class="android.widget.FrameLayout"
|
||||
package="app.blackwallet.ar" content-desc="" checkable="false" checked="false" clickable="false"
|
||||
enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false"
|
||||
password="false" selected="false" bounds="[0,0][1080,2400]" drawing-order="2" hint="">
|
||||
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="app.blackwallet.ar"
|
||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
||||
focusable="true" focused="true" scrollable="false" long-clickable="false" password="false"
|
||||
selected="false" bounds="[0,0][1080,2400]" drawing-order="1" hint="">
|
||||
<node index="0" text="" resource-id="" class="android.view.View" package="app.blackwallet.ar"
|
||||
content-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.view.View" package="app.blackwallet.ar"
|
||||
content-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.view.View"
|
||||
package="app.blackwallet.ar" content-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.view.View"
|
||||
package="app.blackwallet.ar" content-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.view.View"
|
||||
package="app.blackwallet.ar" content-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,283]" drawing-order="0" hint="">
|
||||
<node index="0" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" content-desc="Registrate" checkable="false"
|
||||
checked="false" clickable="false" enabled="true" focusable="true"
|
||||
focused="false" scrollable="false" long-clickable="false" password="false"
|
||||
selected="false" bounds="[42,173][315,246]" drawing-order="0" hint=""/>
|
||||
</node>
|
||||
<node index="1" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" content-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,2018]" drawing-order="0" hint="">
|
||||
<node index="0" text="" resource-id="" class="android.widget.ImageView"
|
||||
package="app.blackwallet.ar"
|
||||
content-desc="Ingresá tu código PIN Es un código de seguridad que te va a permitir operar con más seguridad Ingresá tu PIN"
|
||||
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,1396]"
|
||||
drawing-order="0" hint=""/>
|
||||
<node NAF="true" index="1" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" content-desc="" checkable="false"
|
||||
checked="false" clickable="true" enabled="true" focusable="true"
|
||||
focused="false" scrollable="false" long-clickable="true" password="false"
|
||||
selected="false" bounds="[263,1449][818,1514]" drawing-order="0" hint=""/>
|
||||
<node index="2" text="" resource-id="" class="android.widget.EditText"
|
||||
package="app.blackwallet.ar" content-desc="" checkable="false"
|
||||
checked="false" clickable="false" enabled="true" focusable="true"
|
||||
focused="true" scrollable="false" long-clickable="false" password="true"
|
||||
selected="false" bounds="[263,1449][818,1556]" drawing-order="0" hint=""/>
|
||||
<node index="3" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" content-desc="¿Olvidaste tu PIN?"
|
||||
checkable="false" checked="false" clickable="true" enabled="true"
|
||||
focusable="true" focused="false" scrollable="false" long-clickable="false"
|
||||
password="false" selected="false" bounds="[357,1687][723,1750]"
|
||||
drawing-order="0" hint=""/>
|
||||
<node index="4" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar"
|
||||
content-desc="Tengo un código de verificación" checkable="false"
|
||||
checked="false" clickable="true" enabled="true" focusable="true"
|
||||
focused="false" scrollable="false" long-clickable="false" password="false"
|
||||
selected="false" bounds="[218,1803][862,1866]" drawing-order="0" hint=""/>
|
||||
<node index="5" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" content-desc="Cerrar sesión"
|
||||
checkable="false" checked="false" clickable="true" enabled="true"
|
||||
focusable="true" focused="false" scrollable="false" long-clickable="false"
|
||||
password="false" selected="false" bounds="[435,1918][645,1966]"
|
||||
drawing-order="0" hint=""/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</hierarchy>
|
||||
BIN
assets/black/profile_page.png
Normal file
|
After Width: | Height: | Size: 139 KiB |
184
assets/black/profile_page.xml
Normal file
@ -0,0 +1,184 @@
|
||||
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
|
||||
<hierarchy rotation="0">
|
||||
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="app.blackwallet.ar"
|
||||
content-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="app.blackwallet.ar"
|
||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
|
||||
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
|
||||
bounds="[0,0][1080,2400]" drawing-order="1" hint="">
|
||||
<node index="0" text="" resource-id="android:id/content" class="android.widget.FrameLayout"
|
||||
package="app.blackwallet.ar" content-desc="" checkable="false" checked="false" clickable="false"
|
||||
enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false"
|
||||
password="false" selected="false" bounds="[0,0][1080,2400]" drawing-order="2" hint="">
|
||||
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="app.blackwallet.ar"
|
||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
||||
focusable="true" focused="true" scrollable="false" long-clickable="false" password="false"
|
||||
selected="false" bounds="[0,0][1080,2400]" drawing-order="1" hint="">
|
||||
<node index="0" text="" resource-id="" class="android.view.View" package="app.blackwallet.ar"
|
||||
content-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.view.View" package="app.blackwallet.ar"
|
||||
content-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.view.View"
|
||||
package="app.blackwallet.ar" content-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.view.View"
|
||||
package="app.blackwallet.ar" content-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.view.View"
|
||||
package="app.blackwallet.ar" content-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,283]" drawing-order="0" hint="">
|
||||
<node index="0" text="" resource-id="" class="android.widget.Button"
|
||||
package="app.blackwallet.ar" content-desc="Atrás" checkable="false"
|
||||
checked="false" clickable="true" enabled="true" focusable="true"
|
||||
focused="false" scrollable="false" long-clickable="false" password="false"
|
||||
selected="false" bounds="[0,136][147,283]" drawing-order="0" hint=""/>
|
||||
<node index="1" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" content-desc="Tu información"
|
||||
checkable="false" checked="false" clickable="false" enabled="true"
|
||||
focusable="true" focused="false" scrollable="false" long-clickable="false"
|
||||
password="false" selected="false" bounds="[189,173][581,246]"
|
||||
drawing-order="0" hint=""/>
|
||||
</node>
|
||||
<node index="1" text="" resource-id="" class="android.widget.ScrollView"
|
||||
package="app.blackwallet.ar" 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,2400]" drawing-order="0" hint="">
|
||||
<node index="0" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" content-desc="vc" checkable="false"
|
||||
checked="false" clickable="false" enabled="true" focusable="true"
|
||||
focused="false" scrollable="false" long-clickable="false" password="false"
|
||||
selected="false" bounds="[496,494][584,597]" drawing-order="0" hint=""/>
|
||||
<node index="1" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" content-desc="veronica cintia heredia "
|
||||
checkable="false" checked="false" clickable="false" enabled="true"
|
||||
focusable="true" focused="false" scrollable="false" long-clickable="false"
|
||||
password="false" selected="false" bounds="[205,716][875,800]"
|
||||
drawing-order="0" hint=""/>
|
||||
<node index="2" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" content-desc="12 de febrero 1989"
|
||||
checkable="false" checked="false" clickable="false" enabled="true"
|
||||
focusable="true" focused="false" scrollable="false" long-clickable="false"
|
||||
password="false" selected="false" bounds="[348,826][732,882]"
|
||||
drawing-order="0" hint=""/>
|
||||
<node index="3" text="" resource-id="" class="android.widget.ImageView"
|
||||
package="app.blackwallet.ar" content-desc="" checkable="false"
|
||||
checked="false" clickable="false" enabled="true" focusable="false"
|
||||
focused="false" scrollable="false" long-clickable="false" password="false"
|
||||
selected="false" bounds="[66,951][118,1043]" drawing-order="0" hint=""/>
|
||||
<node index="4" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" content-desc="Tu CVU" checkable="false"
|
||||
checked="false" clickable="false" enabled="true" focusable="true"
|
||||
focused="false" scrollable="false" long-clickable="false" password="false"
|
||||
selected="false" bounds="[171,950][287,997]" drawing-order="0" hint=""/>
|
||||
<node index="5" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" content-desc="0000177501057000175004"
|
||||
checkable="false" checked="false" clickable="false" enabled="true"
|
||||
focusable="true" focused="false" scrollable="false" long-clickable="false"
|
||||
password="false" selected="false" bounds="[171,997][606,1044]"
|
||||
drawing-order="0" hint=""/>
|
||||
<node NAF="true" index="6" text="" resource-id=""
|
||||
class="android.widget.ImageView" package="app.blackwallet.ar"
|
||||
content-desc="" checkable="false" checked="false" clickable="true"
|
||||
enabled="true" focusable="true" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false"
|
||||
bounds="[962,934][1041,1060]" drawing-order="0" hint=""/>
|
||||
<node index="7" text="" resource-id="" class="android.widget.ImageView"
|
||||
package="app.blackwallet.ar" content-desc="" checkable="false"
|
||||
checked="false" clickable="false" enabled="true" focusable="false"
|
||||
focused="false" scrollable="false" long-clickable="false" password="false"
|
||||
selected="false" bounds="[66,1106][118,1198]" drawing-order="0" hint=""/>
|
||||
<node index="8" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" content-desc="Tu Alias" checkable="false"
|
||||
checked="false" clickable="false" enabled="true" focusable="true"
|
||||
focused="false" scrollable="false" long-clickable="false" password="false"
|
||||
selected="false" bounds="[171,1105][294,1152]" drawing-order="0" hint=""/>
|
||||
<node index="9" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" content-desc="27335723320.black"
|
||||
checkable="false" checked="false" clickable="false" enabled="true"
|
||||
focusable="true" focused="false" scrollable="false" long-clickable="false"
|
||||
password="false" selected="false" bounds="[171,1152][481,1199]"
|
||||
drawing-order="0" hint=""/>
|
||||
<node NAF="true" index="10" text="" resource-id=""
|
||||
class="android.widget.ImageView" package="app.blackwallet.ar"
|
||||
content-desc="" checkable="false" checked="false" clickable="true"
|
||||
enabled="true" focusable="true" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false"
|
||||
bounds="[883,1089][962,1215]" drawing-order="0" hint=""/>
|
||||
<node NAF="true" index="11" text="" resource-id=""
|
||||
class="android.widget.ImageView" package="app.blackwallet.ar"
|
||||
content-desc="" checkable="false" checked="false" clickable="true"
|
||||
enabled="true" focusable="true" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false"
|
||||
bounds="[962,1089][1041,1215]" drawing-order="0" hint=""/>
|
||||
<node index="12" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" content-desc="Editá tu información"
|
||||
checkable="false" checked="false" clickable="false" enabled="true"
|
||||
focusable="true" focused="false" scrollable="false" long-clickable="false"
|
||||
password="false" selected="false" bounds="[79,1359][449,1414]"
|
||||
drawing-order="0" hint=""/>
|
||||
<node index="13" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" content-desc="" checkable="false"
|
||||
checked="false" clickable="false" enabled="true" focusable="false"
|
||||
focused="false" scrollable="false" long-clickable="false" password="false"
|
||||
selected="false" bounds="[79,1467][1001,2400]" drawing-order="0" hint="">
|
||||
<node index="0" text="veronica cintia " resource-id=""
|
||||
class="android.view.View" package="app.blackwallet.ar" content-desc=""
|
||||
checkable="false" checked="false" clickable="false" enabled="true"
|
||||
focusable="true" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false"
|
||||
bounds="[79,1467][1001,1635]" drawing-order="0" hint="Nombre"/>
|
||||
<node index="1" text="heredia " resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" content-desc="" checkable="false"
|
||||
checked="false" clickable="false" enabled="true" focusable="true"
|
||||
focused="false" scrollable="false" long-clickable="false"
|
||||
password="false" selected="false" bounds="[79,1714][1001,1882]"
|
||||
drawing-order="0" hint="Apellido"/>
|
||||
<node index="2" text="Fiorinogriselda4@gmail.com" resource-id=""
|
||||
class="android.view.View" package="app.blackwallet.ar" content-desc=""
|
||||
checkable="false" checked="false" clickable="false" enabled="true"
|
||||
focusable="true" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false"
|
||||
bounds="[79,1960][1001,2128]" drawing-order="0" hint="E-mail"/>
|
||||
<node index="3" text="12/2/1989" resource-id=""
|
||||
class="android.widget.EditText" package="app.blackwallet.ar"
|
||||
content-desc="" checkable="false" checked="false" clickable="true"
|
||||
enabled="true" focusable="true" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false"
|
||||
bounds="[79,2207][1001,2375]" drawing-order="0"
|
||||
hint="Fecha de nacimiento"/>
|
||||
<node index="4" text="" resource-id="" class="android.widget.ImageView"
|
||||
package="app.blackwallet.ar" content-desc="" checkable="false"
|
||||
checked="false" clickable="false" enabled="true" focusable="false"
|
||||
focused="false" scrollable="false" long-clickable="false"
|
||||
password="false" selected="false" bounds="[875,2228][1001,2354]"
|
||||
drawing-order="0" hint=""/>
|
||||
<node index="5" text="" resource-id="" class="android.widget.ImageView"
|
||||
package="app.blackwallet.ar" content-desc="" checkable="false"
|
||||
checked="false" clickable="false" enabled="true" focusable="false"
|
||||
focused="false" scrollable="false" long-clickable="false"
|
||||
password="false" selected="false" bounds="[0,0][0,0]"
|
||||
drawing-order="0" hint=""/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</hierarchy>
|
||||
BIN
assets/black/profile_page_2.png
Normal file
|
After Width: | Height: | Size: 112 KiB |
142
assets/black/profile_page_2.xml
Normal file
@ -0,0 +1,142 @@
|
||||
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
|
||||
<hierarchy rotation="0">
|
||||
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="app.blackwallet.ar"
|
||||
content-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="app.blackwallet.ar"
|
||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
|
||||
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
|
||||
bounds="[0,0][1080,2400]" drawing-order="1" hint="">
|
||||
<node index="0" text="" resource-id="android:id/content" class="android.widget.FrameLayout"
|
||||
package="app.blackwallet.ar" content-desc="" checkable="false" checked="false" clickable="false"
|
||||
enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false"
|
||||
password="false" selected="false" bounds="[0,0][1080,2400]" drawing-order="2" hint="">
|
||||
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="app.blackwallet.ar"
|
||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
||||
focusable="true" focused="true" scrollable="false" long-clickable="false" password="false"
|
||||
selected="false" bounds="[0,0][1080,2400]" drawing-order="1" hint="">
|
||||
<node index="0" text="" resource-id="" class="android.view.View" package="app.blackwallet.ar"
|
||||
content-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.view.View" package="app.blackwallet.ar"
|
||||
content-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.view.View"
|
||||
package="app.blackwallet.ar" content-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.view.View"
|
||||
package="app.blackwallet.ar" content-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.view.View"
|
||||
package="app.blackwallet.ar" content-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,283]" drawing-order="0" hint="">
|
||||
<node index="0" text="" resource-id="" class="android.widget.Button"
|
||||
package="app.blackwallet.ar" content-desc="Atrás" checkable="false"
|
||||
checked="false" clickable="true" enabled="true" focusable="true"
|
||||
focused="false" scrollable="false" long-clickable="false" password="false"
|
||||
selected="false" bounds="[0,136][147,283]" drawing-order="0" hint=""/>
|
||||
<node index="1" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" content-desc="Tu información"
|
||||
checkable="false" checked="false" clickable="false" enabled="true"
|
||||
focusable="true" focused="false" scrollable="false" long-clickable="false"
|
||||
password="false" selected="false" bounds="[189,173][581,246]"
|
||||
drawing-order="0" hint=""/>
|
||||
</node>
|
||||
<node index="1" text="" resource-id="" class="android.widget.ScrollView"
|
||||
package="app.blackwallet.ar" 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,2400]" drawing-order="0" hint="">
|
||||
<node index="0" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" content-desc="Editá tu información"
|
||||
checkable="false" checked="false" clickable="false" enabled="true"
|
||||
focusable="true" focused="false" scrollable="false" long-clickable="false"
|
||||
password="false" selected="false" bounds="[79,283][449,305]"
|
||||
drawing-order="0" hint=""/>
|
||||
<node index="1" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" content-desc="" checkable="false"
|
||||
checked="false" clickable="false" enabled="true" focusable="false"
|
||||
focused="false" scrollable="false" long-clickable="false" password="false"
|
||||
selected="false" bounds="[79,358][1001,2295]" drawing-order="0" hint="">
|
||||
<node index="0" text="veronica cintia " resource-id=""
|
||||
class="android.view.View" package="app.blackwallet.ar" content-desc=""
|
||||
checkable="false" checked="false" clickable="false" enabled="true"
|
||||
focusable="true" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false"
|
||||
bounds="[79,358][1001,526]" drawing-order="0" hint="Nombre"/>
|
||||
<node index="1" text="heredia " resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" content-desc="" checkable="false"
|
||||
checked="false" clickable="false" enabled="true" focusable="true"
|
||||
focused="false" scrollable="false" long-clickable="false"
|
||||
password="false" selected="false" bounds="[79,605][1001,773]"
|
||||
drawing-order="0" hint="Apellido"/>
|
||||
<node index="2" text="Fiorinogriselda4@gmail.com" resource-id=""
|
||||
class="android.view.View" package="app.blackwallet.ar" content-desc=""
|
||||
checkable="false" checked="false" clickable="false" enabled="true"
|
||||
focusable="true" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false"
|
||||
bounds="[79,851][1001,1019]" drawing-order="0" hint="E-mail"/>
|
||||
<node index="3" text="12/2/1989" resource-id=""
|
||||
class="android.widget.EditText" package="app.blackwallet.ar"
|
||||
content-desc="" checkable="false" checked="false" clickable="true"
|
||||
enabled="true" focusable="true" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false"
|
||||
bounds="[79,1098][1001,1266]" drawing-order="0"
|
||||
hint="Fecha de nacimiento"/>
|
||||
<node index="4" text="" resource-id="" class="android.widget.ImageView"
|
||||
package="app.blackwallet.ar" content-desc="" checkable="false"
|
||||
checked="false" clickable="false" enabled="true" focusable="false"
|
||||
focused="false" scrollable="false" long-clickable="false"
|
||||
password="false" selected="false" bounds="[875,1119][1001,1245]"
|
||||
drawing-order="0" hint=""/>
|
||||
<node index="5" text="" resource-id="" class="android.widget.Button"
|
||||
package="app.blackwallet.ar" content-desc="Género Femenino"
|
||||
checkable="false" checked="false" clickable="true" enabled="true"
|
||||
focusable="true" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false"
|
||||
bounds="[79,1345][1001,1513]" drawing-order="0" hint=""/>
|
||||
<node index="6" text="3543554877" resource-id=""
|
||||
class="android.widget.EditText" package="app.blackwallet.ar"
|
||||
content-desc="" checkable="false" checked="false" clickable="true"
|
||||
enabled="true" focusable="true" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false"
|
||||
bounds="[79,1592][1001,1760]" drawing-order="0"
|
||||
hint="Teléfono celular"/>
|
||||
<node index="7" text="********" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" content-desc="" checkable="false"
|
||||
checked="false" clickable="false" enabled="true" focusable="true"
|
||||
focused="false" scrollable="false" long-clickable="false"
|
||||
password="false" selected="false" bounds="[79,1838][1001,2006]"
|
||||
drawing-order="0" hint="Contraseña"/>
|
||||
<node index="8" text="" resource-id="" class="android.widget.ImageView"
|
||||
package="app.blackwallet.ar" content-desc="" checkable="false"
|
||||
checked="false" clickable="false" enabled="true" focusable="false"
|
||||
focused="false" scrollable="false" long-clickable="false"
|
||||
password="false" selected="false" bounds="[875,1856][1001,1989]"
|
||||
drawing-order="0" hint=""/>
|
||||
<node index="9" text="" resource-id="" class="android.widget.Button"
|
||||
package="app.blackwallet.ar" content-desc="Guardar cambios"
|
||||
checkable="false" checked="false" clickable="true" enabled="true"
|
||||
focusable="true" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false"
|
||||
bounds="[79,2111][1001,2243]" drawing-order="0" hint=""/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</hierarchy>
|
||||
BIN
assets/black/side_menu.png
Normal file
|
After Width: | Height: | Size: 173 KiB |
169
assets/black/side_menu.xml
Normal file
@ -0,0 +1,169 @@
|
||||
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
|
||||
<hierarchy rotation="0">
|
||||
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="app.blackwallet.ar"
|
||||
content-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="app.blackwallet.ar"
|
||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
|
||||
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
|
||||
bounds="[0,0][1080,2400]" drawing-order="1" hint="">
|
||||
<node index="0" text="" resource-id="android:id/content" class="android.widget.FrameLayout"
|
||||
package="app.blackwallet.ar" content-desc="" checkable="false" checked="false" clickable="false"
|
||||
enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false"
|
||||
password="false" selected="false" bounds="[0,0][1080,2400]" drawing-order="2" hint="">
|
||||
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="app.blackwallet.ar"
|
||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
||||
focusable="true" focused="true" scrollable="false" long-clickable="false" password="false"
|
||||
selected="false" bounds="[0,0][1080,2400]" drawing-order="1" hint="">
|
||||
<node index="0" text="" resource-id="" class="android.view.View" package="app.blackwallet.ar"
|
||||
content-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.view.View" package="app.blackwallet.ar"
|
||||
content-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.view.View"
|
||||
package="app.blackwallet.ar" content-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.view.View"
|
||||
package="app.blackwallet.ar" content-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.view.View"
|
||||
package="app.blackwallet.ar" content-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.view.View"
|
||||
package="app.blackwallet.ar" content-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.view.View"
|
||||
package="app.blackwallet.ar" content-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.view.View"
|
||||
package="app.blackwallet.ar"
|
||||
content-desc="vc veronica cintia heredia " checkable="false"
|
||||
checked="false" clickable="false" enabled="true" focusable="true"
|
||||
focused="false" scrollable="false" long-clickable="false"
|
||||
password="false" selected="false" bounds="[0,0][1080,1856]"
|
||||
drawing-order="0" hint="">
|
||||
<node NAF="true" index="0" text="" resource-id=""
|
||||
class="android.widget.ImageView" package="app.blackwallet.ar"
|
||||
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,178][134,238]"
|
||||
drawing-order="0" hint=""/>
|
||||
<node index="1" text="" resource-id=""
|
||||
class="android.widget.ImageView" package="app.blackwallet.ar"
|
||||
content-desc="Tu Información" checkable="false"
|
||||
checked="false" clickable="true" enabled="true"
|
||||
focusable="true" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false"
|
||||
bounds="[42,685][1038,763]" drawing-order="0" hint=""/>
|
||||
<node index="2" text="" resource-id=""
|
||||
class="android.widget.ImageView" package="app.blackwallet.ar"
|
||||
content-desc="Notificaciones" checkable="false"
|
||||
checked="false" clickable="true" enabled="true"
|
||||
focusable="true" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false"
|
||||
bounds="[42,845][1038,923]" drawing-order="0" hint=""/>
|
||||
<node index="3" text="" resource-id=""
|
||||
class="android.widget.ImageView" package="app.blackwallet.ar"
|
||||
content-desc="Ajustes y preferencias" checkable="false"
|
||||
checked="false" clickable="true" enabled="true"
|
||||
focusable="true" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false"
|
||||
bounds="[42,1005][1038,1084]" drawing-order="0" hint=""/>
|
||||
<node index="4" text="" resource-id=""
|
||||
class="android.widget.ImageView" package="app.blackwallet.ar"
|
||||
content-desc="Ayuda" checkable="false" checked="false"
|
||||
clickable="true" enabled="true" focusable="true"
|
||||
focused="false" scrollable="false" long-clickable="false"
|
||||
password="false" selected="false"
|
||||
bounds="[42,1165][1038,1244]" drawing-order="0" hint=""/>
|
||||
<node index="5" text="" resource-id=""
|
||||
class="android.widget.ImageView" package="app.blackwallet.ar"
|
||||
content-desc="Invitar a Black Wallet" checkable="false"
|
||||
checked="false" clickable="true" enabled="true"
|
||||
focusable="true" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false"
|
||||
bounds="[42,1325][1038,1404]" drawing-order="0" hint=""/>
|
||||
<node index="6" text="" resource-id=""
|
||||
class="android.widget.ImageView" package="app.blackwallet.ar"
|
||||
content-desc="Cerrar sesión" checkable="false" checked="false"
|
||||
clickable="true" enabled="true" focusable="true"
|
||||
focused="false" scrollable="false" long-clickable="false"
|
||||
password="false" selected="false"
|
||||
bounds="[42,1669][1038,1748]" drawing-order="0" hint=""/>
|
||||
</node>
|
||||
<node index="1" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" content-desc="" checkable="false"
|
||||
checked="false" clickable="false" enabled="true" focusable="false"
|
||||
focused="false" scrollable="false" long-clickable="false"
|
||||
password="false" selected="false" bounds="[0,1856][1080,1882]"
|
||||
drawing-order="0" hint=""/>
|
||||
<node index="2" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" content-desc="" checkable="false"
|
||||
checked="false" clickable="false" enabled="true" focusable="false"
|
||||
focused="false" scrollable="false" long-clickable="false"
|
||||
password="false" selected="false" bounds="[0,1882][1080,2223]"
|
||||
drawing-order="0" hint="">
|
||||
<node index="0" text="" resource-id=""
|
||||
class="android.widget.ImageView" package="app.blackwallet.ar"
|
||||
content-desc="Inicio" checkable="false" checked="false"
|
||||
clickable="true" enabled="true" focusable="true"
|
||||
focused="false" scrollable="false" long-clickable="false"
|
||||
password="false" selected="false" bounds="[88,2024][162,2145]"
|
||||
drawing-order="0" hint=""/>
|
||||
<node index="1" text="" resource-id=""
|
||||
class="android.widget.ImageView" package="app.blackwallet.ar"
|
||||
content-desc="Enviar" checkable="false" checked="false"
|
||||
clickable="true" enabled="true" focusable="true"
|
||||
focused="false" scrollable="false" long-clickable="false"
|
||||
password="false" selected="false"
|
||||
bounds="[251,2024][336,2145]" drawing-order="0" hint=""/>
|
||||
<node NAF="true" index="2" text="" resource-id=""
|
||||
class="android.widget.ImageView" package="app.blackwallet.ar"
|
||||
content-desc="" checkable="false" checked="false"
|
||||
clickable="true" enabled="true" focusable="true"
|
||||
focused="false" scrollable="false" long-clickable="false"
|
||||
password="false" selected="false"
|
||||
bounds="[456,1898][624,2066]" drawing-order="0" hint=""/>
|
||||
<node index="3" text="" resource-id=""
|
||||
class="android.widget.ImageView" package="app.blackwallet.ar"
|
||||
content-desc="Recibir" checkable="false" checked="false"
|
||||
clickable="true" enabled="true" focusable="true"
|
||||
focused="false" scrollable="false" long-clickable="false"
|
||||
password="false" selected="false"
|
||||
bounds="[729,2024][824,2145]" drawing-order="0" hint=""/>
|
||||
<node index="4" text="" resource-id=""
|
||||
class="android.widget.ImageView" package="app.blackwallet.ar"
|
||||
content-desc="Pagar" checkable="false" checked="false"
|
||||
clickable="true" enabled="true" focusable="true"
|
||||
focused="false" scrollable="false" long-clickable="false"
|
||||
password="false" selected="false"
|
||||
bounds="[913,2024][992,2145]" drawing-order="0" hint=""/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</hierarchy>
|
||||
@ -1,5 +1,5 @@
|
||||
[apps]
|
||||
list=ozon
|
||||
list=ozon, black
|
||||
|
||||
[common]
|
||||
currencies=USD, KRW, AZN, RUB
|
||||
@ -25,6 +25,11 @@ paymentsGet=http://localhost:9999/api/v1/payments
|
||||
transactionInsert=http://localhost:9999/api/v1/transaction/insert
|
||||
transactionUpdate=http://localhost:9999/api/v1/transaction/update
|
||||
|
||||
[black]
|
||||
android_package_name=app.blackwallet.ar
|
||||
currency=USD
|
||||
name=Black
|
||||
|
||||
[ozon]
|
||||
android_package_name=ru.ozon.fintech.finance
|
||||
currency=RUB
|
||||
|
||||
@ -128,6 +128,7 @@ void DatabaseManager::initSchema() {
|
||||
install TEXT DEFAULT 'no',
|
||||
comment TEXT,
|
||||
phone TEXT DEFAULT '',
|
||||
email TEXT DEFAULT '',
|
||||
full_name TEXT DEFAULT '',
|
||||
bank_profile_id TEXT DEFAULT '',
|
||||
currency TEXT DEFAULT '',
|
||||
@ -223,6 +224,15 @@ void DatabaseManager::initSchema() {
|
||||
q.exec("PRAGMA user_version = 1");
|
||||
qDebug() << "[DB] Migration 1 applied";
|
||||
}
|
||||
|
||||
// ── Версия 2: добавляем email в applications ─────────────────────────────
|
||||
if (version < 2) {
|
||||
db.transaction();
|
||||
q.exec("ALTER TABLE applications ADD COLUMN email TEXT DEFAULT ''");
|
||||
db.commit();
|
||||
q.exec("PRAGMA user_version = 2");
|
||||
qDebug() << "[DB] Migration 2 applied";
|
||||
}
|
||||
}
|
||||
|
||||
void DatabaseManager::closeConnection() {
|
||||
|
||||
@ -10,13 +10,14 @@ bool AccountDAO::upsertAccount(const AccountInfo &info) {
|
||||
QSqlQuery query(DatabaseManager::instance().database());
|
||||
|
||||
query.prepare(R"(
|
||||
INSERT INTO accounts (device_id, app_code, last_numbers, amount, update_time, status, description, currency)
|
||||
VALUES (:device_id, :app_code, :last_numbers, :amount, :update_time, :status, :description, :currency)
|
||||
INSERT INTO accounts (device_id, app_code, last_numbers, card_number, amount, update_time, status, description, currency)
|
||||
VALUES (:device_id, :app_code, :last_numbers, :card_number, :amount, :update_time, :status, :description, :currency)
|
||||
ON CONFLICT(device_id, app_code, last_numbers)
|
||||
DO UPDATE SET
|
||||
amount = excluded.amount,
|
||||
update_time = excluded.update_time,
|
||||
last_numbers = excluded.last_numbers,
|
||||
card_number = excluded.card_number,
|
||||
status = excluded.status,
|
||||
description = excluded.description,
|
||||
currency = excluded.currency
|
||||
@ -25,6 +26,7 @@ bool AccountDAO::upsertAccount(const AccountInfo &info) {
|
||||
query.bindValue(":device_id", info.deviceId);
|
||||
query.bindValue(":app_code", info.appCode);
|
||||
query.bindValue(":last_numbers", info.lastNumbers);
|
||||
query.bindValue(":card_number", info.cardNumber);
|
||||
query.bindValue(":currency", info.currency);
|
||||
query.bindValue(":description", info.description);
|
||||
query.bindValue(":amount", info.amount);
|
||||
|
||||
@ -128,6 +128,7 @@ ApplicationInfo parseApplication(const QSqlQuery &query) {
|
||||
app.install = query.value("install").toString() == "yes";
|
||||
app.pinCodeChecked = query.value("pin_code_checked").toString() == "yes";
|
||||
app.phone = query.value("phone").toString();
|
||||
app.email = query.value("email").toString();
|
||||
app.fullName = query.value("full_name").toString();
|
||||
app.bankProfileId = query.value("bank_profile_id").toString();
|
||||
app.currency = query.value("currency").toString();
|
||||
@ -139,7 +140,7 @@ ApplicationInfo ApplicationDAO::getApplication(const QString &deviceId, const QS
|
||||
QSqlQuery query(DatabaseManager::instance().database());
|
||||
|
||||
query.prepare(R"(
|
||||
SELECT id, device_id, pin_code, code, name, package, status, comment, install, pin_code_checked, phone, full_name, bank_profile_id, currency, amount
|
||||
SELECT id, device_id, pin_code, code, name, package, status, comment, install, pin_code_checked, phone, email, full_name, bank_profile_id, currency, amount
|
||||
FROM applications
|
||||
WHERE device_id = :device_id AND code = :code
|
||||
LIMIT 1
|
||||
@ -164,7 +165,7 @@ QList<ApplicationInfo> ApplicationDAO::getApplicationsByDeviceId(const QString &
|
||||
QList<ApplicationInfo> list;
|
||||
|
||||
query.prepare(R"(
|
||||
SELECT id, device_id, pin_code, code, name, package, status, comment, install, pin_code_checked, phone, full_name, bank_profile_id, currency, amount
|
||||
SELECT id, device_id, pin_code, code, name, package, status, comment, install, pin_code_checked, phone, email, full_name, bank_profile_id, currency, amount
|
||||
FROM applications
|
||||
WHERE device_id = :device_id AND install = 'yes'
|
||||
)");
|
||||
@ -185,19 +186,21 @@ QList<ApplicationInfo> ApplicationDAO::getApplicationsByDeviceId(const QString &
|
||||
bool ApplicationDAO::updateProfileInfo(
|
||||
const int &appId,
|
||||
const QString &fullName,
|
||||
const QString &phone
|
||||
const QString &phone,
|
||||
const QString &email
|
||||
) {
|
||||
QSqlQuery query(DatabaseManager::instance().database());
|
||||
|
||||
query.prepare(R"(
|
||||
UPDATE applications
|
||||
SET full_name = :full_name, phone = :phone
|
||||
SET full_name = :full_name, phone = :phone, email = :email
|
||||
WHERE id = :id
|
||||
)");
|
||||
|
||||
query.bindValue(":id", appId);
|
||||
query.bindValue(":full_name", fullName);
|
||||
query.bindValue(":phone", phone);
|
||||
query.bindValue(":email", email);
|
||||
|
||||
if (!query.exec()) {
|
||||
qWarning() << "Ошибка при обновлении профиля приложения:" << query.lastError().text();
|
||||
|
||||
@ -24,7 +24,8 @@ public:
|
||||
[[nodiscard]] static bool updateProfileInfo(
|
||||
const int &appId,
|
||||
const QString &fullName,
|
||||
const QString &phone
|
||||
const QString &phone,
|
||||
const QString &email = ""
|
||||
);
|
||||
|
||||
[[nodiscard]] static bool updateBankProfileId(int appId, const QString &bankProfileId);
|
||||
|
||||
BIN
images/black_icon.png
Normal file
|
After Width: | Height: | Size: 2.9 KiB |
@ -45,6 +45,7 @@ public:
|
||||
QString hint;
|
||||
bool clickable = false;
|
||||
bool focusable = false;
|
||||
bool password = false;
|
||||
|
||||
private:
|
||||
int m_x1 = -1, m_y1 = -1, m_x2 = -1, m_y2 = -1;
|
||||
|
||||
@ -16,6 +16,7 @@ struct ApplicationInfo {
|
||||
QString status;
|
||||
QString comment;
|
||||
QString phone;
|
||||
QString email;
|
||||
QString fullName;
|
||||
QString bankProfileId;
|
||||
QString currency;
|
||||
|
||||
@ -17,6 +17,9 @@
|
||||
#include "ozon/GetCardInfoScript.h"
|
||||
#include "ozon/GetLastTransactionsScript.h"
|
||||
#include "toss/LoginAndCheckAccountsTossScript.h"
|
||||
#include "black/LoginAndCheckAccountsScript.h"
|
||||
#include "black/GetProfileInfoScript.h"
|
||||
#include "black/GetCardInfoScript.h"
|
||||
#include "dao/AccountDAO.h"
|
||||
#include "dao/ApplicationDAO.h"
|
||||
#include "bank/TransactionWindow.h"
|
||||
@ -238,6 +241,80 @@ AccountSettingsWindow::AccountSettingsWindow(
|
||||
layout->addLayout(ozonRow);
|
||||
}
|
||||
|
||||
if (m_applicationInfo.code == "black" && m_applicationInfo.pinCodeChecked) {
|
||||
QHBoxLayout *blackRow = new QHBoxLayout();
|
||||
|
||||
QPushButton *profileButton = new QPushButton("Обновить профиль");
|
||||
profileButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
|
||||
profileButton->setStyleSheet("background-color: #1565C0; color: white;");
|
||||
QObject::connect(profileButton, &QPushButton::clicked, [this]() {
|
||||
QMessageBox msgBox(this);
|
||||
msgBox.setWindowTitle(tr("Обновить профиль?"));
|
||||
msgBox.setText(
|
||||
"Запустится скрипт получения профиля из " + m_applicationInfo.name +
|
||||
". Окно с настройками закроется.");
|
||||
QPushButton *runBtn = msgBox.addButton(tr("Запустить"), QMessageBox::AcceptRole);
|
||||
QPushButton *cancelBtn = msgBox.addButton(tr("Отмена"), QMessageBox::RejectRole);
|
||||
msgBox.setDefaultButton(cancelBtn);
|
||||
msgBox.setModal(true);
|
||||
msgBox.exec();
|
||||
if (msgBox.clickedButton() == runBtn) {
|
||||
startGetProfileInfo(m_applicationInfo.code);
|
||||
close();
|
||||
}
|
||||
});
|
||||
|
||||
QPushButton *cardButton = new QPushButton("Проверить аккаунты");
|
||||
cardButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
|
||||
cardButton->setStyleSheet("background-color: #1565C0; color: white;");
|
||||
QObject::connect(cardButton, &QPushButton::clicked, [this]() {
|
||||
QMessageBox msgBox(this);
|
||||
msgBox.setWindowTitle(tr("Проверить аккаунты?"));
|
||||
msgBox.setText(
|
||||
"Запустится скрипт получения данных карты из " + m_applicationInfo.name +
|
||||
". Окно с настройками закроется.");
|
||||
QPushButton *runBtn = msgBox.addButton(tr("Запустить"), QMessageBox::AcceptRole);
|
||||
QPushButton *cancelBtn = msgBox.addButton(tr("Отмена"), QMessageBox::RejectRole);
|
||||
msgBox.setDefaultButton(cancelBtn);
|
||||
msgBox.setModal(true);
|
||||
msgBox.exec();
|
||||
if (msgBox.clickedButton() == runBtn) {
|
||||
startGetCardInfo(m_applicationInfo.code);
|
||||
close();
|
||||
}
|
||||
});
|
||||
|
||||
QPushButton *transactionsButton = new QPushButton("Проверить транзакции");
|
||||
transactionsButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
|
||||
transactionsButton->setStyleSheet("background-color: #1565C0; color: white;");
|
||||
QObject::connect(transactionsButton, &QPushButton::clicked, [this]() {
|
||||
QMessageBox msgBox(this);
|
||||
msgBox.setWindowTitle(tr("Проверить транзакции?"));
|
||||
msgBox.setText(
|
||||
"Запустится скрипт получения последних транзакций из " + m_applicationInfo.name +
|
||||
". Окно с настройками закроется.");
|
||||
QPushButton *runBtn = msgBox.addButton(tr("За 24 часа"), QMessageBox::AcceptRole);
|
||||
QPushButton *last5Btn = msgBox.addButton(tr("Последние 5"), QMessageBox::AcceptRole);
|
||||
QPushButton *cancelBtn = msgBox.addButton(tr("Отмена"), QMessageBox::RejectRole);
|
||||
msgBox.setDefaultButton(cancelBtn);
|
||||
msgBox.setModal(true);
|
||||
msgBox.exec();
|
||||
if (msgBox.clickedButton() == runBtn) {
|
||||
startGetLastTransactions(m_applicationInfo.code);
|
||||
close();
|
||||
} else if (msgBox.clickedButton() == last5Btn) {
|
||||
startGetLastTransactions(m_applicationInfo.code, 5);
|
||||
close();
|
||||
}
|
||||
});
|
||||
|
||||
blackRow->addWidget(profileButton);
|
||||
blackRow->addWidget(cardButton);
|
||||
blackRow->addWidget(transactionsButton);
|
||||
blackRow->addStretch();
|
||||
layout->addLayout(blackRow);
|
||||
}
|
||||
|
||||
layout->addWidget(new QLabel("Счета"));
|
||||
QTableWidget *tableWidget = new QTableWidget(this);
|
||||
tableWidget->setSelectionMode(QAbstractItemView::NoSelection);
|
||||
@ -315,6 +392,13 @@ void AccountSettingsWindow::startCheckPinCode(const QString &appCode) {
|
||||
connect(worker, &Ozon::LoginAndCheckAccountsScript::finished, thread, &QThread::quit);
|
||||
connect(worker, &Ozon::LoginAndCheckAccountsScript::finished, worker, &QObject::deleteLater);
|
||||
connect(thread, &QThread::finished, thread, &QObject::deleteLater);
|
||||
} else if (appCode == "black") {
|
||||
auto *worker = new Black::LoginAndCheckAccountsScript(m_deviceId, appCode, nullptr);
|
||||
worker->moveToThread(thread);
|
||||
connect(thread, &QThread::started, worker, &Black::LoginAndCheckAccountsScript::start);
|
||||
connect(worker, &Black::LoginAndCheckAccountsScript::finished, thread, &QThread::quit);
|
||||
connect(worker, &Black::LoginAndCheckAccountsScript::finished, worker, &QObject::deleteLater);
|
||||
connect(thread, &QThread::finished, thread, &QObject::deleteLater);
|
||||
} else {
|
||||
thread->deleteLater();
|
||||
return;
|
||||
@ -324,21 +408,32 @@ void AccountSettingsWindow::startCheckPinCode(const QString &appCode) {
|
||||
}
|
||||
|
||||
void AccountSettingsWindow::startGetProfileInfo(const QString &appCode) {
|
||||
if (appCode != "ozon") return;
|
||||
|
||||
QThread *thread = new QThread(nullptr);
|
||||
|
||||
if (appCode == "ozon") {
|
||||
auto *worker = new Ozon::GetProfileInfoScript(m_deviceId, appCode, nullptr);
|
||||
worker->moveToThread(thread);
|
||||
connect(thread, &QThread::started, worker, &Ozon::GetProfileInfoScript::start);
|
||||
connect(worker, &Ozon::GetProfileInfoScript::finished, thread, &QThread::quit);
|
||||
connect(worker, &Ozon::GetProfileInfoScript::finished, worker, &QObject::deleteLater);
|
||||
connect(thread, &QThread::finished, thread, &QObject::deleteLater);
|
||||
} else if (appCode == "black") {
|
||||
auto *worker = new Black::GetProfileInfoScript(m_deviceId, appCode, nullptr);
|
||||
worker->moveToThread(thread);
|
||||
connect(thread, &QThread::started, worker, &Black::GetProfileInfoScript::start);
|
||||
connect(worker, &Black::GetProfileInfoScript::finished, thread, &QThread::quit);
|
||||
connect(worker, &Black::GetProfileInfoScript::finished, worker, &QObject::deleteLater);
|
||||
connect(thread, &QThread::finished, thread, &QObject::deleteLater);
|
||||
} else {
|
||||
thread->deleteLater();
|
||||
return;
|
||||
}
|
||||
|
||||
thread->start();
|
||||
}
|
||||
|
||||
void AccountSettingsWindow::startGetCardInfo(const QString &appCode) {
|
||||
if (appCode != "ozon") return;
|
||||
|
||||
if (appCode == "ozon") {
|
||||
QThread *thread = new QThread(nullptr);
|
||||
auto *worker = new Ozon::GetCardInfoScript(m_deviceId, appCode, "", nullptr);
|
||||
worker->moveToThread(thread);
|
||||
@ -347,6 +442,16 @@ void AccountSettingsWindow::startGetCardInfo(const QString &appCode) {
|
||||
connect(worker, &Ozon::GetCardInfoScript::finished, worker, &QObject::deleteLater);
|
||||
connect(thread, &QThread::finished, thread, &QObject::deleteLater);
|
||||
thread->start();
|
||||
} else if (appCode == "black") {
|
||||
QThread *thread = new QThread(nullptr);
|
||||
auto *worker = new Black::GetCardInfoScript(m_deviceId, appCode, nullptr);
|
||||
worker->moveToThread(thread);
|
||||
connect(thread, &QThread::started, worker, &Black::GetCardInfoScript::start);
|
||||
connect(worker, &Black::GetCardInfoScript::finished, thread, &QThread::quit);
|
||||
connect(worker, &Black::GetCardInfoScript::finished, worker, &QObject::deleteLater);
|
||||
connect(thread, &QThread::finished, thread, &QObject::deleteLater);
|
||||
thread->start();
|
||||
}
|
||||
}
|
||||
|
||||
void AccountSettingsWindow::startGetLastTransactions(const QString &appCode, int maxCount) {
|
||||
|
||||
@ -26,6 +26,7 @@
|
||||
#include "toss/LoginAndCheckAccountsTossScript.h"
|
||||
#include "widget/common/CollapsibleSection.h"
|
||||
#include "ziraat/LoginAndCheckAccountsZiraatScript.h"
|
||||
#include "black/LoginAndCheckAccountsScript.h"
|
||||
|
||||
QTableWidgetItem *BankSettingsWindow::createTableWidget(const QString &text) {
|
||||
QTableWidgetItem *item = new QTableWidgetItem(text);
|
||||
@ -87,6 +88,13 @@ void BankSettingsWindow::startCheckPinCode(const QString &appCode) {
|
||||
connect(worker, &LoginAndCheckAccountsTossScript::finished, thread, &QThread::quit);
|
||||
connect(worker, &LoginAndCheckAccountsTossScript::finished, worker, &QObject::deleteLater);
|
||||
connect(thread, &QThread::finished, thread, &QObject::deleteLater);
|
||||
} else if (appCode == "black") {
|
||||
auto *worker = new Black::LoginAndCheckAccountsScript(m_deviceId, appCode, nullptr);
|
||||
worker->moveToThread(thread);
|
||||
connect(thread, &QThread::started, worker, &Black::LoginAndCheckAccountsScript::start);
|
||||
connect(worker, &Black::LoginAndCheckAccountsScript::finished, thread, &QThread::quit);
|
||||
connect(worker, &Black::LoginAndCheckAccountsScript::finished, worker, &QObject::deleteLater);
|
||||
connect(thread, &QThread::finished, thread, &QObject::deleteLater);
|
||||
} else {
|
||||
thread->deleteLater();
|
||||
return;
|
||||
|
||||