Ventilation
Ventiler, c'est démonter une entrée du registre en plusieurs entrées filles, chacune rattachée au numéro d'ordre de son parent : un ordinateur acheté en lot devient une carte mère, deux barrettes de mémoire et une alimentation, revendables séparément.
La filiation répond à une exigence de traçabilité : chaque pièce revendue doit pouvoir être rattachée à l'objet dont elle provient, et par lui au vendeur d'origine. Sans elle, une pièce apparaîtrait au registre sans origine.
Module optionnel, désactivé par défaut
La ventilation relève du module Ventilation, qui n'est pas ouvert par défaut. Il est activé établissement par établissement par l'équipe Registeo, sur demande — contactez-nous pour l'ouvrir sur le vôtre.
Tant qu'il ne l'est pas, l'API se comporte exactement comme si le module n'existait pas :
| Appel | Réponse sans le module |
|---|---|
POST /api/objets/{id}/ventilation | 403 VENTILATION_DESACTIVEE |
Mouvement avec statut: "ventile" | 400 STATUT_INVALIDE — ventile n'apparaît pas dans validStatuts |
Le module ne conditionne que l'écriture : si vous le faites refermer après usage, les entrées filles déjà inscrites restent lisibles et imprimées, avec leur filiation. On ne masque pas des écritures du registre.
Ventiler une entrée
POST /api/objets/{id}/ventilation
Ce que porte une entrée fille
Une pièce issue d'un démontage n'a ni vendeur, ni prix d'achat, ni mode de règlement : personne ne la lui a vendue. Son origine, c'est parentNumero — le numéro d'ordre de l'entrée démontée, qui porte le vendeur, le prix et le règlement réels. C'est cette filiation qui tient lieu de mention d'origine au registre, et elle est scellée dans le journal d'audit.
En conséquence, l'obligation de prix d'achat portée par certains régimes (Objets d'occasion, Métaux ferreux et non ferreux) ne s'applique pas aux entrées filles.
Une pièce peut être ventilée à son tour : la filiation forme alors une chaîne.
Champs ajoutés à ObjetMobilier
Le module ajoute trois champs au modèle ObjetMobilier, renseignés sur les entrées filles et null partout ailleurs :
typeOperation: string // "ventilation" sur une entrée fille, en plus des valeurs usuelles
parentNumero: string | null // Numéro d'ordre de l'entrée démontée
parentObjetId: string | null // Identifiant de cette même entrée
valeurEstimee: number | null // Valeur attribuée au démontage — n'est PAS un prix d'achat
typeOperation: "ventilation" n'est pas acceptée à la création d'un objet : elle décrit une origine, pas un mode d'acquisition, et n'est posée que par cet endpoint.
Modifier une entrée fille
PUT /api/objets/{id} s'applique aux pièces comme aux autres entrées, à trois différences près :
- ni vendeur, ni mode de règlement, ni prix d'achat ne sont exigés — les imposer rendrait la pièce inéditable, et les remplir reviendrait à inventer une transaction ;
typeOperationetparentNumerosont figés : ils décrivent d'où vient la pièce, pas une saisie ;valeurEstimeeest corrigeable — une estimation se révise, et la correction est inscrite au journal d'audit. Omise du corps de la requête, elle est préservée : une intégration qui ignore ce champ ne le fera pas disparaître du registre.
Cette opération ne touche pas au stock
L'endpoint crée les pièces, rien d'autre. Il ne sort pas l'entrée parente et ne consomme aucune quantité. Sortir le parent est une opération distincte, à enregistrer via POST /api/objets/{id}/mouvements avec le statut ventile — une écriture volontaire et datée, jamais un effet de bord.
Le statut ventile
Ce statut appartient au module : il n'apparaît pas dans les statuts des établissements qui ne l'ont pas souscrit, et y est refusé en 400 STATUT_INVALIDE.
| Propriété | Valeur |
|---|---|
| Catégorie | sorti |
| Date | requise |
| Prix | sans objet — un objet démonté n'a pas été vendu |
| Acheteur | jamais demandé, même sous un régime qui l'impose habituellement (Métaux précieux) : il n'y a pas de contrepartie à identifier |
Sortir un objet démonté en vendu ferait mentir le registre. C'est la raison d'être de ce statut distinct.
Header obligatoire : X-Agent
Comme pour la création d'objet. 400 MISSING_AGENT sans ce header.
Corps de la requête
| Champ | Type | Requis | Description |
|---|---|---|---|
pieces | object[] | Oui | 1 à 50 pièces à créer. Vide → 400 PIECES_MANQUANTES, au-delà de 50 → 400 PIECES_TROP_NOMBREUSES. |
date | string | Non | Date du démontage (ISO 8601, par défaut : maintenant). Elle devient la date d'entrée des pièces. Antérieure à celle du parent → 400 DATE_VENTILATION_ANTERIEURE ; dans le futur → 400 DATE_VENTILATION_FUTURE. |
Chaque élément de pieces :
| Champ | Type | Requis | Description |
|---|---|---|---|
designation | string | Oui | Absente → 400 DESIGNATION_MANQUANTE |
marques | string | Non | Marques et signes particuliers |
quantite | number | Non | Défaut 1. Doit être strictement positive, sinon 400 QUANTITE_INVALIDE. |
valeurEstimee | number | Non | Valeur attribuée à la pièce. Ce n'est pas un prix d'achat. Aucune contrainte avec le prix du parent : le reste part souvent au rebut. Négative ou non numérique → 400 VALEUR_INVALIDE. Corrigeable ensuite par PUT /api/objets/{id} — voir ci-dessous. |
regimes | string[] | Non | Par défaut, les régimes du parent. Un régime non actif sur l'établissement → 400 REGIME_NON_ACTIF. |
champsActivite | object | Non | Mêmes clés autorisées qu'à la création d'un objet, sinon 400 CHAMPS_ACTIVITE_INVALIDES. |
photoKeys | string[] | Non | Clés obtenues via upload-photo?context=objets, sinon 400 FICHIER_INTROUVABLE. |
Toutes les pièces sont validées avant qu'une seule ne soit écrite : une ventilation à moitié inscrite laisserait des pièces orphelines et un parent dont on ne saurait plus s'il est démonté.
Exemple
{
"date": "2025-06-15",
"pieces": [
{ "designation": "Carte mère", "marques": "OptiPlex 7050", "valeurEstimee": 40 },
{ "designation": "Barrette RAM 8 Go DDR4", "quantite": 2, "valeurEstimee": 15 },
{ "designation": "Alimentation 240W" }
]
}
Réponse 201
{
"success": true,
"parent": { "id": "objet-uuid", "numero": "312" },
"pieces": [
{
"id": "objet-uuid-1",
"numero": "456",
"designation": "Carte mère",
"marques": "OptiPlex 7050",
"quantite": 1,
"valeurEstimee": 40,
"dateAchat": "2025-06-15T00:00:00.000Z",
"typeOperation": "ventilation",
"parentNumero": "312",
"parentObjetId": "objet-uuid",
"statut": "en_stock",
"regimes": ["OBJETS_OCCASION"]
}
]
}
Codes d'erreur
Codes propres au module, en plus de ceux de l'API générale.
code | Statut | Signification |
|---|---|---|
VENTILATION_DESACTIVEE | 403 | Le module n'est pas ouvert sur cet établissement |
PIECES_MANQUANTES | 400 | Aucune pièce à créer |
PIECES_TROP_NOMBREUSES | 400 | Au-delà de 50 pièces |
DESIGNATION_MANQUANTE | 400 | Une pièce n'a pas de désignation |
QUANTITE_INVALIDE | 400 | Quantité de pièce nulle ou négative |
VALEUR_INVALIDE | 400 | valeurEstimee négative ou non numérique |
DATE_VENTILATION_ANTERIEURE | 400 | La date du démontage précède la date d'entrée de l'objet démonté |
DATE_VENTILATION_FUTURE | 400 | La date du démontage est postérieure à aujourd'hui |
DATE_VENTILATION_INVALIDE | 400 | Date de démontage illisible |
Les codes communs s'appliquent aussi : MISSING_AGENT, AGENT_INTROUVABLE, REGIME_NON_ACTIF, CHAMPS_ACTIVITE_INVALIDES, FICHIER_INTROUVABLE, SUBSCRIPTION_INACTIVE, FREE_LIMIT_REACHED — une ventilation de trois pièces compte pour trois enregistrements.