Daily commit
This commit is contained in:
parent
688a71c0b2
commit
45544ad607
@ -190,14 +190,20 @@ bool CommonScript::goToAllProducts(
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CommonScript::readTransactionData() {
|
||||
bool CommonScript::findAndTapOnAccount(const QString &deviceId, const QString &accountNumbers) {
|
||||
QList<QPair<AccountInfo, Node> > accounts = xmlScreenParser.parseAccountsInfo();
|
||||
for (auto &[account, node]: accounts) {
|
||||
// FIXME будем считать что числа последние везде уникальные
|
||||
if (accountNumbers == account.lastNumbers) {
|
||||
qDebug() << "findAndTapOnAccount: " << accountNumbers;
|
||||
AdbUtils::makeTap(deviceId, node.x(), node.y());
|
||||
QThread::msleep(1000);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// 1. топаем на домашнюю
|
||||
// 2. распарсить мои карты и вернуть данные
|
||||
// 3. синхронизировать историю транзакций (с домашней)
|
||||
|
||||
|
||||
void CommonScript::stop() {
|
||||
m_running = false;
|
||||
|
||||
@ -23,6 +23,8 @@ protected:
|
||||
int height
|
||||
);
|
||||
|
||||
bool findAndTapOnAccount(const QString &deviceId, const QString &accountNumbers);
|
||||
|
||||
Node swipeToButton(
|
||||
const QString &deviceId,
|
||||
const QString &text,
|
||||
@ -41,14 +43,13 @@ protected:
|
||||
const QString &deviceId, int width, int height
|
||||
);
|
||||
|
||||
bool readTransactionData();
|
||||
|
||||
bool m_running = true;
|
||||
ScreenXmlParser xmlScreenParser;
|
||||
int m_counter = 0;
|
||||
|
||||
signals:
|
||||
void finished();
|
||||
void finishedWithResult(const QString &result);
|
||||
|
||||
public slots:
|
||||
virtual void start() final;
|
||||
|
||||
@ -2,16 +2,13 @@
|
||||
|
||||
#include <QRandomGenerator>
|
||||
#include <QThread>
|
||||
#include <QTimeZone>
|
||||
#include <utility>
|
||||
|
||||
#include "DatabaseManager.h"
|
||||
#include "adb/AdbUtils.h"
|
||||
#include "dao/AccountDAO.h"
|
||||
#include "dao/ApplicationDAO.h"
|
||||
#include "dao/DeviceDAO.h"
|
||||
#include "dao/TransactionDAO.h"
|
||||
#include "db/ApplicationInfo.h"
|
||||
#include "db/DeviceInfo.h"
|
||||
#include "time/DateUtils.h"
|
||||
|
||||
@ -33,11 +30,19 @@ QList<TransactionInfo> findSavedTransaction(
|
||||
|
||||
for (const TransactionInfo &info: transactions) {
|
||||
QDateTime timestamp = info.timestamp;
|
||||
QString shortDescription = parsed.shortDescription;
|
||||
// если тот же день
|
||||
if (dateTime.date() == timestamp.date() && parsed.amount == info.amount) {
|
||||
// Перевод Надежда Юрьевна К** в Альфа-Банк через СБП, по номеру телефона +79641815...
|
||||
if (parsed.shortDescription.contains(info.name)) {
|
||||
txs.append(info);
|
||||
if (shortDescription.contains("Перевод")) {
|
||||
if (shortDescription.contains(info.name)) {
|
||||
txs.append(info);
|
||||
}
|
||||
} else {
|
||||
// Перевод по карте
|
||||
if (shortDescription == info.shortDescription) {
|
||||
txs.append(info);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -45,16 +50,16 @@ QList<TransactionInfo> findSavedTransaction(
|
||||
return txs;
|
||||
}
|
||||
|
||||
bool isSingle(const TransactionInfo &transaction, const QList<TransactionInfo> &transactions) {
|
||||
int countSimilar(const TransactionInfo &transaction, const QList<TransactionInfo> &transactions) {
|
||||
int count = 0;
|
||||
for (const TransactionInfo &info: transactions) {
|
||||
if (info.amount == transaction.amount
|
||||
&& info.shortDescription == transaction.shortDescription
|
||||
&& info.bankTime == transaction.bankTime) {
|
||||
count++;
|
||||
++count;
|
||||
}
|
||||
}
|
||||
return count == 1;
|
||||
return count;
|
||||
}
|
||||
|
||||
QString formatPrice(const double value) {
|
||||
@ -141,16 +146,7 @@ void GetLastDaysHistoryScript::doStart() {
|
||||
if (xmlScreenParser.isHomeScreen()) {
|
||||
// парсим все транзакции
|
||||
if (goToAllProducts(device.id, device.screenWidth, device.screenHeight)) {
|
||||
QList<QPair<AccountInfo, Node> > accounts = xmlScreenParser.parseAccountsInfo();
|
||||
for (auto &[account, node]: accounts) {
|
||||
// FIXME будем считать что числа последние везде уникальные
|
||||
if (m_account.lastNumbers == account.lastNumbers) {
|
||||
qDebug() << "Tap by card";
|
||||
AdbUtils::makeTap(device.id, node.x(), node.y());
|
||||
QThread::msleep(1000);
|
||||
break;
|
||||
}
|
||||
}
|
||||
findAndTapOnAccount(device.id, m_account.lastNumbers);
|
||||
|
||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter));
|
||||
Node filterBtn = xmlScreenParser.findButtonNode("РСХБ Онлайн", false);
|
||||
@ -185,52 +181,55 @@ void GetLastDaysHistoryScript::doStart() {
|
||||
|
||||
qDebug() << "--- parsedTransactions: " << parsedTransactions.length();
|
||||
// localTransactions
|
||||
QList<TransactionInfo> updatedTransactions;
|
||||
for (TransactionInfo &transaction: parsedTransactions) {
|
||||
// если shortDescription + сумма + день и Complete совпадает и одна
|
||||
bool single = isSingle(transaction, parsedTransactions);
|
||||
int cSimilar = countSimilar(transaction, parsedTransactions);
|
||||
QList<TransactionInfo> txs = findSavedTransaction(localTransactions, transaction);
|
||||
|
||||
if (single && txs.length() < 2) {
|
||||
if (cSimilar == 1 && txs.length() < 2) {
|
||||
if (txs.length() == 1) {
|
||||
// смотрим, надо ли обновление
|
||||
if (txs[0].status != TransactionStatus::Complete || txs[0].shortDescription.isEmpty()) {
|
||||
txs[0].shortDescription = transaction.shortDescription;
|
||||
openAndSaveDitailInfo(txs[0], device.screenWidth, device.screenHeight);
|
||||
updatedTransactions.append(txs[0]);
|
||||
}
|
||||
} else {
|
||||
// создаем новую
|
||||
openAndSaveDitailInfo(transaction, device.screenWidth, device.screenHeight);
|
||||
}
|
||||
} else {
|
||||
// в списке за день нашли более чем 1 одинаковых транзакций
|
||||
// FIXME - что то делать если две одинаковые
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (txs.length() == 1) {
|
||||
qDebug() << "--- one transaction with same amount";
|
||||
qDebug().noquote().nospace() << convertTransactionToString(transaction);
|
||||
|
||||
if (transaction.status == TransactionStatus::Complete && !transaction.shortDescription.isEmpty()) {
|
||||
continue;
|
||||
if (cSimilar == txs.length()) {
|
||||
// одинаковые транзакции (2 - 2)
|
||||
for (TransactionInfo &tx: txs) {
|
||||
if (!updatedTransactions.contains(tx)) {
|
||||
openAndSaveDitailInfo(tx, device.screenWidth, device.screenHeight);
|
||||
updatedTransactions.append(tx);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (cSimilar < txs.length()) {
|
||||
// Дубликаты транзакций или название изменилось (1 - 2)
|
||||
qDebug() << "--- Дубликаты транзакций или название изменилось (1 - 2)!!!!!!!!!!!!";
|
||||
// FIXME alert!!!
|
||||
} else {
|
||||
// нужно создать новую транзакцию, которой не было (2 - 1)
|
||||
bool updated = false;
|
||||
for (TransactionInfo &tx: txs) {
|
||||
if (!updatedTransactions.contains(tx)) {
|
||||
openAndSaveDitailInfo(tx, device.screenWidth, device.screenHeight);
|
||||
updatedTransactions.append(tx);
|
||||
updated = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!updated) {
|
||||
// создаем новую, так как у нас появилась одинаковая транзакция
|
||||
openAndSaveDitailInfo(transaction, device.screenWidth, device.screenHeight);
|
||||
}
|
||||
}
|
||||
// посмотреть подробности и обновить статус и описание
|
||||
} else if (txs.length() > 1) {
|
||||
// FIXME - что то делать если две одинаковые
|
||||
// Alert !!!
|
||||
qDebug() << "--- two transactions with same amount";
|
||||
} else {
|
||||
// Создаем новую, так как не найдено в БД
|
||||
qDebug() << "--- new transaction";
|
||||
qDebug().noquote().nospace() << convertTransactionToString(transaction);
|
||||
|
||||
// посмотреть подробности и создать
|
||||
}
|
||||
// qDebug() << transaction.amount;
|
||||
// qDebug() << transaction.shortDescription;
|
||||
// qDebug().noquote().nospace() << convertTransactionToString(transaction);
|
||||
// TODO вот мы дошли до списка транзакций
|
||||
|
||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter));
|
||||
}
|
||||
|
||||
@ -40,7 +40,9 @@ void PayByPhoneScript::makePayment(
|
||||
AdbUtils::makeTap(deviceId, payBtn.x(), payBtn.y());
|
||||
QThread::msleep(1000);
|
||||
} else {
|
||||
qWarning() << "--- payBtn not found";
|
||||
m_error = "Кнопка 'Оплатить' не нашлась";
|
||||
qDebug() << m_error;
|
||||
return;
|
||||
}
|
||||
|
||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
|
||||
@ -52,10 +54,14 @@ void PayByPhoneScript::makePayment(
|
||||
AdbUtils::makeTap(deviceId, payByPhoneBtn.x(), payByPhoneBtn.y());
|
||||
QThread::msleep(1000);
|
||||
} else {
|
||||
qWarning() << "--- payByPhoneBtn not found";
|
||||
m_error = "Не смогли найти пункт 'По номеру телефона В РСХБ и через'";
|
||||
qDebug() << m_error;
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
qWarning() << "--- payTitle not found";
|
||||
m_error = "Не смогли перейти на экран 'Платежи и переводы'";
|
||||
qDebug() << m_error;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@ -69,7 +75,9 @@ void PayByPhoneScript::makePayment(
|
||||
AdbUtils::inputText(deviceId, m_phone);
|
||||
QThread::msleep(1000);
|
||||
} else {
|
||||
qWarning() << "--- payByPhoneTitle not found (no continueBtn)";
|
||||
m_error = "Не смогли найти пункт 'Перевод по телефону'";
|
||||
qDebug() << m_error;
|
||||
return;
|
||||
}
|
||||
|
||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
|
||||
@ -80,7 +88,9 @@ void PayByPhoneScript::makePayment(
|
||||
AdbUtils::makeTap(deviceId, payOtherBankBtn.x(), payOtherBankBtn.y());
|
||||
QThread::msleep(1000);
|
||||
} else {
|
||||
qWarning() << "--- payOtherBankBtn not found";
|
||||
m_error = "Не смогли нажать на первичный выбор банка";
|
||||
qDebug() << m_error;
|
||||
return;
|
||||
}
|
||||
|
||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
|
||||
@ -96,7 +106,7 @@ void PayByPhoneScript::makePayment(
|
||||
QThread::msleep(1000);
|
||||
break;
|
||||
} else {
|
||||
qWarning() << "--- allBanksTitle not found, i: " << i;
|
||||
qDebug() << "--- allBanksTitle not found, i: " << i;
|
||||
}
|
||||
QThread::msleep(1000);
|
||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
|
||||
@ -110,7 +120,7 @@ void PayByPhoneScript::makePayment(
|
||||
QThread::msleep(1000);
|
||||
break;
|
||||
} else {
|
||||
qWarning() << "--- bankNameListItem not found, i: " << i;
|
||||
qDebug() << "--- bankNameListItem not found, i: " << i;
|
||||
}
|
||||
QThread::msleep(1000);
|
||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
|
||||
@ -136,16 +146,23 @@ void PayByPhoneScript::makePayment(
|
||||
AdbUtils::makeTap(deviceId, continuePayBtn.x(), continuePayBtn.y());
|
||||
QThread::msleep(1000);
|
||||
} else {
|
||||
qWarning() << "--- readyBtn not found";
|
||||
m_error = "Не смогли нажать 'Готово'";
|
||||
qDebug() << m_error;
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
qWarning() << "--- sumBtn not found";
|
||||
m_error = "Не смогли нажать 'Продолжить'";
|
||||
qDebug() << m_error;
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
qWarning() << "--- payByPhoneScreenTitle not found";
|
||||
m_error = "Не смогли найти 'Перевод по телефону'";
|
||||
qDebug() << m_error;
|
||||
return;
|
||||
}
|
||||
|
||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
|
||||
bool inputedPinCode = false;
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
// TODO кнопка содержит "Перевести 10 ₽" если будет от 1000 то скорее всвего будет "Перевести 1 000 ₽",
|
||||
// TODO не ясно как форматирование будет, поэтому пока на начало зашьем
|
||||
@ -158,6 +175,7 @@ void PayByPhoneScript::makePayment(
|
||||
if (const QList<Node> pincode = xmlScreenParser.tryToFindPinCode(pinCode, "Введите код доступа");
|
||||
pincode.size() == 4) {
|
||||
inputPinCode(deviceId, pincode);
|
||||
inputedPinCode = true;
|
||||
// После ввода пин-кода, ждем 3с
|
||||
QThread::msleep(3000);
|
||||
}
|
||||
@ -169,9 +187,14 @@ void PayByPhoneScript::makePayment(
|
||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
|
||||
}
|
||||
|
||||
if (!inputedPinCode) {
|
||||
m_error = "Не смогли ввести пин-код!'";
|
||||
qDebug() << m_error;
|
||||
return;
|
||||
}
|
||||
|
||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
|
||||
|
||||
bool isPaymentCompleted = false;
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
Node moreDetailBtn = xmlScreenParser.findButtonNode("Детали операции", false);
|
||||
if (!moreDetailBtn.isEmpty()) {
|
||||
@ -194,7 +217,6 @@ void PayByPhoneScript::makePayment(
|
||||
for (int k = 0; k < 10; ++k) {
|
||||
Node paymentCompleted = xmlScreenParser.findTextNode("Исполнен", 0, 0, width, height / 2);
|
||||
if (!paymentCompleted.isEmpty()) {
|
||||
isPaymentCompleted = true;
|
||||
if (!TransactionDAO::updateTransactionStatus(transaction.id, TransactionStatus::Complete)) {
|
||||
qDebug() << "Not updated: " << transaction.id;
|
||||
}
|
||||
@ -215,9 +237,7 @@ void PayByPhoneScript::makePayment(
|
||||
|
||||
Node homeBtn = xmlScreenParser.findButtonNode("Вернуться на главную", false);
|
||||
AdbUtils::makeTap(deviceId, homeBtn.x(), homeBtn.y());
|
||||
if (!isPaymentCompleted) {
|
||||
qDebug() << "--- payment not completed";
|
||||
}
|
||||
QThread::msleep(1000);
|
||||
}
|
||||
|
||||
void PayByPhoneScript::doStart() {
|
||||
@ -253,9 +273,13 @@ void PayByPhoneScript::doStart() {
|
||||
qDebug() << "======== 3. Make payment";
|
||||
makePayment(device.id, app.pinCode, device.screenWidth, device.screenHeight);
|
||||
} else {
|
||||
qDebug() << "Не смогли открыть 'Все продукты'";
|
||||
m_error = "Не смогли открыть 'Все продукты'";
|
||||
qDebug() << m_error;
|
||||
}
|
||||
} else {
|
||||
qDebug() << "Не смогли дойти до домашней страницы....";
|
||||
m_error = "Не смогли дойти до домашней страницы....";
|
||||
qDebug() << m_error;
|
||||
}
|
||||
|
||||
emit finishedWithResult(m_error);
|
||||
}
|
||||
|
||||
@ -23,6 +23,7 @@ private:
|
||||
const QString m_phone;
|
||||
const QString m_bankName;
|
||||
const double m_amount;
|
||||
QString m_error;
|
||||
|
||||
void makePayment(
|
||||
const QString &deviceId,
|
||||
|
||||
47
main.cpp
47
main.cpp
@ -56,24 +56,53 @@ void setupScriptAutoPaymentAndThread(QCoreApplication &app) {
|
||||
const QString phoneNumber = "79641815146";
|
||||
const QString bankName = "Альфа-Банк";
|
||||
// const QString bankName = "Сбербанк";
|
||||
const double ammount = 310;
|
||||
const double amount = 310;
|
||||
|
||||
AccountInfo account = AccountDAO::findAppAccount(appName, cardNumber);
|
||||
if (account.id != -1) {
|
||||
auto *thread = new QThread;
|
||||
auto *scriptWorker = new GetLastDaysHistoryScript(account);
|
||||
// auto *scriptWorker = new PayByPhoneScript(account, phoneNumber, bankName, ammount);
|
||||
// Функция для подключения потоков к завершению приложения
|
||||
auto connectStopOnQuit = [&](QObject *worker, QThread *thread) {
|
||||
QObject::connect(&app, &QCoreApplication::aboutToQuit, worker, &QObject::deleteLater);
|
||||
QObject::connect(&app, &QCoreApplication::aboutToQuit, thread, &QThread::quit);
|
||||
QObject::connect(&app, &QCoreApplication::aboutToQuit, thread, &QThread::deleteLater);
|
||||
};
|
||||
|
||||
// Первый поток
|
||||
auto *thread = new QThread;
|
||||
auto *scriptWorker = new PayByPhoneScript(account, phoneNumber, bankName, amount);
|
||||
scriptWorker->moveToThread(thread);
|
||||
QObject::connect(thread, &QThread::started, scriptWorker, &GetLastDaysHistoryScript::start);
|
||||
QObject::connect(scriptWorker, &GetLastDaysHistoryScript::finished, thread, &QThread::quit);
|
||||
QObject::connect(scriptWorker, &GetLastDaysHistoryScript::finished, scriptWorker, &QObject::deleteLater);
|
||||
|
||||
// Запуск первого потока
|
||||
QObject::connect(thread, &QThread::started, scriptWorker, &PayByPhoneScript::start);
|
||||
QObject::connect(scriptWorker, &PayByPhoneScript::finished, thread, &QThread::quit);
|
||||
QObject::connect(scriptWorker, &PayByPhoneScript::finished, scriptWorker, &QObject::deleteLater);
|
||||
QObject::connect(thread, &QThread::finished, thread, &QThread::deleteLater);
|
||||
|
||||
QObject::connect(&app, &QCoreApplication::aboutToQuit, [=]() {
|
||||
scriptWorker->stop();
|
||||
// Обработка результата первого потока
|
||||
QObject::connect(scriptWorker, &PayByPhoneScript::finishedWithResult, &app, [&](const QString &result) {
|
||||
qDebug() << "Получен результат: [" << result << "]";
|
||||
|
||||
// Создаем второй поток после завершения первого
|
||||
auto *thread2 = new QThread;
|
||||
auto *scriptWorker2 = new GetLastDaysHistoryScript(account);
|
||||
scriptWorker2->moveToThread(thread2);
|
||||
|
||||
// Запуск второго потока
|
||||
QObject::connect(thread2, &QThread::started, scriptWorker2, &GetLastDaysHistoryScript::start);
|
||||
QObject::connect(scriptWorker2, &GetLastDaysHistoryScript::finished, thread2, &QThread::quit);
|
||||
QObject::connect(scriptWorker2, &GetLastDaysHistoryScript::finished, scriptWorker2, &QObject::deleteLater);
|
||||
QObject::connect(thread2, &QThread::finished, thread2, &QThread::deleteLater);
|
||||
|
||||
// Остановка второго потока при завершении приложения
|
||||
connectStopOnQuit(scriptWorker2, thread2);
|
||||
|
||||
thread2->start();
|
||||
});
|
||||
|
||||
// Остановка первого потока при завершении приложения
|
||||
connectStopOnQuit(scriptWorker, thread);
|
||||
|
||||
// Запуск первого потока
|
||||
thread->start();
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user