1
0
forked from BRT/arc

Add configurable date search window for transaction history parsing.

This commit is contained in:
slava 2026-06-01 22:27:34 +05:00
parent e5a11b0a57
commit 6d60cecef4
5 changed files with 106 additions and 52 deletions

View File

@ -0,0 +1,13 @@
#include "BankConfigUtils.h"
#include <QSettings>
namespace BankConfigUtils {
int transactionSearchWindowDays(const QString &bankCode) {
const QSettings settings("config.ini", QSettings::IniFormat);
return qMax(1, settings.value(
bankCode + "/transaction_search_window_days", 2).toInt());
}
} // namespace BankConfigUtils

15
android/BankConfigUtils.h Normal file
View File

@ -0,0 +1,15 @@
#pragma once
#include <QString>
// Пер-банковые настройки, читаемые из config.ini.
// bankCode совпадает с именем секции в config.ini и со значением appCode
// ("ozon", "black", "dushanbe_city_bank").
namespace BankConfigUtils {
// Окно поиска транзакций в днях: сегодня + (N-1) предыдущих дней.
// Источник: config.ini → [<bankCode>]/transaction_search_window_days.
// Дефолт 2 (сегодня + вчера). Гарантированный минимум — 1 (только сегодня).
int transactionSearchWindowDays(const QString &bankCode);
} // namespace BankConfigUtils

View File

