call method

Future<Map<String, dynamic>> call(
  1. String name, {
  2. Map<String, dynamic> params = const {},
  3. Duration? timeout,
})

Einen Endpunkt rufen. params kommt zur Kasse dazu; null-Werte fallen weg, damit das Backend „nicht gesetzt" nicht als ausdrückliche Angabe missversteht.

timeout überschreibt die Vorgabe für diesen einen Aufruf – der Abschluss eines Belegs darf länger warten als eine Belegliste.

Fehler tragen outcome: bei ErrorOutcome.unknown nie wiederholen, sondern nachlesen (siehe v3Post).

Implementation

Future<Map<String, dynamic>> call(
  String name, {
  Map<String, dynamic> params = const {},
  Duration? timeout,
}) async {
  // Beides frisch — siehe Klassenkommentar.
  final token = await idToken();
  final sitzung = await sessionId();
  if (token == null || token.isEmpty) {
    throw KasseneckValidationError(name, 'idToken lieferte kein Token', 'request');
  }
  if (sitzung == null || sitzung.isEmpty) {
    throw KasseneckValidationError(name, 'sessionId lieferte keine Sitzung', 'request');
  }

  final nutzlast = <String, dynamic>{'cashregisterId': cashregisterId};
  params.forEach((schluessel, wert) {
    if (wert != null) nutzlast[schluessel] = wert;
  });

  // Ausserhalb des Sendens: ein nicht serialisierbarer Parameter ist ein
  // Programmierfehler und keine Netzstoerung. Sonst haette ihn der
  // Sammelfang als `network` gemeldet — ein Fehler, der nie am Netz lag,
  // saehe aus wie einer, nach dem ein Beleg entstanden sein koennte.
  final String rumpf = jsonEncode({'params': nutzlast});

  // Zeitlimit getrennt vom Netzfehler: die Anfrage war draussen, ueber
  // `createReceipt` kann der Beleg laengst signiert sein. Nur der Typ der
  // Ursache, nie die Meldung: die kann eine Adresse tragen.
  final antwort = await v3Post(
    _http,
    functionName: name,
    basis: baseUrl,
    name: name,
    headers: {
      'Content-Type': 'application/json',
      'Authorization': 'Bearer $token',
      'register-session': sitzung,
    },
    kasseneck: _kopf,
    body: rumpf,
    timeout: timeout ?? _timeout,
  );

  final huelle = readEnvelope(name, antwort);
  if (huelle['status'] == 'success') {
    // Fehlendes `data` ist erlaubt — nicht jeder Aufruf hat eine Nutzlast.
    // Ein `data`, das da ist und **kein Objekt** ist (Array, Zahl, Text), ist
    // dagegen kaputt und darf nicht als leeres Objekt durchgehen: aus dem
    // wurde weiter oben ein voller Standardsatz Einstellungen, und der
    // Bildschirm meldete „der Betrieb hat nichts eingestellt". Dieselbe
    // Grenze wie bei den Listen: leer ist etwas anderes als kaputt.
    return envelopeData(name, huelle, antwort.statusCode);
  }
  throw envelopeError(name, huelle);
}