215 lines
7.1 KiB
Dart
215 lines
7.1 KiB
Dart
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);
|
|
}
|
|
}
|
|
}
|