@ -15,6 +15,7 @@
#include "dao/BankProfileDAO.h"
#include "dao/DeviceDAO.h"
#include "AppLogger.h"
#include "BankConfigUtils.h"
#include <QCoreApplication>
@ -502,6 +503,10 @@ GetLastTransactionsScript::SearchResult GetLastTransactionsScript::searchOne(
const QTimeZone tjTz("Asia/Dushanbe");
const int maxScrolls = 10;
// Окно поиска по датам: сегодня + (N-1) предыдущих дней. Настраивается в
// config.ini → [<bankCode>]/transaction_search_window_days (дефолт 2 = сегодня+вчера).
const int searchWindowDays = BankConfigUtils::transactionSearchWindowDays(m_appCode);
auto interrupted = []() {
return QThread::currentThread()->isInterruptionRequested();
};
@ -984,29 +989,28 @@ GetLastTransactionsScript::SearchResult GetLastTransactionsScript::searchOne(
return SearchResult::Found;
}
// Окно поиска — только "сегодня + вчера". Список Выписки идёт сверху-вниз
// от новых к старым; группы-даты на текущем экране собраны в groupDates.
// Как только самая свежая видимая дата уже старше вчерашнего дня — значит
// окно today+yesterday полностью проскроллено, дальше только старая история.
// Прекращаем скролл (целевой транзакции в окне нет), вместо того чтобы
// листать до упора и упереться в watchdog-таймаут.
// NOTE: окно "сегодня+вчера" временно отключено — скроллим без ограничения по дате.
// {
// const QDate cutoff = todayLocal.addDays(-1); // вчера
// QDate newestVisible;
// for (const QString &gd : groupDates) {
// const QDate d = QDate::fromString(gd, "dd.MM.yyyy");
// if (d.isValid() && (newestVisible.isNull() || d > newestVisible))
// newestVisible = d;
// }
// if (newestVisible.isValid() && newestVisible < cutoff) {
// qDebug() << "[Dushanbe::GetLastTransactions] Past today+yesterday window"
// " (newest visible=" << newestVisible.toString("dd.MM.yyyy")
// << "< cutoff=" << cutoff.toString("dd.MM.yyyy")
// << ") — stopping scroll";
// return SearchResult::PastWindow;
// }
// }
// Окно поиска — "сегодня + (searchWindowDays-1) предыдущих дней". Список
// Выписки идёт сверху-вниз от новых к старым; группы-даты на текущем экране
// собраны в groupDates. Как только самая свежая видимая дата уже старше
// нижней границы окна — значит окно полностью проскроллено, дальше только
// старая история. Прекращаем скролл (целевой транзакции в окне нет), вместо
// того чтобы листать до упора и упереться в watchdog-таймаут.
{
const QDate cutoff = todayLocal.addDays(-(searchWindowDays - 1)); // нижняя граница окна
QDate newestVisible;
for (const QString &gd : groupDates) {
const QDate d = QDate::fromString(gd, "dd.MM.yyyy");
if (d.isValid() && (newestVisible.isNull() || d > newestVisible))
newestVisible = d;
}
if (newestVisible.isValid() && newestVisible < cutoff) {
qDebug() << "[Dushanbe::GetLastTransactions] Past today+yesterday window"
" (newest visible=" << newestVisible.toString("dd.MM.yyyy")
<< "< cutoff=" << cutoff.toString("dd.MM.yyyy")
<< ") — stopping scroll";
return SearchResult::PastWindow;
}
}
// Скроллим вниз — свайп внутри области транзакций
if (scroll < maxScrolls) {

View File

@ -16,6 +16,7 @@
#include "db/MaterialInfo.h"
#include "db/TransactionInfo.h"
#include "time/DateUtils.h"
#include "BankConfigUtils.h"
namespace Ozon {
@ -1218,30 +1219,45 @@ QList<TransactionInfo> ScreenXmlParser::parseTodayAndYesterdayReportHistory() {
return transactions;
}
// Строит заголовок дня в формате Ozon-Выписки для переданной даты.
// offset 0 → "сегодня, ...", 1 → "вчера, ...", иначе "<день> <месяц>, <дн.недели>".
static QString ozonDayTitle(const QDate &day, int offset) {
if (offset == 0)
return QString("сегодня, %1").arg(getDayOfWeekAsString(day.dayOfWeek()));
if (offset == 1)
return QString("вчера, %1").arg(getDayOfWeekAsString(day.dayOfWeek()));
return QString("%1 %2, %3").arg(
QString::number(day.day()),
getMonthAsString(day.month()),
getDayOfWeekAsString(day.dayOfWeek()));
}
QList<TransactionInfo> ScreenXmlParser::parseTodayAndYesterdayHistory() {
QDate today = DateUtils::getMoscowNow().date();
QDate yesterday = today.addDays(-1);
QDate beforeYesterday = today.addDays(-2);
// Окно поиска: сегодня + (N-1) предыдущих дней. Настраивается в
// config.ini → [ozon]/transaction_search_window_days (дефолт 2 = сегодня+вчера).
const int windowDays = BankConfigUtils::transactionSearchWindowDays("ozon");
const QDate today = DateUtils::getMoscowNow().date();
QString todayTitle = QString("сегодня, %1").arg(getDayOfWeekAsString(today.dayOfWeek()));
QString yesterdayTitle = QString("вчера, %1").arg(getDayOfWeekAsString(yesterday.dayOfWeek()));
QString beforeYesterdayTitle = QString("%1 %2, %3").arg(
QString::number(beforeYesterday.day()),
getMonthAsString(beforeYesterday.month()),
getDayOfWeekAsString(beforeYesterday.dayOfWeek())
);
QDomNode todayNode = findNode(m_xml, todayTitle);
QDomNode yesterdayNode = findNode(m_xml, yesterdayTitle);
QDomNode parentNode;
if (!yesterdayNode.isNull()) {
parentNode = yesterdayNode.parentNode();
} else if (!todayNode.isNull()) {
parentNode = todayNode.parentNode();
// Заголовки дней внутри окна [сегодня .. сегодня-(windowDays-1)] → дата дня.
struct DayTitle { QString title; QDate date; };
QList<DayTitle> windowTitles;
for (int i = 0; i < windowDays; ++i) {
const QDate d = today.addDays(-i);
windowTitles.append({ozonDayTitle(d, i), d});
}
// Заголовок первого дня ЗА окном — сигнал "дальше старая история, стоп".
const QDate boundaryDate = today.addDays(-windowDays);
const QString boundaryTitle = ozonDayTitle(boundaryDate, windowDays);
// Родительский контейнер списка: берём первый существующий заголовок окна.
QDomNode parentNode;
for (const DayTitle &dt : windowTitles) {
const QDomNode node = findNode(m_xml, dt.title);
if (!node.isNull()) {
parentNode = node.parentNode();
break;
}
}
QList<TransactionInfo> transactions;
if (!parentNode.isNull()) {
@ -1250,17 +1266,19 @@ QList<TransactionInfo> ScreenXmlParser::parseTodayAndYesterdayHistory() {
QString transactionShortText = transactionNode.toElement().attribute("text");
const QString titleLowerCase = transactionShortText.toLower();
if (titleLowerCase.startsWith(beforeYesterdayTitle)) {
// только сегодня и вчера парсим, позавчера не трогаем
// День за пределами окна — дальше только старая история, прекращаем.
if (titleLowerCase.startsWith(boundaryTitle)) {
break;
}
if (titleLowerCase.startsWith(todayTitle)) {
date = today;
transactionShortText = transactionShortText.mid(todayTitle.length() + 1);
// Заголовок дня внутри окна — обновляем текущую дату и срезаем префикс.
for (const DayTitle &dt : windowTitles) {
if (titleLowerCase.startsWith(dt.title)) {
date = dt.date;
transactionShortText = transactionShortText.mid(dt.title.length() + 1);
break;
}
if (titleLowerCase.startsWith(yesterdayTitle)) {
date = yesterday;
transactionShortText = transactionShortText.mid(yesterdayTitle.length() + 1);
}
if (transactionShortText.contains("ЕСПП")) {

View File

@ -47,6 +47,8 @@ country=russia
name=Ozon
phone_code=7
app_version=19.17.0
# Окно поиска транзакций в днях: сегодня + (N-1) предыдущих дней. 2 = сегодня+вчера.
transaction_search_window_days=2
[dushanbe_city_bank]
android_package_name=tj.dc.next1
@ -55,3 +57,5 @@ country=tajikistan
name=Dushanbe City
phone_code=992
app_version=3.2.34
# Окно поиска транзакций в днях: сегодня + (N-1) предыдущих дней. 2 = сегодня+вчера.
transaction_search_window_days=2