@kreiseck/kasseneck-api 1.13.0 → 1.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +36 -0
- package/README.md +71 -2
- package/dist/cjs/client/api.d.ts +8 -1
- package/dist/cjs/client/api.js +4 -0
- package/dist/cjs/client/aufrufe.d.ts +6 -6
- package/dist/cjs/client/aufrufe.js +11 -2
- package/dist/cjs/client/index.d.ts +2 -1
- package/dist/cjs/client/index.js +13 -1
- package/dist/cjs/client/list-receipts.d.ts +211 -0
- package/dist/cjs/client/list-receipts.js +290 -0
- package/dist/cjs/client/receipts.d.ts +85 -2
- package/dist/cjs/client/receipts.js +164 -5
- package/dist/cjs/enums/voucher-type.d.ts +1 -1
- package/dist/cjs/enums/voucher-type.js +1 -1
- package/dist/cjs/index.d.ts +2 -2
- package/dist/cjs/index.js +24 -3
- package/dist/cjs/invoice/typen.d.ts +1 -1
- package/dist/cjs/invoice/vertrag.d.ts +1 -1
- package/dist/cjs/invoice/vertrag.js +2 -0
- package/dist/cjs/models/index.d.ts +2 -1
- package/dist/cjs/models/index.js +12 -1
- package/dist/cjs/models/receipt-errors.d.ts +1 -1
- package/dist/cjs/models/receipt-errors.js +3 -0
- package/dist/cjs/models/receipt-output.d.ts +79 -0
- package/dist/cjs/models/receipt-output.js +143 -0
- package/dist/cjs/models/receipt.d.ts +2 -2
- package/dist/cjs/models/receipt.js +2 -2
- package/dist/cjs/models/voucher.d.ts +24 -2
- package/dist/cjs/models/voucher.js +2 -2
- package/dist/cjs/partner/typen.d.ts +1 -1
- package/dist/cjs/pos/index.d.ts +2 -1
- package/dist/cjs/pos/index.js +6 -1
- package/dist/cjs/pos/schicht-typen.d.ts +2 -2
- package/dist/cjs/pos/schicht-typen.js +2 -2
- package/dist/cjs/pos/settings.d.ts +1 -1
- package/dist/cjs/pos/settings.js +5 -0
- package/dist/cjs/pos/texte.d.ts +114 -0
- package/dist/cjs/pos/texte.js +64 -0
- package/dist/cjs/receipt/due.d.ts +4 -2
- package/dist/cjs/receipt/due.js +22 -5
- package/dist/cjs/receipt/duplikat.d.ts +35 -0
- package/dist/cjs/receipt/duplikat.js +76 -0
- package/dist/cjs/receipt/gutschein-plan.d.ts +2 -0
- package/dist/cjs/receipt/gutschein-plan.js +5 -0
- package/dist/cjs/receipt/index.d.ts +1 -0
- package/dist/cjs/receipt/index.js +4 -2
- package/dist/cjs/receipt/layout.js +44 -21
- package/dist/cjs/register/pairing.d.ts +6 -2
- package/dist/cjs/register/pairing.js +1 -1
- package/dist/cjs/stored/bon-layout.js +3 -4
- package/dist/cjs/stored/vokabular.d.ts +1 -1
- package/dist/cjs/stored/vokabular.js +47 -3
- package/dist/cjs/version.d.ts +1 -1
- package/dist/cjs/version.js +1 -1
- package/dist/esm/client/api.d.ts +8 -1
- package/dist/esm/client/api.js +5 -1
- package/dist/esm/client/aufrufe.d.ts +6 -6
- package/dist/esm/client/aufrufe.js +11 -2
- package/dist/esm/client/index.d.ts +2 -1
- package/dist/esm/client/index.js +2 -1
- package/dist/esm/client/list-receipts.d.ts +211 -0
- package/dist/esm/client/list-receipts.js +284 -0
- package/dist/esm/client/receipts.d.ts +85 -2
- package/dist/esm/client/receipts.js +164 -6
- package/dist/esm/enums/voucher-type.d.ts +1 -1
- package/dist/esm/enums/voucher-type.js +1 -1
- package/dist/esm/index.d.ts +2 -2
- package/dist/esm/index.js +2 -2
- package/dist/esm/invoice/typen.d.ts +1 -1
- package/dist/esm/invoice/vertrag.d.ts +1 -1
- package/dist/esm/invoice/vertrag.js +2 -0
- package/dist/esm/models/index.d.ts +2 -1
- package/dist/esm/models/index.js +1 -0
- package/dist/esm/models/receipt-errors.d.ts +1 -1
- package/dist/esm/models/receipt-errors.js +3 -0
- package/dist/esm/models/receipt-output.d.ts +79 -0
- package/dist/esm/models/receipt-output.js +135 -0
- package/dist/esm/models/receipt.d.ts +2 -2
- package/dist/esm/models/receipt.js +2 -2
- package/dist/esm/models/voucher.d.ts +24 -2
- package/dist/esm/models/voucher.js +2 -2
- package/dist/esm/partner/typen.d.ts +1 -1
- package/dist/esm/pos/index.d.ts +2 -1
- package/dist/esm/pos/index.js +3 -1
- package/dist/esm/pos/schicht-typen.d.ts +2 -2
- package/dist/esm/pos/schicht-typen.js +2 -2
- package/dist/esm/pos/settings.d.ts +1 -1
- package/dist/esm/pos/settings.js +5 -0
- package/dist/esm/pos/texte.d.ts +114 -0
- package/dist/esm/pos/texte.js +63 -0
- package/dist/esm/receipt/due.d.ts +4 -2
- package/dist/esm/receipt/due.js +23 -6
- package/dist/esm/receipt/duplikat.d.ts +35 -0
- package/dist/esm/receipt/duplikat.js +73 -0
- package/dist/esm/receipt/gutschein-plan.d.ts +2 -0
- package/dist/esm/receipt/gutschein-plan.js +4 -0
- package/dist/esm/receipt/index.d.ts +1 -0
- package/dist/esm/receipt/index.js +1 -0
- package/dist/esm/receipt/layout.js +44 -21
- package/dist/esm/register/pairing.d.ts +6 -2
- package/dist/esm/register/pairing.js +1 -1
- package/dist/esm/stored/bon-layout.js +3 -4
- package/dist/esm/stored/vokabular.d.ts +1 -1
- package/dist/esm/stored/vokabular.js +47 -3
- package/dist/esm/version.d.ts +1 -1
- package/dist/esm/version.js +1 -1
- package/fixtures/code-table-receipts.json +1 -1
- package/fixtures/duplicate-cases.json +5616 -0
- package/fixtures/expected/cancellation-discount.grid32.txt +1 -1
- package/fixtures/expected/cancellation-discount.grid48.txt +1 -1
- package/fixtures/expected/cancellation-discount.lines.json +1 -1
- package/fixtures/expected/cancellation-discount.sheet32.json +1 -1
- package/fixtures/expected/cancellation-discount.sheet48.json +1 -1
- package/fixtures/expected/cancellation-full.grid32.txt +1 -1
- package/fixtures/expected/cancellation-full.grid48.txt +1 -1
- package/fixtures/expected/cancellation-full.lines.json +1 -1
- package/fixtures/expected/cancellation-full.sheet32.json +1 -1
- package/fixtures/expected/cancellation-full.sheet48.json +1 -1
- package/fixtures/expected/cancellation-partial.grid32.txt +1 -1
- package/fixtures/expected/cancellation-partial.grid48.txt +1 -1
- package/fixtures/expected/cancellation-partial.lines.json +1 -1
- package/fixtures/expected/cancellation-partial.sheet32.json +1 -1
- package/fixtures/expected/cancellation-partial.sheet48.json +1 -1
- package/fixtures/expected/cancellation-split-full.grid32.txt +1 -1
- package/fixtures/expected/cancellation-split-full.grid48.txt +1 -1
- package/fixtures/expected/cancellation-split-full.lines.json +1 -1
- package/fixtures/expected/cancellation-split-full.sheet32.json +1 -1
- package/fixtures/expected/cancellation-split-full.sheet48.json +1 -1
- package/fixtures/expected/cancellation-split-partial.grid32.txt +1 -1
- package/fixtures/expected/cancellation-split-partial.grid48.txt +1 -1
- package/fixtures/expected/cancellation-split-partial.lines.json +1 -1
- package/fixtures/expected/cancellation-split-partial.sheet32.json +1 -1
- package/fixtures/expected/cancellation-split-partial.sheet48.json +1 -1
- package/fixtures/expected/card-custom.grid32.txt +1 -1
- package/fixtures/expected/card-custom.grid48.txt +1 -1
- package/fixtures/expected/card-custom.lines.json +1 -1
- package/fixtures/expected/card-custom.sheet32.json +1 -1
- package/fixtures/expected/card-custom.sheet48.json +1 -1
- package/fixtures/expected/card-gptom-ios.grid32.txt +1 -1
- package/fixtures/expected/card-gptom-ios.grid48.txt +1 -1
- package/fixtures/expected/card-gptom-ios.lines.json +1 -1
- package/fixtures/expected/card-gptom-ios.sheet32.json +1 -1
- package/fixtures/expected/card-gptom-ios.sheet48.json +1 -1
- package/fixtures/expected/card-gptom.grid32.txt +1 -1
- package/fixtures/expected/card-gptom.grid48.txt +1 -1
- package/fixtures/expected/card-gptom.lines.json +1 -1
- package/fixtures/expected/card-gptom.sheet32.json +1 -1
- package/fixtures/expected/card-gptom.sheet48.json +1 -1
- package/fixtures/expected/card-hobex-cloud.grid32.txt +1 -1
- package/fixtures/expected/card-hobex-cloud.grid48.txt +1 -1
- package/fixtures/expected/card-hobex-cloud.lines.json +1 -1
- package/fixtures/expected/card-hobex-cloud.sheet32.json +1 -1
- package/fixtures/expected/card-hobex-cloud.sheet48.json +1 -1
- package/fixtures/expected/card-hobex-hps.grid32.txt +1 -1
- package/fixtures/expected/card-hobex-hps.grid48.txt +1 -1
- package/fixtures/expected/card-hobex-hps.lines.json +1 -1
- package/fixtures/expected/card-hobex-hps.sheet32.json +1 -1
- package/fixtures/expected/card-hobex-hps.sheet48.json +1 -1
- package/fixtures/expected/card-mypos.grid32.txt +1 -1
- package/fixtures/expected/card-mypos.grid48.txt +1 -1
- package/fixtures/expected/card-mypos.lines.json +1 -1
- package/fixtures/expected/card-mypos.sheet32.json +1 -1
- package/fixtures/expected/card-mypos.sheet48.json +1 -1
- package/fixtures/expected/card-stripe-eps.grid32.txt +1 -1
- package/fixtures/expected/card-stripe-eps.grid48.txt +1 -1
- package/fixtures/expected/card-stripe-eps.lines.json +1 -1
- package/fixtures/expected/card-stripe-eps.sheet32.json +1 -1
- package/fixtures/expected/card-stripe-eps.sheet48.json +1 -1
- package/fixtures/expected/card-stripe.grid32.txt +1 -1
- package/fixtures/expected/card-stripe.grid48.txt +1 -1
- package/fixtures/expected/card-stripe.lines.json +1 -1
- package/fixtures/expected/card-stripe.sheet32.json +1 -1
- package/fixtures/expected/card-stripe.sheet48.json +1 -1
- package/fixtures/expected/card-sumup.grid32.txt +1 -1
- package/fixtures/expected/card-sumup.grid48.txt +1 -1
- package/fixtures/expected/card-sumup.lines.json +1 -1
- package/fixtures/expected/card-sumup.sheet32.json +1 -1
- package/fixtures/expected/card-sumup.sheet48.json +1 -1
- package/fixtures/expected/code-table-receipt.long-item-name.iso8859_15.hex +1 -1
- package/fixtures/expected/code-table-receipt.long-item-name.pc437.hex +1 -1
- package/fixtures/expected/code-table-receipt.long-item-name.pc850.hex +1 -1
- package/fixtures/expected/code-table-receipt.long-item-name.pc858.hex +1 -1
- package/fixtures/expected/code-table-receipt.long-item-name.replacement.hex +1 -1
- package/fixtures/expected/code-table-receipt.long-item-name.wpc1252.hex +1 -1
- package/fixtures/expected/code-table-receipt.sale-cash.iso8859_15.hex +1 -1
- package/fixtures/expected/code-table-receipt.sale-cash.pc437.hex +1 -1
- package/fixtures/expected/code-table-receipt.sale-cash.pc850.hex +1 -1
- package/fixtures/expected/code-table-receipt.sale-cash.pc858.hex +1 -1
- package/fixtures/expected/code-table-receipt.sale-cash.replacement.hex +1 -1
- package/fixtures/expected/code-table-receipt.sale-cash.wpc1252.hex +1 -1
- package/fixtures/expected/code-table-receipt.special-characters.iso8859_15.hex +1 -1
- package/fixtures/expected/code-table-receipt.special-characters.pc437.hex +1 -1
- package/fixtures/expected/code-table-receipt.special-characters.pc850.hex +1 -1
- package/fixtures/expected/code-table-receipt.special-characters.pc858.hex +1 -1
- package/fixtures/expected/code-table-receipt.special-characters.replacement.hex +1 -1
- package/fixtures/expected/code-table-receipt.special-characters.wpc1252.hex +1 -1
- package/fixtures/expected/code-table-receipt.test-cashregister-sale.iso8859_15.hex +1 -1
- package/fixtures/expected/code-table-receipt.test-cashregister-sale.pc437.hex +1 -1
- package/fixtures/expected/code-table-receipt.test-cashregister-sale.pc850.hex +1 -1
- package/fixtures/expected/code-table-receipt.test-cashregister-sale.pc858.hex +1 -1
- package/fixtures/expected/code-table-receipt.test-cashregister-sale.replacement.hex +1 -1
- package/fixtures/expected/code-table-receipt.test-cashregister-sale.wpc1252.hex +1 -1
- package/fixtures/expected/discount-lines.grid32.txt +1 -1
- package/fixtures/expected/discount-lines.grid48.txt +1 -1
- package/fixtures/expected/discount-lines.lines.json +1 -1
- package/fixtures/expected/discount-lines.sheet32.json +1 -1
- package/fixtures/expected/discount-lines.sheet48.json +1 -1
- package/fixtures/expected/discount-owner-tip.grid32.txt +1 -1
- package/fixtures/expected/discount-owner-tip.grid48.txt +1 -1
- package/fixtures/expected/discount-owner-tip.lines.json +1 -1
- package/fixtures/expected/discount-owner-tip.sheet32.json +1 -1
- package/fixtures/expected/discount-owner-tip.sheet48.json +1 -1
- package/fixtures/expected/discount-simple.grid32.txt +1 -1
- package/fixtures/expected/discount-simple.grid48.txt +1 -1
- package/fixtures/expected/discount-simple.lines.json +1 -1
- package/fixtures/expected/discount-simple.sheet32.json +1 -1
- package/fixtures/expected/discount-simple.sheet48.json +1 -1
- package/fixtures/expected/discount-tip.grid32.txt +1 -1
- package/fixtures/expected/discount-tip.grid48.txt +1 -1
- package/fixtures/expected/discount-tip.lines.json +1 -1
- package/fixtures/expected/discount-tip.sheet32.json +1 -1
- package/fixtures/expected/discount-tip.sheet48.json +1 -1
- package/fixtures/expected/discount-value-voucher.grid32.txt +1 -1
- package/fixtures/expected/discount-value-voucher.grid48.txt +1 -1
- package/fixtures/expected/discount-value-voucher.lines.json +1 -1
- package/fixtures/expected/discount-value-voucher.sheet32.json +1 -1
- package/fixtures/expected/discount-value-voucher.sheet48.json +1 -1
- package/fixtures/expected/duplicate.cancellation-full.hex +44 -0
- package/fixtures/expected/duplicate.cancellation-partial.hex +33 -0
- package/fixtures/expected/duplicate.sale-cash-mm58.hex +28 -0
- package/fixtures/expected/duplicate.sale-cash-twice.hex +35 -0
- package/fixtures/expected/duplicate.sale-cash.hex +35 -0
- package/fixtures/expected/duplicate.shift-close.hex +43 -0
- package/fixtures/expected/duplicate.summer-time-last-second.hex +28 -0
- package/fixtures/expected/duplicate.summer-time-start.hex +35 -0
- package/fixtures/expected/duplicate.test-cashregister-sale-logo.hex +189 -0
- package/fixtures/expected/duplicate.voucher-multi-purpose-redeem.hex +37 -0
- package/fixtures/expected/duplicate.voucher-service-redeem-logo.hex +119 -0
- package/fixtures/expected/duplicate.winter-time-first-second.hex +28 -0
- package/fixtures/expected/duplicate.zero-start.hex +40 -0
- package/fixtures/expected/long-item-name.grid32.txt +1 -1
- package/fixtures/expected/long-item-name.grid48.txt +1 -1
- package/fixtures/expected/long-item-name.lines.json +1 -1
- package/fixtures/expected/long-item-name.sheet32.json +1 -1
- package/fixtures/expected/long-item-name.sheet48.json +1 -1
- package/fixtures/expected/sale-card.grid32.txt +1 -1
- package/fixtures/expected/sale-card.grid48.txt +1 -1
- package/fixtures/expected/sale-card.lines.json +1 -1
- package/fixtures/expected/sale-card.sheet32.json +1 -1
- package/fixtures/expected/sale-card.sheet48.json +1 -1
- package/fixtures/expected/sale-cash.grid32.txt +1 -1
- package/fixtures/expected/sale-cash.grid48.txt +1 -1
- package/fixtures/expected/sale-cash.lines.json +1 -1
- package/fixtures/expected/sale-cash.sheet32.json +1 -1
- package/fixtures/expected/sale-cash.sheet48.json +1 -1
- package/fixtures/expected/sale-small-business.grid32.txt +1 -1
- package/fixtures/expected/sale-small-business.grid48.txt +1 -1
- package/fixtures/expected/sale-small-business.lines.json +1 -1
- package/fixtures/expected/sale-small-business.sheet32.json +1 -1
- package/fixtures/expected/sale-small-business.sheet48.json +1 -1
- package/fixtures/expected/signature-outage-sale.grid32.txt +1 -1
- package/fixtures/expected/signature-outage-sale.grid48.txt +1 -1
- package/fixtures/expected/signature-outage-sale.lines.json +1 -1
- package/fixtures/expected/signature-outage-sale.sheet32.json +1 -1
- package/fixtures/expected/signature-outage-sale.sheet48.json +1 -1
- package/fixtures/expected/split-card-card-cash.grid32.txt +1 -1
- package/fixtures/expected/split-card-card-cash.grid48.txt +1 -1
- package/fixtures/expected/split-card-card-cash.lines.json +1 -1
- package/fixtures/expected/split-card-card-cash.sheet32.json +1 -1
- package/fixtures/expected/split-card-card-cash.sheet48.json +1 -1
- package/fixtures/expected/split-cash-change.grid32.txt +1 -1
- package/fixtures/expected/split-cash-change.grid48.txt +1 -1
- package/fixtures/expected/split-cash-change.lines.json +1 -1
- package/fixtures/expected/split-cash-change.sheet32.json +1 -1
- package/fixtures/expected/split-cash-change.sheet48.json +1 -1
- package/fixtures/expected/split-long-amount.grid32.txt +1 -1
- package/fixtures/expected/split-long-amount.grid48.txt +1 -1
- package/fixtures/expected/split-long-amount.lines.json +1 -1
- package/fixtures/expected/split-long-amount.sheet32.json +1 -1
- package/fixtures/expected/split-long-amount.sheet48.json +1 -1
- package/fixtures/expected/split-one-card-tip.grid32.txt +1 -1
- package/fixtures/expected/split-one-card-tip.grid48.txt +1 -1
- package/fixtures/expected/split-one-card-tip.lines.json +1 -1
- package/fixtures/expected/split-one-card-tip.sheet32.json +1 -1
- package/fixtures/expected/split-one-card-tip.sheet48.json +1 -1
- package/fixtures/expected/split-table-round-tip.grid32.txt +1 -1
- package/fixtures/expected/split-table-round-tip.grid48.txt +1 -1
- package/fixtures/expected/split-table-round-tip.lines.json +1 -1
- package/fixtures/expected/split-table-round-tip.sheet32.json +1 -1
- package/fixtures/expected/split-table-round-tip.sheet48.json +1 -1
- package/fixtures/expected/split-tip-card.grid32.txt +1 -1
- package/fixtures/expected/split-tip-card.grid48.txt +1 -1
- package/fixtures/expected/split-tip-card.lines.json +1 -1
- package/fixtures/expected/split-tip-card.sheet32.json +1 -1
- package/fixtures/expected/split-tip-card.sheet48.json +1 -1
- package/fixtures/expected/split-two-cards-same-provider.grid32.txt +1 -1
- package/fixtures/expected/split-two-cards-same-provider.grid48.txt +1 -1
- package/fixtures/expected/split-two-cards-same-provider.lines.json +1 -1
- package/fixtures/expected/split-two-cards-same-provider.sheet32.json +1 -1
- package/fixtures/expected/split-two-cards-same-provider.sheet48.json +1 -1
- package/fixtures/expected/test-cashregister-sale.grid32.txt +1 -1
- package/fixtures/expected/test-cashregister-sale.grid48.txt +1 -1
- package/fixtures/expected/test-cashregister-sale.lines.json +1 -1
- package/fixtures/expected/test-cashregister-sale.sheet32.json +1 -1
- package/fixtures/expected/test-cashregister-sale.sheet48.json +1 -1
- package/fixtures/expected/test-signature-sale.grid32.txt +1 -1
- package/fixtures/expected/test-signature-sale.grid48.txt +1 -1
- package/fixtures/expected/test-signature-sale.lines.json +1 -1
- package/fixtures/expected/test-signature-sale.sheet32.json +1 -1
- package/fixtures/expected/test-signature-sale.sheet48.json +1 -1
- package/fixtures/expected/training.grid32.txt +1 -1
- package/fixtures/expected/training.grid48.txt +1 -1
- package/fixtures/expected/training.lines.json +1 -1
- package/fixtures/expected/training.sheet32.json +1 -1
- package/fixtures/expected/training.sheet48.json +1 -1
- package/fixtures/expected/voucher-multi-purpose-sale.grid32.txt +1 -2
- package/fixtures/expected/voucher-multi-purpose-sale.grid48.txt +1 -1
- package/fixtures/expected/voucher-multi-purpose-sale.lines.json +1 -1
- package/fixtures/expected/voucher-multi-purpose-sale.sheet32.json +1 -7
- package/fixtures/expected/voucher-multi-purpose-sale.sheet48.json +1 -1
- package/fixtures/expected/voucher-single-purpose-redeem-exempt.grid32.txt +1 -1
- package/fixtures/expected/voucher-single-purpose-redeem-exempt.grid48.txt +1 -1
- package/fixtures/expected/voucher-single-purpose-redeem-exempt.lines.json +1 -1
- package/fixtures/expected/voucher-single-purpose-redeem-exempt.sheet32.json +1 -1
- package/fixtures/expected/voucher-single-purpose-redeem-exempt.sheet48.json +1 -1
- package/fixtures/expected/voucher-single-purpose-redeem.grid32.txt +1 -1
- package/fixtures/expected/voucher-single-purpose-redeem.grid48.txt +1 -1
- package/fixtures/expected/voucher-single-purpose-redeem.lines.json +1 -1
- package/fixtures/expected/voucher-single-purpose-redeem.sheet32.json +1 -1
- package/fixtures/expected/voucher-single-purpose-redeem.sheet48.json +1 -1
- package/fixtures/expected/voucher-single-purpose-sale.grid32.txt +2 -3
- package/fixtures/expected/voucher-single-purpose-sale.grid48.txt +2 -2
- package/fixtures/expected/voucher-single-purpose-sale.lines.json +2 -2
- package/fixtures/expected/voucher-single-purpose-sale.sheet32.json +2 -8
- package/fixtures/expected/voucher-single-purpose-sale.sheet48.json +2 -2
- package/fixtures/expected/zero-annual.grid32.txt +1 -1
- package/fixtures/expected/zero-annual.grid48.txt +1 -1
- package/fixtures/expected/zero-annual.lines.json +1 -1
- package/fixtures/expected/zero-annual.sheet32.json +1 -1
- package/fixtures/expected/zero-annual.sheet48.json +1 -1
- package/fixtures/expected/zero-final.grid32.txt +1 -1
- package/fixtures/expected/zero-final.grid48.txt +1 -1
- package/fixtures/expected/zero-final.lines.json +1 -1
- package/fixtures/expected/zero-final.sheet32.json +1 -1
- package/fixtures/expected/zero-final.sheet48.json +1 -1
- package/fixtures/expected/zero-manual.grid32.txt +1 -1
- package/fixtures/expected/zero-manual.grid48.txt +1 -1
- package/fixtures/expected/zero-manual.lines.json +1 -1
- package/fixtures/expected/zero-manual.sheet32.json +1 -1
- package/fixtures/expected/zero-manual.sheet48.json +1 -1
- package/fixtures/expected/zero-monthly.grid32.txt +1 -1
- package/fixtures/expected/zero-monthly.grid48.txt +1 -1
- package/fixtures/expected/zero-monthly.lines.json +1 -1
- package/fixtures/expected/zero-monthly.sheet32.json +1 -1
- package/fixtures/expected/zero-monthly.sheet48.json +1 -1
- package/fixtures/expected/zero-outage-end.grid32.txt +1 -1
- package/fixtures/expected/zero-outage-end.grid48.txt +1 -1
- package/fixtures/expected/zero-outage-end.lines.json +1 -1
- package/fixtures/expected/zero-outage-end.sheet32.json +1 -1
- package/fixtures/expected/zero-outage-end.sheet48.json +1 -1
- package/fixtures/expected/zero-start.grid32.txt +1 -1
- package/fixtures/expected/zero-start.grid48.txt +1 -1
- package/fixtures/expected/zero-start.lines.json +1 -1
- package/fixtures/expected/zero-start.sheet32.json +1 -1
- package/fixtures/expected/zero-start.sheet48.json +1 -1
- package/fixtures/hobex-hps-codes.json +1 -1
- package/fixtures/invoice-api.schema.json +3 -2
- package/fixtures/invoice-texts.json +1 -1
- package/fixtures/manifest.json +260 -260
- package/fixtures/pos-texts.json +118 -1
- package/fixtures/receipt-due-voucher-generated.json +2 -2
- package/fixtures/receipt-outputs-cases.json +2778 -0
- package/fixtures/receipts/cancellation-discount.json +1 -1
- package/fixtures/receipts/cancellation-full.json +1 -1
- package/fixtures/receipts/cancellation-partial.json +1 -1
- package/fixtures/receipts/cancellation-split-full.json +1 -1
- package/fixtures/receipts/cancellation-split-partial.json +1 -1
- package/fixtures/receipts/card-custom.json +1 -1
- package/fixtures/receipts/card-gptom-ios.json +1 -1
- package/fixtures/receipts/card-gptom.json +1 -1
- package/fixtures/receipts/card-hobex-cloud.json +1 -1
- package/fixtures/receipts/card-hobex-hps.json +1 -1
- package/fixtures/receipts/card-mypos.json +1 -1
- package/fixtures/receipts/card-stripe-eps.json +1 -1
- package/fixtures/receipts/card-stripe.json +1 -1
- package/fixtures/receipts/card-sumup.json +1 -1
- package/fixtures/receipts/discount-lines.json +1 -1
- package/fixtures/receipts/discount-owner-tip.json +1 -1
- package/fixtures/receipts/discount-simple.json +1 -1
- package/fixtures/receipts/discount-tip.json +1 -1
- package/fixtures/receipts/discount-value-voucher.json +1 -1
- package/fixtures/receipts/long-item-name.json +1 -1
- package/fixtures/receipts/sale-card.json +1 -1
- package/fixtures/receipts/sale-cash.json +1 -1
- package/fixtures/receipts/sale-small-business.json +1 -1
- package/fixtures/receipts/signature-outage-sale.json +1 -1
- package/fixtures/receipts/split-card-card-cash.json +1 -1
- package/fixtures/receipts/split-cash-change.json +1 -1
- package/fixtures/receipts/split-long-amount.json +1 -1
- package/fixtures/receipts/split-one-card-tip.json +1 -1
- package/fixtures/receipts/split-table-round-tip.json +1 -1
- package/fixtures/receipts/split-tip-card.json +1 -1
- package/fixtures/receipts/split-two-cards-same-provider.json +1 -1
- package/fixtures/receipts/test-cashregister-sale.json +1 -1
- package/fixtures/receipts/test-signature-sale.json +1 -1
- package/fixtures/receipts/training.json +1 -1
- package/fixtures/receipts/zero-annual.json +1 -1
- package/fixtures/receipts/zero-final.json +1 -1
- package/fixtures/receipts/zero-manual.json +1 -1
- package/fixtures/receipts/zero-monthly.json +1 -1
- package/fixtures/receipts/zero-outage-end.json +1 -1
- package/fixtures/receipts/zero-start.json +1 -1
- package/fixtures/surface.json +30 -7
- package/fixtures/v3/README.md +10 -3
- package/fixtures/v3/antworten/belege.json +623 -125
- package/fixtures/v3/antworten/belegmail.json +2 -2
- package/fixtures/v3/antworten/kasse-belege.json +622 -122
- package/fixtures/v3/antworten/kasse.json +479 -38
- package/fixtures/v3/antworten/lager.json +1 -1
- package/fixtures/v3/antworten/rechnungen.json +4 -4
- package/fixtures/v3/antworten/storno.json +211 -3
- package/fixtures/v3/stored/belege.json +2 -2
- package/fixtures/v3/stored/kasse.json +262 -382
- package/fixtures/v3/stored/rechnungen.json +157 -17
- package/fixtures/v3/v3-vokabular.json +311 -28
- package/fixtures/v3/zahlbetrag-faelle.json +1070 -4
- package/package.json +3 -1
- package/dist/cjs/stored/gutscheine.d.ts +0 -3
- package/dist/cjs/stored/gutscheine.js +0 -60
- package/dist/esm/stored/gutscheine.d.ts +0 -3
- package/dist/esm/stored/gutscheine.js +0 -56
package/dist/esm/pos/texte.d.ts
CHANGED
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
* `only`), die Platzhalter und die Arten der Fehlerregeln (Abschnitte
|
|
21
21
|
* `placeholders` und `structure`).
|
|
22
22
|
*/
|
|
23
|
+
import type { ReceiptOutput } from '../models/receipt-output.js';
|
|
23
24
|
import { type ErrorOutcome } from '../client/errors.js';
|
|
24
25
|
export type Surface = 'web' | 'app';
|
|
25
26
|
export interface TextEntry {
|
|
@@ -1669,6 +1670,9 @@ declare const BESCHRIFTUNGEN_ROH: {
|
|
|
1669
1670
|
readonly 'drawer.reason_shift_close': {
|
|
1670
1671
|
readonly text: "Schichtabschluss";
|
|
1671
1672
|
};
|
|
1673
|
+
readonly 'drawer.reason_voucher_payout': {
|
|
1674
|
+
readonly text: "Gutschein-Auszahlung";
|
|
1675
|
+
};
|
|
1672
1676
|
readonly 'shift.resend': {
|
|
1673
1677
|
readonly text: "Erneut senden";
|
|
1674
1678
|
};
|
|
@@ -1766,6 +1770,79 @@ declare const BESCHRIFTUNGEN_ROH: {
|
|
|
1766
1770
|
readonly text: "Gutschein ····-{suffix}";
|
|
1767
1771
|
readonly placeholders: readonly ["suffix"];
|
|
1768
1772
|
};
|
|
1773
|
+
readonly 'quantity.at_most': {
|
|
1774
|
+
readonly text: "höchstens {count}";
|
|
1775
|
+
readonly placeholders: readonly ["count"];
|
|
1776
|
+
};
|
|
1777
|
+
readonly 'quantity.at_least': {
|
|
1778
|
+
readonly text: "mindestens {count}";
|
|
1779
|
+
readonly placeholders: readonly ["count"];
|
|
1780
|
+
};
|
|
1781
|
+
readonly 'receipts.number_hint': {
|
|
1782
|
+
readonly text: "Nummer";
|
|
1783
|
+
};
|
|
1784
|
+
readonly 'receipts.clear_number': {
|
|
1785
|
+
readonly text: "Nummer löschen";
|
|
1786
|
+
};
|
|
1787
|
+
readonly 'receipts.open': {
|
|
1788
|
+
readonly text: "Öffnen";
|
|
1789
|
+
};
|
|
1790
|
+
readonly 'receipt.creating': {
|
|
1791
|
+
readonly text: "Beleg wird erstellt …";
|
|
1792
|
+
};
|
|
1793
|
+
readonly 'receipt_done.sale_title': {
|
|
1794
|
+
readonly text: "Verkauf abgeschlossen";
|
|
1795
|
+
};
|
|
1796
|
+
readonly 'receipt_done.paid_by_voucher': {
|
|
1797
|
+
readonly text: "mit Gutschein bezahlt";
|
|
1798
|
+
};
|
|
1799
|
+
readonly 'receipt_done.payout_title': {
|
|
1800
|
+
readonly text: "Auszahlung abgeschlossen";
|
|
1801
|
+
};
|
|
1802
|
+
readonly 'receipt_done.paid_out': {
|
|
1803
|
+
readonly text: "{method} ausgezahlt";
|
|
1804
|
+
readonly placeholders: readonly ["method"];
|
|
1805
|
+
};
|
|
1806
|
+
readonly 'voucher.code_mask': {
|
|
1807
|
+
readonly text: "····-{suffix}";
|
|
1808
|
+
readonly placeholders: readonly ["suffix"];
|
|
1809
|
+
};
|
|
1810
|
+
readonly 'cart.close': {
|
|
1811
|
+
readonly text: "Warenkorb schließen";
|
|
1812
|
+
};
|
|
1813
|
+
readonly 'nav.register': {
|
|
1814
|
+
readonly text: "Kasse";
|
|
1815
|
+
};
|
|
1816
|
+
readonly 'nav.receipts': {
|
|
1817
|
+
readonly text: "Belege";
|
|
1818
|
+
};
|
|
1819
|
+
readonly 'nav.vouchers': {
|
|
1820
|
+
readonly text: "Gutscheine";
|
|
1821
|
+
};
|
|
1822
|
+
readonly 'nav.open_drawer': {
|
|
1823
|
+
readonly text: "Kassenlade öffnen";
|
|
1824
|
+
};
|
|
1825
|
+
readonly 'nav.stocktake': {
|
|
1826
|
+
readonly text: "Inventur";
|
|
1827
|
+
};
|
|
1828
|
+
readonly 'nav.settings': {
|
|
1829
|
+
readonly text: "Einstellungen";
|
|
1830
|
+
};
|
|
1831
|
+
readonly 'nav.settings_locked': {
|
|
1832
|
+
readonly text: "nur mit Chef-Anmeldung";
|
|
1833
|
+
};
|
|
1834
|
+
readonly 'nav.logout': {
|
|
1835
|
+
readonly text: "Abmelden";
|
|
1836
|
+
};
|
|
1837
|
+
readonly 'nav.logging_out': {
|
|
1838
|
+
readonly text: "Wird abgemeldet …";
|
|
1839
|
+
};
|
|
1840
|
+
readonly 'nav.fullscreen': {
|
|
1841
|
+
readonly text: "Vollbild";
|
|
1842
|
+
};
|
|
1843
|
+
readonly 'nav.fullscreen_exit': {
|
|
1844
|
+
readonly text: "Vollbild verlassen";
|
|
1845
|
+
};
|
|
1769
1846
|
readonly 'voucher.covers_items': {
|
|
1770
1847
|
readonly text: "Deckt: {items}";
|
|
1771
1848
|
readonly placeholders: readonly ["items"];
|
|
@@ -1988,6 +2065,35 @@ declare const BESCHRIFTUNGEN_ROH: {
|
|
|
1988
2065
|
readonly text: "{amount} auszahlen";
|
|
1989
2066
|
readonly placeholders: readonly ["amount"];
|
|
1990
2067
|
};
|
|
2068
|
+
readonly 'receipt.outputs_title': {
|
|
2069
|
+
readonly text: "Ausgaben";
|
|
2070
|
+
};
|
|
2071
|
+
readonly 'receipt.outputs_count': {
|
|
2072
|
+
readonly text: "{count} Ausgaben";
|
|
2073
|
+
readonly placeholders: readonly ["count"];
|
|
2074
|
+
};
|
|
2075
|
+
readonly 'receipt.output_print': {
|
|
2076
|
+
readonly text: "Erstdruck";
|
|
2077
|
+
};
|
|
2078
|
+
readonly 'receipt.output_reprint': {
|
|
2079
|
+
readonly text: "Duplikat";
|
|
2080
|
+
};
|
|
2081
|
+
readonly 'receipt.output_email': {
|
|
2082
|
+
readonly text: "E-Mail";
|
|
2083
|
+
};
|
|
2084
|
+
readonly 'receipt.output_link_shared': {
|
|
2085
|
+
readonly text: "Link geteilt";
|
|
2086
|
+
};
|
|
2087
|
+
readonly 'receipt.output_pdf_shared': {
|
|
2088
|
+
readonly text: "PDF geteilt";
|
|
2089
|
+
};
|
|
2090
|
+
readonly 'receipt.output_opened': {
|
|
2091
|
+
readonly text: "Link geöffnet ({count}×)";
|
|
2092
|
+
readonly placeholders: readonly ["count"];
|
|
2093
|
+
};
|
|
2094
|
+
readonly 'receipt.output_failed': {
|
|
2095
|
+
readonly text: "fehlgeschlagen";
|
|
2096
|
+
};
|
|
1991
2097
|
};
|
|
1992
2098
|
export type LabelKey = keyof typeof BESCHRIFTUNGEN_ROH;
|
|
1993
2099
|
export declare const LABELS: Record<LabelKey, TextEntry>;
|
|
@@ -2002,6 +2108,14 @@ export declare const RETURN_DISPOSITION_LABELS: {
|
|
|
2002
2108
|
readonly defective: "stock.return_defective";
|
|
2003
2109
|
readonly disposed: "stock.return_disposed";
|
|
2004
2110
|
};
|
|
2111
|
+
/**
|
|
2112
|
+
* Die Beschriftung der Art einer Ausgabe (Belegdetail, Zeile „Ausgaben“), nie
|
|
2113
|
+
* eine Ausnahme: `null` bei einer Art, die dieses Paket nicht kennt (neuerer
|
|
2114
|
+
* Server); `opened` ohne gueltige Anzahl (ganze Zahl ab 1) zaehlt als ein
|
|
2115
|
+
* Abruf. Nur die Art: „fehlgeschlagen“ (`receipt.output_failed`) setzt die
|
|
2116
|
+
* Kasse selbst dazu, wenn `result` `failed` ist.
|
|
2117
|
+
*/
|
|
2118
|
+
export declare function receiptOutputLabel(output: ReceiptOutput): string | null;
|
|
2005
2119
|
/** Die Beschriftung zum Schluessel, Platzhalter ersetzt; fehlt ein Wert, wirft es wie `messageText`. */
|
|
2006
2120
|
export declare function labelText(key: LabelKey, values?: Record<string, string | number>): string;
|
|
2007
2121
|
/** Der Satz zum Schluessel, Platzhalter ersetzt. Fehlt ein Wert, wirft es — ein `{status}` am Tresen waere schlimmer. */
|
package/dist/esm/pos/texte.js
CHANGED
|
@@ -867,6 +867,7 @@ const BESCHRIFTUNGEN_ROH = {
|
|
|
867
867
|
'drawer.reason_cash_movement': { text: 'Kassenbewegung' },
|
|
868
868
|
'drawer.reason_shift_open': { text: 'Schichtbeginn' },
|
|
869
869
|
'drawer.reason_shift_close': { text: 'Schichtabschluss' },
|
|
870
|
+
'drawer.reason_voucher_payout': { text: 'Gutschein-Auszahlung' },
|
|
870
871
|
'shift.resend': { text: 'Erneut senden' },
|
|
871
872
|
'shift.next': { text: 'Weiter' },
|
|
872
873
|
'shift.print_close': { text: 'Schichtabschluss drucken' },
|
|
@@ -899,6 +900,30 @@ const BESCHRIFTUNGEN_ROH = {
|
|
|
899
900
|
'voucher.service': { text: 'Leistungsgutschein' },
|
|
900
901
|
'voucher.promotion': { text: 'Aktionsgutschein' },
|
|
901
902
|
'voucher.payment_line': { text: 'Gutschein ····-{suffix}', placeholders: ['suffix'] },
|
|
903
|
+
// Kassen-Navigation, Beleg-Fertig-Seite, Mengen (Paket-Nachzug Gutscheine).
|
|
904
|
+
'quantity.at_most': { text: 'höchstens {count}', placeholders: ['count'] },
|
|
905
|
+
'quantity.at_least': { text: 'mindestens {count}', placeholders: ['count'] },
|
|
906
|
+
'receipts.number_hint': { text: 'Nummer' },
|
|
907
|
+
'receipts.clear_number': { text: 'Nummer löschen' },
|
|
908
|
+
'receipts.open': { text: 'Öffnen' },
|
|
909
|
+
'receipt.creating': { text: 'Beleg wird erstellt …' },
|
|
910
|
+
'receipt_done.sale_title': { text: 'Verkauf abgeschlossen' },
|
|
911
|
+
'receipt_done.paid_by_voucher': { text: 'mit Gutschein bezahlt' },
|
|
912
|
+
'receipt_done.payout_title': { text: 'Auszahlung abgeschlossen' },
|
|
913
|
+
'receipt_done.paid_out': { text: '{method} ausgezahlt', placeholders: ['method'] },
|
|
914
|
+
'voucher.code_mask': { text: '····-{suffix}', placeholders: ['suffix'] },
|
|
915
|
+
'cart.close': { text: 'Warenkorb schließen' },
|
|
916
|
+
'nav.register': { text: 'Kasse' },
|
|
917
|
+
'nav.receipts': { text: 'Belege' },
|
|
918
|
+
'nav.vouchers': { text: 'Gutscheine' },
|
|
919
|
+
'nav.open_drawer': { text: 'Kassenlade öffnen' },
|
|
920
|
+
'nav.stocktake': { text: 'Inventur' },
|
|
921
|
+
'nav.settings': { text: 'Einstellungen' },
|
|
922
|
+
'nav.settings_locked': { text: 'nur mit Chef-Anmeldung' },
|
|
923
|
+
'nav.logout': { text: 'Abmelden' },
|
|
924
|
+
'nav.logging_out': { text: 'Wird abgemeldet …' },
|
|
925
|
+
'nav.fullscreen': { text: 'Vollbild' },
|
|
926
|
+
'nav.fullscreen_exit': { text: 'Vollbild verlassen' },
|
|
902
927
|
'voucher.covers_items': { text: 'Deckt: {items}', placeholders: ['items'] },
|
|
903
928
|
'voucher.code_shown_once': { text: 'Code nur jetzt sichtbar: {code}', placeholders: ['code'] },
|
|
904
929
|
'voucher.not_in_split': { text: 'Gutscheine gehen beim getrennten Kassieren nicht.' },
|
|
@@ -975,6 +1000,18 @@ const BESCHRIFTUNGEN_ROH = {
|
|
|
975
1000
|
'shift.pay_outs': { text: 'Auszahlungen' },
|
|
976
1001
|
'cash_movement.pay_in_amount': { text: '{amount} einzahlen', placeholders: ['amount'] },
|
|
977
1002
|
'cash_movement.pay_out_amount': { text: '{amount} auszahlen', placeholders: ['amount'] },
|
|
1003
|
+
// Belegdetail: Zeile „Ausgaben“ (eingeklappt mit Anzahl), aufgeklappt je Eintrag die Art
|
|
1004
|
+
// (`receipt.output_<kind>`, Arten wie RECEIPT_OUTPUT_KINDS), dazu „fehlgeschlagen“ bei Ergebnis `failed`.
|
|
1005
|
+
// `{count}` beim Abruf ist die Zahl der Abrufe in dieser Stunde.
|
|
1006
|
+
'receipt.outputs_title': { text: 'Ausgaben' },
|
|
1007
|
+
'receipt.outputs_count': { text: '{count} Ausgaben', placeholders: ['count'] },
|
|
1008
|
+
'receipt.output_print': { text: 'Erstdruck' },
|
|
1009
|
+
'receipt.output_reprint': { text: 'Duplikat' },
|
|
1010
|
+
'receipt.output_email': { text: 'E-Mail' },
|
|
1011
|
+
'receipt.output_link_shared': { text: 'Link geteilt' },
|
|
1012
|
+
'receipt.output_pdf_shared': { text: 'PDF geteilt' },
|
|
1013
|
+
'receipt.output_opened': { text: 'Link geöffnet ({count}×)', placeholders: ['count'] },
|
|
1014
|
+
'receipt.output_failed': { text: 'fehlgeschlagen' },
|
|
978
1015
|
};
|
|
979
1016
|
export const LABELS = BESCHRIFTUNGEN_ROH;
|
|
980
1017
|
/**
|
|
@@ -988,6 +1025,32 @@ export const RETURN_DISPOSITION_LABELS = {
|
|
|
988
1025
|
defective: 'stock.return_defective',
|
|
989
1026
|
disposed: 'stock.return_disposed',
|
|
990
1027
|
};
|
|
1028
|
+
/** Art einer Ausgabe -> Beschriftung (`receipt.output_<kind>`). */
|
|
1029
|
+
const AUSGABE_BESCHRIFTUNG = {
|
|
1030
|
+
print: 'receipt.output_print',
|
|
1031
|
+
reprint: 'receipt.output_reprint',
|
|
1032
|
+
email: 'receipt.output_email',
|
|
1033
|
+
link_shared: 'receipt.output_link_shared',
|
|
1034
|
+
pdf_shared: 'receipt.output_pdf_shared',
|
|
1035
|
+
opened: 'receipt.output_opened',
|
|
1036
|
+
};
|
|
1037
|
+
/**
|
|
1038
|
+
* Die Beschriftung der Art einer Ausgabe (Belegdetail, Zeile „Ausgaben“), nie
|
|
1039
|
+
* eine Ausnahme: `null` bei einer Art, die dieses Paket nicht kennt (neuerer
|
|
1040
|
+
* Server); `opened` ohne gueltige Anzahl (ganze Zahl ab 1) zaehlt als ein
|
|
1041
|
+
* Abruf. Nur die Art: „fehlgeschlagen“ (`receipt.output_failed`) setzt die
|
|
1042
|
+
* Kasse selbst dazu, wenn `result` `failed` ist.
|
|
1043
|
+
*/
|
|
1044
|
+
export function receiptOutputLabel(output) {
|
|
1045
|
+
const art = output?.kind;
|
|
1046
|
+
if (typeof art !== 'string' || !Object.prototype.hasOwnProperty.call(AUSGABE_BESCHRIFTUNG, art))
|
|
1047
|
+
return null;
|
|
1048
|
+
const key = AUSGABE_BESCHRIFTUNG[art];
|
|
1049
|
+
if (art !== 'opened')
|
|
1050
|
+
return labelText(key);
|
|
1051
|
+
const anzahl = output.count;
|
|
1052
|
+
return labelText(key, { count: typeof anzahl === 'number' && Number.isSafeInteger(anzahl) && anzahl >= 1 ? anzahl : 1 });
|
|
1053
|
+
}
|
|
991
1054
|
/** Die Beschriftung zum Schluessel, Platzhalter ersetzt; fehlt ein Wert, wirft es wie `messageText`. */
|
|
992
1055
|
export function labelText(key, values = {}) {
|
|
993
1056
|
return ersetze(`labelText(${key})`, LABELS[key].text, values);
|
|
@@ -183,7 +183,8 @@ export interface VoucherRedeemContext {
|
|
|
183
183
|
* Hoechstbetrag zum Vorbelegen einer Einloesung an der Kasse, in Cent, nie
|
|
184
184
|
* negativ: der groesste Betrag, den der Server fuer diesen Gutschein annimmt.
|
|
185
185
|
*
|
|
186
|
-
* Obergrenze: Saldo, offener Betrag
|
|
186
|
+
* Obergrenze: Saldo, offener Betrag ohne Trinkgeld (ein Gutschein deckt nie
|
|
187
|
+
* das Trinkgeld, Personal wie Inhaber); bei Einzweck die deckbaren Positionen im
|
|
187
188
|
* Topf seines Satzes abzueglich der schon gewaehlten Einloesungen dort. Befreit
|
|
188
189
|
* verkauft bzw. als Kleinunternehmer verteilt der Server anteilig auf alle
|
|
189
190
|
* Saetze (`kuTeile`); dann begrenzt jeder Topf: sein Anteil plus die schon
|
|
@@ -195,6 +196,7 @@ export interface VoucherRedeemContext {
|
|
|
195
196
|
* Bisektion ueber [1, Grenze] und prueft danach 16 Cent aufwaerts: am Rand
|
|
196
197
|
* des groessten Rests ist die Annahme nicht monoton. Leistung (wird ueber
|
|
197
198
|
* Positionen eingeloest), Aktion (Rabatt rechnet der Server) und jeder nicht
|
|
198
|
-
* aktive Gutschein: 0.
|
|
199
|
+
* aktive Gutschein: 0. Wirft nie [ReceiptDueError]: ist der Beleg ohne den
|
|
200
|
+
* Gutschein nicht rechenbar (etwa `tip_without_goods`), ist das Ergebnis 0.
|
|
199
201
|
*/
|
|
200
202
|
export declare function voucherRedeemMaxCents(items: readonly ReceiptItem[], voucher: VoucherCheck, before?: VoucherRedeemContext): number;
|
package/dist/esm/receipt/due.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ReceiptType, VoucherAction, VoucherType } from '../enums/index.js';
|
|
2
2
|
import { VoucherCode } from '@kreiseck/validator';
|
|
3
3
|
import { toViennaWallClock } from '../vienna-time.js';
|
|
4
|
-
import { centSumme, istDeckbar, kuSaetze, planeGutscheine, topfFuerSatz, } from './gutschein-plan.js';
|
|
4
|
+
import { centSumme, istDeckbar, kuSaetze, planeGutscheine, topfFuerSatz, trinkgeldCents, } from './gutschein-plan.js';
|
|
5
5
|
export { VOUCHER_ZERO_RATE_BUCKET_FROM } from './gutschein-plan.js';
|
|
6
6
|
/**
|
|
7
7
|
* Warum sich der Zahlbetrag nicht rechnen laesst. Fest wie ein Backend-Code;
|
|
@@ -101,6 +101,12 @@ function rechne(items, vouchers, receiptType, options) {
|
|
|
101
101
|
if (plan.mitPlan && dueCents + plan.auszahlungCents < 0) {
|
|
102
102
|
throw new ReceiptDueError('invalid_voucher', 'die Gutscheine uebersteigen die Summe des Belegs.', 'voucher_exceeds_total');
|
|
103
103
|
}
|
|
104
|
+
// Ein Gutschein deckt nie das Trinkgeld (Personal wie Inhaber): der Zahlbetrag nach den Gutscheinen
|
|
105
|
+
// muss die Trinkgeldzeilen tragen. Storno ausgenommen (dort gibt es keinen Plan).
|
|
106
|
+
const trinkgeld = trinkgeldCents(kunde);
|
|
107
|
+
if (plan.mitPlan && art !== 'cancellation' && trinkgeld > 0 && dueCents + plan.auszahlungCents < trinkgeld) {
|
|
108
|
+
throw new ReceiptDueError('invalid_voucher', 'die Gutscheine decken das Trinkgeld.', 'voucher_exceeds_total');
|
|
109
|
+
}
|
|
104
110
|
return {
|
|
105
111
|
ergebnis: {
|
|
106
112
|
dueCents,
|
|
@@ -124,7 +130,8 @@ function rechne(items, vouchers, receiptType, options) {
|
|
|
124
130
|
* Hoechstbetrag zum Vorbelegen einer Einloesung an der Kasse, in Cent, nie
|
|
125
131
|
* negativ: der groesste Betrag, den der Server fuer diesen Gutschein annimmt.
|
|
126
132
|
*
|
|
127
|
-
* Obergrenze: Saldo, offener Betrag
|
|
133
|
+
* Obergrenze: Saldo, offener Betrag ohne Trinkgeld (ein Gutschein deckt nie
|
|
134
|
+
* das Trinkgeld, Personal wie Inhaber); bei Einzweck die deckbaren Positionen im
|
|
128
135
|
* Topf seines Satzes abzueglich der schon gewaehlten Einloesungen dort. Befreit
|
|
129
136
|
* verkauft bzw. als Kleinunternehmer verteilt der Server anteilig auf alle
|
|
130
137
|
* Saetze (`kuTeile`); dann begrenzt jeder Topf: sein Anteil plus die schon
|
|
@@ -136,7 +143,8 @@ function rechne(items, vouchers, receiptType, options) {
|
|
|
136
143
|
* Bisektion ueber [1, Grenze] und prueft danach 16 Cent aufwaerts: am Rand
|
|
137
144
|
* des groessten Rests ist die Annahme nicht monoton. Leistung (wird ueber
|
|
138
145
|
* Positionen eingeloest), Aktion (Rabatt rechnet der Server) und jeder nicht
|
|
139
|
-
* aktive Gutschein: 0.
|
|
146
|
+
* aktive Gutschein: 0. Wirft nie [ReceiptDueError]: ist der Beleg ohne den
|
|
147
|
+
* Gutschein nicht rechenbar (etwa `tip_without_goods`), ist das Ergebnis 0.
|
|
140
148
|
*/
|
|
141
149
|
export function voucherRedeemMaxCents(items, voucher, before = {}) {
|
|
142
150
|
if (voucher.status !== 'active')
|
|
@@ -146,9 +154,18 @@ export function voucherRedeemMaxCents(items, voucher, before = {}) {
|
|
|
146
154
|
const saldo = Number.isInteger(voucher.balanceCents) ? voucher.balanceCents : 0;
|
|
147
155
|
const options = before.options ?? {};
|
|
148
156
|
const vorher = before.vouchers ?? [];
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
157
|
+
let r;
|
|
158
|
+
try {
|
|
159
|
+
r = rechne(items, vorher, 'standard', options);
|
|
160
|
+
}
|
|
161
|
+
catch (fehler) {
|
|
162
|
+
// Nicht rechenbar (etwa Trinkgeld ohne Ware): nichts vorbelegen, die Kasse meldet es beim Zahlbetrag.
|
|
163
|
+
if (fehler instanceof ReceiptDueError)
|
|
164
|
+
return 0;
|
|
165
|
+
throw fehler;
|
|
166
|
+
}
|
|
167
|
+
// Rundung je Topf: hoechstens ein halber Cent je Topf ueber dem offenen Betrag. Das Trinkgeld deckt nie ein Gutschein.
|
|
168
|
+
let oben = Math.min(saldo, r.ergebnis.dueCents + r.auszahlungCents - trinkgeldCents(r.kunde) + 6, HOECHSTBETRAG_CENTS);
|
|
152
169
|
if (voucher.type === 'single_purpose') {
|
|
153
170
|
const deckbar = r.kunde.filter(istDeckbar);
|
|
154
171
|
const topfBasis = (topf) => centSumme(deckbar.filter((it) => topfFuerSatz(it.vat) === topf));
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { ReceiptLayout } from './layout.js';
|
|
2
|
+
/**
|
|
3
|
+
* Kennzeichnet einen Nachdruck als **Belegduplikat**. Registrierkassen-Erlass
|
|
4
|
+
* BMF-AV Nr. 2/2026, Abschnitt 4.5.6: „Ein Belegduplikat ist als solches zu
|
|
5
|
+
* bezeichnen, nicht nochmals zu signieren, nicht neuerlich im
|
|
6
|
+
* Datenerfassungsprotokoll aufzunehmen und darf zu keiner Veränderung des
|
|
7
|
+
* Umsatzzählers führen.“ Signatur, DEP und Zähler bleiben ohnehin unberührt,
|
|
8
|
+
* weil ein Nachdruck den gespeicherten Beleg druckt; diese Funktion liefert
|
|
9
|
+
* die Bezeichnung.
|
|
10
|
+
*
|
|
11
|
+
* Die Kasse ruft sie bei **jedem** Nachdruck und bei „Kopie drucken“ mit dem
|
|
12
|
+
* Zeitpunkt des Drucks auf, nie beim Erstdruck und nie fuer Mail, Link oder
|
|
13
|
+
* PDF, und gibt das Ergebnis an denselben Druckweg (`escPosLayoutBytes`,
|
|
14
|
+
* `eposPrintXml`, `receiptSheet`, React-Ansicht).
|
|
15
|
+
*
|
|
16
|
+
* Neu ist genau eine Zeile im Kennungsblock, direkt unter `Beleg-ID:`, in
|
|
17
|
+
* der Spaltenform von `Datum:` (nicht fett, Wert rechtsbuendig):
|
|
18
|
+
*
|
|
19
|
+
* ```
|
|
20
|
+
* Beleg-ID: AT0-KASSE1-42
|
|
21
|
+
* Duplikat am: 24.10.2026 14:10:05
|
|
22
|
+
* ```
|
|
23
|
+
*
|
|
24
|
+
* `printedAt` ist ein Zeitpunkt; gedruckt wird er in Wiener Zeit
|
|
25
|
+
* (Sommerzeit nach EU-Regel), nie in der Zeitzone des Rechners. Ohne
|
|
26
|
+
* Spaltenzeile `Beleg-ID:` (Schicht-Bons) steht die Zeile ganz oben. Alles
|
|
27
|
+
* andere bleibt Zeile fuer Zeile wie beim Erstdruck.
|
|
28
|
+
*
|
|
29
|
+
* Reine Funktion: die Eingabe bleibt unangetastet, das Ergebnis ist eine
|
|
30
|
+
* eigene Kopie. Traegt das Layout schon eine Zeile `Duplikat am:`, bekommt
|
|
31
|
+
* nur sie die neue Zeit (der letzte Nachdruck gilt); es bleibt bei einer
|
|
32
|
+
* Zeile. Ein unbrauchbarer Zeitpunkt wirft `KasseneckValidationError`
|
|
33
|
+
* (`scope: 'request'`).
|
|
34
|
+
*/
|
|
35
|
+
export declare function markAsDuplicate(layout: ReceiptLayout, printedAt: Date): ReceiptLayout;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { KasseneckValidationError } from '../client/errors.js';
|
|
2
|
+
import { toViennaWallClock } from '../vienna-time.js';
|
|
3
|
+
/** Beschriftung der Duplikat-Zeile; derselbe Text im Dart-Zwilling. */
|
|
4
|
+
const DUPLIKAT_AM = 'Duplikat am:';
|
|
5
|
+
/**
|
|
6
|
+
* Spaltenbreiten in Zwoelfteln. 5:7 setzt Beschriftung (12 Zeichen) und Zeit
|
|
7
|
+
* (19 Zeichen) auf 32 und 48 Zeichen ohne Umbruch in eine Zeile, den Wert am
|
|
8
|
+
* rechten Rand wie bei `Datum:`: 13 + 19 bzw. 20 + 28 Zeichen. Die Breiten
|
|
9
|
+
* von `Beleg-ID:` (6:6) und `Datum:` (4:8) reichen auf 32 Zeichen nicht.
|
|
10
|
+
*/
|
|
11
|
+
const LINKS = 5;
|
|
12
|
+
const RECHTS = 7;
|
|
13
|
+
/** Eigene Kopie einer Zeile: wer am Duplikat dreht, dreht nie am Erstdruck. */
|
|
14
|
+
function kopie(zeile) {
|
|
15
|
+
return zeile.kind === 'columns' ? { ...zeile, columns: zeile.columns.map((c) => ({ ...c })) } : { ...zeile };
|
|
16
|
+
}
|
|
17
|
+
const istZeile = (z, beschriftung) => z.kind === 'columns' && z.columns[0]?.text === beschriftung;
|
|
18
|
+
/** Zeitpunkt als `TT.MM.JJJJ HH:MM:SS` in Wiener Zeit; Bruchteile fallen weg. */
|
|
19
|
+
function wienerZeit(zeitpunkt) {
|
|
20
|
+
const t = toViennaWallClock(zeitpunkt);
|
|
21
|
+
const zwei = (n) => String(n).padStart(2, '0');
|
|
22
|
+
return `${zwei(t.day)}.${zwei(t.month)}.${t.year} ${zwei(t.hour)}:${zwei(t.minute)}:${zwei(t.second)}`;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Kennzeichnet einen Nachdruck als **Belegduplikat**. Registrierkassen-Erlass
|
|
26
|
+
* BMF-AV Nr. 2/2026, Abschnitt 4.5.6: „Ein Belegduplikat ist als solches zu
|
|
27
|
+
* bezeichnen, nicht nochmals zu signieren, nicht neuerlich im
|
|
28
|
+
* Datenerfassungsprotokoll aufzunehmen und darf zu keiner Veränderung des
|
|
29
|
+
* Umsatzzählers führen.“ Signatur, DEP und Zähler bleiben ohnehin unberührt,
|
|
30
|
+
* weil ein Nachdruck den gespeicherten Beleg druckt; diese Funktion liefert
|
|
31
|
+
* die Bezeichnung.
|
|
32
|
+
*
|
|
33
|
+
* Die Kasse ruft sie bei **jedem** Nachdruck und bei „Kopie drucken“ mit dem
|
|
34
|
+
* Zeitpunkt des Drucks auf, nie beim Erstdruck und nie fuer Mail, Link oder
|
|
35
|
+
* PDF, und gibt das Ergebnis an denselben Druckweg (`escPosLayoutBytes`,
|
|
36
|
+
* `eposPrintXml`, `receiptSheet`, React-Ansicht).
|
|
37
|
+
*
|
|
38
|
+
* Neu ist genau eine Zeile im Kennungsblock, direkt unter `Beleg-ID:`, in
|
|
39
|
+
* der Spaltenform von `Datum:` (nicht fett, Wert rechtsbuendig):
|
|
40
|
+
*
|
|
41
|
+
* ```
|
|
42
|
+
* Beleg-ID: AT0-KASSE1-42
|
|
43
|
+
* Duplikat am: 24.10.2026 14:10:05
|
|
44
|
+
* ```
|
|
45
|
+
*
|
|
46
|
+
* `printedAt` ist ein Zeitpunkt; gedruckt wird er in Wiener Zeit
|
|
47
|
+
* (Sommerzeit nach EU-Regel), nie in der Zeitzone des Rechners. Ohne
|
|
48
|
+
* Spaltenzeile `Beleg-ID:` (Schicht-Bons) steht die Zeile ganz oben. Alles
|
|
49
|
+
* andere bleibt Zeile fuer Zeile wie beim Erstdruck.
|
|
50
|
+
*
|
|
51
|
+
* Reine Funktion: die Eingabe bleibt unangetastet, das Ergebnis ist eine
|
|
52
|
+
* eigene Kopie. Traegt das Layout schon eine Zeile `Duplikat am:`, bekommt
|
|
53
|
+
* nur sie die neue Zeit (der letzte Nachdruck gilt); es bleibt bei einer
|
|
54
|
+
* Zeile. Ein unbrauchbarer Zeitpunkt wirft `KasseneckValidationError`
|
|
55
|
+
* (`scope: 'request'`).
|
|
56
|
+
*/
|
|
57
|
+
export function markAsDuplicate(layout, printedAt) {
|
|
58
|
+
if (!(printedAt instanceof Date) || Number.isNaN(printedAt.getTime())) {
|
|
59
|
+
throw new KasseneckValidationError('markAsDuplicate', 'printedAt: kein gueltiger Zeitpunkt (Date)', 'request');
|
|
60
|
+
}
|
|
61
|
+
const neu = {
|
|
62
|
+
kind: 'columns',
|
|
63
|
+
columns: [
|
|
64
|
+
{ text: DUPLIKAT_AM, width: LINKS, align: 'left' },
|
|
65
|
+
{ text: wienerZeit(printedAt), width: RECHTS, align: 'right' },
|
|
66
|
+
],
|
|
67
|
+
};
|
|
68
|
+
const vorhanden = layout.lines.findIndex((z) => istZeile(z, DUPLIKAT_AM));
|
|
69
|
+
const lines = layout.lines.filter((z) => !istZeile(z, DUPLIKAT_AM)).map(kopie);
|
|
70
|
+
const stelle = vorhanden >= 0 ? vorhanden : lines.findIndex((z) => istZeile(z, 'Beleg-ID:')) + 1;
|
|
71
|
+
lines.splice(stelle, 0, neu);
|
|
72
|
+
return { ...layout, lines };
|
|
73
|
+
}
|
|
@@ -89,6 +89,8 @@ type TopfName = 'amountRateStandard' | 'amountRateReduced1' | 'amountRateReduced
|
|
|
89
89
|
export declare function topfFuerSatz(vat: number): TopfName;
|
|
90
90
|
/** Position, die ein Gutschein decken darf: weder Trinkgeld noch Gutscheinzeile. */
|
|
91
91
|
export declare function istDeckbar(p: Innen): boolean;
|
|
92
|
+
/** Summe der Trinkgeldzeilen (Personal und Inhaber) in Cent, wie `centSumme(kunde.filter(istTip))` im Backend. */
|
|
93
|
+
export declare function trinkgeldCents(kunde: readonly Innen[]): number;
|
|
92
94
|
/** Wie beleg-toepfe: Euro in Positionsreihenfolge aufsummieren, erst die Summe auf Cent runden. */
|
|
93
95
|
export declare function centSumme(liste: readonly Innen[]): number;
|
|
94
96
|
/** Die Saetze, auf die `kuTeile` verteilt: je Satz `centSumme` der deckbaren Positionen, nur positive. */
|
|
@@ -29,6 +29,10 @@ function istGutscheinZeile(p) {
|
|
|
29
29
|
export function istDeckbar(p) {
|
|
30
30
|
return p.tip == null && p.kind !== 'tip' && !istGutscheinZeile(p);
|
|
31
31
|
}
|
|
32
|
+
/** Summe der Trinkgeldzeilen (Personal und Inhaber) in Cent, wie `centSumme(kunde.filter(istTip))` im Backend. */
|
|
33
|
+
export function trinkgeldCents(kunde) {
|
|
34
|
+
return centSumme(kunde.filter((p) => p.tip != null || p.kind === 'tip'));
|
|
35
|
+
}
|
|
32
36
|
/** Wie beleg-toepfe: Euro in Positionsreihenfolge aufsummieren, erst die Summe auf Cent runden. */
|
|
33
37
|
export function centSumme(liste) {
|
|
34
38
|
return Math.round(liste.reduce((s, it) => s + it.priceOne * it.amount, 0) * 100);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { type LayoutAlign, type LayoutColumn, type LayoutTextLine, type LayoutColumnsLine, type LayoutRuleLine, type LayoutSpaceLine, type LayoutQrLine, type LayoutLine, type ReceiptLayout, type BuildReceiptLayoutOptions, buildReceiptLayout, receiptSignatureFailed, receiptSignatureIsTest, receiptIsZero, receiptAmountsAreZero, receiptIsSmallBusinessConsistent, receiptZdaText, CURRENT_LAYOUT_RULESET, type LayoutBannerLine, type LayoutBannerTone, type LayoutRuleset, SMALL_BUSINESS_NOTICE, formatCents, } from './layout.js';
|
|
2
|
+
export { markAsDuplicate } from './duplikat.js';
|
|
2
3
|
export { type EscPosLayoutOptions, type EscPosLayoutResult, type QrPrintMode, type PrintLogo, assertLogoRaster, escPosLayoutBytes, escPosLayoutResult, } from './layout-escpos.js';
|
|
3
4
|
export { type GridLine, type GridLineKind, type ReceiptGrid, type RenderReceiptGridOptions, renderReceiptGrid, gridColumnWidths, gridToText, CHARS_PER_PAPER_SIZE, } from './grid.js';
|
|
4
5
|
export { type EposPrintXmlOptions, type EposPrintResult, type EposDirectOptions, type EposResponse, EposConnectionError, eposPrintXml, eposPrintXmlResult, eposXmlEscape, eposImageXml, eposServiceUrl, eposSoapEnvelope, eposParseResponse, eposDirectPrint, eposDirectStatus } from './epos.js';
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { buildReceiptLayout, receiptSignatureFailed, receiptSignatureIsTest, receiptIsZero, receiptAmountsAreZero, receiptIsSmallBusinessConsistent, receiptZdaText, CURRENT_LAYOUT_RULESET, SMALL_BUSINESS_NOTICE, formatCents, } from './layout.js';
|
|
2
|
+
export { markAsDuplicate } from './duplikat.js';
|
|
2
3
|
export { assertLogoRaster, escPosLayoutBytes, escPosLayoutResult, } from './layout-escpos.js';
|
|
3
4
|
export { renderReceiptGrid, gridColumnWidths, gridToText, CHARS_PER_PAPER_SIZE, } from './grid.js';
|
|
4
5
|
export { EposConnectionError, eposPrintXml, eposPrintXmlResult, eposXmlEscape, eposImageXml, eposServiceUrl, eposSoapEnvelope, eposParseResponse, eposDirectPrint, eposDirectStatus } from './epos.js';
|
|
@@ -441,19 +441,31 @@ function barZeilen(zahlung) {
|
|
|
441
441
|
*/
|
|
442
442
|
function zahlungsZeilen(receipt) {
|
|
443
443
|
const zahlungen = receipt.payments;
|
|
444
|
+
// Trägt der Beleg eine Gutschein-Zahlungszeile, entfällt, was 0 Cent kostet
|
|
445
|
+
// (§ 132a Abs. 3 BAO: die Zahlungsart ist kein Pflichtinhalt, der Betrag bleibt).
|
|
446
|
+
const mitGutschein = receipt.vouchers.some((v) => v.action === VoucherAction.redeem && v.type !== VoucherType.promo);
|
|
444
447
|
if (zahlungen == null || zahlungen.length === 0) {
|
|
448
|
+
if (mitGutschein && receiptSumCents(receipt) === 0)
|
|
449
|
+
return [];
|
|
445
450
|
return [paarZeile('Zahlungsart:', zahlungsartText(receipt.paymentMethod))];
|
|
446
451
|
}
|
|
447
452
|
if (zahlungen.length === 1) {
|
|
448
453
|
const zahlung = zahlungen[0];
|
|
454
|
+
if (mitGutschein && zahlung.amountCents === 0)
|
|
455
|
+
return [];
|
|
449
456
|
return [paarZeile('Zahlungsart:', zahlungsartText(zahlung.method)), ...zahlungTrinkgeldZeilen(zahlung), ...barZeilen(zahlung)];
|
|
450
457
|
}
|
|
458
|
+
// Mehrere Zahlungen: mit Gutschein entfallen die mit 0 Cent (Nummer bleibt die des Kartenblocks).
|
|
459
|
+
const alle = zahlungen.map((zahlung, i) => ({ zahlung, i }));
|
|
460
|
+
const liste = mitGutschein ? alle.filter(({ zahlung }) => zahlung.amountCents !== 0) : alle;
|
|
461
|
+
if (liste.length === 0)
|
|
462
|
+
return [];
|
|
451
463
|
const zeilen = [textZeile('Zahlungsarten:')];
|
|
452
|
-
|
|
464
|
+
for (const { zahlung, i } of liste) {
|
|
453
465
|
zeilen.push(paarZeile(zahlungNummerText(zahlung, i), `${formatCents(zahlung.amountCents)} €`, 8, 4));
|
|
454
466
|
zeilen.push(...zahlungTrinkgeldZeilen(zahlung));
|
|
455
467
|
zeilen.push(...barZeilen(zahlung));
|
|
456
|
-
}
|
|
468
|
+
}
|
|
457
469
|
return zeilen;
|
|
458
470
|
}
|
|
459
471
|
// -------------------------------------------------------- Kleinunternehmer
|
|
@@ -542,10 +554,12 @@ function gutscheinText(voucher) {
|
|
|
542
554
|
text += 'Wertgutschein';
|
|
543
555
|
}
|
|
544
556
|
else if (voucher.type === VoucherType.promo) {
|
|
545
|
-
text += '
|
|
557
|
+
text += 'Aktionsgutschein';
|
|
546
558
|
}
|
|
547
559
|
const name = voucher.name;
|
|
548
|
-
|
|
560
|
+
// Alte Belege nennen den Aktionsgutschein noch „Promotionsgutschein": auch dieser Name steht allein.
|
|
561
|
+
if (name != null && (name.toLowerCase().includes(text.toLowerCase())
|
|
562
|
+
|| (voucher.type === VoucherType.promo && name.toLowerCase().includes('promotionsgutschein')))) {
|
|
549
563
|
return name;
|
|
550
564
|
}
|
|
551
565
|
// Der Betrag steht in derselben Zeile rechts in der Betragsspalte — ihn
|
|
@@ -554,7 +568,7 @@ function gutscheinText(voucher) {
|
|
|
554
568
|
// identifiziert den Gutschein (Mehrzweck: der Kunde will wissen, WELCHER
|
|
555
569
|
// eingeloest wurde).
|
|
556
570
|
if (voucher.code != null && voucher.code !== '') {
|
|
557
|
-
text += ` ${voucher
|
|
571
|
+
text += ` ${codeKurz(voucher)}`;
|
|
558
572
|
}
|
|
559
573
|
if (name != null && name.length > 0) {
|
|
560
574
|
text += ` - ${name}`;
|
|
@@ -572,21 +586,20 @@ function gutscheinText(voucher) {
|
|
|
572
586
|
* Leistung Zeile dieses Gutscheins Text „ Einzweck, versteuert mit
|
|
573
587
|
* Beleg K1-ID-4711“ (bzw. „Leistung, …“, „…, befreit
|
|
574
588
|
* verkauft (Kleinunternehmer)“, 47 Zeichen: passt auf
|
|
575
|
-
* 80 mm) und 8:4 „ Rest am Gutschein“ | „19,50
|
|
589
|
+
* 80 mm) und 8:4 „ Rest am Gutschein“ | „19,50 €“ bzw.
|
|
576
590
|
* „2 Stück“
|
|
577
591
|
* Einloesung Mehrzweck nach „Zwischensumme“ 8:4 „Gutschein ····-9DWT“ |
|
|
578
592
|
* „-17,50 €“ und „ Rest am Gutschein“ | „32,50 €“
|
|
579
593
|
* Auszahlung 8:4 „Auszahlung Gutschein ····-9DWT“ | „-12,00 D“,
|
|
580
594
|
* Text „ Grund: <Grund>“
|
|
581
|
-
* Aktion Rabattzeile wie bisher (
|
|
595
|
+
* Aktion Rabattzeile wie bisher (Aktionsgutschein)
|
|
582
596
|
*
|
|
583
597
|
* Vermerke sind Textzeilen mit zwei fuehrenden Leerzeichen; das Raster bricht
|
|
584
598
|
* sie mit demselben Einzug um (grid.ts, haengender Einzug), auf 58 mm etwa
|
|
585
599
|
* „ Einzweck, versteuert mit“ / „ Beleg K1-ID-4711“.
|
|
586
600
|
*
|
|
587
|
-
* Die Zusatzzeilen kommen nur aus dem Eintrag: ein Beleg
|
|
588
|
-
*
|
|
589
|
-
* der Position, functions/beleg-layout.js `gutscheineFuerPaket`), zeigt seine
|
|
601
|
+
* Die Zusatzzeilen kommen nur aus dem Eintrag: ein Beleg ohne Eintrag (aeltere
|
|
602
|
+
* Belege, bei denen der Code schon an der Position steht) zeigt seine
|
|
590
603
|
* Positionen wie jede andere Position. Ein Betrag zaehlt immer genau einmal:
|
|
591
604
|
* Positionen in der Steuertabelle, Eintraege mit `zeroRateBucket` nie.
|
|
592
605
|
*/
|
|
@@ -599,12 +612,22 @@ function istMehrzweckMitCode(voucher) {
|
|
|
599
612
|
return voucher.type === VoucherType.value && voucher.voucherType === VoucherType.multi_purpose;
|
|
600
613
|
}
|
|
601
614
|
/**
|
|
602
|
-
* Code fuer die Belegzeile: die Maske
|
|
603
|
-
*
|
|
604
|
-
*
|
|
615
|
+
* Code fuer die Belegzeile: immer die kurze Maske `····-XXXX` aus dem Code-Ende
|
|
616
|
+
* (auch wenn ein alter Beleg die lange `····-····-XXXX` im Eintrag traegt),
|
|
617
|
+
* ohne den Platzhalter `no-code`, den der Server Alt-Eintraegen ohne Code
|
|
618
|
+
* setzt (index.js checkVouchersIsValid). Leer, wenn es keinen gibt.
|
|
605
619
|
*/
|
|
606
620
|
function gutscheinCodeZusatz(voucher) {
|
|
607
|
-
return typeof voucher.code === 'string' && voucher.code !== '' && voucher.code !== 'no-code' ? ` ${voucher
|
|
621
|
+
return typeof voucher.code === 'string' && voucher.code !== '' && voucher.code !== 'no-code' ? ` ${codeKurz(voucher)}` : '';
|
|
622
|
+
}
|
|
623
|
+
/**
|
|
624
|
+
* Maskierte Codes (`····-····-XXXX` alt, `····-XXXX` neu) drucken immer kurz;
|
|
625
|
+
* ein Alt-Code ohne Maske (z. B. `GS-1`) bleibt, wie er ist.
|
|
626
|
+
*/
|
|
627
|
+
function codeKurz(voucher) {
|
|
628
|
+
const code = voucher.code ?? '';
|
|
629
|
+
const endung = gutscheinEndung(voucher);
|
|
630
|
+
return code.includes('····') && endung != null ? `····-${endung}` : code;
|
|
608
631
|
}
|
|
609
632
|
/** Die vier letzten Zeichen des Codes (`codeSuffix`, sonst aus der Maske), oder null. */
|
|
610
633
|
function gutscheinEndung(voucher) {
|
|
@@ -618,7 +641,7 @@ const MEHRZWECK_UST_TEXT = ' USt bei Einlösung';
|
|
|
618
641
|
* Eintrag? Jede Position hoechstens einem Eintrag, Eintraege in ihrer
|
|
619
642
|
* Reihenfolge (der Server haengt die Positionen in derselben Reihenfolge an).
|
|
620
643
|
* Verkauf: erste freie Position der Art mit demselben Betrag und ohne Code im
|
|
621
|
-
* Namen (wie
|
|
644
|
+
* Namen (wie die Zuordnung des Servers). Einloesung: freie Positionen
|
|
622
645
|
* mit genau dem Namen `Gutschein ····-<Endung>`, Auszahlung: `Auszahlung
|
|
623
646
|
* Gutschein ····-<Endung>` (gutschein-beleg.plane) -- der Reihe nach, bis
|
|
624
647
|
* ihr Betrag den des Eintrags erreicht (ein Kleinunternehmer-Einzweck oder
|
|
@@ -696,14 +719,14 @@ function gutscheinPositionsZeilen(item, satz, zu) {
|
|
|
696
719
|
else if (v.exempt === true) {
|
|
697
720
|
zeilen.push(textZeile(` ${art}, befreit verkauft (Kleinunternehmer)`));
|
|
698
721
|
}
|
|
699
|
-
// Rest: Betrag
|
|
700
|
-
//
|
|
722
|
+
// Rest: Betrag mit „€“ wie beim Mehrzweckgutschein, Stueck rechtsbuendig.
|
|
723
|
+
// Die Gesamtzahl kennt der Beleg nicht.
|
|
701
724
|
if (v.type === VoucherType.service) {
|
|
702
725
|
if (Number.isInteger(v.remainingQuantityAfter))
|
|
703
726
|
zeilen.push(paarZeile(' Rest am Gutschein', `${v.remainingQuantityAfter} Stück`, 8, 4));
|
|
704
727
|
}
|
|
705
728
|
else if (Number.isInteger(v.balanceAfterCents)) {
|
|
706
|
-
zeilen.push(paarZeile(' Rest am Gutschein', `${formatCents(v.balanceAfterCents)}
|
|
729
|
+
zeilen.push(paarZeile(' Rest am Gutschein', `${formatCents(v.balanceAfterCents)} €`, 8, 4));
|
|
707
730
|
}
|
|
708
731
|
return zeilen;
|
|
709
732
|
}
|
|
@@ -1093,7 +1116,7 @@ export function buildReceiptLayout(receipt, company, options = {}) {
|
|
|
1093
1116
|
lines.push(...(art === 'discount' ? rabattZeilen(item.name, teile) : trinkgeldZeilen(item.name, teile)));
|
|
1094
1117
|
}
|
|
1095
1118
|
// --- Gutscheine: verkaufte Wertgutscheine sind Umsatz zu 0 %, eingeloeste
|
|
1096
|
-
//
|
|
1119
|
+
// Aktionsgutscheine mindern die Steuergruppen anteilig.
|
|
1097
1120
|
// Am Storno-Beleg zaehlen Wertgutscheine mit umgekehrtem Vorzeichen
|
|
1098
1121
|
// (receiptValueVoucherSign): der verkaufte wird zurueckgezahlt.
|
|
1099
1122
|
// Eintraege mit `zeroRateBucket` stehen schon als Position (0-%-Topf).
|
|
@@ -1123,7 +1146,7 @@ export function buildReceiptLayout(receipt, company, options = {}) {
|
|
|
1123
1146
|
lines.push(textZeile(MEHRZWECK_UST_TEXT));
|
|
1124
1147
|
}
|
|
1125
1148
|
if (voucher.action === VoucherAction.redeem && voucher.type === VoucherType.promo) {
|
|
1126
|
-
// Am Storno-Beleg steht der
|
|
1149
|
+
// Am Storno-Beleg steht der Aktionsgutschein nur als Bezug: den Rabatt
|
|
1127
1150
|
// nimmt dort die Position „Gutschein-Ausgleich“ zurueck (receiptSubSumCents).
|
|
1128
1151
|
if (wgVz === 1)
|
|
1129
1152
|
promoCents += wert;
|
|
@@ -1243,7 +1266,7 @@ export function buildReceiptLayout(receipt, company, options = {}) {
|
|
|
1243
1266
|
return { lines, paperSize, ruleset };
|
|
1244
1267
|
}
|
|
1245
1268
|
/**
|
|
1246
|
-
* Verteilt einen eingeloesten
|
|
1269
|
+
* Verteilt einen eingeloesten Aktionsgutschein anteilig auf die
|
|
1247
1270
|
* Steuergruppen — Zwilling von `print_paper.dart` (Zeilen 296-325).
|
|
1248
1271
|
*
|
|
1249
1272
|
* Der Gutschein mindert keinen einzelnen Artikel, sondern den Umsatz: jede
|
|
@@ -120,8 +120,12 @@ export type RegisterLoginMode = 'select_user' | 'pin';
|
|
|
120
120
|
export interface RegisterDeviceUsers {
|
|
121
121
|
/** Im Modus `pin` bewusst leer — Namen haben am nur-PIN-Geraet nichts verloren. */
|
|
122
122
|
users: RegisterUserSummary[];
|
|
123
|
-
/**
|
|
124
|
-
|
|
123
|
+
/**
|
|
124
|
+
* Kassen-Einstellungen (betriebsweit + Geraet), gemischt mit den Standardwerten.
|
|
125
|
+
* Ohne `vouchers`: die Antwort des Servers fuehrt den Block nicht, er kommt
|
|
126
|
+
* mit `getPosSettings`; ein Vorgabe-Block waere erfunden.
|
|
127
|
+
*/
|
|
128
|
+
settings: Omit<PosSettings, 'vouchers'>;
|
|
125
129
|
/** Belegkopf-Daten des Betriebs (Name, Anschrift, UID, Fusszeilen), ohne Geheimnisse. */
|
|
126
130
|
receiptHeader: ReceiptCompany | null;
|
|
127
131
|
/**
|