# Як налаштувати поля клієнтів?

Налаштування полів клієнтів дозволяє **визначити кастомні поля** та **керувати їх видимістю** для операторів. Без кастомних полів у картці клієнта доступний лише обмежений набір стандартних полів.

## Коли знадобиться

- Потрібно додати додаткові поля до картки клієнта (наприклад, "Номер клієнта", "Категорія", "Дата реєстрації").
- Інтеграція з зовнішніми системами вимагає зберігання додаткової інформації про клієнтів.
- Потрібно розширити стандартний профіль клієнта під бізнес-процеси.

## Що важливо знати

- **Сторінка «Поля клієнтів»** (`/settings-page/client-fields`): у першому блоці — визначення кастомних полів (форма + JSON); нижче — **видимість** полів у картці (перемикачі + опційно JSON). **Одна кнопка «Зберегти» у заголовку сторінки** зберігає **і** поля (`client_fields_json`), **і** видимість (`client_card_fields`) — окремої кнопки в блоці видимості немає.
- **Той самий екран видимості** доступний також у **«Редактор полів у картці клієнта»** (`/settings-page/op-settings/client-fields`, меню **Налаштування** операторської панелі): там можна змінювати лише видимість; збереження — **верхньою кнопкою «Зберегти»** в макеті op-settings (пакетно; потрібне право `canSave` для секції **settings**). Детальніше — [Редактор полів у картці клієнта](/uk/settings/how-to/configure-client-card-fields.md).
- **Стандартні поля** — нативні колонки OpClients: `phone`, `bot_id`, `bot_name`, `fullName` (від `full_name`). Поля типу `clientType`, `whiteLabel` у прикладах можуть бути кастомними в `extra_data` або застарілими.
- **Кастомні поля** зберігаються в `extra_data` клієнта.
- **Форма та JSON полів** — для кожного поля доступні базові поля (ключ, тип, мітка) і додаткові параметри; повний перелік — у [довіднику JSON полів клієнта](/uk/settings/reference/client-fields-json.md). У редакторі полів є блок **«Приклади JSON»** з готовими фрагментами.
- **Client Portal (self-registration):** перемикач **«Показувати при реєстрації в Client Portal»** додає поле на форму `/register` у клієнтському порталі. Потрібно, щоб на інстансі було увімкнено `portal_registration_enabled` (налаштування інстансу, root). Детальніше — [Налаштування інстансу](/uk/settings/how-to/configure-instance.md).

## Перед початком

- [x] Ви увійшли в систему з правами адміністратора або інтегратора.
- [x] Ви маєте дозвіл на редагування полів клієнтів (`canSave` для секції users).

## Покрокова інструкція (об’єднана сторінка)

### 1. Відкрити «Поля клієнтів»

1. Перейдіть до модуля **Налаштування** через меню або за адресою `/settings-page`.
2. У бічному меню розгорніть розділ **«Боти»** (Process Library).
3. Виберіть **«Поля клієнтів»** (`/settings-page/client-fields`).

### 2. Задати кастомні поля та видимість

1. У **першому** блоці перегляньте список полів і JSON (`custom_fields_json`). Додайте поле **«Додати поле»** або відредагуйте JSON (ключ, тип, мітка — див. [довідник](/uk/settings/reference/client-fields-json.md)).
2. У **другому** блоці змініть перемикачі видимості для стандартних і кастомних полів.
3. За потреби розгорніть **JSON видимості** — той самий зміст, що й перемикачі; зміни синхронізуються між редактором і перемикачами.
4. Натисніть **одну кнопку «Зберегти»** у **заголовку** сторінки — збережуться і поля, і видимість. Після успішного збереження з’явиться сповіщення про успіх.

### 3. Альтернатива: лише видимість у op-settings

Якщо зручніше працювати з розділу **Налаштування** операторської панелі, відкрийте **«Редактор полів у картці клієнта»** (`/settings-page/op-settings/client-fields`). Там ті самі перемикачі видимості; повне визначення кастомних полів — за посиланням з сторінки на **«Поля клієнтів»**. Збереження — через верхню кнопку в op-settings. Див. [окрему інструкцію](/uk/settings/how-to/configure-client-card-fields.md).

