245 lines
5.3 KiB
Dart
245 lines
5.3 KiB
Dart
/// Entité métier Budget
|
|
///
|
|
/// Représente un budget prévisionnel (mensuel/annuel) avec suivi réalisé
|
|
library budget;
|
|
|
|
import 'package:equatable/equatable.dart';
|
|
|
|
/// Période du budget
|
|
enum BudgetPeriod {
|
|
/// Budget mensuel
|
|
monthly,
|
|
|
|
/// Budget trimestriel
|
|
quarterly,
|
|
|
|
/// Budget semestriel
|
|
semiannual,
|
|
|
|
/// Budget annuel
|
|
annual,
|
|
}
|
|
|
|
/// Statut du budget
|
|
enum BudgetStatus {
|
|
/// Brouillon (en cours de création)
|
|
draft,
|
|
|
|
/// Actif
|
|
active,
|
|
|
|
/// Clos (période terminée)
|
|
closed,
|
|
|
|
/// Annulé
|
|
cancelled,
|
|
}
|
|
|
|
/// Catégorie budgétaire
|
|
enum BudgetCategory {
|
|
/// Cotisations/contributions
|
|
contributions,
|
|
|
|
/// Épargne
|
|
savings,
|
|
|
|
/// Solidarité
|
|
solidarity,
|
|
|
|
/// Événements
|
|
events,
|
|
|
|
/// Fonctionnement (frais généraux)
|
|
operational,
|
|
|
|
/// Investissements
|
|
investments,
|
|
|
|
/// Autres
|
|
other,
|
|
}
|
|
|
|
/// Entité Budget
|
|
class Budget extends Equatable {
|
|
final String id;
|
|
final String name;
|
|
final String? description;
|
|
final String organizationId;
|
|
final BudgetPeriod period;
|
|
final int year;
|
|
final int? month;
|
|
final BudgetStatus status;
|
|
final List<BudgetLine> lines;
|
|
final double totalPlanned;
|
|
final double totalRealized;
|
|
final String currency;
|
|
final String createdBy;
|
|
final DateTime createdAt;
|
|
final DateTime? approvedAt;
|
|
final String? approvedBy;
|
|
final DateTime startDate;
|
|
final DateTime endDate;
|
|
final Map<String, dynamic>? metadata;
|
|
|
|
const Budget({
|
|
required this.id,
|
|
required this.name,
|
|
this.description,
|
|
required this.organizationId,
|
|
required this.period,
|
|
required this.year,
|
|
this.month,
|
|
required this.status,
|
|
this.lines = const [],
|
|
required this.totalPlanned,
|
|
this.totalRealized = 0,
|
|
this.currency = 'XOF',
|
|
required this.createdBy,
|
|
required this.createdAt,
|
|
this.approvedAt,
|
|
this.approvedBy,
|
|
required this.startDate,
|
|
required this.endDate,
|
|
this.metadata,
|
|
});
|
|
|
|
/// Taux de réalisation (%)
|
|
double get realizationRate {
|
|
if (totalPlanned == 0) return 0;
|
|
return (totalRealized / totalPlanned) * 100;
|
|
}
|
|
|
|
/// Écart (réalisé - prévu)
|
|
double get variance => totalRealized - totalPlanned;
|
|
|
|
/// Taux d'écart (%)
|
|
double get varianceRate {
|
|
if (totalPlanned == 0) return 0;
|
|
return (variance / totalPlanned) * 100;
|
|
}
|
|
|
|
/// Vérifie si le budget est dépassé
|
|
bool get isOverBudget => totalRealized > totalPlanned;
|
|
|
|
/// Vérifie si le budget est actif
|
|
bool get isActive => status == BudgetStatus.active;
|
|
|
|
/// Vérifie si la période est en cours
|
|
bool get isCurrentPeriod {
|
|
final now = DateTime.now();
|
|
return now.isAfter(startDate) && now.isBefore(endDate);
|
|
}
|
|
|
|
/// Copie avec modifications
|
|
Budget copyWith({
|
|
String? id,
|
|
String? name,
|
|
String? description,
|
|
String? organizationId,
|
|
BudgetPeriod? period,
|
|
int? year,
|
|
int? month,
|
|
BudgetStatus? status,
|
|
List<BudgetLine>? lines,
|
|
double? totalPlanned,
|
|
double? totalRealized,
|
|
String? currency,
|
|
String? createdBy,
|
|
DateTime? createdAt,
|
|
DateTime? approvedAt,
|
|
String? approvedBy,
|
|
DateTime? startDate,
|
|
DateTime? endDate,
|
|
Map<String, dynamic>? metadata,
|
|
}) {
|
|
return Budget(
|
|
id: id ?? this.id,
|
|
name: name ?? this.name,
|
|
description: description ?? this.description,
|
|
organizationId: organizationId ?? this.organizationId,
|
|
period: period ?? this.period,
|
|
year: year ?? this.year,
|
|
month: month ?? this.month,
|
|
status: status ?? this.status,
|
|
lines: lines ?? this.lines,
|
|
totalPlanned: totalPlanned ?? this.totalPlanned,
|
|
totalRealized: totalRealized ?? this.totalRealized,
|
|
currency: currency ?? this.currency,
|
|
createdBy: createdBy ?? this.createdBy,
|
|
createdAt: createdAt ?? this.createdAt,
|
|
approvedAt: approvedAt ?? this.approvedAt,
|
|
approvedBy: approvedBy ?? this.approvedBy,
|
|
startDate: startDate ?? this.startDate,
|
|
endDate: endDate ?? this.endDate,
|
|
metadata: metadata ?? this.metadata,
|
|
);
|
|
}
|
|
|
|
@override
|
|
List<Object?> get props => [
|
|
id,
|
|
name,
|
|
description,
|
|
organizationId,
|
|
period,
|
|
year,
|
|
month,
|
|
status,
|
|
lines,
|
|
totalPlanned,
|
|
totalRealized,
|
|
currency,
|
|
createdBy,
|
|
createdAt,
|
|
approvedAt,
|
|
approvedBy,
|
|
startDate,
|
|
endDate,
|
|
metadata,
|
|
];
|
|
}
|
|
|
|
/// Ligne budgétaire
|
|
class BudgetLine extends Equatable {
|
|
final String id;
|
|
final BudgetCategory category;
|
|
final String name;
|
|
final String? description;
|
|
final double amountPlanned;
|
|
final double amountRealized;
|
|
final String? notes;
|
|
|
|
const BudgetLine({
|
|
required this.id,
|
|
required this.category,
|
|
required this.name,
|
|
this.description,
|
|
required this.amountPlanned,
|
|
this.amountRealized = 0,
|
|
this.notes,
|
|
});
|
|
|
|
/// Taux de réalisation (%)
|
|
double get realizationRate {
|
|
if (amountPlanned == 0) return 0;
|
|
return (amountRealized / amountPlanned) * 100;
|
|
}
|
|
|
|
/// Écart
|
|
double get variance => amountRealized - amountPlanned;
|
|
|
|
/// Vérifie si la ligne est dépassée
|
|
bool get isOverBudget => amountRealized > amountPlanned;
|
|
|
|
@override
|
|
List<Object?> get props => [
|
|
id,
|
|
category,
|
|
name,
|
|
description,
|
|
amountPlanned,
|
|
amountRealized,
|
|
notes,
|
|
];
|
|
}
|