newMap static method
Construye un nuevo mapa newDataToSend a partir de las diferencias entre
mapaOriginal y mapaActualizado, según el esquema y reglas de exclusión/mantenimiento.
Implementation
static Map<String, dynamic> newMap({
required Map<String, dynamic> esquema,
required Map<String, dynamic> mapaOriginal,
required Map<String, dynamic> mapaActualizado,
List<String>? lstKeyExcluir,
List<String>? lstKeyMantener,
List<String>? lstPrefijosExcluir,
}) {
try {
final Map<String, dynamic> newDataToSend = <String, dynamic>{};
final Map<String, dynamic> mapaA =
esUnMapa(mapaActualizado) ? mapaActualizado : <String, dynamic>{};
final Map<String, dynamic> mapaO =
esUnMapa(mapaOriginal) ? mapaOriginal : <String, dynamic>{};
for (final entry in mapaA.entries) {
final key = entry.key;
final value = entry.value;
// Exclusión por lista de claves
if (lstKeyExcluir != null && lstKeyExcluir.contains(key)) {
continue;
}
// Exclusión por prefijos
if (lstPrefijosExcluir != null &&
lstPrefijosExcluir.any((element) => key.contains(element))) {
FlutterUtilsProvider.logDebug('key a excluir por prefijo: $key');
continue;
}
// Si la clave está en "lstKeyMantener" o no existe en el original,
// omite valores vacíos (listas vacías, mapas vacíos o string vacío).
if ((lstKeyMantener != null && lstKeyMantener.contains(key)) ||
!mapaO.containsKey(key)) {
if (_esValorVacio(value)) {
continue;
}
}
// Determina el tipo esperado según el esquema
final String tipoValue = esquema[CamposPropiedadEsquema.properties.name]
?[key]?[EnvironmentApiRest.type] ??
TypeEsquema.unknown.name;
final Map<String, dynamic> mapEsquema =
esquema[CamposPropiedadEsquema.properties.name]?[key] ??
<String, dynamic>{};
// Manejo de arrays de objetos
if (tipoValue == TypeEsquema.arrayObjects.name ||
(tipoValue == TypeEsquema.unknown.name &&
esUnaListaDeMapas(value))) {
final List<Map<String, dynamic>> diferencias = newLstMap(
esquema: mapEsquema,
dataOriginal: mapaO[key] ?? [],
dataActualizado: value as List<dynamic>,
lstKeyExcluir: lstKeyExcluir,
lstKeyMantener: lstKeyMantener,
lstPrefijosExcluir: lstPrefijosExcluir,
);
if (diferencias.isNotEmpty) {
newDataToSend[key] = diferencias;
}
// Manejo de objetos
} else if (tipoValue == TypeEsquema.object.name ||
(tipoValue == TypeEsquema.unknown.name && esUnMapa(value))) {
final Map<String, dynamic> newData = newMap(
esquema: mapEsquema,
mapaOriginal: (mapaO[key] == null)
? <String, dynamic>{}
: decodeJsonOrJsonOriginal(mapaO[key]),
mapaActualizado: decodeJsonOrJsonOriginal(value),
lstKeyExcluir: lstKeyExcluir,
lstKeyMantener: lstKeyMantener,
lstPrefijosExcluir: lstPrefijosExcluir,
);
if (newData.isNotEmpty) {
newDataToSend[key] = newData;
}
// Manejo de listas (arrays simples)
} else if (tipoValue == TypeEsquema.array.name ||
(value is List && mapaO[key] is List)) {
FlutterUtilsProvider.logDebug(
'$tipoValue value is List => ${(value is List)} '
'newMap - key: $key - value: $value - mapaO[key]: ${mapaO[key]}',
);
if (compararListas(mapaO[key] ?? [], value)) {
newDataToSend[key] = value;
}
// Comparación final de valores (si no es array u objeto)
} else if ('$value' != '${mapaO[key]}') {
// Omite actualización si el original empieza con #auto#
// y el nuevo valor está vacío
if ('${mapaO[key]}'.startsWith('#auto#') && '$value'.trim().isEmpty) {
continue;
}
newDataToSend[key] = value;
}
}
return newDataToSend;
} catch (error) {
FlutterUtilsProvider.logDebug('error newMap $error');
return <String, dynamic>{};
}
}