sell method

Future<KasseneckReceipt> sell({
  1. required List<KasseneckItem> items,
  2. required List<KeckPaymentInput> payments,
  3. int? tipCents,
  4. List<String>? customerLines,
  5. List<String>? legalNotices,
})

Normalbeleg (Verkauf): der signierte Beleg samt Belegkopf.

Unter /v3 gehen die Zahlungen immer als payments hinaus (siehe KeckPaymentInput: Karte mit Anbieter und Kennung, Bar mit tenderedCents), nie die Einzelfelder paymentMethod, creditCardProvider, cardPaymentId, cardPaymentData aus 0.x; mixed wird nie gesendet. Den Zahlbetrag rechnet der Server; weicht die Summe ab, kommt payments_sum_mismatch mit expectedCents (paymentsExpectedCents), und es wurde nichts signiert.

Implementation

Future<KasseneckReceipt> sell({
  required List<KasseneckItem> items,
  required List<KeckPaymentInput> payments,
  int? tipCents,
  List<String>? customerLines,
  List<String>? legalNotices,
}) async {
  const name = Aufrufe.createReceipt;
  if (items.isEmpty) {
    // Ein leerer Verkauf ist kein Verkauf, und der Fehler soll fallen,
    // bevor irgendetwas in die Signaturkette geraet.
    throw const KasseneckValidationError(name, 'Positionen fehlen', 'request');
  }
  if (items.any((p) => !p.isValid)) {
    throw const KasseneckValidationError(name, 'Ungueltige Position uebergeben', 'request');
  }
  if (tipCents != null && tipCents < 0) {
    throw const KasseneckValidationError(name, 'Trinkgeld muss >= 0 sein', 'request');
  }
  final fehler = paymentsError(payments, cancellation: false);
  if (fehler != null) throw KasseneckValidationError(name, fehler, 'request');

  final daten = await _signiertRufen(
    name,
    params: {
      'receiptType': 'standard',
      'items': items.map((p) => p.toJson()).toList(),
      'payments': [for (final z in payments) z.toJson()],
      if (tipCents != null && tipCents > 0) 'tip': tipCents,
      if (customerLines != null && customerLines.isNotEmpty) 'customerDetails': customerLines.join('\n'),
      if (legalNotices != null && legalNotices.isNotEmpty) 'legalMessage': legalNotices.join('\n'),
    },
  );
  // Ab hier ist der Beleg signiert: wer ihn nicht lesen kann, bekommt
  // `response_unreadable` (Ausgang unklar) mit der Kennung, nie einen
  // gewoehnlichen Fehler, der zum zweiten Verkauf einluede.
  return readSignedResponse(name, () => _belegAus(daten, name), receiptId: () => _kennungAus(daten));
}