
# Champs formule

Un champ `formula` ne stocke rien que quelqu'un saisit. Sa valeur est calculée à partir d'une expression référençant d'autres champs du même enregistrement, et elle est recalculée dès que l'une de ces entrées change.

```yaml
- { id: 1, name: total_price, type: formula, formula: 'price * quantity', resultType: number }
```

Comme tous les types de champs, `formula` accepte aussi les [propriétés de base des champs](/fr/docs/tables-overview#proprits-de-base-des-champs).

| Propriété            | Description                                                                               |
| -------------------- | ----------------------------------------------------------------------------------------- |
| `formula`            | Expression à calculer. Accepte les références de champs, les opérateurs et les fonctions. |
| `resultType`         | Type de données attendu du résultat.                                                      |
| `format`             | Format d'affichage du résultat (`currency`, `percentage`, …).                             |
| `currency`           | Code de devise ISO 4217 à trois lettres (`USD`, `EUR`, `GBP`). `USD` par défaut.          |
| `precision`          | Nombre de décimales, de `0` à `10`. `2` par défaut pour la plupart des devises.           |
| `symbolPosition`     | Position du symbole monétaire par rapport au montant : `before` ou `after`.               |
| `negativeFormat`     | Affichage des montants négatifs : `minus` ou `parentheses`.                               |
| `thousandsSeparator` | Séparateur de milliers : `comma`, `period`, `space` ou `none`.                            |

## Un montant calculé par une formule

Une formule portant sur des champs monétaires reste de la monnaie, mais elle **n'hérite pas** de la devise des champs qu'elle référence. Une expression peut en toucher plusieurs, ou aucune : il n'y aurait donc rien à hériter sans deviner. Déclarez le code :

```yaml
- id: 12
  name: unit_price
  type: currency
  currency: EUR
  precision: 2
- id: 27
  name: stock_value
  type: formula
  formula: unit_price * stock_on_hand
  resultType: number
  format: currency
  currency: EUR
```

Sans `currency`, le montant s'affiche avec la valeur par défaut `USD` — c'est ainsi qu'une colonne `stock_value` a fini par afficher `$224,430.90` à côté du `€28.63` dont elle était calculée.

Les cinq propriétés d'affichage — `currency`, `precision`, `symbolPosition`, `negativeFormat`, `thousandsSeparator` — sont exactement celles qu'accepte un [champ `currency`](/fr/docs/number-fields), avec un comportement identique.

## Ce qui est vérifié, et ce qui ne l'est pas

`resultType` et `format` sont des chaînes libres, pas des vocabulaires fermés. Les valeurs d'usage sont `string`, `number`, `boolean` et `date` pour la première, `currency`, `percentage`, `decimal` et `date` pour la seconde — mais le schéma accepte n'importe quelle chaîne et n'en valide aucune. Une faute de frappe passe donc `sovrium validate` et se révèle plus tard comme une surprise de rendu plutôt que comme une erreur.

Les cinq propriétés d'affichage monétaire font exception : elles **sont** validées, et une valeur invalide est refusée au décodage de la configuration.

`formula` elle-même est vérifiée sur les références de champs qu'elle fait : une expression nommant une colonne absente de la table échoue au décodage.

## Composer une référence lisible

`autonumber` n'accepte délibérément ni préfixe ni remplissage. Une formule est l'endroit où cette présentation se déclare :

```yaml
- { id: 3, name: invoice_number, type: autonumber }
- id: 4
  name: invoice_reference
  type: formula
  formula: "'INV-' || LPAD(invoice_number::text, 5, '0')"
  resultType: string
```

Garder la séquence et sa présentation séparées permet de changer le format de la référence sans toucher aux numéros déjà attribués.

## Une colonne calculée n'est pas modifiable

`formula` est dérivée, comme `count`, `rollup` et `lookup`. Elle se recalcule à partir de ses entrées et n'est pas accessible en écriture, ni par l'API des enregistrements ni par un formulaire : une écriture qui la nomme est refusée plutôt que silencieusement ignorée, parce qu'une valeur qui semble enregistrée sans l'être est la pire des deux défaillances.

## Pages connexes

- [Champs comptage et numérotation](/fr/docs/computed-fields) — `count` et `autonumber`, les deux autres colonnes que le moteur remplit.
- [Champs bouton](/fr/docs/button-fields) — le champ interactif qui déclenche une URL ou une automatisation.
- [Champs relationnels](/fr/docs/relational-fields) — `relationship`, `lookup` et `rollup`.
- [Présentation des types de champs](/fr/docs/field-types-overview) — tous les types par catégorie.
