style(app): остальные экраны под новый визуальный язык и форматирование

Доходы, ребалансировка, налоги, импорт, цели, здоровье данных, правила, транзакции, категории, cashflow, pending: новые виджеты и токены темы, dart format. Тесты подстроены под новые модели.
This commit is contained in:
Dmitry
2026-09-19 22:14:27 +03:00
parent 62d36aa3e8
commit 322c60a359
55 changed files with 2158 additions and 1080 deletions
+43 -31
View File
@@ -41,20 +41,21 @@ class TaxRow {
final String? taxableBaseRub;
final String? estimatedTaxRub;
String get title => accountName ?? (accountId == null ? 'Итого' : 'Счёт #$accountId');
String get title =>
accountName ?? (accountId == null ? 'Итого' : 'Счёт #$accountId');
static TaxRow fromJson(Map<String, dynamic> json) => TaxRow(
accountId: asInt(json['account_id']),
accountName: asString(json['account_name']),
dividendsGrossRub: asString(json['dividends_gross_rub']),
couponsGrossRub: asString(json['coupons_gross_rub']),
taxWithheldRub: asString(json['tax_withheld_rub']),
realizedGainRub: asString(json['realized_gain_rub']),
realizedLossRub: asString(json['realized_loss_rub']),
ldvExemptRub: asString(json['ldv_exempt_rub']),
taxableBaseRub: asString(json['taxable_base_rub']),
estimatedTaxRub: asString(json['estimated_tax_rub']),
);
accountId: asInt(json['account_id']),
accountName: asString(json['account_name']),
dividendsGrossRub: asString(json['dividends_gross_rub']),
couponsGrossRub: asString(json['coupons_gross_rub']),
taxWithheldRub: asString(json['tax_withheld_rub']),
realizedGainRub: asString(json['realized_gain_rub']),
realizedLossRub: asString(json['realized_loss_rub']),
ldvExemptRub: asString(json['ldv_exempt_rub']),
taxableBaseRub: asString(json['taxable_base_rub']),
estimatedTaxRub: asString(json['estimated_tax_rub']),
);
}
class TaxSummary {
@@ -83,7 +84,9 @@ class TaxSummary {
final totals = asObject(json['totals']);
return TaxSummary(
year: asInt(json['year']) ?? DateTime.now().year,
estimated: json.containsKey('estimated') ? asBool(json['estimated']) : true,
estimated: json.containsKey('estimated')
? asBool(json['estimated'])
: true,
taxRate: asString(json['tax_rate']),
accounts: asObjects(json['accounts']).map(TaxRow.fromJson).toList(),
totals: totals == null ? null : TaxRow.fromJson(totals),
@@ -128,23 +131,24 @@ class TaxLot {
/// horizon at which a person can still decide to wait.
bool get nearLdv => !ldvEligible && daysToLdv != null && daysToLdv! <= 183;
String get title => ticker ?? (instrumentId == null ? '#$lotId' : '#$instrumentId');
String get title =>
ticker ?? (instrumentId == null ? '#$lotId' : '#$instrumentId');
static TaxLot fromJson(Map<String, dynamic> json) => TaxLot(
lotId: asInt(json['lot_id']) ?? 0,
instrumentId: asInt(json['instrument_id']),
ticker: asString(json['ticker']),
accountId: asInt(json['account_id']),
openDate: asDate(json['open_date']),
qtyRemaining: asString(json['qty_remaining']),
costRub: asString(json['cost_rub']),
marketValueRub: asString(json['market_value_rub']),
unrealizedGainRub: asString(json['unrealized_gain_rub']),
ldvEligible: asBool(json['ldv_eligible']),
ldvDate: asDate(json['ldv_date']),
daysToLdv: asInt(json['days_to_ldv']),
taxIfSoldNowRub: asString(json['tax_if_sold_now_rub']),
);
lotId: asInt(json['lot_id']) ?? 0,
instrumentId: asInt(json['instrument_id']),
ticker: asString(json['ticker']),
accountId: asInt(json['account_id']),
openDate: asDate(json['open_date']),
qtyRemaining: asString(json['qty_remaining']),
costRub: asString(json['cost_rub']),
marketValueRub: asString(json['market_value_rub']),
unrealizedGainRub: asString(json['unrealized_gain_rub']),
ldvEligible: asBool(json['ldv_eligible']),
ldvDate: asDate(json['ldv_date']),
daysToLdv: asInt(json['days_to_ldv']),
taxIfSoldNowRub: asString(json['tax_if_sold_now_rub']),
);
}
class TaxApi {
@@ -156,12 +160,18 @@ class TaxApi {
/// See `docs/ai/offline-cache.md`: this hand-written client returns `Cached<T>` directly
/// (there is no generated `Response<T>` for the screen to unwrap `r.cached` from).
Future<Cached<TaxSummary>> summary({required int year, int? accountId}) async {
Future<Cached<TaxSummary>> summary({
required int year,
int? accountId,
}) async {
final r = await _dio.get<Map<String, dynamic>>(
_base,
queryParameters: {'year': year, 'account_id': ?accountId},
);
return Cached(TaxSummary.fromJson(r.data ?? const {}), fetchedAt: r.extra['fetchedAt'] as DateTime?);
return Cached(
TaxSummary.fromJson(r.data ?? const {}),
fetchedAt: r.extra['fetchedAt'] as DateTime?,
);
}
Future<Cached<List<TaxLot>>> lots({required int year, int? accountId}) async {
@@ -169,7 +179,9 @@ class TaxApi {
'$_base/lots',
queryParameters: {'year': year, 'account_id': ?accountId},
);
final lots = asObjects((r.data ?? const {})['lots']).map(TaxLot.fromJson).toList();
final lots = asObjects((r.data ?? const {})['lots'])
.map(TaxLot.fromJson)
.toList();
return Cached(lots, fetchedAt: r.extra['fetchedAt'] as DateTime?);
}
}