syncPendingUpdates function
Sincroniza los registros que quedaron pendientes en la base local.
Implementation
Future<void> syncPendingUpdates() async {
final dbHelper = DatabaseHelper();
// 1) Mostrar todos los locales en consola (debug)
final allIndividuos = await dbHelper.getAllIndividuos();
print('Todos los individuos en la base de datos local:');
print(allIndividuos);
// 2) Obtener la lista de pendientes
final pendingUpdates = await dbHelper.getPendingUpdates();
print('Total de pendientes a sincronizar: ${pendingUpdates.length}');
for (var update in pendingUpdates) {
final dataJson = update['data'] as String;
final decoded = jsonDecode(dataJson) as Map<String, dynamic>;
// Extraer el ID alfanumérico
final id = decoded['id'] as String;
print('Procesando pendiente con ID: $id');
print('Datos obtenidos de la tabla de pendientes:');
print(decoded);
// 3) Obtener el individuo original de la base local
final originalIndividuo = await dbHelper.getIndividuoById(id);
if (originalIndividuo == null) {
print('No se encontró el individuo original para el ID: $id');
await dbHelper.deletePendingUpdate(update['id']);
continue;
}
// 4) Detectar qué campos cambiaron (decoded vs originalIndividuo)
final changedFields = <String, dynamic>{};
decoded.forEach((key, value) {
if (value != originalIndividuo[key]) {
changedFields[key] = value;
}
});
// Si no hay cambios reales, eliminar el pendiente
if (changedFields.isEmpty) {
print('No hay cambios para el ID: $id');
await dbHelper.deletePendingUpdate(update['id']);
continue;
}
// 5) Validar / heredar cod_especie_id:
if (changedFields.containsKey('cod_especie_code_specie')) {
// Si el usuario modificó el código
final newCode = changedFields['cod_especie_code_specie'].toString();
final species = await dbHelper.getSpeciesByCode(newCode);
if (species == null) {
print('Código de especie inválido en pendiente para ID: $id');
// No eliminamos el pendiente; queda para que el usuario corrija
continue;
}
changedFields['cod_especie_id'] = species['code_specie'];
} else {
// Si no cambió el código, intentar heredar cod_especie_id del original
if (originalIndividuo['cod_especie_id'] != null) {
changedFields['cod_especie_id'] = originalIndividuo['cod_especie_id'];
} else {
// Si en original solo existía cod_especie_code_specie, buscar su ID
final originalCode =
originalIndividuo['cod_especie_code_specie']?.toString();
if (originalCode != null && originalCode.isNotEmpty) {
final species = await dbHelper.getSpeciesByCode(originalCode);
if (species != null) {
changedFields['cod_especie_id'] = species['code_specie'];
}
}
}
}
// 6) Preparar JSON para la API
final apiData = _prepareApiData(changedFields, originalIndividuo);
print('Datos a enviar a la API para el ID $id:');
print(apiData);
// 7) Enviar la petición PUT
final url = 'https://api.corpoamazonia.gov.co/candidates/trees/$id';
String? accessToken = await tokenManager.getToken();
if (accessToken == null) {
print(
'No se pudo obtener un token de acceso válido para sincronizar pendientes');
continue;
}
try {
final client = http.Client();
final response = await client.put(
Uri.parse(url),
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer $accessToken',
'Accept': 'application/json',
},
body: jsonEncode(apiData),
);
print('Respuesta del servidor: ${response.statusCode}');
print('Cuerpo de la respuesta: ${response.body}');
if (response.statusCode == 200) {
print('Pendiente enviado con éxito: $id');
await notificationHelper.sendNotification('Sincronización Exitosa',
'Pendiente enviado con éxito para ID: $id.');
await dbHelper.deletePendingUpdate(update['id']);
} else {
print('Error al enviar pendiente: ${response.statusCode}');
await notificationHelper.sendNotification('Error de Sincronización',
'Error al enviar pendiente para ID $id: ${response.statusCode}.');
// No borramos el pendiente: se reintentará más tarde
}
client.close();
} catch (error) {
print('Error al enviar pendiente: $error');
await notificationHelper.sendNotification('Error de Sincronización',
'Error al enviar pendiente para ID $id: $error.');
// Se conserva en pendientes para reintentar
}
}
}