# QR-коды

Системный QR-код может содержать идентификатор объекта, данные объекта или сведения об интерфейсе, который требуется открыть.

При автоматическом формировании QR-кода для прикладного объекта его JSON-значение хранится в автовычисляемом поле `jQRCode`. В базе данных поле имеет тип `jsonb`.

Для внешних и произвольных QR-кодов используется таблица `BS_QRCODE`. Строковое значение QR-кода хранится в поле `sQrCode`, а связь с объектом — в поле `gidSrc`.

QR-код может использоваться для идентификации объекта или для открытия указанной выборки с заданными параметрами. Для минимального системного QR-кода достаточно передать GID объекта в `genCodeNString()`.

## Принцип работы

Системный QR-код представляет собой JSON-структуру, которая может содержать служебные идентификаторы, данные объекта или параметры интерфейса.

При обработке система использует содержимое QR-кода:

- если в структуре указана выборка, открывается эта выборка с переданными параметрами;
- если указан `GID`, открывается соответствующий объект;
- если значение не распознано как системный QR-код или системная структура не содержит данных для выполнения действия, выполняется поиск зарегистрированного значения в `BS_QRCODE`.

## Структура QR-кода

Системный QR-код может содержать следующие блоки:

- `global_qr` — служебные идентификаторы;
- `obj` — данные объекта;
- `sel` — данные выборки, отображения и параметры.

Пример:

<!-- Начало кода -->
```json
{
  "obj": {
    "Наименование": "Пила",
    "Код": "338",
    "Место": "Кладовая"
  },
  "sel": {
    "SEL": "Bs_GostAvi",
    "REP": "Card",
    "PARAM": [
      {
        "NAME": "IdItem#",
        "VALUE": 74631
      },
      {
        "NAME": "EDITINGTYPE",
        "VALUE": "edit"
      }
    ]
  },
  "global_qr": {
    "GID": "213123/123",
    "GUID": "d988a3b2-2210-485d-a941-4b611ccbe50d",
    "NODE": "PGDEV"
  }
}
```
<!-- Конец кода -->

Блок `global_qr` содержит служебные идентификаторы, используемые при обработке системного QR-кода. Блоки `obj` и `sel` формируются в зависимости от переданных данных.

<!-- Начало кода -->
```{attention}
Структурой предусмотрен блок `script`, но его формирование и обработка не реализованы.
```
<!-- Конец кода -->

## Формирование QR-кодов

Для автоматического формирования системного QR-кода на типе объекта настраивается автовычисляемая колонка `jQRCode`.

Значение колонки формируется методами `Bs_QrCodePkg` и автоматически обновляется при `flush` объекта.

Для формирования QR-кода только со служебными идентификаторами объекта в выражении автовычисляемой колонки используется:

<!-- Начало кода -->
```java
Bs_QrCodePkg.genCodeNString(rop.gid)
```
<!-- Конец кода -->

Для объекта с GID `10951/218904` в `jQRCode` будет записано:

<!-- Начало кода -->
```json
{
  "global_qr": {
    "GID": "10951/218904",
    "NODE": "PGDEV",
    "GUID": "42ed483f-4b7c-49ed-8b1e-ef0bb91030dc"
  }
}
```
<!-- Конец кода -->

Полученное JSON-значение является содержимым системного QR-кода.

## API формирования QR-кодов

Для формирования системных QR-кодов используются методы пакета `Bs_QrCodePkg`:

- `genCode` — формирует конечную JSON-структуру QR-кода;
- `genCodeNString` — формирует QR-код и возвращает структуру в строковом представлении;
- `genObj` — формирует блок `obj`;
- `genSel` — формирует блок `sel`.

### genCode

Метод `genCode` формирует конечную JSON-структуру QR-кода.

Метод принимает три обязательных параметра:

- `gid` — GID объекта;
- `json` — JSON с дополнительными данными;
- `spType` — тип дополнительного блока: `obj` или `sel`.

Необязательные варианты параметров, описанные для `genCodeNString`, к `genCode` не относятся.

### genCodeNString

Метод `genCodeNString` формирует QR-код и возвращает полученную структуру в виде строки. В JEXL-скриптах автовычисляемых атрибутов используется именно этот метод.

Для `genCodeNString` доступны перегруженные варианты вызова:

