1
0
forked from BRT/arc
arc/android/rshb/GetLastDaysHistoryScript.cpp
trnsmkot 688a71c0b2 Update transaction handling with a new history parsing script.
Replaced `PayByPhoneScript` with `GetLastDaysHistoryScript` in `main.cpp`. Introduced enhanced date/time utilities and improved database timestamp handling with `DateUtils`. Refactored `TransactionDAO` methods to separate parsing logic and added support for retrieving recent transactions within specified hours. Added the `GetLastDaysHistoryScript` class to parse and save recent transaction history.
2025-05-09 22:44:29 +07:00

274 lines
12 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "GetLastDaysHistoryScript.h"
#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"
GetLastDaysHistoryScript::GetLastDaysHistoryScript(
AccountInfo account,
QObject *parent
) : CommonScript(parent),
m_account(std::move(account)) {
}
GetLastDaysHistoryScript::~GetLastDaysHistoryScript() = default;
QList<TransactionInfo> findSavedTransaction(
const QList<TransactionInfo> &transactions,
const TransactionInfo &parsed
) {
QList<TransactionInfo> txs;
const QDateTime dateTime = QDateTime::fromString(parsed.bankTime, "dd.MM.yyyy"); // Московское время
for (const TransactionInfo &info: transactions) {
QDateTime timestamp = info.timestamp;
// если тот же день
if (dateTime.date() == timestamp.date() && parsed.amount == info.amount) {
// Перевод Надежда Юрьевна К** в Альфа-Банк через СБП, по номеру телефона +79641815...
if (parsed.shortDescription.contains(info.name)) {
txs.append(info);
}
}
}
return txs;
}
bool isSingle(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++;
}
}
return count == 1;
}
QString formatPrice(const double value) {
QString sign = value < 0 ? "Минус" : "Плюс";
const auto intValue = static_cast<qint64>(std::abs(value)); // округление до целого
QString number = QString::number(intValue);
QString formatted;
int count = 0;
for (int i = number.length() - 1; i >= 0; --i) {
formatted.prepend(number[i]);
++count;
if (count % 3 == 0 && i != 0) {
formatted.prepend(' ');
}
}
return QString("%1 %2").arg(sign, formatted);
}
bool GetLastDaysHistoryScript::openAndSaveDitailInfo(TransactionInfo &transaction, int width, int height) {
QString text = QString("%1 %2").arg(transaction.shortDescription, formatPrice(transaction.amount));
Node trButton = swipeToButton(m_account.deviceId, text, m_counter, width, height);
if (!trButton.isEmpty()) {
AdbUtils::makeTap(m_account.deviceId, trButton.x(), trButton.y());
QThread::msleep(500);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter));
Node moreDetailBtn = xmlScreenParser.findButtonNode("Детали операции", false);
if (!moreDetailBtn.isEmpty()) {
AdbUtils::makeTap(m_account.deviceId, moreDetailBtn.x(), moreDetailBtn.y());
QThread::msleep(200);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter));
TransactionInfo info = xmlScreenParser.parseTransactionInfoHistory(width, height);
if (transaction.id == -1) {
info.accountId = m_account.id;
info.shortDescription = transaction.shortDescription;
info.amount = transaction.amount;
info.type = info.phone.isEmpty() ? TransactionType::Card : TransactionType::Phone;
info.updateTime = DateUtils::getUtcNow();
if (info.status == TransactionStatus::Complete) {
info.completeTime = DateUtils::getUtcNow();
}
if (TransactionDAO::insertTransaction(info) == -1) {
qWarning() << "--- insertTransaction failed";
}
} else {
transaction.status = info.status;
transaction.description = info.description;
if (transaction.trExternalId.isEmpty()) {
transaction.trExternalId = info.trExternalId;
}
transaction.updateTime = DateUtils::getUtcNow();
if (transaction.status == TransactionStatus::Complete && !transaction.completeTime.isValid()) {
transaction.completeTime = DateUtils::getUtcNow();
}
if (!TransactionDAO::updateTransaction(transaction)) {
qWarning() << "--- updateTransaction failed";
}
}
}
AdbUtils::goBack(m_account.deviceId);
QThread::msleep(200);
} else {
qWarning() << "--- trButton not found..........";
}
return false;
}
void GetLastDaysHistoryScript::doStart() {
// берем все транзакции из БД
QList<TransactionInfo> localTransactions = TransactionDAO::getTransactionsWithinHours(m_account.id, 48);
// for (const TransactionInfo& transaction: transactions) {
// qDebug().noquote().nospace() << convertTransactionToString(transaction);
// }
const DeviceInfo device = DeviceDAO::getDeviceById(m_account.deviceId);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter));
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;
}
}
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter));
Node filterBtn = xmlScreenParser.findButtonNode("РСХБ Онлайн", false);
if (!filterBtn.isEmpty()) {
AdbUtils::makeTap(m_account.deviceId, filterBtn.x(), filterBtn.y());
QThread::msleep(1000);
} else {
qWarning() << "--- filterBtn not found";
}
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter));
Node allTransactionFilerBtn = xmlScreenParser.findButtonNode("Все операции", false);
if (!allTransactionFilerBtn.isEmpty()) {
AdbUtils::makeTap(m_account.deviceId, allTransactionFilerBtn.x(), allTransactionFilerBtn.y());
QThread::msleep(1000);
} else {
qWarning() << "--- allTransactionFilerBtn not found";
}
QList<TransactionInfo> parsedTransactions;
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter));
for (int i = 0; i < 5; ++i) {
parsedTransactions = xmlScreenParser.parseTodayAndYesterdayHistory();
if (!parsedTransactions.empty()) {
break;
}
QThread::msleep(1000);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter));
}
qDebug() << "--- parsedTransactions: " << parsedTransactions.length();
// localTransactions
for (TransactionInfo &transaction: parsedTransactions) {
// если shortDescription + сумма + день и Complete совпадает и одна
bool single = isSingle(transaction, parsedTransactions);
QList<TransactionInfo> txs = findSavedTransaction(localTransactions, transaction);
if (single && 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);
}
} 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;
}
// посмотреть подробности и обновить статус и описание
} 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));
}
// сначала обработаем
}
} else {
qDebug() << "--- home screen not found";
}
}
/**
amount: -250
shortDescription: Перевод Надежда Юрьевна К** в Сбербанк через СБП, по номеру телефона +7964181514...
bankTime: 08.05.2025
amount: -305
shortDescription: Перевод Надежда Юрьевна К** в Альфа-Банк через СБП, по номеру телефона +79641815...
bankTime: 08.05.2025
amount: -250
shortDescription: Перевод Надежда Юрьевна К** в Альфа-Банк через СБП, по номеру телефона +79641815...
bankTime: 07.05.2025
amount: -250
shortDescription: Перевод Надежда Юрьевна К** в Сбербанк через СБП, по номеру телефона +7964181514...
bankTime: 07.05.2025
amount: -250
shortDescription: Перевод Надежда Юрьевна К** в Альфа-Банк через СБП, по номеру телефона +79641815...
bankTime: 07.05.2025
amount: 2100
shortDescription: Перевод через СБП от Надежда Юрьевна К (+7(964)-181-51-46) из Альфа-Банк на 4081...
bankTime: 07.05.2025
amount: 250
shortDescription: Перевод через СБП от Надежда Юрьевна К (+7(964)-181-51-46) из Сбербанк на 408178...
bankTime: 07.05.2025
*/