132 lines
3.7 KiB
Dart
132 lines
3.7 KiB
Dart
import 'dart:convert';
|
|
|
|
import 'package:dio/dio.dart';
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
|
|
import '../../../core/auth/auth_provider.dart';
|
|
import '../../../core/api/api_client.dart';
|
|
import '../../../core/api/api_endpoints.dart';
|
|
import '../../../core/api/api_response.dart';
|
|
import '../domain/wash.dart';
|
|
|
|
/// Référence machine extraite d'un QR code scanné.
|
|
class QrMachineReference {
|
|
const QrMachineReference({
|
|
this.machineUuid,
|
|
this.qrCode,
|
|
});
|
|
|
|
final String? machineUuid;
|
|
final String? qrCode;
|
|
|
|
bool get isValid =>
|
|
(machineUuid != null && machineUuid!.isNotEmpty) ||
|
|
(qrCode != null && qrCode!.isNotEmpty);
|
|
|
|
factory QrMachineReference.parse(String raw) {
|
|
final trimmed = raw.trim();
|
|
if (trimmed.isEmpty) {
|
|
return const QrMachineReference();
|
|
}
|
|
|
|
try {
|
|
final decoded = jsonDecode(trimmed);
|
|
if (decoded is Map<String, dynamic>) {
|
|
return QrMachineReference(
|
|
machineUuid: decoded['machine_uuid'] as String?,
|
|
qrCode: decoded['qr_code'] as String?,
|
|
);
|
|
}
|
|
} catch (_) {
|
|
// Contenu texte brut (ex. LAVERIE-DEMO-001).
|
|
}
|
|
|
|
final uuidPattern = RegExp(
|
|
r'^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$',
|
|
);
|
|
if (uuidPattern.hasMatch(trimmed)) {
|
|
return QrMachineReference(machineUuid: trimmed);
|
|
}
|
|
|
|
return QrMachineReference(qrCode: trimmed);
|
|
}
|
|
}
|
|
|
|
/// Dépôt de données pour les lavages.
|
|
class WashRepository {
|
|
WashRepository(this._apiClient);
|
|
|
|
final ApiClient _apiClient;
|
|
|
|
Future<List<Wash>> fetchWashes() async {
|
|
final response = await _apiClient.get(ApiEndpoints.washes);
|
|
final list = ApiResponse.list(response.data, 'washes');
|
|
|
|
return list
|
|
.map((json) => Wash.fromJson(json as Map<String, dynamic>))
|
|
.toList();
|
|
}
|
|
|
|
Future<Wash> startWashFromMachine(String machineUuid) async {
|
|
try {
|
|
final response = await _apiClient.post(
|
|
ApiEndpoints.washesStart,
|
|
data: {
|
|
'machine_uuid': machineUuid,
|
|
'trigger_method': 'qr_code',
|
|
},
|
|
);
|
|
final washJson = ApiResponse.object(response.data, 'wash');
|
|
return Wash.fromJson(washJson);
|
|
} on DioException catch (error) {
|
|
throw WashStartException(ApiResponse.errorMessage(error, fallback: 'Impossible de démarrer le lavage'));
|
|
}
|
|
}
|
|
|
|
Future<Wash> startWashFromQr(String scannedValue) async {
|
|
final reference = QrMachineReference.parse(scannedValue);
|
|
if (!reference.isValid) {
|
|
throw const FormatException('QR code invalide ou vide');
|
|
}
|
|
|
|
final payload = <String, dynamic>{
|
|
'trigger_method': 'qr_code',
|
|
if (reference.machineUuid != null) 'machine_uuid': reference.machineUuid,
|
|
if (reference.qrCode != null) 'qr_code': reference.qrCode,
|
|
};
|
|
|
|
try {
|
|
final response = await _apiClient.post(
|
|
ApiEndpoints.washesStart,
|
|
data: payload,
|
|
);
|
|
final washJson = ApiResponse.object(response.data, 'wash');
|
|
return Wash.fromJson(washJson);
|
|
} on DioException catch (error) {
|
|
throw WashStartException(ApiResponse.errorMessage(error, fallback: 'Impossible de démarrer le lavage'));
|
|
}
|
|
}
|
|
}
|
|
|
|
class WashStartException implements Exception {
|
|
WashStartException(this.message);
|
|
|
|
final String message;
|
|
|
|
@override
|
|
String toString() => message;
|
|
}
|
|
|
|
final washRepositoryProvider = Provider<WashRepository>((ref) {
|
|
return WashRepository(ref.watch(apiClientProvider));
|
|
});
|
|
|
|
final washesProvider = FutureProvider<List<Wash>>((ref) async {
|
|
final token = ref.watch(authProvider.select((state) => state.accessToken));
|
|
if (token == null || token.isEmpty) {
|
|
throw StateError('Non authentifié');
|
|
}
|
|
|
|
return ref.watch(washRepositoryProvider).fetchWashes();
|
|
});
|