#include "GetLastDaysHistoryScript.h" #include #include #include #include #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 findSavedTransaction( const QList &transactions, const TransactionInfo &parsed ) { QList 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 &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(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 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 > 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 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 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 */