import { Callout } from "zudoku/ui/Callout";

# Barcode

Codeunit `5523960` `bdev.Barcode` is the entry point of the app. It encodes a value as a barcode image, reads a barcode back out of an image, and builds a vCard barcode from a contact.

```pascal
    barcode: Codeunit "bdev.Barcode";
```

Every method returns or takes the image as a `Temp Blob` codeunit, which is what a `Media` or `Blob` field, a report item and a file download all accept.

## Encode(Enum, Text)

Encodes a value in a symbology, with the default appearance.

```pascal
    procedure Encode(barcodeSymbology: Enum "bdev.Barcode Symbology"; value: Text): Codeunit "Temp Blob"
```

| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `barcodeSymbology` | Enum "bdev.Barcode Symbology" | The symbology, for example `QR Code` or `Code 128`. |
| `value` | Text | The value to encode. |

**Returns** the barcode image as a `Temp Blob` codeunit.

The defaults are a black code on a white background, 50 pixels high. Everything else is left to the symbology.

### Example

```pascal
    procedure AttachBarcodeToItem(var item: Record Item)
    var
        barcode: Codeunit "bdev.Barcode";
        image: Codeunit "Temp Blob";
        recRef: RecordRef;
    begin
        image := barcode.Encode(Enum::"bdev.Barcode Symbology"::"QR Code", item."No.");

        recRef.GetTable(item);
        image.ToRecordRef(recRef, item.FieldNo("My Barcode"));
        recRef.Modify(true);
        recRef.SetTable(item);
    end;
```

## Encode(Record, Text)

Encodes a value according to a `Barcode Settings` record - the way to control the appearance and the symbology-specific options.

```pascal
    procedure Encode(barcodeSettings: Record "bdev.Barcode Settings"; value: Text): Codeunit "Temp Blob"
```

| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `barcodeSettings` | Record "bdev.Barcode Settings" | The settings to use. |
| `value` | Text | The value to encode. |

**Returns** the barcode image as a `Temp Blob` codeunit.

The settings carry the symbology, the colors, the height, the margin, whether the value is printed below the code, whether the value is in GS1 format, and the options of the chosen symbology - error correction, symbol shape, aspect ratio, encoding.

A user maintains them on the `Barcode Settings` page, which is usually what you want: the appearance of a barcode is a setup decision, not something to hard-code. Read the record and pass it on:

```pascal
    procedure EncodeWithSetup(value: Text): Codeunit "Temp Blob"
    var
        barcodeSettings: Record "bdev.Barcode Settings";
        mySetup: Record "My Setup";
        barcode: Codeunit "bdev.Barcode";
    begin
        mySetup.Get();
        mySetup.TestField("Barcode Settings Code");
        barcodeSettings.Get(mySetup."Barcode Settings Code");

        exit(barcode.Encode(barcodeSettings, value));
    end;
```

Settings that are not stored anywhere work as well - initialize a record in memory, set what you need, and pass it:

```pascal
    var
        barcodeSettings: Record "bdev.Barcode Settings" temporary;
    begin
        barcodeSettings.Init();
        barcodeSettings."Barcode Symbology" := barcodeSettings."Barcode Symbology"::"Data Matrix";
        barcodeSettings.Height := 80;
        barcodeSettings."Show Barcode Value" := true;
```

<Callout type="caution" title="A symbology that cannot encode raises an error">
Not every symbology supports encoding, and each accepts only a part of the settings. Encoding with a symbology that does not support it fails with an error naming the symbology; properties it does not accept are ignored silently.
</Callout>

## Decode(Text)

Reads the barcode in a Base64 encoded image.

```pascal
    procedure Decode(base64ImageData: Text): Text
```

| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `base64ImageData` | Text | The image containing the barcode, Base64 encoded. |

**Returns** the decoded value.

## Decode(Codeunit)

Reads the barcode in an image held in a `Temp Blob` codeunit - the usual case when the image comes from a `Media` field or an upload.

```pascal
    procedure Decode(tempBlob: Codeunit "Temp Blob"): Text
```

| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `tempBlob` | Codeunit "Temp Blob" | The image containing the barcode. |

**Returns** the decoded value.

Both overloads raise an error when the service cannot read a barcode in the image - there is no "nothing found" result to check for. Wrap the call when a missing barcode is an expected outcome:

```pascal
    [TryFunction]
    local procedure TryDecode(image: Codeunit "Temp Blob"; var value: Text)
    var
        barcode: Codeunit "bdev.Barcode";
    begin
        value := barcode.Decode(image);
    end;
```

## EncodeVCard(Record, Record)

Encodes a contact as a vCard barcode. Scanning it adds the contact to a phone.

```pascal
    procedure EncodeVCard(barcodeSettings: Record "bdev.Barcode Settings"; contact: Record Contact): Codeunit "Temp Blob"
    procedure EncodeVCard(barcodeSettings: Record "bdev.Barcode Settings"; salespersonPurchaser: Record "Salesperson/Purchaser"): Codeunit "Temp Blob"
```

| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `barcodeSettings` | Record "bdev.Barcode Settings" | The settings to use. The symbology **must** be `vCard QR Code`. |
| `contact` / `salespersonPurchaser` | Record | The record the vCard is built from. |

**Returns** the barcode image as a `Temp Blob` codeunit.

What goes into the vCard differs between the two:

| vCard field | From a `Contact` | From a `Salesperson/Purchaser` |
| --- | --- | --- |
| Name, organization | `Name`, `Company Name` | `Name`, company name from `Company Information` |
| Address | the address of the contact | the address from `Company Information` |
| Phone, e-mail, website | of the contact | phone and e-mail of the salesperson, website from `Company Information` |
| Picture | `Image` of the contact | `Image` of the salesperson |

The picture is only embedded when `Include Picture` is set in the settings. A vCard with a picture produces a considerably denser QR code - check that your label still scans before switching it on.

<Callout type="caution" title="The symbology is checked">
`EncodeVCard` raises a `TestField` error when the settings do not use the `vCard QR Code` symbology. Give the vCard its own `Barcode Settings` record rather than reusing the one your labels print.
</Callout>

## See also

- [365 business Barcode - Overview](readme.mdx)
- [Barcode API (obsolete)](barcode-api.mdx)
- [Documentation - Barcode Settings](../../en-us/365-business-barcode/barcode-settings.mdx)
