feat: merge branche IA (beta) - Intégration assistant IA logisticien Gemini
This commit is contained in:
@@ -553,6 +553,156 @@ class DataService {
|
||||
}
|
||||
}
|
||||
|
||||
/// Recherche des équipements pour l'assistant IA avec fallback paginé.
|
||||
Future<List<Map<String, dynamic>>> searchEquipmentsForAssistant({
|
||||
required String query,
|
||||
int limit = 12,
|
||||
}) async {
|
||||
final normalizedQuery = query.trim();
|
||||
if (normalizedQuery.isEmpty) {
|
||||
return [];
|
||||
}
|
||||
|
||||
try {
|
||||
final quickResults = await quickSearch(
|
||||
normalizedQuery,
|
||||
limit: limit,
|
||||
includeEquipments: true,
|
||||
includeContainers: false,
|
||||
);
|
||||
|
||||
final equipmentResults = quickResults
|
||||
.where((item) =>
|
||||
(item['type']?.toString().toLowerCase() ?? '') == 'equipment')
|
||||
.map(_normalizeAssistantEquipment)
|
||||
.toList();
|
||||
|
||||
if (equipmentResults.isNotEmpty) {
|
||||
return equipmentResults;
|
||||
}
|
||||
|
||||
final paginated = await getEquipmentsPaginated(
|
||||
limit: limit,
|
||||
searchQuery: normalizedQuery,
|
||||
sortBy: 'id',
|
||||
sortOrder: 'asc',
|
||||
);
|
||||
|
||||
final equipments =
|
||||
paginated['equipments'] as List<Map<String, dynamic>>? ?? [];
|
||||
return equipments.map(_normalizeAssistantEquipment).toList();
|
||||
} catch (e) {
|
||||
DebugLog.error('[DataService] Error in searchEquipmentsForAssistant', e);
|
||||
throw Exception('Erreur lors de la recherche de matériel: $e');
|
||||
}
|
||||
}
|
||||
|
||||
/// Vérifie la disponibilité d'un équipement dans un format normalisé pour l'IA.
|
||||
Future<Map<String, dynamic>> checkEquipmentAvailabilityForAssistant({
|
||||
required String equipmentId,
|
||||
required DateTime startDate,
|
||||
required DateTime endDate,
|
||||
String? excludeEventId,
|
||||
}) async {
|
||||
try {
|
||||
final result = await checkEquipmentAvailability(
|
||||
equipmentId: equipmentId,
|
||||
startDate: startDate,
|
||||
endDate: endDate,
|
||||
excludeEventId: excludeEventId,
|
||||
);
|
||||
|
||||
final available = result['available'] as bool? ?? true;
|
||||
final conflicts = (result['conflicts'] as List<dynamic>? ?? const [])
|
||||
.whereType<Map<String, dynamic>>()
|
||||
.map((conflict) {
|
||||
final eventData =
|
||||
conflict['eventData'] as Map<String, dynamic>? ?? const {};
|
||||
final eventName =
|
||||
(eventData['Name'] ?? conflict['eventName'] ?? '').toString();
|
||||
return {
|
||||
'eventId': conflict['eventId']?.toString() ?? '',
|
||||
'eventName': eventName,
|
||||
'overlapDays': conflict['overlapDays'] as int? ?? 0,
|
||||
};
|
||||
}).toList();
|
||||
|
||||
return {
|
||||
'equipmentId': equipmentId,
|
||||
'available': available,
|
||||
'conflictCount': conflicts.length,
|
||||
'conflicts': conflicts,
|
||||
};
|
||||
} catch (e) {
|
||||
DebugLog.error(
|
||||
'[DataService] Error in checkEquipmentAvailabilityForAssistant', e);
|
||||
throw Exception('Erreur lors de la vérification de disponibilité: $e');
|
||||
}
|
||||
}
|
||||
|
||||
/// Retourne des événements passés, idéalement filtrés par type d'événement.
|
||||
Future<List<Map<String, dynamic>>> getPastEventsForAssistant({
|
||||
String? eventTypeId,
|
||||
int limit = 10,
|
||||
}) async {
|
||||
try {
|
||||
final now = DateTime.now();
|
||||
final events = eventTypeId != null && eventTypeId.isNotEmpty
|
||||
? await getEventsByEventType(eventTypeId)
|
||||
: (await getEvents())['events'] as List<Map<String, dynamic>>? ?? [];
|
||||
|
||||
final pastEvents = events.where((event) {
|
||||
final endDate = _parseEventDate(event['EndDateTime']);
|
||||
return endDate != null && endDate.isBefore(now);
|
||||
}).toList();
|
||||
|
||||
pastEvents.sort((a, b) {
|
||||
final aDate = _parseEventDate(a['StartDateTime']) ??
|
||||
DateTime.fromMillisecondsSinceEpoch(0);
|
||||
final bDate = _parseEventDate(b['StartDateTime']) ??
|
||||
DateTime.fromMillisecondsSinceEpoch(0);
|
||||
return bDate.compareTo(aDate);
|
||||
});
|
||||
|
||||
return pastEvents.take(limit).map((event) {
|
||||
final assignedEquipment =
|
||||
event['assignedEquipment'] as List<dynamic>? ?? const [];
|
||||
return {
|
||||
'id': event['id']?.toString() ?? '',
|
||||
'name': (event['Name'] ?? '').toString(),
|
||||
'startDate': event['StartDateTime']?.toString() ?? '',
|
||||
'endDate': event['EndDateTime']?.toString() ?? '',
|
||||
'assignedEquipment': assignedEquipment,
|
||||
'assignedEquipmentCount': assignedEquipment.length,
|
||||
};
|
||||
}).toList();
|
||||
} catch (e) {
|
||||
DebugLog.error('[DataService] Error in getPastEventsForAssistant', e);
|
||||
throw Exception(
|
||||
'Erreur lors de la récupération des événements passés: $e');
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, dynamic> _normalizeAssistantEquipment(Map<String, dynamic> item) {
|
||||
return {
|
||||
'id': (item['id'] ?? '').toString(),
|
||||
'name': (item['name'] ?? item['id'] ?? '').toString(),
|
||||
'category': (item['category'] ?? '').toString(),
|
||||
'status': (item['status'] ?? '').toString(),
|
||||
'brand': item['brand']?.toString(),
|
||||
'model': item['model']?.toString(),
|
||||
'availableQuantity': item['availableQuantity'],
|
||||
'totalQuantity': item['totalQuantity'],
|
||||
};
|
||||
}
|
||||
|
||||
DateTime? _parseEventDate(dynamic rawValue) {
|
||||
if (rawValue is String) {
|
||||
return DateTime.tryParse(rawValue);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// USER - Current User
|
||||
// ============================================================================
|
||||
|
||||
Reference in New Issue
Block a user