273 lines
12 KiB
C++
273 lines
12 KiB
C++
#include "GetLastDaysHistoryScript.h"
|
||
|
||
#include <QRandomGenerator>
|
||
#include <QThread>
|
||
#include <utility>
|
||
|
||
#include "DatabaseManager.h"
|
||
#include "adb/AdbUtils.h"
|
||
#include "dao/AccountDAO.h"
|
||
#include "dao/DeviceDAO.h"
|
||
#include "dao/TransactionDAO.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;
|
||
QString shortDescription = parsed.shortDescription;
|
||
// если тот же день
|
||
if (dateTime.date() == timestamp.date() && parsed.amount == info.amount) {
|
||
// Перевод Надежда Юрьевна К** в Альфа-Банк через СБП, по номеру телефона +79641815...
|
||
if (shortDescription.contains("Перевод")) {
|
||
if (shortDescription.contains(info.name)) {
|
||
txs.append(info);
|
||
}
|
||
} else {
|
||
// Перевод по карте
|
||
if (shortDescription == info.shortDescription) {
|
||
txs.append(info);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
return txs;
|
||
}
|
||
|
||
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;
|
||
}
|
||
}
|
||
return count;
|
||
}
|
||
|
||
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)) {
|
||
findAndTapOnAccount(device.id, m_account.lastNumbers);
|
||
|
||
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
|
||
QList<TransactionInfo> updatedTransactions;
|
||
for (TransactionInfo &transaction: parsedTransactions) {
|
||
// если shortDescription + сумма + день и Complete совпадает и одна
|
||
int cSimilar = countSimilar(transaction, parsedTransactions);
|
||
QList<TransactionInfo> txs = findSavedTransaction(localTransactions, transaction);
|
||
|
||
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 {
|
||
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);
|
||
}
|
||
}
|
||
}
|
||
|
||
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
|
||
*/
|