verkaufen method

Future<KasseneckReceipt> verkaufen({
  1. required List<KasseneckItem> positionen,
  2. required KeckPaymentMethod zahlungsart,
  3. int? trinkgeldCents,
  4. List<String>? kundendaten,
  5. List<String>? rechtshinweise,
  6. String? kartenzahlungId,
  7. Map<String, dynamic>? kartenzahlungsdaten,
})

Normalbeleg (Verkauf) — der signierte Beleg samt Belegkopf.

Implementation

Future<KasseneckReceipt> verkaufen({
  required List<KasseneckItem> positionen,
  required KeckPaymentMethod zahlungsart,
  int? trinkgeldCents,
  List<String>? kundendaten,
  List<String>? rechtshinweise,
  String? kartenzahlungId,
  Map<String, dynamic>? kartenzahlungsdaten,
}) async {
  const name = 'createReceipt';
  if (positionen.isEmpty) {
    // Ein leerer Verkauf ist kein Verkauf — und der Fehler soll fallen,
    // bevor irgendetwas in die Signaturkette gerät.
    throw const KasseneckValidationError(name, 'Positionen fehlen', 'request');
  }
  if (positionen.any((p) => !p.isValid)) {
    throw const KasseneckValidationError(name, 'Ungueltige Position uebergeben', 'request');
  }
  if (trinkgeldCents != null && trinkgeldCents < 0) {
    throw const KasseneckValidationError(name, 'Trinkgeld muss >= 0 sein', 'request');
  }

  final daten = await transport.rufen(
    name,
    params: {
      'receiptType': 'standard',
      'items': positionen.map((p) => p.toJson()).toList(),
      'paymentMethod': zahlungsart.name,
      if (trinkgeldCents != null && trinkgeldCents > 0) 'tip': trinkgeldCents,
      if (kundendaten != null && kundendaten.isNotEmpty) 'customerDetails': kundendaten.join('\n'),
      if (rechtshinweise != null && rechtshinweise.isNotEmpty) 'legalMessage': rechtshinweise.join('\n'),
      if (kartenzahlungId != null) 'cardPaymentId': kartenzahlungId,
      if (kartenzahlungsdaten != null) 'cardPaymentData': kartenzahlungsdaten,
    },
    frist: abschlussFrist,
  );
  return _belegAus(daten, name);
}