## Приклади JSON (як у блоці «Приклади JSON» на сторінці)

У нижній частині екрана **Поля клієнтів** є перемикач із п’ятьма сценаріями — нижче той самий вміст JSON. Назви сценаріїв у інтерфейсі короткі; тут зазначено, **на що саме варто звернути увагу** в кожному фрагменті. Кожен блок — це **вміст об’єкта полів** (у збережених налаштуваннях він лежить у `custom_fields_json`). Скопіюйте фрагмент, перейменуйте ключі полів під свій проєкт і натисніть **«Зберегти»** у заголовку сторінки.

**Два рівні ключів:** зовнішні (`full_name`, `store_id` тощо) — це **ваші імена полів** у даних клієнта; вкладені ключі (`type`, `label`, `association`…) — це **параметри схеми**, які розуміє інтерфейс. Після кожного прикладу — список, навіщо потрібен кожен використаний параметр.

### Базовий

Три незалежні поля різних типів: короткий текст, дата та ціле число зі значенням за замовчуванням (`default`). Зручний стартовий шаблон без валідацій і зв’язків між полями.

```json
{
  "full_name": {
    "type": "STRING",
    "label": "Full name"
  },
  "birth_date": {
    "type": "DATE",
    "label": "Date of birth"
  },
  "loyalty_points": {
    "type": "INTEGER",
    "label": "Points",
    "default": "0"
  }
}
```

**Ключі та навіщо вони:** `type` — тип даних у формі; `label` — підпис для оператора; `default` — підставити значення за замовчуванням (тут для числового поля). Імена `full_name`, `birth_date`, `loyalty_points` у прикладі довільні — замініть на свої.

### Дата / час + валідація

Два поля часу (`type_string`: time, формат `HH:mm`). Обидва позначені як обов’язкові; для поля «кінець» додано **перехресну перевірку** через об’єкт `validate`: час закінчення має бути пізнішим за початок. Такі правила не виводяться окремими перемикачами у формі — їх задають у JSON.

```json
{
  "start_time": {
    "type": "STRING",
    "label": "Start",
    "type_string": "time",
    "format": "HH:mm",
    "string_input": {},
    "rules": ["required"]
  },
  "end_time": {
    "type": "STRING",
    "label": "End",
    "type_string": "time",
    "format": "HH:mm",
    "string_input": {},
    "rules": ["required"],
    "validate": {
      "required_field_not_empty": "start_time",
      "rules": {
        "type": "time",
        "val_from_field": "start_time",
        "action": "gt"
      }
    }
  }
}
```

**Ключі та навіщо вони:** базово знову `type` і `label`. Для поля часу на базі рядка: `type_string`: `"time"` каже інтерфейсу трактувати ввід як час; `format` — маска (`HH:mm`); `string_input`: `{}` — увімкнути відповідний віджет вводу. `rules`: `["required"]` — обов’язковість (те саме можна задати у формі). Об’єкт **`validate`** задає **перехресну** перевірку: `required_field_not_empty` вимагає заповненого `start_time`; вкладений `rules` порівнює час «кінця» з полем `start_time` дією `gt` (greater than — пізніше). Деталі структури `validate` залежать від сценарію — орієнтуйтесь на цей зразок.

### Пов'язане поле

Поле з **`association`** зберігає ідентифікатор запису з пов’язаної моделі; друге поле показує людині зрозумілу мітку (наприклад, назву), приховане у вікні швидкого створення і недоступне для ручного редагування. Типовий патерн «ID у даних + підпис для оператора».

```json
{
  "store_id": {
    "type": "INTEGER",
    "label": "Store",
    "association": {
      "as": "store_name",
      "model_field_label": "name",
      "fetch_limit": 500
    }
  },
  "store_name": {
    "type": "STRING",
    "label": "Store name",
    "hidden_in_create_popup": true,
    "non_editable": "true"
  }
}
```

**Ключі та навіщо вони:** **`association`** описує зв’язок з іншою сутністю: `as` — ключ **іншого поля** в цьому ж JSON, куди підставляється підпис; `model_field_label` — яке поле з пов’язаного запису показувати як мітку; `fetch_limit` — скільки записів можна підвантажити для вибору. Поле `store_name`: `hidden_in_create_popup`: `true` — не показувати у швидкому створенні; `non_editable`: `"true"` — лише читання (мітку зазвичай заповнює зв’язок з `store_id`).

