newMap static method

Map<String, dynamic> newMap({
  1. required Map<String, dynamic> esquema,
  2. required Map<String, dynamic> mapaOriginal,
  3. required Map<String, dynamic> mapaActualizado,
  4. List<String>? lstKeyExcluir,
  5. List<String>? lstKeyMantener,
  6. List<String>? lstPrefijosExcluir,
})

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>{};
  }
}