mirror of
https://github.com/koloideal/Casha.git
synced 2026-06-10 10:25:28 +03:00
update
This commit is contained in:
@@ -13,7 +13,7 @@ class AppDatabase extends _$AppDatabase {
|
|||||||
AppDatabase() : super(_openConnection());
|
AppDatabase() : super(_openConnection());
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get schemaVersion => 3;
|
int get schemaVersion => 4;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
MigrationStrategy get migration => MigrationStrategy(
|
MigrationStrategy get migration => MigrationStrategy(
|
||||||
@@ -23,11 +23,10 @@ class AppDatabase extends _$AppDatabase {
|
|||||||
await customStatement(
|
await customStatement(
|
||||||
'INSERT INTO accounts (name, is_main, currency, sort_order, created_at) '
|
'INSERT INTO accounts (name, is_main, currency, sort_order, created_at) '
|
||||||
'VALUES (?, ?, ?, ?, ?)',
|
'VALUES (?, ?, ?, ?, ?)',
|
||||||
['Main', 1, 'USD', 0, DateTime.now().millisecondsSinceEpoch],
|
['main', 1, 'USD', 0, DateTime.now().millisecondsSinceEpoch],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (from == 2) {
|
if (from == 2) {
|
||||||
// Add currency column to existing accounts table
|
|
||||||
await customStatement(
|
await customStatement(
|
||||||
'ALTER TABLE accounts ADD COLUMN currency TEXT NOT NULL DEFAULT "USD"',
|
'ALTER TABLE accounts ADD COLUMN currency TEXT NOT NULL DEFAULT "USD"',
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -113,6 +113,17 @@ class $TransactionsTable extends Transactions
|
|||||||
requiredDuringInsert: false,
|
requiredDuringInsert: false,
|
||||||
defaultValue: const Constant('USD'),
|
defaultValue: const Constant('USD'),
|
||||||
);
|
);
|
||||||
|
static const VerificationMeta _accountIdMeta = const VerificationMeta(
|
||||||
|
'accountId',
|
||||||
|
);
|
||||||
|
@override
|
||||||
|
late final GeneratedColumn<int> accountId = GeneratedColumn<int>(
|
||||||
|
'account_id',
|
||||||
|
aliasedName,
|
||||||
|
false,
|
||||||
|
type: DriftSqlType.int,
|
||||||
|
requiredDuringInsert: true,
|
||||||
|
);
|
||||||
static const VerificationMeta _createdAtMeta = const VerificationMeta(
|
static const VerificationMeta _createdAtMeta = const VerificationMeta(
|
||||||
'createdAt',
|
'createdAt',
|
||||||
);
|
);
|
||||||
@@ -137,6 +148,7 @@ class $TransactionsTable extends Transactions
|
|||||||
lastOccurrence,
|
lastOccurrence,
|
||||||
currency,
|
currency,
|
||||||
currencyCode,
|
currencyCode,
|
||||||
|
accountId,
|
||||||
createdAt,
|
createdAt,
|
||||||
];
|
];
|
||||||
@override
|
@override
|
||||||
@@ -224,6 +236,14 @@ class $TransactionsTable extends Transactions
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
if (data.containsKey('account_id')) {
|
||||||
|
context.handle(
|
||||||
|
_accountIdMeta,
|
||||||
|
accountId.isAcceptableOrUnknown(data['account_id']!, _accountIdMeta),
|
||||||
|
);
|
||||||
|
} else if (isInserting) {
|
||||||
|
context.missing(_accountIdMeta);
|
||||||
|
}
|
||||||
if (data.containsKey('created_at')) {
|
if (data.containsKey('created_at')) {
|
||||||
context.handle(
|
context.handle(
|
||||||
_createdAtMeta,
|
_createdAtMeta,
|
||||||
@@ -279,6 +299,10 @@ class $TransactionsTable extends Transactions
|
|||||||
DriftSqlType.string,
|
DriftSqlType.string,
|
||||||
data['${effectivePrefix}currency_code'],
|
data['${effectivePrefix}currency_code'],
|
||||||
)!,
|
)!,
|
||||||
|
accountId: attachedDatabase.typeMapping.read(
|
||||||
|
DriftSqlType.int,
|
||||||
|
data['${effectivePrefix}account_id'],
|
||||||
|
)!,
|
||||||
createdAt: attachedDatabase.typeMapping.read(
|
createdAt: attachedDatabase.typeMapping.read(
|
||||||
DriftSqlType.dateTime,
|
DriftSqlType.dateTime,
|
||||||
data['${effectivePrefix}created_at'],
|
data['${effectivePrefix}created_at'],
|
||||||
@@ -303,6 +327,7 @@ class Transaction extends DataClass implements Insertable<Transaction> {
|
|||||||
final DateTime? lastOccurrence;
|
final DateTime? lastOccurrence;
|
||||||
final String currency;
|
final String currency;
|
||||||
final String currencyCode;
|
final String currencyCode;
|
||||||
|
final int accountId;
|
||||||
final DateTime createdAt;
|
final DateTime createdAt;
|
||||||
const Transaction({
|
const Transaction({
|
||||||
required this.id,
|
required this.id,
|
||||||
@@ -315,6 +340,7 @@ class Transaction extends DataClass implements Insertable<Transaction> {
|
|||||||
this.lastOccurrence,
|
this.lastOccurrence,
|
||||||
required this.currency,
|
required this.currency,
|
||||||
required this.currencyCode,
|
required this.currencyCode,
|
||||||
|
required this.accountId,
|
||||||
required this.createdAt,
|
required this.createdAt,
|
||||||
});
|
});
|
||||||
@override
|
@override
|
||||||
@@ -334,6 +360,7 @@ class Transaction extends DataClass implements Insertable<Transaction> {
|
|||||||
}
|
}
|
||||||
map['currency'] = Variable<String>(currency);
|
map['currency'] = Variable<String>(currency);
|
||||||
map['currency_code'] = Variable<String>(currencyCode);
|
map['currency_code'] = Variable<String>(currencyCode);
|
||||||
|
map['account_id'] = Variable<int>(accountId);
|
||||||
map['created_at'] = Variable<DateTime>(createdAt);
|
map['created_at'] = Variable<DateTime>(createdAt);
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
@@ -352,6 +379,7 @@ class Transaction extends DataClass implements Insertable<Transaction> {
|
|||||||
: Value(lastOccurrence),
|
: Value(lastOccurrence),
|
||||||
currency: Value(currency),
|
currency: Value(currency),
|
||||||
currencyCode: Value(currencyCode),
|
currencyCode: Value(currencyCode),
|
||||||
|
accountId: Value(accountId),
|
||||||
createdAt: Value(createdAt),
|
createdAt: Value(createdAt),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -372,6 +400,7 @@ class Transaction extends DataClass implements Insertable<Transaction> {
|
|||||||
lastOccurrence: serializer.fromJson<DateTime?>(json['lastOccurrence']),
|
lastOccurrence: serializer.fromJson<DateTime?>(json['lastOccurrence']),
|
||||||
currency: serializer.fromJson<String>(json['currency']),
|
currency: serializer.fromJson<String>(json['currency']),
|
||||||
currencyCode: serializer.fromJson<String>(json['currencyCode']),
|
currencyCode: serializer.fromJson<String>(json['currencyCode']),
|
||||||
|
accountId: serializer.fromJson<int>(json['accountId']),
|
||||||
createdAt: serializer.fromJson<DateTime>(json['createdAt']),
|
createdAt: serializer.fromJson<DateTime>(json['createdAt']),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -389,6 +418,7 @@ class Transaction extends DataClass implements Insertable<Transaction> {
|
|||||||
'lastOccurrence': serializer.toJson<DateTime?>(lastOccurrence),
|
'lastOccurrence': serializer.toJson<DateTime?>(lastOccurrence),
|
||||||
'currency': serializer.toJson<String>(currency),
|
'currency': serializer.toJson<String>(currency),
|
||||||
'currencyCode': serializer.toJson<String>(currencyCode),
|
'currencyCode': serializer.toJson<String>(currencyCode),
|
||||||
|
'accountId': serializer.toJson<int>(accountId),
|
||||||
'createdAt': serializer.toJson<DateTime>(createdAt),
|
'createdAt': serializer.toJson<DateTime>(createdAt),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -404,6 +434,7 @@ class Transaction extends DataClass implements Insertable<Transaction> {
|
|||||||
Value<DateTime?> lastOccurrence = const Value.absent(),
|
Value<DateTime?> lastOccurrence = const Value.absent(),
|
||||||
String? currency,
|
String? currency,
|
||||||
String? currencyCode,
|
String? currencyCode,
|
||||||
|
int? accountId,
|
||||||
DateTime? createdAt,
|
DateTime? createdAt,
|
||||||
}) => Transaction(
|
}) => Transaction(
|
||||||
id: id ?? this.id,
|
id: id ?? this.id,
|
||||||
@@ -418,6 +449,7 @@ class Transaction extends DataClass implements Insertable<Transaction> {
|
|||||||
: this.lastOccurrence,
|
: this.lastOccurrence,
|
||||||
currency: currency ?? this.currency,
|
currency: currency ?? this.currency,
|
||||||
currencyCode: currencyCode ?? this.currencyCode,
|
currencyCode: currencyCode ?? this.currencyCode,
|
||||||
|
accountId: accountId ?? this.accountId,
|
||||||
createdAt: createdAt ?? this.createdAt,
|
createdAt: createdAt ?? this.createdAt,
|
||||||
);
|
);
|
||||||
Transaction copyWithCompanion(TransactionsCompanion data) {
|
Transaction copyWithCompanion(TransactionsCompanion data) {
|
||||||
@@ -438,6 +470,7 @@ class Transaction extends DataClass implements Insertable<Transaction> {
|
|||||||
currencyCode: data.currencyCode.present
|
currencyCode: data.currencyCode.present
|
||||||
? data.currencyCode.value
|
? data.currencyCode.value
|
||||||
: this.currencyCode,
|
: this.currencyCode,
|
||||||
|
accountId: data.accountId.present ? data.accountId.value : this.accountId,
|
||||||
createdAt: data.createdAt.present ? data.createdAt.value : this.createdAt,
|
createdAt: data.createdAt.present ? data.createdAt.value : this.createdAt,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -455,6 +488,7 @@ class Transaction extends DataClass implements Insertable<Transaction> {
|
|||||||
..write('lastOccurrence: $lastOccurrence, ')
|
..write('lastOccurrence: $lastOccurrence, ')
|
||||||
..write('currency: $currency, ')
|
..write('currency: $currency, ')
|
||||||
..write('currencyCode: $currencyCode, ')
|
..write('currencyCode: $currencyCode, ')
|
||||||
|
..write('accountId: $accountId, ')
|
||||||
..write('createdAt: $createdAt')
|
..write('createdAt: $createdAt')
|
||||||
..write(')'))
|
..write(')'))
|
||||||
.toString();
|
.toString();
|
||||||
@@ -472,6 +506,7 @@ class Transaction extends DataClass implements Insertable<Transaction> {
|
|||||||
lastOccurrence,
|
lastOccurrence,
|
||||||
currency,
|
currency,
|
||||||
currencyCode,
|
currencyCode,
|
||||||
|
accountId,
|
||||||
createdAt,
|
createdAt,
|
||||||
);
|
);
|
||||||
@override
|
@override
|
||||||
@@ -488,6 +523,7 @@ class Transaction extends DataClass implements Insertable<Transaction> {
|
|||||||
other.lastOccurrence == this.lastOccurrence &&
|
other.lastOccurrence == this.lastOccurrence &&
|
||||||
other.currency == this.currency &&
|
other.currency == this.currency &&
|
||||||
other.currencyCode == this.currencyCode &&
|
other.currencyCode == this.currencyCode &&
|
||||||
|
other.accountId == this.accountId &&
|
||||||
other.createdAt == this.createdAt);
|
other.createdAt == this.createdAt);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -502,6 +538,7 @@ class TransactionsCompanion extends UpdateCompanion<Transaction> {
|
|||||||
final Value<DateTime?> lastOccurrence;
|
final Value<DateTime?> lastOccurrence;
|
||||||
final Value<String> currency;
|
final Value<String> currency;
|
||||||
final Value<String> currencyCode;
|
final Value<String> currencyCode;
|
||||||
|
final Value<int> accountId;
|
||||||
final Value<DateTime> createdAt;
|
final Value<DateTime> createdAt;
|
||||||
final Value<int> rowid;
|
final Value<int> rowid;
|
||||||
const TransactionsCompanion({
|
const TransactionsCompanion({
|
||||||
@@ -515,6 +552,7 @@ class TransactionsCompanion extends UpdateCompanion<Transaction> {
|
|||||||
this.lastOccurrence = const Value.absent(),
|
this.lastOccurrence = const Value.absent(),
|
||||||
this.currency = const Value.absent(),
|
this.currency = const Value.absent(),
|
||||||
this.currencyCode = const Value.absent(),
|
this.currencyCode = const Value.absent(),
|
||||||
|
this.accountId = const Value.absent(),
|
||||||
this.createdAt = const Value.absent(),
|
this.createdAt = const Value.absent(),
|
||||||
this.rowid = const Value.absent(),
|
this.rowid = const Value.absent(),
|
||||||
});
|
});
|
||||||
@@ -529,13 +567,15 @@ class TransactionsCompanion extends UpdateCompanion<Transaction> {
|
|||||||
this.lastOccurrence = const Value.absent(),
|
this.lastOccurrence = const Value.absent(),
|
||||||
this.currency = const Value.absent(),
|
this.currency = const Value.absent(),
|
||||||
this.currencyCode = const Value.absent(),
|
this.currencyCode = const Value.absent(),
|
||||||
|
required int accountId,
|
||||||
this.createdAt = const Value.absent(),
|
this.createdAt = const Value.absent(),
|
||||||
this.rowid = const Value.absent(),
|
this.rowid = const Value.absent(),
|
||||||
}) : id = Value(id),
|
}) : id = Value(id),
|
||||||
amount = Value(amount),
|
amount = Value(amount),
|
||||||
category = Value(category),
|
category = Value(category),
|
||||||
type = Value(type),
|
type = Value(type),
|
||||||
date = Value(date);
|
date = Value(date),
|
||||||
|
accountId = Value(accountId);
|
||||||
static Insertable<Transaction> custom({
|
static Insertable<Transaction> custom({
|
||||||
Expression<String>? id,
|
Expression<String>? id,
|
||||||
Expression<double>? amount,
|
Expression<double>? amount,
|
||||||
@@ -547,6 +587,7 @@ class TransactionsCompanion extends UpdateCompanion<Transaction> {
|
|||||||
Expression<DateTime>? lastOccurrence,
|
Expression<DateTime>? lastOccurrence,
|
||||||
Expression<String>? currency,
|
Expression<String>? currency,
|
||||||
Expression<String>? currencyCode,
|
Expression<String>? currencyCode,
|
||||||
|
Expression<int>? accountId,
|
||||||
Expression<DateTime>? createdAt,
|
Expression<DateTime>? createdAt,
|
||||||
Expression<int>? rowid,
|
Expression<int>? rowid,
|
||||||
}) {
|
}) {
|
||||||
@@ -561,6 +602,7 @@ class TransactionsCompanion extends UpdateCompanion<Transaction> {
|
|||||||
if (lastOccurrence != null) 'last_occurrence': lastOccurrence,
|
if (lastOccurrence != null) 'last_occurrence': lastOccurrence,
|
||||||
if (currency != null) 'currency': currency,
|
if (currency != null) 'currency': currency,
|
||||||
if (currencyCode != null) 'currency_code': currencyCode,
|
if (currencyCode != null) 'currency_code': currencyCode,
|
||||||
|
if (accountId != null) 'account_id': accountId,
|
||||||
if (createdAt != null) 'created_at': createdAt,
|
if (createdAt != null) 'created_at': createdAt,
|
||||||
if (rowid != null) 'rowid': rowid,
|
if (rowid != null) 'rowid': rowid,
|
||||||
});
|
});
|
||||||
@@ -577,6 +619,7 @@ class TransactionsCompanion extends UpdateCompanion<Transaction> {
|
|||||||
Value<DateTime?>? lastOccurrence,
|
Value<DateTime?>? lastOccurrence,
|
||||||
Value<String>? currency,
|
Value<String>? currency,
|
||||||
Value<String>? currencyCode,
|
Value<String>? currencyCode,
|
||||||
|
Value<int>? accountId,
|
||||||
Value<DateTime>? createdAt,
|
Value<DateTime>? createdAt,
|
||||||
Value<int>? rowid,
|
Value<int>? rowid,
|
||||||
}) {
|
}) {
|
||||||
@@ -591,6 +634,7 @@ class TransactionsCompanion extends UpdateCompanion<Transaction> {
|
|||||||
lastOccurrence: lastOccurrence ?? this.lastOccurrence,
|
lastOccurrence: lastOccurrence ?? this.lastOccurrence,
|
||||||
currency: currency ?? this.currency,
|
currency: currency ?? this.currency,
|
||||||
currencyCode: currencyCode ?? this.currencyCode,
|
currencyCode: currencyCode ?? this.currencyCode,
|
||||||
|
accountId: accountId ?? this.accountId,
|
||||||
createdAt: createdAt ?? this.createdAt,
|
createdAt: createdAt ?? this.createdAt,
|
||||||
rowid: rowid ?? this.rowid,
|
rowid: rowid ?? this.rowid,
|
||||||
);
|
);
|
||||||
@@ -629,6 +673,9 @@ class TransactionsCompanion extends UpdateCompanion<Transaction> {
|
|||||||
if (currencyCode.present) {
|
if (currencyCode.present) {
|
||||||
map['currency_code'] = Variable<String>(currencyCode.value);
|
map['currency_code'] = Variable<String>(currencyCode.value);
|
||||||
}
|
}
|
||||||
|
if (accountId.present) {
|
||||||
|
map['account_id'] = Variable<int>(accountId.value);
|
||||||
|
}
|
||||||
if (createdAt.present) {
|
if (createdAt.present) {
|
||||||
map['created_at'] = Variable<DateTime>(createdAt.value);
|
map['created_at'] = Variable<DateTime>(createdAt.value);
|
||||||
}
|
}
|
||||||
@@ -651,6 +698,7 @@ class TransactionsCompanion extends UpdateCompanion<Transaction> {
|
|||||||
..write('lastOccurrence: $lastOccurrence, ')
|
..write('lastOccurrence: $lastOccurrence, ')
|
||||||
..write('currency: $currency, ')
|
..write('currency: $currency, ')
|
||||||
..write('currencyCode: $currencyCode, ')
|
..write('currencyCode: $currencyCode, ')
|
||||||
|
..write('accountId: $accountId, ')
|
||||||
..write('createdAt: $createdAt, ')
|
..write('createdAt: $createdAt, ')
|
||||||
..write('rowid: $rowid')
|
..write('rowid: $rowid')
|
||||||
..write(')'))
|
..write(')'))
|
||||||
@@ -2276,6 +2324,7 @@ typedef $$TransactionsTableCreateCompanionBuilder =
|
|||||||
Value<DateTime?> lastOccurrence,
|
Value<DateTime?> lastOccurrence,
|
||||||
Value<String> currency,
|
Value<String> currency,
|
||||||
Value<String> currencyCode,
|
Value<String> currencyCode,
|
||||||
|
required int accountId,
|
||||||
Value<DateTime> createdAt,
|
Value<DateTime> createdAt,
|
||||||
Value<int> rowid,
|
Value<int> rowid,
|
||||||
});
|
});
|
||||||
@@ -2291,6 +2340,7 @@ typedef $$TransactionsTableUpdateCompanionBuilder =
|
|||||||
Value<DateTime?> lastOccurrence,
|
Value<DateTime?> lastOccurrence,
|
||||||
Value<String> currency,
|
Value<String> currency,
|
||||||
Value<String> currencyCode,
|
Value<String> currencyCode,
|
||||||
|
Value<int> accountId,
|
||||||
Value<DateTime> createdAt,
|
Value<DateTime> createdAt,
|
||||||
Value<int> rowid,
|
Value<int> rowid,
|
||||||
});
|
});
|
||||||
@@ -2354,6 +2404,11 @@ class $$TransactionsTableFilterComposer
|
|||||||
builder: (column) => ColumnFilters(column),
|
builder: (column) => ColumnFilters(column),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
ColumnFilters<int> get accountId => $composableBuilder(
|
||||||
|
column: $table.accountId,
|
||||||
|
builder: (column) => ColumnFilters(column),
|
||||||
|
);
|
||||||
|
|
||||||
ColumnFilters<DateTime> get createdAt => $composableBuilder(
|
ColumnFilters<DateTime> get createdAt => $composableBuilder(
|
||||||
column: $table.createdAt,
|
column: $table.createdAt,
|
||||||
builder: (column) => ColumnFilters(column),
|
builder: (column) => ColumnFilters(column),
|
||||||
@@ -2419,6 +2474,11 @@ class $$TransactionsTableOrderingComposer
|
|||||||
builder: (column) => ColumnOrderings(column),
|
builder: (column) => ColumnOrderings(column),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
ColumnOrderings<int> get accountId => $composableBuilder(
|
||||||
|
column: $table.accountId,
|
||||||
|
builder: (column) => ColumnOrderings(column),
|
||||||
|
);
|
||||||
|
|
||||||
ColumnOrderings<DateTime> get createdAt => $composableBuilder(
|
ColumnOrderings<DateTime> get createdAt => $composableBuilder(
|
||||||
column: $table.createdAt,
|
column: $table.createdAt,
|
||||||
builder: (column) => ColumnOrderings(column),
|
builder: (column) => ColumnOrderings(column),
|
||||||
@@ -2470,6 +2530,9 @@ class $$TransactionsTableAnnotationComposer
|
|||||||
builder: (column) => column,
|
builder: (column) => column,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
GeneratedColumn<int> get accountId =>
|
||||||
|
$composableBuilder(column: $table.accountId, builder: (column) => column);
|
||||||
|
|
||||||
GeneratedColumn<DateTime> get createdAt =>
|
GeneratedColumn<DateTime> get createdAt =>
|
||||||
$composableBuilder(column: $table.createdAt, builder: (column) => column);
|
$composableBuilder(column: $table.createdAt, builder: (column) => column);
|
||||||
}
|
}
|
||||||
@@ -2515,6 +2578,7 @@ class $$TransactionsTableTableManager
|
|||||||
Value<DateTime?> lastOccurrence = const Value.absent(),
|
Value<DateTime?> lastOccurrence = const Value.absent(),
|
||||||
Value<String> currency = const Value.absent(),
|
Value<String> currency = const Value.absent(),
|
||||||
Value<String> currencyCode = const Value.absent(),
|
Value<String> currencyCode = const Value.absent(),
|
||||||
|
Value<int> accountId = const Value.absent(),
|
||||||
Value<DateTime> createdAt = const Value.absent(),
|
Value<DateTime> createdAt = const Value.absent(),
|
||||||
Value<int> rowid = const Value.absent(),
|
Value<int> rowid = const Value.absent(),
|
||||||
}) => TransactionsCompanion(
|
}) => TransactionsCompanion(
|
||||||
@@ -2528,6 +2592,7 @@ class $$TransactionsTableTableManager
|
|||||||
lastOccurrence: lastOccurrence,
|
lastOccurrence: lastOccurrence,
|
||||||
currency: currency,
|
currency: currency,
|
||||||
currencyCode: currencyCode,
|
currencyCode: currencyCode,
|
||||||
|
accountId: accountId,
|
||||||
createdAt: createdAt,
|
createdAt: createdAt,
|
||||||
rowid: rowid,
|
rowid: rowid,
|
||||||
),
|
),
|
||||||
@@ -2543,6 +2608,7 @@ class $$TransactionsTableTableManager
|
|||||||
Value<DateTime?> lastOccurrence = const Value.absent(),
|
Value<DateTime?> lastOccurrence = const Value.absent(),
|
||||||
Value<String> currency = const Value.absent(),
|
Value<String> currency = const Value.absent(),
|
||||||
Value<String> currencyCode = const Value.absent(),
|
Value<String> currencyCode = const Value.absent(),
|
||||||
|
required int accountId,
|
||||||
Value<DateTime> createdAt = const Value.absent(),
|
Value<DateTime> createdAt = const Value.absent(),
|
||||||
Value<int> rowid = const Value.absent(),
|
Value<int> rowid = const Value.absent(),
|
||||||
}) => TransactionsCompanion.insert(
|
}) => TransactionsCompanion.insert(
|
||||||
@@ -2556,6 +2622,7 @@ class $$TransactionsTableTableManager
|
|||||||
lastOccurrence: lastOccurrence,
|
lastOccurrence: lastOccurrence,
|
||||||
currency: currency,
|
currency: currency,
|
||||||
currencyCode: currencyCode,
|
currencyCode: currencyCode,
|
||||||
|
accountId: accountId,
|
||||||
createdAt: createdAt,
|
createdAt: createdAt,
|
||||||
rowid: rowid,
|
rowid: rowid,
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ class Transactions extends Table {
|
|||||||
DateTimeColumn get lastOccurrence => dateTime().nullable()();
|
DateTimeColumn get lastOccurrence => dateTime().nullable()();
|
||||||
TextColumn get currency => text().withDefault(const Constant('\$'))();
|
TextColumn get currency => text().withDefault(const Constant('\$'))();
|
||||||
TextColumn get currencyCode => text().withDefault(const Constant('USD'))();
|
TextColumn get currencyCode => text().withDefault(const Constant('USD'))();
|
||||||
|
IntColumn get accountId => integer()();
|
||||||
DateTimeColumn get createdAt => dateTime().withDefault(currentDateAndTime)();
|
DateTimeColumn get createdAt => dateTime().withDefault(currentDateAndTime)();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|||||||
@@ -64,11 +64,8 @@ class AccountRepository {
|
|||||||
..orderBy([(a) => OrderingTerm.asc(a.sortOrder)]))
|
..orderBy([(a) => OrderingTerm.asc(a.sortOrder)]))
|
||||||
.get();
|
.get();
|
||||||
|
|
||||||
print('AccountRepository.getAll(): rows.length = ${rows.length}');
|
|
||||||
|
|
||||||
// Fallback: insert default account if none exists
|
// Fallback: insert default account if none exists
|
||||||
if (rows.isEmpty) {
|
if (rows.isEmpty) {
|
||||||
print('AccountRepository.getAll(): inserting default account');
|
|
||||||
try {
|
try {
|
||||||
await _db.into(_db.accounts).insert(
|
await _db.into(_db.accounts).insert(
|
||||||
AccountsCompanion.insert(
|
AccountsCompanion.insert(
|
||||||
@@ -78,18 +75,16 @@ class AccountRepository {
|
|||||||
sortOrder: const Value(0),
|
sortOrder: const Value(0),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
print('AccountRepository.getAll(): default account inserted');
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print('AccountRepository.getAll(): insert error: $e');
|
// Ignore if already exists
|
||||||
}
|
}
|
||||||
// Re-query after insert
|
// Re-query after insert
|
||||||
rows = await (_db.select(_db.accounts)
|
rows = await (_db.select(_db.accounts)
|
||||||
..orderBy([(a) => OrderingTerm.asc(a.sortOrder)]))
|
..orderBy([(a) => OrderingTerm.asc(a.sortOrder)]))
|
||||||
.get();
|
.get();
|
||||||
print('AccountRepository.getAll(): after insert, rows.length = ${rows.length}');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final accounts = rows
|
return rows
|
||||||
.map((row) => model.Account(
|
.map((row) => model.Account(
|
||||||
id: row.id,
|
id: row.id,
|
||||||
name: row.name,
|
name: row.name,
|
||||||
@@ -99,12 +94,7 @@ class AccountRepository {
|
|||||||
createdAt: row.createdAt,
|
createdAt: row.createdAt,
|
||||||
))
|
))
|
||||||
.toList();
|
.toList();
|
||||||
|
} catch (e) {
|
||||||
print('AccountRepository.getAll(): returning ${accounts.length} accounts');
|
|
||||||
return accounts;
|
|
||||||
} catch (e, stack) {
|
|
||||||
print('AccountRepository.getAll(): error: $e');
|
|
||||||
print('Stack: $stack');
|
|
||||||
// Return empty list on error
|
// Return empty list on error
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -148,6 +148,7 @@ class TransactionRepository {
|
|||||||
lastOccurrence: dbTransaction.lastOccurrence as DateTime?,
|
lastOccurrence: dbTransaction.lastOccurrence as DateTime?,
|
||||||
currency: dbTransaction.currency as String,
|
currency: dbTransaction.currency as String,
|
||||||
currencyCode: dbTransaction.currencyCode as String,
|
currencyCode: dbTransaction.currencyCode as String,
|
||||||
|
accountId: dbTransaction.accountId as int,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -165,6 +166,7 @@ class TransactionRepository {
|
|||||||
lastOccurrence: Value(transaction.lastOccurrence),
|
lastOccurrence: Value(transaction.lastOccurrence),
|
||||||
currency: Value(transaction.currency),
|
currency: Value(transaction.currency),
|
||||||
currencyCode: Value(transaction.currencyCode),
|
currencyCode: Value(transaction.currencyCode),
|
||||||
|
accountId: Value(transaction.accountId),
|
||||||
createdAt: Value(DateTime.now()),
|
createdAt: Value(DateTime.now()),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -182,6 +184,7 @@ class TransactionRepository {
|
|||||||
lastOccurrence: Value(transaction.lastOccurrence),
|
lastOccurrence: Value(transaction.lastOccurrence),
|
||||||
currency: Value(transaction.currency),
|
currency: Value(transaction.currency),
|
||||||
currencyCode: Value(transaction.currencyCode),
|
currencyCode: Value(transaction.currencyCode),
|
||||||
|
accountId: Value(transaction.accountId),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,11 +15,18 @@ import 'provider.dart';
|
|||||||
|
|
||||||
const _uuid = Uuid();
|
const _uuid = Uuid();
|
||||||
|
|
||||||
// Provider to get main account name
|
// Provider to get the account for new transactions
|
||||||
final mainAccountNameProvider = FutureProvider<String>((ref) async {
|
final transactionAccountProvider = Provider<({int id, String name})>((ref) {
|
||||||
final repository = ref.watch(accountRepositoryProvider);
|
final activeAccount = ref.watch(activeAccountProvider);
|
||||||
final mainAccount = await repository.getMain();
|
|
||||||
return mainAccount.name;
|
if (activeAccount != null) {
|
||||||
|
// User is on a specific account page
|
||||||
|
return (id: activeAccount.id, name: activeAccount.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
// User is on Total Balance page, use Main account
|
||||||
|
// This will be resolved in the widget
|
||||||
|
return (id: 0, name: ''); // Placeholder, will be replaced
|
||||||
});
|
});
|
||||||
|
|
||||||
class AddTransactionScreen extends ConsumerStatefulWidget {
|
class AddTransactionScreen extends ConsumerStatefulWidget {
|
||||||
@@ -146,6 +153,11 @@ class _AddTransactionScreenState extends ConsumerState<AddTransactionScreen>
|
|||||||
? null
|
? null
|
||||||
: _noteController.text.trim();
|
: _noteController.text.trim();
|
||||||
|
|
||||||
|
// Get account ID: use active account or fallback to main
|
||||||
|
final activeAccount = ref.read(activeAccountProvider);
|
||||||
|
final accountId = activeAccount?.id ??
|
||||||
|
(await ref.read(accountRepositoryProvider).getMain()).id;
|
||||||
|
|
||||||
final tx = Transaction(
|
final tx = Transaction(
|
||||||
id: state.editingId ?? _uuid.v4(),
|
id: state.editingId ?? _uuid.v4(),
|
||||||
amount: amount,
|
amount: amount,
|
||||||
@@ -155,6 +167,7 @@ class _AddTransactionScreenState extends ConsumerState<AddTransactionScreen>
|
|||||||
note: note,
|
note: note,
|
||||||
currency: state.overrideCurrency,
|
currency: state.overrideCurrency,
|
||||||
currencyCode: state.overrideCurrencyCode,
|
currencyCode: state.overrideCurrencyCode,
|
||||||
|
accountId: accountId,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (state.isEditing) {
|
if (state.isEditing) {
|
||||||
@@ -226,7 +239,10 @@ class _AddTransactionScreenState extends ConsumerState<AddTransactionScreen>
|
|||||||
final categories = ref.watch(availableCategoriesProvider(widget.initial));
|
final categories = ref.watch(availableCategoriesProvider(widget.initial));
|
||||||
final overrideCurrency = state.overrideCurrency;
|
final overrideCurrency = state.overrideCurrency;
|
||||||
final isDark = Theme.of(context).brightness == Brightness.dark;
|
final isDark = Theme.of(context).brightness == Brightness.dark;
|
||||||
final accountNameAsync = ref.watch(mainAccountNameProvider);
|
|
||||||
|
// Get active account or fallback to main
|
||||||
|
final activeAccount = ref.watch(activeAccountProvider);
|
||||||
|
final accountRepository = ref.watch(accountRepositoryProvider);
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
|
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
|
||||||
@@ -278,18 +294,24 @@ class _AddTransactionScreenState extends ConsumerState<AddTransactionScreen>
|
|||||||
child: ListView(
|
child: ListView(
|
||||||
padding: const EdgeInsets.all(20),
|
padding: const EdgeInsets.all(20),
|
||||||
children: [
|
children: [
|
||||||
accountNameAsync.when(
|
FutureBuilder<String>(
|
||||||
data: (accountName) => Padding(
|
future: activeAccount != null
|
||||||
padding: const EdgeInsets.only(bottom: 16),
|
? Future.value(activeAccount.name)
|
||||||
child: Text(
|
: accountRepository.getMain().then((acc) => acc.name),
|
||||||
'Account: $accountName',
|
builder: (context, snapshot) {
|
||||||
style: Theme.of(context).textTheme.bodySmall?.copyWith(
|
if (snapshot.hasData) {
|
||||||
color: Theme.of(context).colorScheme.onSurface.withOpacity(0.5),
|
return Padding(
|
||||||
),
|
padding: const EdgeInsets.only(bottom: 16),
|
||||||
),
|
child: Text(
|
||||||
),
|
'Account: ${snapshot.data}',
|
||||||
loading: () => const SizedBox.shrink(),
|
style: Theme.of(context).textTheme.bodySmall?.copyWith(
|
||||||
error: (_, __) => const SizedBox.shrink(),
|
color: Theme.of(context).colorScheme.onSurface.withOpacity(0.5),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return const SizedBox.shrink();
|
||||||
|
},
|
||||||
),
|
),
|
||||||
_TypeToggle(
|
_TypeToggle(
|
||||||
selected: state.type,
|
selected: state.type,
|
||||||
|
|||||||
@@ -117,9 +117,23 @@ final timeFilterProvider = StateProvider<TimeFilter>(
|
|||||||
(ref) => TimeFilter.lastMonth,
|
(ref) => TimeFilter.lastMonth,
|
||||||
);
|
);
|
||||||
|
|
||||||
final totalBalanceProvider = Provider<double>((ref) {
|
// Base filtered transactions by active account
|
||||||
|
final accountFilteredTransactionsProvider = Provider<List<Transaction>>((ref) {
|
||||||
final txsAsync = ref.watch(transactionsProvider);
|
final txsAsync = ref.watch(transactionsProvider);
|
||||||
final txs = txsAsync.valueOrNull ?? [];
|
final txs = txsAsync.valueOrNull ?? [];
|
||||||
|
final activeAccount = ref.watch(activeAccountProvider);
|
||||||
|
|
||||||
|
// If activeAccount is null (Total Balance page), return all transactions
|
||||||
|
if (activeAccount == null) {
|
||||||
|
return txs;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filter by account ID
|
||||||
|
return txs.where((t) => t.accountId == activeAccount.id).toList();
|
||||||
|
});
|
||||||
|
|
||||||
|
final totalBalanceProvider = Provider<double>((ref) {
|
||||||
|
final txs = ref.watch(accountFilteredTransactionsProvider);
|
||||||
final exchangeService = ref.watch(exchangeRateServiceProvider);
|
final exchangeService = ref.watch(exchangeRateServiceProvider);
|
||||||
final targetCurrency = ref.watch(currencyProvider).code;
|
final targetCurrency = ref.watch(currencyProvider).code;
|
||||||
|
|
||||||
@@ -134,8 +148,7 @@ final totalBalanceProvider = Provider<double>((ref) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
final totalIncomeProvider = Provider<double>((ref) {
|
final totalIncomeProvider = Provider<double>((ref) {
|
||||||
final txsAsync = ref.watch(transactionsProvider);
|
final txs = ref.watch(accountFilteredTransactionsProvider);
|
||||||
final txs = txsAsync.valueOrNull ?? [];
|
|
||||||
final filtered = txs.where((t) => t.type == TransactionType.income);
|
final filtered = txs.where((t) => t.type == TransactionType.income);
|
||||||
final exchangeService = ref.watch(exchangeRateServiceProvider);
|
final exchangeService = ref.watch(exchangeRateServiceProvider);
|
||||||
final targetCurrency = ref.watch(currencyProvider).code;
|
final targetCurrency = ref.watch(currencyProvider).code;
|
||||||
@@ -147,8 +160,7 @@ final totalIncomeProvider = Provider<double>((ref) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
final totalExpenseProvider = Provider<double>((ref) {
|
final totalExpenseProvider = Provider<double>((ref) {
|
||||||
final txsAsync = ref.watch(transactionsProvider);
|
final txs = ref.watch(accountFilteredTransactionsProvider);
|
||||||
final txs = txsAsync.valueOrNull ?? [];
|
|
||||||
final filtered = txs.where((t) => t.type == TransactionType.expense);
|
final filtered = txs.where((t) => t.type == TransactionType.expense);
|
||||||
final exchangeService = ref.watch(exchangeRateServiceProvider);
|
final exchangeService = ref.watch(exchangeRateServiceProvider);
|
||||||
final targetCurrency = ref.watch(currencyProvider).code;
|
final targetCurrency = ref.watch(currencyProvider).code;
|
||||||
@@ -161,8 +173,7 @@ final totalExpenseProvider = Provider<double>((ref) {
|
|||||||
|
|
||||||
final currentMonthExpenseProvider = Provider<double>((ref) {
|
final currentMonthExpenseProvider = Provider<double>((ref) {
|
||||||
final now = DateTime.now();
|
final now = DateTime.now();
|
||||||
final txsAsync = ref.watch(transactionsProvider);
|
final txs = ref.watch(accountFilteredTransactionsProvider);
|
||||||
final txs = txsAsync.valueOrNull ?? [];
|
|
||||||
final filtered = txs.where(
|
final filtered = txs.where(
|
||||||
(t) =>
|
(t) =>
|
||||||
t.type == TransactionType.expense &&
|
t.type == TransactionType.expense &&
|
||||||
@@ -179,8 +190,7 @@ final currentMonthExpenseProvider = Provider<double>((ref) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
final filteredTransactionsProvider = Provider<List<Transaction>>((ref) {
|
final filteredTransactionsProvider = Provider<List<Transaction>>((ref) {
|
||||||
final txsAsync = ref.watch(transactionsProvider);
|
final txs = ref.watch(accountFilteredTransactionsProvider);
|
||||||
final txs = txsAsync.valueOrNull ?? [];
|
|
||||||
final query = ref.watch(searchQueryProvider).toLowerCase();
|
final query = ref.watch(searchQueryProvider).toLowerCase();
|
||||||
final typeFilter = ref.watch(transactionFilterProvider);
|
final typeFilter = ref.watch(transactionFilterProvider);
|
||||||
final timeFilter = ref.watch(timeFilterProvider);
|
final timeFilter = ref.watch(timeFilterProvider);
|
||||||
@@ -236,6 +246,25 @@ final accountsProvider = StreamProvider<List<Account>>((ref) async* {
|
|||||||
// Ephemeral UI state — active carousel index, starts at 0, not persisted
|
// Ephemeral UI state — active carousel index, starts at 0, not persisted
|
||||||
final activeAccountIndexProvider = StateProvider<int>((ref) => 0);
|
final activeAccountIndexProvider = StateProvider<int>((ref) => 0);
|
||||||
|
|
||||||
|
// Returns the currently active Account based on carousel index
|
||||||
|
final activeAccountProvider = Provider<Account?>((ref) {
|
||||||
|
final index = ref.watch(activeAccountIndexProvider);
|
||||||
|
final accountsAsync = ref.watch(accountsProvider);
|
||||||
|
|
||||||
|
if (index == 0) return null; // 0 means "Total Balance"
|
||||||
|
|
||||||
|
return accountsAsync.when(
|
||||||
|
data: (accounts) {
|
||||||
|
if (index > 0 && index <= accounts.length) {
|
||||||
|
return accounts[index - 1];
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
loading: () => null,
|
||||||
|
error: (_, __) => null,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
class CardColors {
|
class CardColors {
|
||||||
final Color primary;
|
final Color primary;
|
||||||
final Color secondary;
|
final Color secondary;
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ class BalanceCard extends ConsumerStatefulWidget {
|
|||||||
final Color? previewPrimary;
|
final Color? previewPrimary;
|
||||||
final Color? previewSecondary;
|
final Color? previewSecondary;
|
||||||
final GradientType? previewGradientType;
|
final GradientType? previewGradientType;
|
||||||
|
final String? accountName;
|
||||||
|
|
||||||
const BalanceCard({
|
const BalanceCard({
|
||||||
super.key,
|
super.key,
|
||||||
@@ -43,6 +44,7 @@ class BalanceCard extends ConsumerStatefulWidget {
|
|||||||
this.previewPrimary,
|
this.previewPrimary,
|
||||||
this.previewSecondary,
|
this.previewSecondary,
|
||||||
this.previewGradientType,
|
this.previewGradientType,
|
||||||
|
this.accountName,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -181,6 +183,25 @@ class BalanceCardState extends ConsumerState<BalanceCard>
|
|||||||
borderRadius: BorderRadius.circular(20),
|
borderRadius: BorderRadius.circular(20),
|
||||||
child: Stack(
|
child: Stack(
|
||||||
children: [
|
children: [
|
||||||
|
if (widget.accountName != null)
|
||||||
|
Positioned(
|
||||||
|
top: 20,
|
||||||
|
left: 24,
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
widget.accountName!,
|
||||||
|
style: TextStyle(
|
||||||
|
color: Colors.white.withOpacity(0.7),
|
||||||
|
fontSize: 12,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
letterSpacing: 0.3,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.symmetric(
|
padding: const EdgeInsets.symmetric(
|
||||||
horizontal: 24,
|
horizontal: 24,
|
||||||
@@ -196,15 +217,17 @@ class BalanceCardState extends ConsumerState<BalanceCard>
|
|||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
if (widget.accountName == null)
|
||||||
s.totalBalance,
|
Text(
|
||||||
style: TextStyle(
|
s.totalBalance,
|
||||||
fontSize: 11,
|
style: TextStyle(
|
||||||
letterSpacing: 1.5,
|
fontSize: 11,
|
||||||
color: Colors.white.withOpacity(0.6),
|
letterSpacing: 1.5,
|
||||||
|
color: Colors.white.withOpacity(0.6),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
if (widget.accountName == null)
|
||||||
const SizedBox(height: 6),
|
const SizedBox(height: 6),
|
||||||
FittedBox(
|
FittedBox(
|
||||||
fit: BoxFit.scaleDown,
|
fit: BoxFit.scaleDown,
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import '../../../core/services/card_color_service.dart';
|
import '../../../core/services/card_color_service.dart';
|
||||||
|
import '../../../core/services/haptic_service.dart';
|
||||||
|
import '../../../shared/models/transaction.dart';
|
||||||
import '../../settings/provider.dart';
|
import '../../settings/provider.dart';
|
||||||
import '../provider.dart';
|
import '../provider.dart';
|
||||||
import 'balance_card.dart';
|
import 'balance_card.dart';
|
||||||
@@ -34,7 +36,8 @@ class _BalanceCardCarouselState extends ConsumerState<BalanceCardCarousel> {
|
|||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
_pageController = PageController(viewportFraction: 1.0);
|
// 0.92 позволяет видеть края предыдущей/следующей карточки
|
||||||
|
_pageController = PageController(viewportFraction: 0.92);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -50,63 +53,59 @@ class _BalanceCardCarouselState extends ConsumerState<BalanceCardCarousel> {
|
|||||||
|
|
||||||
return accountsAsync.when(
|
return accountsAsync.when(
|
||||||
data: (accounts) {
|
data: (accounts) {
|
||||||
// Debug logging
|
|
||||||
debugPrint('BalanceCardCarousel: accounts.length = ${accounts.length}');
|
|
||||||
if (accounts.isNotEmpty) {
|
|
||||||
debugPrint('BalanceCardCarousel: first account = ${accounts[0].name}');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Page 0: Total balance
|
|
||||||
// Pages 1..N: Account cards
|
|
||||||
// Page N+1: AddAccountCard (if < 5 accounts)
|
|
||||||
final totalPages = 1 + accounts.length + (accounts.length < 5 ? 1 : 0);
|
final totalPages = 1 + accounts.length + (accounts.length < 5 ? 1 : 0);
|
||||||
|
|
||||||
return Column(
|
return Column(
|
||||||
children: [
|
children: [
|
||||||
SizedBox(
|
SizedBox(
|
||||||
height: 220,
|
height: 230,
|
||||||
child: PageView.builder(
|
// OverflowBox позволяет PageView игнорировать паддинги родителя (DashboardScreen)
|
||||||
clipBehavior: Clip.none,
|
// и растянуться на всю ширину экрана
|
||||||
controller: _pageController,
|
child: OverflowBox(
|
||||||
itemCount: totalPages,
|
maxWidth: MediaQuery.of(context).size.width,
|
||||||
onPageChanged: (index) {
|
child: PageView.builder(
|
||||||
ref.read(activeAccountIndexProvider.notifier).state = index;
|
controller: _pageController,
|
||||||
},
|
clipBehavior: Clip.none, // Не обрезает карточку при 3D-наклоне
|
||||||
itemBuilder: (context, index) {
|
itemCount: totalPages,
|
||||||
Widget pageContent;
|
onPageChanged: (index) {
|
||||||
|
ref.read(activeAccountIndexProvider.notifier).state = index;
|
||||||
|
if (ref.read(hapticEnabledProvider)) {
|
||||||
|
HapticService.light();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
Widget cardWidget;
|
||||||
|
|
||||||
if (index == 0) {
|
if (index == 0) {
|
||||||
// Page 0: Total balance card
|
cardWidget = BalanceCard(
|
||||||
pageContent = BalanceCard(
|
balance: widget.balance,
|
||||||
balance: widget.balance,
|
currencyInfo: widget.currencyInfo,
|
||||||
currencyInfo: widget.currencyInfo,
|
onLongPress: widget.onLongPress,
|
||||||
onLongPress: widget.onLongPress,
|
previewPrimary: widget.previewPrimary,
|
||||||
previewPrimary: widget.previewPrimary,
|
previewSecondary: widget.previewSecondary,
|
||||||
previewSecondary: widget.previewSecondary,
|
previewGradientType: widget.previewGradientType,
|
||||||
previewGradientType: widget.previewGradientType,
|
);
|
||||||
);
|
} else if (index <= accounts.length) {
|
||||||
} else if (index <= accounts.length) {
|
final account = accounts[index - 1];
|
||||||
// Pages 1..N: Account cards
|
cardWidget = BalanceCard(
|
||||||
final account = accounts[index - 1];
|
balance: widget.balance, // TODO: Calculate per-account balance
|
||||||
debugPrint('BalanceCardCarousel: building account card at index $index for ${account.name}');
|
currencyInfo: widget.currencyInfo,
|
||||||
pageContent = _AccountBalanceCard(
|
onLongPress: null,
|
||||||
account: account,
|
accountName: account.name,
|
||||||
balance: widget.balance, // TODO: Calculate per-account balance
|
);
|
||||||
currencyInfo: widget.currencyInfo,
|
} else {
|
||||||
);
|
cardWidget = AddAccountCard(
|
||||||
} else {
|
onTap: () {},
|
||||||
// Page N+1: AddAccountCard
|
);
|
||||||
pageContent = AddAccountCard(
|
}
|
||||||
onTap: () {},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add horizontal padding to create gap between cards
|
// Отступ между карточками во время свайпа
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 6),
|
padding: const EdgeInsets.symmetric(horizontal: 8),
|
||||||
child: pageContent,
|
child: cardWidget,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 12),
|
const SizedBox(height: 12),
|
||||||
@@ -122,27 +121,21 @@ class _BalanceCardCarouselState extends ConsumerState<BalanceCardCarousel> {
|
|||||||
child: Center(child: CircularProgressIndicator()),
|
child: Center(child: CircularProgressIndicator()),
|
||||||
),
|
),
|
||||||
error: (error, stack) {
|
error: (error, stack) {
|
||||||
debugPrint('BalanceCardCarousel error: $error');
|
|
||||||
debugPrint('Stack: $stack');
|
|
||||||
// Show total balance card on error
|
|
||||||
return Column(
|
return Column(
|
||||||
children: [
|
children: [
|
||||||
SizedBox(
|
SizedBox(
|
||||||
height: 220,
|
height: 220,
|
||||||
child: Padding(
|
child: BalanceCard(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 6),
|
balance: widget.balance,
|
||||||
child: BalanceCard(
|
currencyInfo: widget.currencyInfo,
|
||||||
balance: widget.balance,
|
onLongPress: widget.onLongPress,
|
||||||
currencyInfo: widget.currencyInfo,
|
previewPrimary: widget.previewPrimary,
|
||||||
onLongPress: widget.onLongPress,
|
previewSecondary: widget.previewSecondary,
|
||||||
previewPrimary: widget.previewPrimary,
|
previewGradientType: widget.previewGradientType,
|
||||||
previewSecondary: widget.previewSecondary,
|
|
||||||
previewGradientType: widget.previewGradientType,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 12),
|
const SizedBox(height: 12),
|
||||||
_DotIndicators(
|
const _DotIndicators(
|
||||||
count: 1,
|
count: 1,
|
||||||
activeIndex: 0,
|
activeIndex: 0,
|
||||||
),
|
),
|
||||||
@@ -153,48 +146,6 @@ class _BalanceCardCarouselState extends ConsumerState<BalanceCardCarousel> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class _AccountBalanceCard extends ConsumerWidget {
|
|
||||||
final dynamic account;
|
|
||||||
final double balance;
|
|
||||||
final CurrencyInfo currencyInfo;
|
|
||||||
|
|
||||||
const _AccountBalanceCard({
|
|
||||||
required this.account,
|
|
||||||
required this.balance,
|
|
||||||
required this.currencyInfo,
|
|
||||||
});
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
|
||||||
return Stack(
|
|
||||||
clipBehavior: Clip.none,
|
|
||||||
children: [
|
|
||||||
BalanceCard(
|
|
||||||
balance: balance,
|
|
||||||
currencyInfo: currencyInfo,
|
|
||||||
onLongPress: null, // No long press for account cards
|
|
||||||
previewPrimary: null,
|
|
||||||
previewSecondary: null,
|
|
||||||
previewGradientType: null,
|
|
||||||
),
|
|
||||||
Positioned(
|
|
||||||
top: 16,
|
|
||||||
left: 24,
|
|
||||||
child: Text(
|
|
||||||
account.name,
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 11,
|
|
||||||
letterSpacing: 1.5,
|
|
||||||
color: Colors.white.withOpacity(0.6),
|
|
||||||
fontWeight: FontWeight.w600,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class AddAccountCard extends StatelessWidget {
|
class AddAccountCard extends StatelessWidget {
|
||||||
final VoidCallback? onTap;
|
final VoidCallback? onTap;
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ class Transaction {
|
|||||||
final DateTime? lastOccurrence;
|
final DateTime? lastOccurrence;
|
||||||
final String currency;
|
final String currency;
|
||||||
final String currencyCode;
|
final String currencyCode;
|
||||||
|
final int accountId;
|
||||||
|
|
||||||
const Transaction({
|
const Transaction({
|
||||||
required this.id,
|
required this.id,
|
||||||
@@ -28,6 +29,7 @@ class Transaction {
|
|||||||
this.lastOccurrence,
|
this.lastOccurrence,
|
||||||
this.currency = '\$',
|
this.currency = '\$',
|
||||||
this.currencyCode = 'USD',
|
this.currencyCode = 'USD',
|
||||||
|
required this.accountId,
|
||||||
});
|
});
|
||||||
|
|
||||||
factory Transaction.fromJson(Map<String, dynamic> json) => Transaction(
|
factory Transaction.fromJson(Map<String, dynamic> json) => Transaction(
|
||||||
@@ -50,6 +52,7 @@ class Transaction {
|
|||||||
: null,
|
: null,
|
||||||
currency: json['currency'] as String? ?? '\$',
|
currency: json['currency'] as String? ?? '\$',
|
||||||
currencyCode: json['currencyCode'] as String? ?? 'USD',
|
currencyCode: json['currencyCode'] as String? ?? 'USD',
|
||||||
|
accountId: json['accountId'] as int,
|
||||||
);
|
);
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
Map<String, dynamic> toJson() => {
|
||||||
@@ -63,6 +66,7 @@ class Transaction {
|
|||||||
'lastOccurrence': lastOccurrence?.toIso8601String(),
|
'lastOccurrence': lastOccurrence?.toIso8601String(),
|
||||||
'currency': currency,
|
'currency': currency,
|
||||||
'currencyCode': currencyCode,
|
'currencyCode': currencyCode,
|
||||||
|
'accountId': accountId,
|
||||||
};
|
};
|
||||||
|
|
||||||
Transaction copyWith({
|
Transaction copyWith({
|
||||||
@@ -76,6 +80,7 @@ class Transaction {
|
|||||||
DateTime? lastOccurrence,
|
DateTime? lastOccurrence,
|
||||||
String? currency,
|
String? currency,
|
||||||
String? currencyCode,
|
String? currencyCode,
|
||||||
|
int? accountId,
|
||||||
}) =>
|
}) =>
|
||||||
Transaction(
|
Transaction(
|
||||||
id: id ?? this.id,
|
id: id ?? this.id,
|
||||||
@@ -88,5 +93,6 @@ class Transaction {
|
|||||||
lastOccurrence: lastOccurrence ?? this.lastOccurrence,
|
lastOccurrence: lastOccurrence ?? this.lastOccurrence,
|
||||||
currency: currency ?? this.currency,
|
currency: currency ?? this.currency,
|
||||||
currencyCode: currencyCode ?? this.currencyCode,
|
currencyCode: currencyCode ?? this.currencyCode,
|
||||||
|
accountId: accountId ?? this.accountId,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -178,6 +178,7 @@ class StorageService {
|
|||||||
note: tx.note,
|
note: tx.note,
|
||||||
recurrence: tx.recurrence,
|
recurrence: tx.recurrence,
|
||||||
lastOccurrence: today,
|
lastOccurrence: today,
|
||||||
|
accountId: tx.accountId,
|
||||||
);
|
);
|
||||||
transactions.add(newTx);
|
transactions.add(newTx);
|
||||||
|
|
||||||
@@ -248,6 +249,7 @@ class StorageService {
|
|||||||
lastOccurrence: today,
|
lastOccurrence: today,
|
||||||
currency: tx.currency,
|
currency: tx.currency,
|
||||||
currencyCode: tx.currencyCode,
|
currencyCode: tx.currencyCode,
|
||||||
|
accountId: tx.accountId,
|
||||||
);
|
);
|
||||||
transactions.add(newTx);
|
transactions.add(newTx);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user