> ## Documentation Index
> Fetch the complete documentation index at: https://api-doc.fidly.be/llms.txt
> Use this file to discover all available pages before exploring further.

# Relations

> Les tiers de l'entreprise : sociétés et contacts individuels, unifiés.

Une `relation` est un tiers de l'entreprise : soit une **société**, soit un
**contact** individuel. Les deux passent par la même ressource ; `type`
(`company` | `contact`) dit lequel vous regardez.

## Lister les relations

`GET /relations` — liste paginée. Filtres : `type`, `is_customer`, `is_supplier`,
`vat`, `identifier`. Les filtres propres aux sociétés excluent naturellement les
contacts quand ils sont posés.

## Récupérer une relation

`GET /relations/{id}` — le tiers complet, avec son `address`.

### Société ou contact

|                           | `company`                                                               | `contact`                       |
| ------------------------- | ----------------------------------------------------------------------- | ------------------------------- |
| obligatoire à la création | `type`, `name`, `address`                                               | `type`, `first_name`, `address` |
| optionnel, commun         | `email`, `phone`, `language`                                            | `email`, `phone`, `language`    |
| optionnel, propre au type | `vat`, `identifier`, `electronic_address`, `is_customer`, `is_supplier` | `last_name`                     |

Les champs qui n'existent pas pour un type sont **absents** de la réponse, pas à
`null`. Le `name` d'un contact est dérivé de `first_name` + `last_name` et ne se
fournit pas.

## Créer une relation

`POST /relations` — droit requis : création de relations. La réponse est le tiers
complet (`201`), tel qu'un `GET` ultérieur le renverra.

* `language` ∈ `fr`, `en`, `nl`, `de` — défaut `en`.
* `is_customer` / `is_supplier` valent `true` par défaut.
* Envoyer un champ qui appartient à l'autre type renvoie `422 field_not_editable`.

### Adresse

`address` est obligatoire, avec au minimum `country_code` (ISO 3166-1 alpha-2,
normalisé en majuscules). Deux règles valent toujours, sinon `422 invalid_address` :
un tiers ne peut jamais se retrouver sans `country_code`, et `street_number` ne se
pose pas sans `street`. `province` est du texte libre (province, état ou région
selon le pays).

### Doublons

Une société dont le `vat`, l'`identifier` ou l'`electronic_address` appartient déjà
à une autre de vos sociétés est refusée (`409 duplicate_relation`), le message
donnant l'id de celle qui existe. Les valeurs vides ne comptent pas. Pour créer le
doublon malgré tout, ajoutez `?ignore_duplicate=true`.

<Note>
  Le contrôle des doublons ne concerne que les sociétés : un contact n'a aucun de ces
  champs, et `?ignore_duplicate=true` sur un contact renvoie `422 invalid_parameter`.
</Note>

## Mettre à jour une relation

`PATCH /relations/{id}` — droit requis : modification de relations. Seuls les champs
présents dans le corps sont appliqués ; la réponse est le tiers complet. Une requête
qui viole une règle est refusée en bloc.

### Type

Le `type` d'un tiers est fixé à la création : une société ne devient pas un contact,
ni l'inverse. Le modifier renvoie `422 field_not_editable` — supprimez et recréez le
tiers.

### Fusion de l'adresse

Chaque champ envoyé remplace la valeur stockée, sauf `address`, qui est
**fusionnée** : n'envoyer que `city` corrige la ville sans redonner le reste. Les
règles de l'adresse sont vérifiées sur le résultat de la fusion.

### Effacer un champ

Envoyer `null` vide un champ, sauf ceux que la création rend obligatoires (`name`
d'une société, `first_name` d'un contact, `address`).

### Doublons à la modification

Les mêmes règles qu'à la création s'appliquent : une modification qui donnerait à
une société le `vat`, l'`identifier` ou l'`electronic_address` d'une autre est
refusée (`409 duplicate_relation`), sauf avec `?ignore_duplicate=true`.

## Supprimer une relation

`DELETE /relations/{id}` — droit requis : suppression de relations. Renvoie `204`.
La suppression est définitive, et refusée (`409 relation_in_use`) tant que quelque
chose pointe encore sur le tiers : un document qu'il a émis ou reçu, un abonnement,
une facture d'abonnement, une ligne de prestation, un projet, ou sa correspondance
avec le système comptable. Le message dit ce qui bloque.

<Warning>
  La suppression d'un tiers entraîne celle de ses adresses de livraison et de ses
  liens vers des contacts. Les contacts eux-mêmes ne
  sont jamais supprimés avec la société, seulement les liens.
</Warning>

## Sur les documents

`documents.relation_id` porte l'UUID public du tiers lié (`relation_type` en donne
la nature), résolvable via `GET /relations/{id}`. Pour émettre un document, le tiers
doit avoir une adresse.
