validateOnBoardingSignDocumentData function

FormData validateOnBoardingSignDocumentData(
  1. Map<String, dynamic>? signData
)

Valida datos para firmar documento (OnBoarding).

Implementation

FormData validateOnBoardingSignDocumentData(Map<String, dynamic>? signData) {
  if (signData == null) {
    throw ApacuanaAPIError(
      'Sign data is required and must be an object.',
      statusCode: 400,
      errorCode: 'INVALID_PARAMETER',
    );
  }

  final signature = signData['signature'];
  final cert = signData['cert'];
  final signedDigest = signData['signedDigest'];

  // Misma lógica que JS: signature debe ser objeto con id
  if (signature == null || signature is! Map || signature['id'] == null) {
    throw ApacuanaAPIError(
      "Signature object with an 'id' property is required.",
      statusCode: 400,
      errorCode: 'INVALID_PARAMETER',
    );
  }

  // positions debe ser array
  final positionsRaw = signature['positions'];
  if (positionsRaw is! List) {
    throw ApacuanaAPIError(
      "Signature 'positions' must be an array.",
      statusCode: 400,
      errorCode: 'INVALID_PARAMETER',
    );
  }

  // cert string requerido
  if (cert == null || cert is! String) {
    throw ApacuanaAPIError(
      "Certificate 'cert' is required and must be a string.",
      statusCode: 400,
      errorCode: 'INVALID_PARAMETER',
    );
  }

  // signedDigest string requerido
  if (signedDigest == null || signedDigest is! String) {
    throw ApacuanaAPIError(
      "Signed digest 'signedDigest' is required and must be a string.",
      statusCode: 400,
      errorCode: 'INVALID_PARAMETER',
    );
  }

  print('llego 3');

  // Map positions -> agrega status:1 igual que JS
  final positions = positionsRaw
      .map((p) => {
            'x': (p as Map)['x'],
            'y': p['y'],
            'page': p['page'],
            'status': 1,
          })
      .toList();

  final formData = FormData();
  formData.fields.add(MapEntry('positions', jsonEncode(positions)));
  formData.fields.add(MapEntry('publickey', cert));
  formData.fields.add(MapEntry('signeddigest', signedDigest));

  print('llego 4');

  final docVal = signData['document'];
  if (docVal is MultipartFile) {
    formData.files.add(MapEntry('document', docVal));
  } else if (docVal is Map) {
    final isRnLike = docVal['uri'] != null &&
        docVal['name'] != null &&
        docVal['type'] != null;
    final hasBytes =
        docVal['bytes'] is List<int> || docVal['bytes'] is Uint8List;
    if (hasBytes && docVal['filename'] != null) {
      // Construimos MultipartFile desde bytes provistos
      try {
        final bytes = docVal['bytes'] is Uint8List
            ? docVal['bytes'] as Uint8List
            : Uint8List.fromList((docVal['bytes'] as List<int>));
        final filename = docVal['filename'].toString();
        formData.files.add(
          MapEntry(
            'document',
            MultipartFile.fromBytes(
              bytes,
              filename: filename,
              // contentType removido para compatibilidad; integrador puede establecerlo en cabecera si necesita.
            ),
          ),
        );
      } catch (_) {}
    } else if (isRnLike) {
      // No podemos convertir uri a bytes aquí; se requiere que el integrador pase MultipartFile o bytes.
      // Se omite para mantener consistencia silenciosa tal como haría FormData JS si el objeto no es File ni RNFile válido.
    }
  }

  return formData;
}