Restructuration majeure du projet: migration de flutt vers app, ajout de l'API et mise à jour du site web

This commit is contained in:
d6soft
2025-05-16 09:19:03 +02:00
parent b5aafc424b
commit 5c2620de30
391 changed files with 19780 additions and 7233 deletions

View 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);
}
}
}