Print receipts with a custom codeunit

Use a custom print codeunit to generate sales receipts and other line-based printouts, with full control over the content and as many receipt variants as you need.

NP Retail can print sales receipts from a custom print codeunit instead of a print template. This is the recommended approach for sales receipts and other line-based outputs (such as Z/X reports and kitchen prints), because it gives you full control over the content and lets you define as many receipt variants as you need — for example, a business copy, a customer copy, and a Bewirtungsbeleg.

You build this entirely from your own extension (PTE), with no change to NP Retail core. The print codeunits are ordinary AL codeunits with TableNo = "NPR POS Entry", written just like NP Retail’s standard receipt codeunit (6248348 "NPR Static Sales Receipt"). A full reference implementation is available in the sales-receipt-print-codeunit-example repository.

Note: This approach applies to tenants that have switched to the New Sales Receipt Experience in NP Retail. Because NP Retail’s underlying tables are Access = Internal, custom codeunits read receipt data through the public facade codeunit NPR ReceiptPrintUtilities.

Clearing up a common misconception

The single Codeunit ID field on Report Selection - Retail is only the auto-print-on-sale hook — it is not the only way to run a receipt codeunit. Under the hood, NP Retail simply calls Codeunit.Run(<your codeunit>, <POS Entry>), and a POS action can make that same call itself, as many times and from as many buttons as you want.

In other words, there is no “one codeunit only” limit. The auto-print field handles the receipt printed automatically after each sale, and your own POS actions handle any additional variants you print on demand.

How receipt dispatch works

When a sale is finalized, NP Retail reads the Report Selection - Retail row for Sales Receipt (POS Entry) (the unit-specific row by Register No. if one exists, otherwise the blank row) and resolves what to print in this priority order:

  1. Print Template is set → the template is run (the legacy path, blocked once the New Sales Receipt Experience is enabled).
  2. Report ID is set → the report is run.
  3. Codeunit ID is set → the codeunit is invoked with the POS Entry (a RecordRef) bound to Rec in OnRun.

To print from a custom codeunit, set only the Codeunit ID and leave Report ID and Print Template empty, since those take precedence.

This is the standard auto-print pattern.

  1. Write your business-copy print codeunit with TableNo = "NPR POS Entry", modeled on the example codeunit.

  2. Search for Report Selection - Retail in Business Central, and open the related link.

  3. Filter to the Sales Receipt (POS Entry) report type.

  4. On the target row, set the Codeunit ID to your codeunit, and leave Report ID and Print Template empty.

    Tip: Set the Register No. to scope the codeunit to a specific till. Leave it blank to apply it to all units.

NP Retail then prints this receipt on every sale. Nothing else is required.

For variants that are printed on demand — such as a customer copy or a Bewirtungsbeleg — do not reuse the standard Print Receipt action. Its setting only resolves to the standard or “large” receipt type, and that dispatch is internal. Instead, create your own POS action(s), which use only public, supported surface:

  1. Implement the public NPR IPOS Workflow interface and register the action via an enumextension on the public, extensible NPR POS Workflow enum — the same way any custom POS button is built. See the pos-action-example repository.
  2. In the action, get the current POS unit with Setup.GetPOSUnit.
  3. Find the relevant POS Entry — the last one, or let the cashier pick — by filtering the public NPR POS Entry table.
  4. Call Codeunit.Run(<your customer-copy or Bewirtungsbeleg codeunit>, POSEntry).

Add one POS unit button per variant (for example, Print customer copy and Print Bewirtungsbeleg). You can also use a single action with an option parameter to choose the variant.

The variant codeunits are ordinary print codeunits (TableNo = "NPR POS Entry"), written just like the business copy. A Bewirtungsbeleg codeunit simply adds the extra header and text fields it requires.

Because the on-demand buttons bypass NP Retail’s internal print path, the Allow Printing Receipt Copy reprint limit and the POS Entry output log are not applied automatically. The public NPR ReceiptPrintUtilities codeunit exposes helpers to restore that behavior and to match the standard receipt:

  • IsReprint(EntryNo) — identifies reprint receipts, so you can gate on it to enforce reprint-limiting and logging.
  • AddReceiptFooterText(...) — applies the configured receipt footer text.
  • ShowBarcodeAsQRCode(...) — matches the standard receipt’s barcode/QR behavior.

See also