- `gid`;
- `gid, json`;
- `json, spType`;
- `gid, json, spType`.

При вызове только с `gid` формируется блок `global_qr`.

При передаче `json` дополнительный блок определяется используемым вариантом вызова и значением `spType`.

Для блока `obj` требуется GID объекта. Для блока `sel` доступен вариант вызова без GID; в этом случае `global_qr` содержит только `NODE`.

### genObj

Метод `genObj` формирует блок `obj` с данными объекта.

Параметры:

- `rop` — объект, данные которого включаются в QR-код;
- `spAttrs` — системные имена атрибутов, включаемых в QR-код, перечисленные через запятую.

<!-- Начало кода -->
```{attention}
Перечень атрибутов передается одной строкой, например `"sArticle, sName, idMeasureItem"`.
```
<!-- Конец кода -->

Пример:

<!-- Начало кода -->
```java
var jsonObj = Bs_QrCodePkg.genObj(
  rop.data(),
  "sArticle, sName, idMeasureItem"
);

Bs_QrCodePkg.genCodeNString(rop.gid, jsonObj);
```
<!-- Конец кода -->

Результат:

<!-- Начало кода -->
```json
{
  "global_qr": {
    "GID": "10951/218904",
    "NODE": "PGDEV",
    "GUID": "42ed483f-4b7c-49ed-8b1e-ef0bb91030dc"
  },
  "obj": {
    "Наименование": "Болт ГОСТ 7798-70",
    "ЕИ": 34210,
    "Ном.№": "001000006"
  }
}
```
<!-- Конец кода -->

Также доступен вариант метода `genObj`, который принимает данные в виде `Map[String, Any]`. Для формирования `Map` в JEXL можно использовать `asScala()`.

### genSel

Метод `genSel` формирует блок `sel`, по данным которого при обработке QR-кода открывается указанная выборка.

Параметры:

- `spSel` — системное имя выборки;
- `spRep` — наименование отображения;
- `params` — параметры отображения в виде `Map[String, Any]`.

Пример:

<!-- Начало кода -->
```java
var params = asScala({
  "IdItem#": rop.id,
  "EDITINGTYPE": "edit"
});

var jsonSel = Bs_QrCodePkg.genSel(
  "Bs_GostAvi",
  "Card",
  params
);

Bs_QrCodePkg.genCodeNString(jsonSel, "sel");
```
<!-- Конец кода -->

Результат:

<!-- Начало кода -->
```json
{
  "global_qr": {
    "NODE": "PGDEV"
  },
  "sel": {
    "SEL": "Bs_GostAvi",
    "PARAM": [
      {
        "VALUE": 74631,
        "NAME": "IdItem#"
      },
      {
        "VALUE": "edit",
        "NAME": "EDITINGTYPE"
      }
    ],
    "REP": "Card"
  }
}
```
<!-- Конец кода -->

<!-- Начало кода -->
```{attention}
При обработке QR-кода учитывается регистр в системном имени выборки и наименовании отображения.
```
<!-- Конец кода -->

## Обработка QR-кодов

Для обработки строки QR-кода используется метод `processQrCode` библиотеки `Bs_QrCodeLib`.

Метод обрабатывает значение в следующем порядке:

- если QR-код содержит системную JSON-структуру с блоком `sel`, открывается указанная в нем выборка с переданными параметрами;
- если QR-код содержит блок `global_qr` с `GID`, открывается карточка объекта по `GID`;
- если значение не распознано как системный QR-код или в системной структуре отсутствуют данные для выполнения действия, исходное значение ищется в `BS_QRCODE`, после чего открывается объект, указанный в `gidSrc`.

Действия по умолчанию можно переопределить на уровне выборки в обработчике события сканирования.

Пример формирования и обработки QR-кода для открытия выборки:

<!-- Начало кода -->
```java
var jSel = Bs_QrCodePkg.genSel(
  "Bs_GostAvi",
  "Card",
  asScala({
    "IdItem#": 74631L,
    "EDITINGTYPE": "edit"
  })
);

var sQrCode = Bs_QrCodePkg.genCodeNString(jSel, "sel");

Bs_QrCodeLib.processQrCode(sQrCode);
```
<!-- Конец кода -->

Прием считанных значений от сканеров описан на странице [Работа со сканерами](030_работа_со_сканерами.md).
