Restructuration majeure du projet: migration de flutt vers app, ajout de l'API et mise à jour du site web
This commit is contained in:
214
app/lib/presentation/widgets/charts/passage_utils.dart
Normal file
214
app/lib/presentation/widgets/charts/passage_utils.dart
Normal file
@@ -0,0 +1,214 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:geosector_app/core/constants/app_keys.dart';
|
||||
import 'package:geosector_app/presentation/widgets/charts/passage_data.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
/// Utilitaires pour les passages et règlements
|
||||
class PassageUtils {
|
||||
/// Convertit les données de passage brutes en liste de PassageData
|
||||
///
|
||||
/// [passageData] est une liste d'objets contenant date, type_passage et nb
|
||||
static List<List<PassageData>> getPassageDataByType(
|
||||
List<Map<String, dynamic>> passageData) {
|
||||
// Créer un Map pour stocker les données par type de passage
|
||||
final Map<int, List<PassageData>> passagesByType = {};
|
||||
|
||||
// Initialiser les listes pour chaque type de passage
|
||||
for (final entry in AppKeys.typesPassages.entries) {
|
||||
passagesByType[entry.key] = [];
|
||||
}
|
||||
|
||||
// Grouper les passages par type
|
||||
for (final data in passageData) {
|
||||
final int typeId = data['type_passage'];
|
||||
final int count = data['nb'];
|
||||
|
||||
if (AppKeys.typesPassages.containsKey(typeId)) {
|
||||
final typeData = AppKeys.typesPassages[typeId]!;
|
||||
final Color color = Color(typeData['couleur1'] as int);
|
||||
final String iconPath = typeData['icone'] as String;
|
||||
final String title = typeData['titre'] as String;
|
||||
|
||||
// Utiliser la méthode factory qui gère les dates au format ISO 8601
|
||||
if (data['date'] is String) {
|
||||
passagesByType[typeId]!.add(
|
||||
PassageData.fromIsoDate(
|
||||
isoDate: data['date'],
|
||||
typeId: typeId,
|
||||
count: count,
|
||||
color: color,
|
||||
iconPath: iconPath,
|
||||
title: title,
|
||||
),
|
||||
);
|
||||
} else {
|
||||
// Fallback pour les objets DateTime (pour compatibilité)
|
||||
final DateTime date = data['date'] as DateTime;
|
||||
passagesByType[typeId]!.add(
|
||||
PassageData(
|
||||
date: date,
|
||||
typeId: typeId,
|
||||
count: count,
|
||||
color: color,
|
||||
iconPath: iconPath,
|
||||
title: title,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Convertir le Map en liste de listes
|
||||
return passagesByType.values.toList();
|
||||
}
|
||||
|
||||
/// Convertit les données de règlement brutes en liste de PaymentAmountData
|
||||
///
|
||||
/// [paymentData] est une liste d'objets contenant date, type_reglement et montant
|
||||
static List<List<PaymentAmountData>> getPaymentDataByType(
|
||||
List<Map<String, dynamic>> paymentData) {
|
||||
// Créer un Map pour stocker les données par type de règlement
|
||||
final Map<int, List<PaymentAmountData>> paymentsByType = {};
|
||||
|
||||
// Initialiser les listes pour chaque type de règlement (sauf 0 qui est "Pas de règlement")
|
||||
for (final entry in AppKeys.typesReglements.entries) {
|
||||
if (entry.key > 0) {
|
||||
// Ignorer le type 0 (Pas de règlement)
|
||||
paymentsByType[entry.key] = [];
|
||||
}
|
||||
}
|
||||
|
||||
// Grouper les règlements par type
|
||||
for (final data in paymentData) {
|
||||
final int typeId = data['type_reglement'];
|
||||
final double amount = data['montant'] is double
|
||||
? data['montant']
|
||||
: double.parse(data['montant'].toString());
|
||||
|
||||
if (typeId > 0 && AppKeys.typesReglements.containsKey(typeId)) {
|
||||
final typeData = AppKeys.typesReglements[typeId]!;
|
||||
final Color color = Color(typeData['couleur'] as int);
|
||||
final dynamic iconData = _getIconForPaymentType(typeId);
|
||||
final String title = typeData['titre'] as String;
|
||||
|
||||
// Utiliser la méthode factory qui gère les dates au format ISO 8601
|
||||
if (data['date'] is String) {
|
||||
paymentsByType[typeId]!.add(
|
||||
PaymentAmountData.fromIsoDate(
|
||||
isoDate: data['date'],
|
||||
typeId: typeId,
|
||||
amount: amount,
|
||||
color: color,
|
||||
iconData: iconData,
|
||||
title: title,
|
||||
),
|
||||
);
|
||||
} else {
|
||||
// Fallback pour les objets DateTime (pour compatibilité)
|
||||
final DateTime date = data['date'] as DateTime;
|
||||
paymentsByType[typeId]!.add(
|
||||
PaymentAmountData(
|
||||
date: date,
|
||||
typeId: typeId,
|
||||
amount: amount,
|
||||
color: color,
|
||||
iconData: iconData,
|
||||
title: title,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Convertir le Map en liste de listes
|
||||
return paymentsByType.values.toList();
|
||||
}
|
||||
|
||||
/// Génère des données de passage fictives pour les 14 derniers jours
|
||||
static List<Map<String, dynamic>> generateMockPassageData() {
|
||||
final List<Map<String, dynamic>> mockData = [];
|
||||
final now = DateTime.now();
|
||||
|
||||
for (int i = 13; i >= 0; i--) {
|
||||
final date = now.subtract(Duration(days: i));
|
||||
|
||||
// Ajouter des données pour chaque type de passage
|
||||
for (int typeId = 1; typeId <= 6; typeId++) {
|
||||
// Générer un nombre aléatoire de passages entre 0 et 5
|
||||
final count = (typeId == 1 || typeId == 2)
|
||||
? (1 + (date.day % 5)) // Plus de passages pour les types 1 et 2
|
||||
: (date.day % 3); // Moins pour les autres types
|
||||
|
||||
if (count > 0) {
|
||||
mockData.add({
|
||||
'date': date,
|
||||
'type_passage': typeId,
|
||||
'nb': count,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return mockData;
|
||||
}
|
||||
|
||||
/// Génère des données de règlement fictives pour les 14 derniers jours
|
||||
static List<Map<String, dynamic>> generateMockPaymentData() {
|
||||
final List<Map<String, dynamic>> mockData = [];
|
||||
final now = DateTime.now();
|
||||
|
||||
for (int i = 13; i >= 0; i--) {
|
||||
final date = now.subtract(Duration(days: i));
|
||||
|
||||
// Ajouter des données pour chaque type de règlement
|
||||
for (int typeId = 1; typeId <= 3; typeId++) {
|
||||
// Générer un montant aléatoire
|
||||
final amount = (typeId * 100.0) + (date.day * 10.0);
|
||||
|
||||
mockData.add({
|
||||
'date': date,
|
||||
'type_reglement': typeId,
|
||||
'montant': amount,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return mockData;
|
||||
}
|
||||
|
||||
/// Obtenir l'icône correspondant au type de règlement
|
||||
/// Retourne un IconData pour les règlements car ils n'ont pas de chemin d'icône défini dans AppKeys
|
||||
static IconData _getIconForPaymentType(int typeId) {
|
||||
switch (typeId) {
|
||||
case 1: // Espèces
|
||||
return Icons.payments;
|
||||
case 2: // Chèque
|
||||
return Icons.money;
|
||||
case 3: // CB
|
||||
return Icons.credit_card;
|
||||
default:
|
||||
return Icons.euro;
|
||||
}
|
||||
}
|
||||
|
||||
/// Formater une date pour l'affichage dans les graphiques
|
||||
static String formatDateForChart(DateTime date, String periodType) {
|
||||
switch (periodType.toLowerCase()) {
|
||||
case 'jour':
|
||||
return DateFormat('dd/MM').format(date);
|
||||
case 'semaine':
|
||||
// Calculer le numéro de la semaine dans l'année
|
||||
final firstDayOfYear = DateTime(date.year, 1, 1);
|
||||
final dayOfYear = date.difference(firstDayOfYear).inDays;
|
||||
final weekNumber =
|
||||
((dayOfYear + firstDayOfYear.weekday - 1) / 7).ceil();
|
||||
return 'S$weekNumber';
|
||||
case 'mois':
|
||||
return DateFormat('MMM').format(date);
|
||||
case 'année':
|
||||
return DateFormat('yyyy').format(date);
|
||||
default:
|
||||
return DateFormat('dd/MM').format(date);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user