Files
dahoud d094d6db9c Initial commit: unionflow-mobile-apps
Application Flutter complète (sans build artifacts).

Signed-off-by: lions dev Team
2026-03-15 16:30:08 +00:00

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,
];
}