createPartnerCustomer method

Future<NeuerBetrieb> createPartnerCustomer({
  1. required String appId,
  2. required Map<String, dynamic> betrieb,
  3. String? idempotencyKey,
  4. bool? einladen,
  5. PartnerEnv? env,
})

Legt einen Betrieb an.

Ohne Panel-Zugang, solange nicht einladen = true dabeisteht: viele Betriebe arbeiten ausschliesslich in der App des Partners, und ein stillschweigend erzeugter Login samt Einladungsmail waere dort etwas, das niemand erwartet. Fuer die Einladung braucht das Partner-Konto ausserdem PartnerInfo.darfZugangEinrichten -- sonst zugang_nicht_erlaubt, und es entsteht nichts, auch kein Betrieb.

env waehlt die Umgebung. Ohne Angabe entscheidet der Schluessel; ein LIVE-Schluessel darf PartnerEnv.test verlangen -- das ist der vorgesehene Weg, die ganze Kette zu proben, ohne sich einen zweiten Schluessel zu holen. Umgekehrt nie: ein Test-Schluessel mit PartnerEnv.live bekommt live_not_allowed, und es entsteht nichts. Ein so angelegter Live-Betrieb ist sofort freigeschaltet und traegt das Modul registrierkasse.

idempotencyKey benutzen. Ein verlorener Antwortweg ist kein Sonderfall, und ohne Schluessel legt der zweite Versuch einen zweiten Betrieb an. Mit Schluessel kommt die gespeicherte Antwort zurueck (NeuerBetrieb.wiederholt) -- auch dann, wenn der Rumpf inzwischen abweicht. Die eigene Kundennummer ist der natuerliche Wert dafuer.

betrieb sind die Stammdaten, so wie die Referenz sie beschreibt -- eine Karte, weil Dart keine Form dafuer erzwingen kann, die der Server nicht ohnehin prueft. Das Backend weist ein unbekanntes Feld ab, statt es stillschweigend zu verwerfen; unbekannteBetriebsfelder beantwortet dieselbe Frage vor dem Senden, mit denselben Pfaden.

Implementation

Future<NeuerBetrieb> createPartnerCustomer({
  required String appId,
  required Map<String, dynamic> betrieb,
  String? idempotencyKey,
  bool? einladen,
  PartnerEnv? env,
}) async {
  final app = _pflicht(appId, 'createPartnerCustomer', 'appId');
  if (betrieb.isEmpty) {
    throw const KasseneckValidationError('createPartnerCustomer', 'betrieb ist leer', 'request');
  }
  if (idempotencyKey != null && idempotencyKey.length > 120) {
    throw const KasseneckValidationError(
        'createPartnerCustomer', 'idempotencyKey ist laenger als 120 Zeichen', 'request');
  }
  final d = await _t.rufen(Aufrufe.createPartnerCustomer, params: <String, dynamic>{
    'appId': app,
    'business': betrieb,
    'idempotencyKey': idempotencyKey,
    'access': einladen == null ? null : <String, dynamic>{'invite': einladen},
    'env': env == null ? null : envName(env),
  });
  final ergebnis = NeuerBetrieb.aus(d, app);
  if (ergebnis.customerId.isEmpty) {
    throw const KasseneckValidationError(
        'createPartnerCustomer', 'Antwort enthaelt keine customerId', 'response');
  }
  return ergebnis;
}