style(app): остальные экраны под новый визуальный язык и форматирование
Доходы, ребалансировка, налоги, импорт, цели, здоровье данных, правила, транзакции, категории, cashflow, pending: новые виджеты и токены темы, dart format. Тесты подстроены под новые модели.
This commit is contained in:
@@ -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?);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user