### Підсвічування рядків

Два поля планового та фактичного часу; на одному з полів задано **`sting_highlight`** (умовні кольори рядка таблиці залежно від порівняння двох значень часу). Це розширена поведінка — її підключають лише через JSON, не через форму поля.

```json
{
  "planned_finish": {
    "type": "STRING",
    "label": "Planned",
    "type_string": "time",
    "format": "HH:mm",
    "string_input": {}
  },
  "actual_finish": {
    "type": "STRING",
    "label": "Actual",
    "type_string": "time",
    "format": "HH:mm",
    "string_input": {},
    "sting_highlight": {
      "type": "STRING",
      "highlight_rules": {
        "type": "time",
        "rules": [
          { "0": "actual_finish", "1": "planned_finish", "action": "gt",  "color": "red"   },
          { "0": "actual_finish", "1": "planned_finish", "action": "lte", "color": "green" }
        ]
      }
    }
  }
}
```

**Ключі та навіщо вони:** для звичайних часових полів — знову `type_string`, `format`, `string_input`. **`sting_highlight`** (назва в продукті) — вузол умовного підсвічування табличного рядка; всередині **`highlight_rules`**: `type`: `"time"` задає тип порівняння; масив **`rules`** — умови: поля `"0"` і `"1"` посилаються на ключі інших полів, `action` (`gt`, `lte` тощо) — операція порівняння, `color` — колір рядка при виконанні умови.

### Підсумки і посилання в таблиці

Числове поле з **підсумком у підсумковому рядку** таблиці (`total_sum`), шириною, вирівнюванням і сортуванням; окреме текстове поле з **`display_type`: link**, щоб значення відкривалося як посилання. Параметри на кшталт `total_sum` задають у JSON, якщо їх немає у формі.

```json
{
  "amount": {
    "type": "FLOAT",
    "label": "Amount",
    "width": "90",
    "align": "end",
    "sortable": "true",
    "total_sum": true
  },
  "invoice_url": {
    "type": "STRING",
    "label": "Invoice",
    "display_type": "link",
    "width": "60"
  }
}
```

**Ключі та навіщо вони:** для таблиці клієнтів — `width` (ширина колонки в px), `align` (`end` — вирівнювання для чисел), `sortable`: `"true"` — сортування по колонці; **`total_sum`**: `true` — додати значення поля до підсумкового рядка. Для посилання: **`display_type`**: `"link"` — значення комірки відкривати як URL у новій вкладці (див. також [довідник](/uk/settings/reference/client-fields-json.md)).

## Що відбувається після

- Визначення кастомних полів зберігаються в `client_fields_json` (налаштування інстансу).
- Видимість полів у картці зберігається в `client_card_fields` (налаштування операторської панелі).
- Оператори бачать і заповнюють поля згідно з перемикачами / JSON видимості.

## Як переконатися, що все вдалось

- На сторінці **Поля клієнтів** перевірте, що поля та перемикачі відповідають задуму.
- Відкрийте картку клієнта в операторській панелі та переконайтеся, що відображаються потрібні поля.

## Пов'язані матеріали

- [Довідник JSON: поля клієнта](/uk/settings/reference/client-fields-json.md) — усі властивості поля в `custom_fields_json`
- [Налаштувати поля користувачів](/uk/settings/how-to/configure-user-fields.md)
- [Редактор полів у картці клієнта (op-settings)](/uk/settings/how-to/configure-client-card-fields.md) — той самий блок видимості, інший макет збереження
- [Налаштування інстансу](/uk/settings/how-to/configure-instance.md) — `portal_registration_enabled`, `client_portal_url`

## Важливі примітки

- ⚠️ На сторінці **Поля клієнтів** одна кнопка **«Зберегти»** у заголовку записує **обидві** частини (поля та видимість). На **op-settings/client-fields** збереження — іншою кнопкою у шапці розділу (права на секцію `settings`).
- ⚠️ **Видалення полів**: дані в `extra_data` можуть бути втрачені.
- 💡 **Резервне копіювання**: зробіть копію JSON перед великими змінами.
