saveDevice method

Future<PosDeviceSettings> saveDevice(
  1. Map<String, dynamic> patch
)

Einstellungen dieses Geräts schreiben (Recht layout). shortcuts nur als ganze Karte aller bekannten Aktionen (posSettingsChanges liefert sie bei jeder Tastenänderung); sie wird vorab auf Doppelbelegung geprüft.

Implementation

Future<PosDeviceSettings> saveDevice(Map<String, dynamic> patch) async {
  const name = Aufrufe.setMyRegisterDeviceSettings;
  if (deviceId.trim().isEmpty) {
    throw const KasseneckValidationError(name, 'deviceId fehlt', 'request');
  }
  // Die optionale Lade getrennt: `null` heisst hier „Zuordnung entfernen“ und
  // geht hinaus, waehrend `_pruefeTeil` Nullwerte als „nicht geaendert“ faellt.
  final mitLade = patch.containsKey('drawerId');
  final lade = patch['drawerId'];
  if (mitLade && lade != null && !isPosOptionalId(lade)) {
    throw const KasseneckValidationError(
        name, 'device.drawerId: keine Kennung (1-64 Zeichen aus A-Z a-z 0-9 _ -, oder null zum Entfernen)', 'request');
  }
  final gesendet = mitLade && patch.length == 1
      ? <String, dynamic>{}
      : _pruefeTeil(name, 'device', {...patch}..remove('drawerId'), const PosDeviceSettings().toJson(), posDeviceValues);
  if (mitLade) gesendet['drawerId'] = lade;
  if (gesendet.containsKey('shortcuts')) {
    final karte = gesendet['shortcuts'];
    if (karte is! Map) {
      throw const KasseneckValidationError(name, 'device.shortcuts: keine Tastenkarte', 'request');
    }
    final tasten = <String, Object?>{};
    for (final e in karte.entries) {
      if (e.value == null) continue;
      final aktion = e.key.toString();
      if (!posShortcutActions.contains(aktion)) {
        throw KasseneckValidationError(name, 'device.shortcuts.$aktion: unbekannte Aktion', 'request');
      }
      tasten[aktion] = e.value;
    }
    // Nur die ganze Karte: der Server prüft Doppelbelegungen nur in der
    // gesendeten Karte, eine halbe (`{cash: ['Mod+K']}`) ließe eine
    // Doppelbelegung mit einer gespeicherten Taste durch.
    final fehlt = posShortcutActions.where((a) => !tasten.containsKey(a)).toList();
    if (fehlt.isNotEmpty) {
      throw KasseneckValidationError(
          name,
          'device.shortcuts: ganze Karte senden (posSettingsChanges), es fehlen ${fehlt.join(', ')}',
          'request');
    }
    // Doppelbelegung in der ganzen Karte, also in der ganzen Belegung.
    final konflikt = posShortcutConflict(tasten);
    if (konflikt != null) {
      throw KasseneckValidationError(
          name,
          'device.shortcuts.${konflikt.action}: Taste ${konflikt.key} schon belegt (${konflikt.heldBy})',
          'request');
    }
    gesendet['shortcuts'] = tasten;
  }
  final daten = await transport.call(name, params: {'deviceId': deviceId, 'device': gesendet});
  return PosDeviceSettings.fromJson(_stand(name, daten, 'device'));
}