setKeckReceipt method
Implementation
Future setKeckReceipt(KasseneckReceipt receipt, {QrPrintMode qrMode = QrPrintMode.imageRaster}) async {
reset();
if (receipt.logo != null) {
Image image = decodeImage(receipt.logo!)!;
Image resized = copyResize(image, width: paperSize.imageWidth);
addImage(resized);
addFeed();
}
addText(receipt.companyName, styles: PosStyles(align: PosAlign.center, bold: true));
addText(receipt.street, styles: PosStyles(align: PosAlign.center));
addText('${receipt.zip} ${receipt.city}', styles: PosStyles(align: PosAlign.center));
addText(receipt.taxInfo, styles: PosStyles(align: PosAlign.center));
addText(receipt.phone, styles: PosStyles(align: PosAlign.center));
if (receipt.customerDetails.isNotEmpty) {
addFeed();
for (int i = 0; i < receipt.customerDetails.length; i++) {
if (i == 0) {
addDoubleText('Kunde:', receipt.customerDetails[i], leftWidth: 5, rightWidth: 7);
} else {
addDoubleText('', receipt.customerDetails[i], leftWidth: 1, rightWidth: 11);
}
}
}
addFeed();
addDoubleText('Datum:', receipt.readableTime, leftWidth: 4, rightWidth: 8);
addDoubleText('Kassen-ID:', receipt.cashregisterId);
addDoubleText('Beleg-ID:', receipt.receiptId);
addFeed();
Map<VatRate, List<KasseneckItem>> itemsByVat = {};
for (KasseneckItem item in receipt.items) {
if (itemsByVat[item.vat] == null) {
itemsByVat[item.vat] = [];
}
itemsByVat[item.vat]!.add(item);
String amount = item.quantity.toString().padRight(2);
if (item.quantity
.toString()
.length > 2) {
amount += ' x';
} else {
amount += ' x ';
}
addDoubleText('$amount${item.name.check()}${item.quantity > 1 ? ' je ${formatAmount(item.singlePrice)}' : ''}', '${formatAmount(item.singlePrice * item.quantity)} ${item.vat.category}', leftWidth: 7, rightWidth: 5);
}
double totalPromoVoucherValue = 0;
for (KeckVoucher voucher in receipt.vouchers??[]) {
if (voucher.isValid && voucher.action == VoucherAction.sell) {
itemsByVat[VatRate.vat0] ??= [];
itemsByVat[VatRate.vat0]!.add(KasseneckItem(
name: voucher.receiptText,
quantity: 1,
singlePrice: voucher.value ?? 0,
vat: VatRate.vat0
));
}
if (voucher.action == VoucherAction.sell && voucher.type == VoucherType.value) {
String amount = '1 x ';
addDoubleText('$amount${voucher.receiptText}', '${formatAmount(voucher.value??0)} ${VatRate.vat0.category}', leftWidth: 7, rightWidth: 5);
}
if (voucher.action == VoucherAction.redeem && voucher.type == VoucherType.promo) {
totalPromoVoucherValue += voucher.value ?? 0;
addDoubleText(voucher.receiptText, '-${formatAmount(voucher.value??0)} EUR', leftWidth: 7, rightWidth: 5);
}
}
final Map<VatRate, int> vatTableBruttoByVatCents = {
for (final VatRate key in itemsByVat.keys) key: 0,
};
itemsByVat.forEach((key, value) {
int bruttoCents = 0;
for (final KasseneckItem element in value) {
bruttoCents += euroToCent(element.singlePrice * element.quantity);
}
vatTableBruttoByVatCents[key] = bruttoCents;
});
final int totalPromoVoucherValueCents = euroToCent(totalPromoVoucherValue);
final int totalAmountCents = vatTableBruttoByVatCents.values.fold(0, (sum, value) => sum + value);
final int usablePromoVoucherValueCents =
totalPromoVoucherValueCents > totalAmountCents ? totalAmountCents : totalPromoVoucherValueCents;
if (usablePromoVoucherValueCents > 0 && totalAmountCents > 0) {
final Map<VatRate, int> promoByVatCents = {
for (final VatRate key in vatTableBruttoByVatCents.keys) key: 0,
};
int usedPromoCents = 0;
vatTableBruttoByVatCents.forEach((key, bruttoCents) {
final int proportionalCents = (usablePromoVoucherValueCents * bruttoCents) ~/ totalAmountCents;
promoByVatCents[key] = proportionalCents;
usedPromoCents += proportionalCents;
});
final int remainingPromoCents = usablePromoVoucherValueCents - usedPromoCents;
if (remainingPromoCents > 0) {
final List<MapEntry<VatRate, int>> sortedGroups = vatTableBruttoByVatCents.entries.toList()
..sort((a, b) => b.value.compareTo(a.value));
if (sortedGroups.isNotEmpty && sortedGroups.first.value > 0) {
promoByVatCents[sortedGroups.first.key] =
(promoByVatCents[sortedGroups.first.key] ?? 0) + remainingPromoCents;
}
}
promoByVatCents.forEach((key, promoCents) {
vatTableBruttoByVatCents[key] = (vatTableBruttoByVatCents[key] ?? 0) - promoCents;
});
}
addFeed();
_addTable('MwSt%', 'MwSt', 'Netto', 'Brutto');
vatTableBruttoByVatCents.forEach((key, bruttoCents) {
final double brutto = centToEuro(bruttoCents);
final num mwstSatz = key.rate;
final double netto = brutto / (1 + (mwstSatz / 100));
final double mwst = brutto - netto;
_addTable('${key.category} ${key.rate.toString().replaceAll('.', ',')}%', formatAmount(mwst), formatAmount(netto), formatAmount(brutto));
});
addFullHorizontalLine();
if (receipt.sum != receipt.subSum) {
addDoubleText('Zwischensumme', '${formatAmount(receipt.subSum)} EUR');
for (KeckVoucher voucher in receipt.vouchers??[]) {
if (voucher.action == VoucherAction.redeem && voucher.type == VoucherType.value) {
addDoubleText(voucher.receiptText, '-${formatAmount(voucher.value??0)} EUR');
}
}
addFullHorizontalLine();
}
addDoubleText('Gesamt:', '${formatAmount(receipt.sum)} EUR');
addFeed();
if (receipt.legalMessage.isNotEmpty) {
for (String line in receipt.legalMessage) {
addText(line, styles: PosStyles(align: PosAlign.center));
}
addFeed();
}
if (receipt.isSigFailed) {
addText(RKSVService.signatureDeviceDamagedKey, styles: PosStyles(align: PosAlign.center));
addFeed();
}
switch (qrMode) {
case QrPrintMode.imageRaster:
await addQrCodeAsImage(receipt.qr, raster: true);
break;
case QrPrintMode.imageBitImage:
await addQrCodeAsImage(receipt.qr, raster: false);
break;
case QrPrintMode.native:
addQrCode(receipt.qr);
break;
}
addFeed();
if (receipt.cardPaymentData != null && receipt.creditCardProvider != null) {
try {
switch (receipt.creditCardProvider!) {
case CreditCardProvider.gpTomAndroid:
case CreditCardProvider.gpTomIos:
_gpTom(receipt.cardPaymentData!);
break;
case CreditCardProvider.hobexCloudApi:
_hobexApi(receipt.cardPaymentData!);
break;
case CreditCardProvider.hobexHps:
_hobexHps(receipt.cardPaymentData!);
break;
case CreditCardProvider.sumup:
_sumup(receipt.cardPaymentData!);
break;
case CreditCardProvider.custom:
break;
case CreditCardProvider.myposPro:
_mypos(receipt.cardPaymentData!);
break;
}
addFeed();
} catch (_) {
// Fehlerhafte cardPaymentData darf den Beleg-Druck nicht abbrechen
}
}
if (receipt.thanksMessage.isNotEmpty) {
addFeed();
for (String message in receipt.thanksMessage) {
addText(message, styles: PosStyles(align: PosAlign.center));
}
}
addText(receipt.footer1, styles: PosStyles(align: PosAlign.center));
addText(receipt.footer2, styles: PosStyles(align: PosAlign.center));
if (receipt.footer3 != null) {
addText(receipt.footer3!, styles: PosStyles(align: PosAlign.center));
}
if (receipt.footer4 != null) {
addText(receipt.footer4!, styles: PosStyles(align: PosAlign.center));
}
addCut();
}