Add configurable date search window for transaction history parsing.
This commit is contained in:
parent
e5a11b0a57
commit
6d60cecef4
13
android/BankConfigUtils.cpp
Normal file
13
android/BankConfigUtils.cpp
Normal 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
15
android/BankConfigUtils.h
Normal 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
|
||||||
@ -15,6 +15,7 @@
|
|||||||
#include "dao/BankProfileDAO.h"
|
#include "dao/BankProfileDAO.h"
|
||||||
#include "dao/DeviceDAO.h"
|
#include "dao/DeviceDAO.h"
|
||||||
#include "AppLogger.h"
|
#include "AppLogger.h"
|
||||||
|
#include "BankConfigUtils.h"
|
||||||
|
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
|
|
||||||
@ -502,6 +503,10 @@ GetLastTransactionsScript::SearchResult GetLastTransactionsScript::searchOne(
|
|||||||
const QTimeZone tjTz("Asia/Dushanbe");
|
const QTimeZone tjTz("Asia/Dushanbe");
|
||||||
const int maxScrolls = 10;
|
const int maxScrolls = 10;
|
||||||
|
|
||||||
|
// Окно поиска по датам: сегодня + (N-1) предыдущих дней. Настраивается в
|
||||||
|
// config.ini → [<bankCode>]/transaction_search_window_days (дефолт 2 = сегодня+вчера).
|
||||||
|
const int searchWindowDays = BankConfigUtils::transactionSearchWindowDays(m_appCode);
|
||||||
|
|
||||||
auto interrupted = []() {
|
auto interrupted = []() {
|
||||||
return QThread::currentThread()->isInterruptionRequested();
|
return QThread::currentThread()->isInterruptionRequested();
|
||||||
};
|
};
|
||||||
@ -984,29 +989,28 @@ GetLastTransactionsScript::SearchResult GetLastTransactionsScript::searchOne(
|
|||||||
return SearchResult::Found;
|
return SearchResult::Found;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Окно поиска — только "сегодня + вчера". Список Выписки идёт сверху-вниз
|
// Окно поиска — "сегодня + (searchWindowDays-1) предыдущих дней". Список
|
||||||
// от новых к старым; группы-даты на текущем экране собраны в groupDates.
|
// Выписки идёт сверху-вниз от новых к старым; группы-даты на текущем экране
|
||||||
// Как только самая свежая видимая дата уже старше вчерашнего дня — значит
|
// собраны в groupDates. Как только самая свежая видимая дата уже старше
|
||||||
// окно today+yesterday полностью проскроллено, дальше только старая история.
|
// нижней границы окна — значит окно полностью проскроллено, дальше только
|
||||||
// Прекращаем скролл (целевой транзакции в окне нет), вместо того чтобы
|
// старая история. Прекращаем скролл (целевой транзакции в окне нет), вместо
|
||||||
// листать до упора и упереться в watchdog-таймаут.
|
// того чтобы листать до упора и упереться в watchdog-таймаут.
|
||||||
// NOTE: окно "сегодня+вчера" временно отключено — скроллим без ограничения по дате.
|
{
|
||||||
// {
|
const QDate cutoff = todayLocal.addDays(-(searchWindowDays - 1)); // нижняя граница окна
|
||||||
// const QDate cutoff = todayLocal.addDays(-1); // вчера
|
QDate newestVisible;
|
||||||
// QDate newestVisible;
|
for (const QString &gd : groupDates) {
|
||||||
// for (const QString &gd : groupDates) {
|
const QDate d = QDate::fromString(gd, "dd.MM.yyyy");
|
||||||
// const QDate d = QDate::fromString(gd, "dd.MM.yyyy");
|
if (d.isValid() && (newestVisible.isNull() || d > newestVisible))
|
||||||
// if (d.isValid() && (newestVisible.isNull() || d > newestVisible))
|
newestVisible = d;
|
||||||
// newestVisible = d;
|
}
|
||||||
// }
|
if (newestVisible.isValid() && newestVisible < cutoff) {
|
||||||
// if (newestVisible.isValid() && newestVisible < cutoff) {
|
qDebug() << "[Dushanbe::GetLastTransactions] Past today+yesterday window"
|
||||||
// qDebug() << "[Dushanbe::GetLastTransactions] Past today+yesterday window"
|
" (newest visible=" << newestVisible.toString("dd.MM.yyyy")
|
||||||
// " (newest visible=" << newestVisible.toString("dd.MM.yyyy")
|
<< "< cutoff=" << cutoff.toString("dd.MM.yyyy")
|
||||||
// << "< cutoff=" << cutoff.toString("dd.MM.yyyy")
|
<< ") — stopping scroll";
|
||||||
// << ") — stopping scroll";
|
return SearchResult::PastWindow;
|
||||||
// return SearchResult::PastWindow;
|
}
|
||||||
// }
|
}
|
||||||
// }
|
|
||||||
|
|
||||||
// Скроллим вниз — свайп внутри области транзакций
|
// Скроллим вниз — свайп внутри области транзакций
|
||||||
if (scroll < maxScrolls) {
|
if (scroll < maxScrolls) {
|
||||||
|
|||||||
@ -16,6 +16,7 @@
|
|||||||
#include "db/MaterialInfo.h"
|
#include "db/MaterialInfo.h"
|
||||||
#include "db/TransactionInfo.h"
|
#include "db/TransactionInfo.h"
|
||||||
#include "time/DateUtils.h"
|
#include "time/DateUtils.h"
|
||||||
|
#include "BankConfigUtils.h"
|
||||||
|
|
||||||
namespace Ozon {
|
namespace Ozon {
|
||||||
|
|
||||||
@ -1218,30 +1219,45 @@ QList<TransactionInfo> ScreenXmlParser::parseTodayAndYesterdayReportHistory() {
|
|||||||
return transactions;
|
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() {
|
QList<TransactionInfo> ScreenXmlParser::parseTodayAndYesterdayHistory() {
|
||||||
QDate today = DateUtils::getMoscowNow().date();
|
// Окно поиска: сегодня + (N-1) предыдущих дней. Настраивается в
|
||||||
QDate yesterday = today.addDays(-1);
|
// config.ini → [ozon]/transaction_search_window_days (дефолт 2 = сегодня+вчера).
|
||||||
QDate beforeYesterday = today.addDays(-2);
|
const int windowDays = BankConfigUtils::transactionSearchWindowDays("ozon");
|
||||||
|
const QDate today = DateUtils::getMoscowNow().date();
|
||||||
|
|
||||||
|
// Заголовки дней внутри окна [сегодня .. сегодня-(windowDays-1)] → дата дня.
|
||||||
QString todayTitle = QString("сегодня, %1").arg(getDayOfWeekAsString(today.dayOfWeek()));
|
struct DayTitle { QString title; QDate date; };
|
||||||
QString yesterdayTitle = QString("вчера, %1").arg(getDayOfWeekAsString(yesterday.dayOfWeek()));
|
QList<DayTitle> windowTitles;
|
||||||
QString beforeYesterdayTitle = QString("%1 %2, %3").arg(
|
for (int i = 0; i < windowDays; ++i) {
|
||||||
QString::number(beforeYesterday.day()),
|
const QDate d = today.addDays(-i);
|
||||||
getMonthAsString(beforeYesterday.month()),
|
windowTitles.append({ozonDayTitle(d, i), d});
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
// Заголовок первого дня ЗА окном — сигнал "дальше старая история, стоп".
|
||||||
|
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;
|
QList<TransactionInfo> transactions;
|
||||||
if (!parentNode.isNull()) {
|
if (!parentNode.isNull()) {
|
||||||
@ -1250,17 +1266,19 @@ QList<TransactionInfo> ScreenXmlParser::parseTodayAndYesterdayHistory() {
|
|||||||
QString transactionShortText = transactionNode.toElement().attribute("text");
|
QString transactionShortText = transactionNode.toElement().attribute("text");
|
||||||
|
|
||||||
const QString titleLowerCase = transactionShortText.toLower();
|
const QString titleLowerCase = transactionShortText.toLower();
|
||||||
if (titleLowerCase.startsWith(beforeYesterdayTitle)) {
|
|
||||||
// только сегодня и вчера парсим, позавчера не трогаем
|
// День за пределами окна — дальше только старая история, прекращаем.
|
||||||
|
if (titleLowerCase.startsWith(boundaryTitle)) {
|
||||||
break;
|
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("ЕСПП")) {
|
if (transactionShortText.contains("ЕСПП")) {
|
||||||
|
|||||||
@ -47,6 +47,8 @@ country=russia
|
|||||||
name=Ozon
|
name=Ozon
|
||||||
phone_code=7
|
phone_code=7
|
||||||
app_version=19.17.0
|
app_version=19.17.0
|
||||||
|
# Окно поиска транзакций в днях: сегодня + (N-1) предыдущих дней. 2 = сегодня+вчера.
|
||||||
|
transaction_search_window_days=2
|
||||||
|
|
||||||
[dushanbe_city_bank]
|
[dushanbe_city_bank]
|
||||||
android_package_name=tj.dc.next1
|
android_package_name=tj.dc.next1
|
||||||
@ -55,3 +57,5 @@ country=tajikistan
|
|||||||
name=Dushanbe City
|
name=Dushanbe City
|
||||||
phone_code=992
|
phone_code=992
|
||||||
app_version=3.2.34
|
app_version=3.2.34
|
||||||
|
# Окно поиска транзакций в днях: сегодня + (N-1) предыдущих дней. 2 = сегодня+вчера.
|
||||||
|
transaction_search_window_days=2
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user