mirror of
https://github.com/koloideal/Casha.git
synced 2026-08-08 09:41:13 +03:00
step
This commit is contained in:
@@ -34,18 +34,22 @@ android {
|
|||||||
versionName = flutter.versionName
|
versionName = flutter.versionName
|
||||||
}
|
}
|
||||||
|
|
||||||
signingConfigs {
|
if (keyPropertiesFile.exists()) {
|
||||||
create("release") {
|
signingConfigs {
|
||||||
keyAlias = keyProperties["keyAlias"] as String
|
create("release") {
|
||||||
keyPassword = keyProperties["keyPassword"] as String
|
keyAlias = keyProperties["keyAlias"] as String
|
||||||
storeFile = file(keyProperties["storeFile"] as String)
|
keyPassword = keyProperties["keyPassword"] as String
|
||||||
storePassword = keyProperties["storePassword"] as String
|
storeFile = file(keyProperties["storeFile"] as String)
|
||||||
|
storePassword = keyProperties["storePassword"] as String
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
buildTypes {
|
buildTypes {
|
||||||
release {
|
release {
|
||||||
signingConfig = signingConfigs.getByName("release")
|
if (keyPropertiesFile.exists()) {
|
||||||
|
signingConfig = signingConfigs.getByName("release")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -122,6 +122,20 @@ class AppStrings {
|
|||||||
String get allAccounts => _ru ? 'Все счета' : 'All accounts';
|
String get allAccounts => _ru ? 'Все счета' : 'All accounts';
|
||||||
String get categories => _ru ? 'Категории' : 'Categories';
|
String get categories => _ru ? 'Категории' : 'Categories';
|
||||||
String get rankedByAmount => _ru ? 'По сумме' : 'Ranked by Amount';
|
String get rankedByAmount => _ru ? 'По сумме' : 'Ranked by Amount';
|
||||||
|
String get overview => _ru ? 'Обзор' : 'Overview';
|
||||||
|
String get netBalance => _ru ? 'Чистый баланс' : 'Net Balance';
|
||||||
|
String get averageIncome => _ru ? 'Средний доход' : 'Average Income';
|
||||||
|
String get averageExpense => _ru ? 'Средний расход' : 'Average Expense';
|
||||||
|
String get transactionsCount => _ru ? 'Транзакции' : 'Transactions';
|
||||||
|
String get expenseStructure => _ru ? 'Структура категорий' : 'Category Structure';
|
||||||
|
String get topCategories => _ru ? 'Топ категорий' : 'Top Categories';
|
||||||
|
String get monthlyTrend => _ru ? 'Тренд по месяцам' : 'Monthly Trend';
|
||||||
|
String get topCategory => _ru ? 'Лидер категории' : 'Top Category';
|
||||||
|
String get shareOfTotal => _ru ? 'Доля от общего' : 'Share of Total';
|
||||||
|
String get thisPeriod => _ru ? 'За период' : 'This Period';
|
||||||
|
String get analyticsInsight => _ru ? 'Финансовый срез по выбранному диапазону и счёту' : 'Financial snapshot for the selected range and account';
|
||||||
|
String get noStatisticsYet => _ru ? 'Пока недостаточно данных' : 'Not enough data yet';
|
||||||
|
String get statisticsWillAppear => _ru ? 'Когда появятся операции, здесь будет красивый аналитический обзор' : 'Once you add transactions, a beautiful analytics overview will appear here';
|
||||||
String get addCategory => _ru ? 'Добавить категорию' : 'Add Category';
|
String get addCategory => _ru ? 'Добавить категорию' : 'Add Category';
|
||||||
String get editCategory => _ru ? 'Редактировать' : 'Edit Category';
|
String get editCategory => _ru ? 'Редактировать' : 'Edit Category';
|
||||||
String get categoryName => _ru ? 'Название' : 'Name';
|
String get categoryName => _ru ? 'Название' : 'Name';
|
||||||
|
|||||||
@@ -3,6 +3,24 @@ import '../../shared/models/transaction.dart';
|
|||||||
import '../dashboard/provider.dart';
|
import '../dashboard/provider.dart';
|
||||||
import '../settings/provider.dart';
|
import '../settings/provider.dart';
|
||||||
|
|
||||||
|
class StatsSummary {
|
||||||
|
final double income;
|
||||||
|
final double expense;
|
||||||
|
final double balance;
|
||||||
|
final int transactionCount;
|
||||||
|
final double averageIncome;
|
||||||
|
final double averageExpense;
|
||||||
|
|
||||||
|
const StatsSummary({
|
||||||
|
required this.income,
|
||||||
|
required this.expense,
|
||||||
|
required this.balance,
|
||||||
|
required this.transactionCount,
|
||||||
|
required this.averageIncome,
|
||||||
|
required this.averageExpense,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
String _statsTargetCurrency(Ref ref) {
|
String _statsTargetCurrency(Ref ref) {
|
||||||
final index = ref.watch(activeAccountIndexProvider);
|
final index = ref.watch(activeAccountIndexProvider);
|
||||||
final accountsAsync = ref.watch(accountsProvider);
|
final accountsAsync = ref.watch(accountsProvider);
|
||||||
@@ -51,21 +69,56 @@ final statsCurrencyProvider = Provider<CurrencyInfo>((ref) {
|
|||||||
return _statsCurrencyInfo(ref);
|
return _statsCurrencyInfo(ref);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
final statsScopedTransactionsProvider = Provider<List<Transaction>>((ref) {
|
||||||
|
return _statsScopedTransactions(ref);
|
||||||
|
});
|
||||||
|
|
||||||
final statsIncomeTotalProvider = Provider<double>((ref) {
|
final statsIncomeTotalProvider = Provider<double>((ref) {
|
||||||
return _statsScopedTransactions(ref)
|
return ref
|
||||||
|
.watch(statsScopedTransactionsProvider)
|
||||||
.where((t) => t.type == TransactionType.income)
|
.where((t) => t.type == TransactionType.income)
|
||||||
.fold(0.0, (sum, t) => sum + _convertAmount(ref, t));
|
.fold(0.0, (sum, t) => sum + _convertAmount(ref, t));
|
||||||
});
|
});
|
||||||
|
|
||||||
final statsExpenseTotalProvider = Provider<double>((ref) {
|
final statsExpenseTotalProvider = Provider<double>((ref) {
|
||||||
return _statsScopedTransactions(ref)
|
return ref
|
||||||
|
.watch(statsScopedTransactionsProvider)
|
||||||
.where((t) => t.type == TransactionType.expense)
|
.where((t) => t.type == TransactionType.expense)
|
||||||
.fold(0.0, (sum, t) => sum + _convertAmount(ref, t));
|
.fold(0.0, (sum, t) => sum + _convertAmount(ref, t));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
final statsSummaryProvider = Provider<StatsSummary>((ref) {
|
||||||
|
final transactions = ref.watch(statsScopedTransactionsProvider);
|
||||||
|
var income = 0.0;
|
||||||
|
var expense = 0.0;
|
||||||
|
var incomeCount = 0;
|
||||||
|
var expenseCount = 0;
|
||||||
|
|
||||||
|
for (final transaction in transactions) {
|
||||||
|
final amount = _convertAmount(ref, transaction);
|
||||||
|
if (transaction.type == TransactionType.income) {
|
||||||
|
income += amount;
|
||||||
|
incomeCount++;
|
||||||
|
}
|
||||||
|
if (transaction.type == TransactionType.expense) {
|
||||||
|
expense += amount;
|
||||||
|
expenseCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return StatsSummary(
|
||||||
|
income: income,
|
||||||
|
expense: expense,
|
||||||
|
balance: income - expense,
|
||||||
|
transactionCount: transactions.length,
|
||||||
|
averageIncome: incomeCount == 0 ? 0 : income / incomeCount,
|
||||||
|
averageExpense: expenseCount == 0 ? 0 : expense / expenseCount,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
final categoryExpenseProvider = Provider<Map<String, double>>((ref) {
|
final categoryExpenseProvider = Provider<Map<String, double>>((ref) {
|
||||||
final map = <String, double>{};
|
final map = <String, double>{};
|
||||||
for (final t in _statsScopedTransactions(ref)) {
|
for (final t in ref.watch(statsScopedTransactionsProvider)) {
|
||||||
if (t.type != TransactionType.expense) continue;
|
if (t.type != TransactionType.expense) continue;
|
||||||
map[t.category] = (map[t.category] ?? 0) + _convertAmount(ref, t);
|
map[t.category] = (map[t.category] ?? 0) + _convertAmount(ref, t);
|
||||||
}
|
}
|
||||||
@@ -74,7 +127,7 @@ final categoryExpenseProvider = Provider<Map<String, double>>((ref) {
|
|||||||
|
|
||||||
final categoryIncomeProvider = Provider<Map<String, double>>((ref) {
|
final categoryIncomeProvider = Provider<Map<String, double>>((ref) {
|
||||||
final map = <String, double>{};
|
final map = <String, double>{};
|
||||||
for (final t in _statsScopedTransactions(ref)) {
|
for (final t in ref.watch(statsScopedTransactionsProvider)) {
|
||||||
if (t.type != TransactionType.income) continue;
|
if (t.type != TransactionType.income) continue;
|
||||||
map[t.category] = (map[t.category] ?? 0) + _convertAmount(ref, t);
|
map[t.category] = (map[t.category] ?? 0) + _convertAmount(ref, t);
|
||||||
}
|
}
|
||||||
|
|||||||
+811
-255
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user