Initial upload: fin65-mobile
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
class Account {
|
||||
final int id;
|
||||
final String name;
|
||||
final String type;
|
||||
final String currency;
|
||||
final double initialBalance;
|
||||
final double appBalance;
|
||||
final bool isActive;
|
||||
|
||||
Account({
|
||||
required this.id,
|
||||
required this.name,
|
||||
required this.type,
|
||||
required this.currency,
|
||||
required this.initialBalance,
|
||||
required this.appBalance,
|
||||
required this.isActive,
|
||||
});
|
||||
|
||||
factory Account.fromJson(Map<String, dynamic> json) {
|
||||
return Account(
|
||||
id: json['id'] as int,
|
||||
name: json['name'] as String,
|
||||
type: json['type'] as String,
|
||||
currency: json['currency'] as String? ?? 'MAD',
|
||||
initialBalance: (json['initial_balance'] as num? ?? 0).toDouble(),
|
||||
appBalance: (json['app_balance'] as num? ?? 0).toDouble(),
|
||||
isActive: json['is_active'] is int
|
||||
? (json['is_active'] as int) == 1
|
||||
: json['is_active'] as bool? ?? true,
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'id': id,
|
||||
'name': name,
|
||||
'type': type,
|
||||
'currency': currency,
|
||||
'initial_balance': initialBalance,
|
||||
'app_balance': appBalance,
|
||||
'is_active': isActive,
|
||||
};
|
||||
}
|
||||
|
||||
Map<String, dynamic> toDbMap() {
|
||||
return {
|
||||
'id': id,
|
||||
'name': name,
|
||||
'type': type,
|
||||
'currency': currency,
|
||||
'initial_balance': initialBalance,
|
||||
'app_balance': appBalance,
|
||||
'is_active': isActive ? 1 : 0,
|
||||
'updated_at': DateTime.now().toIso8601String(),
|
||||
};
|
||||
}
|
||||
|
||||
factory Account.fromDbMap(Map<String, dynamic> map) {
|
||||
return Account(
|
||||
id: map['id'] as int,
|
||||
name: map['name'] as String,
|
||||
type: map['type'] as String,
|
||||
currency: map['currency'] as String? ?? 'MAD',
|
||||
initialBalance: (map['initial_balance'] as num? ?? 0).toDouble(),
|
||||
appBalance: (map['app_balance'] as num? ?? 0).toDouble(),
|
||||
isActive: (map['is_active'] as int? ?? 1) == 1,
|
||||
);
|
||||
}
|
||||
|
||||
Account copyWith({
|
||||
int? id,
|
||||
String? name,
|
||||
String? type,
|
||||
String? currency,
|
||||
double? initialBalance,
|
||||
double? appBalance,
|
||||
bool? isActive,
|
||||
}) {
|
||||
return Account(
|
||||
id: id ?? this.id,
|
||||
name: name ?? this.name,
|
||||
type: type ?? this.type,
|
||||
currency: currency ?? this.currency,
|
||||
initialBalance: initialBalance ?? this.initialBalance,
|
||||
appBalance: appBalance ?? this.appBalance,
|
||||
isActive: isActive ?? this.isActive,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
class Category {
|
||||
final int id;
|
||||
final String name;
|
||||
final String type;
|
||||
final int? parentId;
|
||||
|
||||
Category({
|
||||
required this.id,
|
||||
required this.name,
|
||||
required this.type,
|
||||
this.parentId,
|
||||
});
|
||||
|
||||
factory Category.fromJson(Map<String, dynamic> json) {
|
||||
return Category(
|
||||
id: json['id'] as int,
|
||||
name: json['name'] as String,
|
||||
type: json['type'] as String,
|
||||
parentId: json['parent_id'] as int?,
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'id': id,
|
||||
'name': name,
|
||||
'type': type,
|
||||
'parent_id': parentId,
|
||||
};
|
||||
}
|
||||
|
||||
Map<String, dynamic> toDbMap() {
|
||||
return {
|
||||
'id': id,
|
||||
'name': name,
|
||||
'type': type,
|
||||
'parent_id': parentId,
|
||||
'updated_at': DateTime.now().toIso8601String(),
|
||||
};
|
||||
}
|
||||
|
||||
factory Category.fromDbMap(Map<String, dynamic> map) {
|
||||
return Category(
|
||||
id: map['id'] as int,
|
||||
name: map['name'] as String,
|
||||
type: map['type'] as String,
|
||||
parentId: map['parent_id'] as int?,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,223 @@
|
||||
import 'account.dart';
|
||||
|
||||
class ReconciliationStatus {
|
||||
final int accountId;
|
||||
final String accountName;
|
||||
final double appBalance;
|
||||
final bool checkedToday;
|
||||
final double? realBalance;
|
||||
final double? difference;
|
||||
|
||||
ReconciliationStatus({
|
||||
required this.accountId,
|
||||
required this.accountName,
|
||||
required this.appBalance,
|
||||
required this.checkedToday,
|
||||
this.realBalance,
|
||||
this.difference,
|
||||
});
|
||||
|
||||
factory ReconciliationStatus.fromJson(Map<String, dynamic> json) {
|
||||
return ReconciliationStatus(
|
||||
accountId: json['account_id'] as int,
|
||||
accountName: json['account_name'] as String,
|
||||
appBalance: (json['app_balance'] as num? ?? 0).toDouble(),
|
||||
checkedToday: json['checked_today'] is int
|
||||
? (json['checked_today'] as int) == 1
|
||||
: json['checked_today'] as bool? ?? false,
|
||||
realBalance: (json['real_balance'] as num?)?.toDouble(),
|
||||
difference: (json['difference'] as num?)?.toDouble(),
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'account_id': accountId,
|
||||
'account_name': accountName,
|
||||
'app_balance': appBalance,
|
||||
'checked_today': checkedToday,
|
||||
'real_balance': realBalance,
|
||||
'difference': difference,
|
||||
};
|
||||
}
|
||||
|
||||
ReconciliationStatus copyWith({
|
||||
double? appBalance,
|
||||
bool? checkedToday,
|
||||
double? realBalance,
|
||||
double? difference,
|
||||
}) {
|
||||
return ReconciliationStatus(
|
||||
accountId: accountId,
|
||||
accountName: accountName,
|
||||
appBalance: appBalance ?? this.appBalance,
|
||||
checkedToday: checkedToday ?? this.checkedToday,
|
||||
realBalance: realBalance ?? this.realBalance,
|
||||
difference: difference ?? this.difference,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class DashboardData {
|
||||
final String month;
|
||||
final double totalBalance;
|
||||
final double availableAfterReserves;
|
||||
final double monthlyIncome;
|
||||
final double monthlyExpenses;
|
||||
final double monthlyBalance;
|
||||
final double provisionsCurrentTotal;
|
||||
final double provisionsTargetTotal;
|
||||
final double monthlyChargesRemainingTotal;
|
||||
final double monthlyTransferRemainingTotal;
|
||||
final double monthlyProvisionOperationRemainingTotal;
|
||||
|
||||
// Nouveaux champs backend : échéancier / opérations prévues ponctuelles.
|
||||
final double scheduledExpensesRemainingTotal;
|
||||
final double scheduledIncomeRemainingTotal;
|
||||
final double scheduledTransferRemainingTotal;
|
||||
final double scheduledProvisionRemainingTotal;
|
||||
final double scheduledNetRemainingTotal;
|
||||
final double projectedMonthBalance;
|
||||
|
||||
final List<Account> accounts;
|
||||
final List<ReconciliationStatus> reconciliationsToday;
|
||||
|
||||
DashboardData({
|
||||
required this.month,
|
||||
required this.totalBalance,
|
||||
required this.availableAfterReserves,
|
||||
required this.monthlyIncome,
|
||||
required this.monthlyExpenses,
|
||||
required this.monthlyBalance,
|
||||
required this.provisionsCurrentTotal,
|
||||
required this.provisionsTargetTotal,
|
||||
required this.monthlyChargesRemainingTotal,
|
||||
required this.monthlyTransferRemainingTotal,
|
||||
required this.monthlyProvisionOperationRemainingTotal,
|
||||
required this.scheduledExpensesRemainingTotal,
|
||||
required this.scheduledIncomeRemainingTotal,
|
||||
required this.scheduledTransferRemainingTotal,
|
||||
required this.scheduledProvisionRemainingTotal,
|
||||
required this.scheduledNetRemainingTotal,
|
||||
required this.projectedMonthBalance,
|
||||
required this.accounts,
|
||||
required this.reconciliationsToday,
|
||||
});
|
||||
|
||||
double get plannedExpensesTotal =>
|
||||
monthlyChargesRemainingTotal + scheduledExpensesRemainingTotal;
|
||||
|
||||
double get plannedTransfersTotal =>
|
||||
monthlyTransferRemainingTotal + scheduledTransferRemainingTotal;
|
||||
|
||||
double get plannedProvisionsTotal =>
|
||||
monthlyProvisionOperationRemainingTotal + scheduledProvisionRemainingTotal;
|
||||
|
||||
bool get hasScheduledInfo =>
|
||||
scheduledExpensesRemainingTotal != 0 ||
|
||||
scheduledIncomeRemainingTotal != 0 ||
|
||||
scheduledTransferRemainingTotal != 0 ||
|
||||
scheduledProvisionRemainingTotal != 0;
|
||||
|
||||
factory DashboardData.fromJson(Map<String, dynamic> json) {
|
||||
final availableRaw = json['available_after_reserves'] ?? json['total_balance'] ?? 0;
|
||||
|
||||
final monthlyBalance = (json['monthly_balance'] as num? ?? 0).toDouble();
|
||||
final scheduledIncome = (json['scheduled_income_remaining_total'] as num? ?? 0).toDouble();
|
||||
final scheduledExpenses = (json['scheduled_expenses_remaining_total'] as num? ?? 0).toDouble();
|
||||
|
||||
return DashboardData(
|
||||
month: json['month'] as String? ?? '',
|
||||
totalBalance: (json['total_balance'] as num? ?? 0).toDouble(),
|
||||
availableAfterReserves: (availableRaw as num).toDouble(),
|
||||
monthlyIncome: (json['monthly_income'] as num? ?? 0).toDouble(),
|
||||
monthlyExpenses: (json['monthly_expenses'] as num? ?? 0).toDouble(),
|
||||
monthlyBalance: monthlyBalance,
|
||||
provisionsCurrentTotal: (json['provisions_current_total'] as num? ?? 0).toDouble(),
|
||||
provisionsTargetTotal: (json['provisions_target_total'] as num? ?? 0).toDouble(),
|
||||
monthlyChargesRemainingTotal: (json['monthly_charges_remaining_total'] as num? ?? 0).toDouble(),
|
||||
monthlyTransferRemainingTotal: (json['monthly_transfer_remaining_total'] as num? ?? 0).toDouble(),
|
||||
monthlyProvisionOperationRemainingTotal: (json['monthly_provision_operation_remaining_total'] as num? ?? 0).toDouble(),
|
||||
scheduledExpensesRemainingTotal: scheduledExpenses,
|
||||
scheduledIncomeRemainingTotal: scheduledIncome,
|
||||
scheduledTransferRemainingTotal: (json['scheduled_transfer_remaining_total'] as num? ?? 0).toDouble(),
|
||||
scheduledProvisionRemainingTotal: (json['scheduled_provision_remaining_total'] as num? ?? 0).toDouble(),
|
||||
scheduledNetRemainingTotal: (json['scheduled_net_remaining_total'] as num? ?? (scheduledIncome - scheduledExpenses)).toDouble(),
|
||||
projectedMonthBalance: (json['projected_month_balance'] as num? ?? (monthlyBalance + scheduledIncome - scheduledExpenses)).toDouble(),
|
||||
accounts: (json['accounts'] as List<dynamic>? ?? [])
|
||||
.map((e) => Account.fromJson(e as Map<String, dynamic>))
|
||||
.toList(),
|
||||
reconciliationsToday: (json['reconciliations_today'] as List<dynamic>? ?? [])
|
||||
.map((e) => ReconciliationStatus.fromJson(e as Map<String, dynamic>))
|
||||
.toList(),
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'month': month,
|
||||
'total_balance': totalBalance,
|
||||
'available_after_reserves': availableAfterReserves,
|
||||
'monthly_income': monthlyIncome,
|
||||
'monthly_expenses': monthlyExpenses,
|
||||
'monthly_balance': monthlyBalance,
|
||||
'provisions_current_total': provisionsCurrentTotal,
|
||||
'provisions_target_total': provisionsTargetTotal,
|
||||
'monthly_charges_remaining_total': monthlyChargesRemainingTotal,
|
||||
'monthly_transfer_remaining_total': monthlyTransferRemainingTotal,
|
||||
'monthly_provision_operation_remaining_total': monthlyProvisionOperationRemainingTotal,
|
||||
'scheduled_expenses_remaining_total': scheduledExpensesRemainingTotal,
|
||||
'scheduled_income_remaining_total': scheduledIncomeRemainingTotal,
|
||||
'scheduled_transfer_remaining_total': scheduledTransferRemainingTotal,
|
||||
'scheduled_provision_remaining_total': scheduledProvisionRemainingTotal,
|
||||
'scheduled_net_remaining_total': scheduledNetRemainingTotal,
|
||||
'projected_month_balance': projectedMonthBalance,
|
||||
'accounts': accounts.map((e) => e.toJson()).toList(),
|
||||
'reconciliations_today': reconciliationsToday.map((e) => e.toJson()).toList(),
|
||||
};
|
||||
}
|
||||
|
||||
DashboardData copyWith({
|
||||
String? month,
|
||||
double? totalBalance,
|
||||
double? availableAfterReserves,
|
||||
double? monthlyIncome,
|
||||
double? monthlyExpenses,
|
||||
double? monthlyBalance,
|
||||
double? provisionsCurrentTotal,
|
||||
double? provisionsTargetTotal,
|
||||
double? monthlyChargesRemainingTotal,
|
||||
double? monthlyTransferRemainingTotal,
|
||||
double? monthlyProvisionOperationRemainingTotal,
|
||||
double? scheduledExpensesRemainingTotal,
|
||||
double? scheduledIncomeRemainingTotal,
|
||||
double? scheduledTransferRemainingTotal,
|
||||
double? scheduledProvisionRemainingTotal,
|
||||
double? scheduledNetRemainingTotal,
|
||||
double? projectedMonthBalance,
|
||||
List<Account>? accounts,
|
||||
List<ReconciliationStatus>? reconciliationsToday,
|
||||
}) {
|
||||
return DashboardData(
|
||||
month: month ?? this.month,
|
||||
totalBalance: totalBalance ?? this.totalBalance,
|
||||
availableAfterReserves: availableAfterReserves ?? this.availableAfterReserves,
|
||||
monthlyIncome: monthlyIncome ?? this.monthlyIncome,
|
||||
monthlyExpenses: monthlyExpenses ?? this.monthlyExpenses,
|
||||
monthlyBalance: monthlyBalance ?? this.monthlyBalance,
|
||||
provisionsCurrentTotal: provisionsCurrentTotal ?? this.provisionsCurrentTotal,
|
||||
provisionsTargetTotal: provisionsTargetTotal ?? this.provisionsTargetTotal,
|
||||
monthlyChargesRemainingTotal: monthlyChargesRemainingTotal ?? this.monthlyChargesRemainingTotal,
|
||||
monthlyTransferRemainingTotal: monthlyTransferRemainingTotal ?? this.monthlyTransferRemainingTotal,
|
||||
monthlyProvisionOperationRemainingTotal: monthlyProvisionOperationRemainingTotal ?? this.monthlyProvisionOperationRemainingTotal,
|
||||
scheduledExpensesRemainingTotal: scheduledExpensesRemainingTotal ?? this.scheduledExpensesRemainingTotal,
|
||||
scheduledIncomeRemainingTotal: scheduledIncomeRemainingTotal ?? this.scheduledIncomeRemainingTotal,
|
||||
scheduledTransferRemainingTotal: scheduledTransferRemainingTotal ?? this.scheduledTransferRemainingTotal,
|
||||
scheduledProvisionRemainingTotal: scheduledProvisionRemainingTotal ?? this.scheduledProvisionRemainingTotal,
|
||||
scheduledNetRemainingTotal: scheduledNetRemainingTotal ?? this.scheduledNetRemainingTotal,
|
||||
projectedMonthBalance: projectedMonthBalance ?? this.projectedMonthBalance,
|
||||
accounts: accounts ?? this.accounts,
|
||||
reconciliationsToday: reconciliationsToday ?? this.reconciliationsToday,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
import 'dart:convert';
|
||||
|
||||
class PendingOperation {
|
||||
final int id;
|
||||
final String operationType;
|
||||
final Map<String, dynamic> payload;
|
||||
final DateTime createdAt;
|
||||
final String status;
|
||||
final String? error;
|
||||
|
||||
PendingOperation({
|
||||
required this.id,
|
||||
required this.operationType,
|
||||
required this.payload,
|
||||
required this.createdAt,
|
||||
required this.status,
|
||||
this.error,
|
||||
});
|
||||
|
||||
factory PendingOperation.fromDbMap(Map<String, dynamic> map) {
|
||||
return PendingOperation(
|
||||
id: map['id'] as int,
|
||||
operationType: map['operation_type'] as String,
|
||||
payload: jsonDecode(map['payload_json'] as String) as Map<String, dynamic>,
|
||||
createdAt: DateTime.parse(map['created_at'] as String),
|
||||
status: map['status'] as String? ?? 'pending',
|
||||
error: map['error'] as String?,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
class TransactionItem {
|
||||
final int id;
|
||||
final String label;
|
||||
final double amount;
|
||||
final String type;
|
||||
final int accountId;
|
||||
final int? targetAccountId;
|
||||
final int? categoryId;
|
||||
final int? provisionId;
|
||||
final DateTime date;
|
||||
final String? note;
|
||||
final bool isPending;
|
||||
final int? localOperationId;
|
||||
|
||||
TransactionItem({
|
||||
required this.id,
|
||||
required this.label,
|
||||
required this.amount,
|
||||
required this.type,
|
||||
required this.accountId,
|
||||
required this.date,
|
||||
this.targetAccountId,
|
||||
this.categoryId,
|
||||
this.provisionId,
|
||||
this.note,
|
||||
this.isPending = false,
|
||||
this.localOperationId,
|
||||
});
|
||||
|
||||
factory TransactionItem.fromJson(Map<String, dynamic> json) {
|
||||
return TransactionItem(
|
||||
id: json['id'] as int,
|
||||
label: json['label'] as String,
|
||||
amount: (json['amount'] as num? ?? 0).toDouble(),
|
||||
type: json['type'] as String,
|
||||
accountId: json['account_id'] as int,
|
||||
targetAccountId: json['target_account_id'] as int?,
|
||||
categoryId: json['category_id'] as int?,
|
||||
provisionId: json['provision_id'] as int?,
|
||||
date: DateTime.parse(json['date'] as String),
|
||||
note: json['note'] as String?,
|
||||
isPending: json['is_pending'] is int
|
||||
? (json['is_pending'] as int) == 1
|
||||
: json['is_pending'] as bool? ?? false,
|
||||
localOperationId: json['local_operation_id'] as int?,
|
||||
);
|
||||
}
|
||||
|
||||
factory TransactionItem.fromPending({
|
||||
required int localOperationId,
|
||||
required Map<String, dynamic> payload,
|
||||
}) {
|
||||
return TransactionItem(
|
||||
id: -localOperationId,
|
||||
label: payload['label'] as String? ?? 'Opération mobile',
|
||||
amount: (payload['amount'] as num? ?? 0).toDouble(),
|
||||
type: payload['type'] as String? ?? 'expense',
|
||||
accountId: payload['account_id'] as int,
|
||||
targetAccountId: payload['target_account_id'] as int?,
|
||||
categoryId: payload['category_id'] as int?,
|
||||
provisionId: payload['provision_id'] as int?,
|
||||
date: DateTime.tryParse(payload['date'] as String? ?? '') ?? DateTime.now(),
|
||||
note: payload['note'] as String?,
|
||||
isPending: true,
|
||||
localOperationId: localOperationId,
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'id': id,
|
||||
'label': label,
|
||||
'amount': amount,
|
||||
'type': type,
|
||||
'account_id': accountId,
|
||||
'target_account_id': targetAccountId,
|
||||
'category_id': categoryId,
|
||||
'provision_id': provisionId,
|
||||
'date': date.toIso8601String(),
|
||||
'note': note,
|
||||
'is_pending': isPending,
|
||||
'local_operation_id': localOperationId,
|
||||
};
|
||||
}
|
||||
|
||||
Map<String, dynamic> toDbMap() {
|
||||
return {
|
||||
'id': id,
|
||||
'label': label,
|
||||
'amount': amount,
|
||||
'type': type,
|
||||
'account_id': accountId,
|
||||
'target_account_id': targetAccountId,
|
||||
'category_id': categoryId,
|
||||
'provision_id': provisionId,
|
||||
'date': date.toIso8601String(),
|
||||
'note': note,
|
||||
'is_pending': isPending ? 1 : 0,
|
||||
'local_operation_id': localOperationId,
|
||||
'updated_at': DateTime.now().toIso8601String(),
|
||||
};
|
||||
}
|
||||
|
||||
factory TransactionItem.fromDbMap(Map<String, dynamic> map) {
|
||||
return TransactionItem(
|
||||
id: map['id'] as int,
|
||||
label: map['label'] as String,
|
||||
amount: (map['amount'] as num? ?? 0).toDouble(),
|
||||
type: map['type'] as String,
|
||||
accountId: map['account_id'] as int,
|
||||
targetAccountId: map['target_account_id'] as int?,
|
||||
categoryId: map['category_id'] as int?,
|
||||
provisionId: map['provision_id'] as int?,
|
||||
date: DateTime.parse(map['date'] as String),
|
||||
note: map['note'] as String?,
|
||||
isPending: (map['is_pending'] as int? ?? 0) == 1,
|
||||
localOperationId: map['local_operation_id'] as int?,
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user