updateWhereId method

Future<void> updateWhereId(
  1. String id,
  2. Map<String, dynamic> data
)

Atualiza uma linha inteira em uma única chamada de API

Implementation

Future<void> updateWhereId(String id, Map<String, dynamic> data) async {
  final rows = await getRawRows(forceRefresh: true);
  if (rows.isEmpty) throw Exception("Planilha vazia.");

  final headers = List<String>.from(rows[0]);
  int rowIndex = rows.indexWhere(
    (row) => row.isNotEmpty && row[0].toString() == id,
  );

  if (rowIndex == -1) throw Exception("ID $id não encontrado.");

  // Mescla dados novos com os existentes na linha
  List<Object?> updatedRow = List<Object?>.generate(headers.length, (j) {
    final header = headers[j];
    if (data.containsKey(header) && header != "id") return data[header];

    return j < rows[rowIndex].length ? rows[rowIndex][j] : "";
  });

  for (var i = 0; i < headers.length; i++) {
    final header = headers.elementAt(i);
    final isFk =
        foreignKeys?.any((e) => e.sourceTargetColumn == header) ?? false;

    // Checa se a coluna está configurada em alguma Formula (extraindo a coluna da range)
    // O regex captura a letra da coluna. Ex: range "M2:M2" captura "M".
    // Para ser 100% preciso, se a coluna não foi enviada em `data`, evitamos sobrescrever.
    final isFormula =
        formulas?.any(
          (e) => e.sheet == sheetName && e.range.startsWith(listAlfabetic(i)),
        ) ??
        false;

    if (isFk || isFormula) {
      updatedRow[i] = null;
    }
  }

  await api.spreadsheets.values.update(
    sheets.ValueRange(values: [updatedRow]),
    spreadsheetId,
    '$sheetName!A${rowIndex + 1}',
    valueInputOption: 'USER_ENTERED',
  );

  _cachedRawRows = null; // Invalida o cache
}