<!-- Device Inventory Manager — https://wiki.cyberguard.srl/dim/inventory/custom-fields/ -->

# Custom Fields

A SIM card needs a PIN and a data cap. A software licence needs a version and an edition. A badge needs an access level. None of these belong on every asset, and none of them fit in the Notes box if you ever want to search or filter by them.

**Custom fields** let you add your own fields to a single category. Define them once, and every asset in that category gets them on its form.

---

## Fields belong to a category

A custom field is attached to a **category** — not to the whole inventory, and not to a sub-category. Define "PIN" on *SIM* and it appears on SIM assets only; a software licence never shows a PIN box.

Fields are defined from **Inventory → Manage Catalogue**, by expanding a category row. Unlike the catalogue itself, which populates itself as you go, a custom field is **never created automatically** — not by saving an asset, not by importing a CSV. It changes the form for everyone in your organization, so it is always a deliberate action.

---

## The five field types

| Type | What it accepts | On the form |
|---|---|---|
| **Text** | any text, up to a length you choose (500 by default) | a text box |
| **Number** | a number, with either a comma or a dot as decimal separator | a numeric box |
| **Date** | a date | a date picker |
| **Yes/No** | a true or false value | a checkbox |
| **List** | one of the options you declare | a drop-down |

The type is chosen when the field is created and **cannot be changed afterwards**. Values already saved are stored in the format of the type you picked, and switching type would make them unreadable.

Each field can also be marked **required** — assets in that category can't be saved without it — and can carry a short help text shown under the box.

### Values are normalized

Whatever you type, the value is stored in one consistent form: numbers with a dot as decimal separator, dates as `YYYY-MM-DD`, Yes/No as `true`/`false`, and list values with exactly the spelling you declared in the options. This is what makes them searchable and comparable across assets, and identical in every export.

Ambiguous numbers are rejected rather than guessed. `1.234,56` and `1,234.56` mean different things to different people, and a permissive reading would silently change a value by a factor of a thousand — so the portal asks you to correct it instead.

---

## The key never changes

Every field has two names:

- the **label**, which you see on the form and can rename whenever you like;
- the **key**, generated from the label when the field is created — `Soglia traffico (GB)` becomes `soglia-traffico-gb`.

The key is what appears in CSV files, as the column `custom:soglia-traffico-gb`. **It never changes**, not even when you rename the label. This is deliberate: your spreadsheets, templates, and scripts keep working after a rename. If you rename "Soglia traffico" to "Traffico incluso", the column in your files stays the same and your file still imports.

---

## Searching and filtering

Custom field values are part of the ordinary search: typing a phone number or a customer code in the Inventory search box finds the asset that carries it in a custom field, even when nothing in the asset's name matches.

**List** fields additionally become filter drop-downs on the Inventory page. They appear only once you have selected a category — it is the category that determines which fields exist — and combining two of them narrows the result to assets that match both. Filtering is exact, so an option like "TIM" never also matches "TIM Business".

Text, number, date, and Yes/No fields do not get their own filter box: a dedicated filter per field would make the toolbar unusable. Free-text search covers them.

---

## In import and export

Exports carry one `custom:<key>` column for every active field of the categories present in the extraction. An export limited to SIM assets stays narrow; an export of the whole inventory is as wide as the sum of all categories' fields, and each asset leaves blank the columns that don't belong to its category. That is expected, not a defect.

On import, a `custom:` column is matched to a field by its key. Columns that don't match any field of that row's category are **listed in the preview and ignored** — a field is never created from a file. Values are validated exactly as they are on the form: a row with an invalid value is rejected on its own, with the reason shown, and the other rows are imported normally.

See [Import & Export](https://wiki.cyberguard.srl/dim/inventory/import-export.md) for the rest of the CSV format.

---

## What happens when an asset changes category

Fields belong to a category, so moving an asset to a different category means its form now shows different fields.

The values from the previous category are **not deleted**. They stay stored, and the asset's page shows a notice listing them, with a button to remove them. Nothing disappears because of a change of mind: the deletion is always an explicit choice.

---

## Retiring a field

A field that has been filled in on assets **cannot be deleted** — deleting the definition would leave those values with nothing to describe them, and would remove a column from the CSV files your organization already relies on.

Instead, a field can be **retired**. A retired field:

- no longer appears on the form of new or existing assets;
- keeps every value already recorded, still visible in the database and in exports of files produced before the change;
- can be reactivated at any time, bringing its values back into view.

Before retiring a field the portal tells you how many assets have it filled in, so the decision is made with the number in front of you.

---

## A note on sensitive values

Custom fields are ordinary data: they are not encrypted at rest, and they are not masked on screen. A PIN or PUK stored here is as protected as the rest of your inventory — which is to say, protected by who can access the portal, not by the field itself.

Store what your access policy allows, and treat these fields as you would any other inventory data.
