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.
274 lines
12 KiB
C++
274 lines
12 KiB
C++
#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
|
||
*/
|