Implement CRUD functionality for Articles and Tiers with enhanced API documentation

- Introduced new endpoints for creating and modifying articles (`art_add`, `art_mod`) and tiers (`third_add`, `third_mod`), allowing users to manage these entities effectively.
- Updated the Articles and Tiers pages to include forms for adding and modifying records, complete with parameter tables for clear guidance on required inputs.
- Enhanced the API documentation to include detailed descriptions, examples, and metadata for the new endpoints, improving usability and understanding for developers.
- Created a new rule for writing conventions with French accents to ensure consistency across the project.
- Updated existing documentation to reflect structural changes and added a summary table for CRUD operations.
- Added tests to verify the functionality of the new features and ensure robust error handling.
This commit is contained in:
2026-02-23 15:55:09 +01:00
parent b95ee46b1c
commit 714bdc3dd7
15 changed files with 1479 additions and 145 deletions

View File

@@ -7,12 +7,48 @@ Dernière mise à jour : 2026-02-23
## Table des matières
1. [Pré-requis](#1-pré-requis)
- [Connexion VPN](#connexion-vpn)
- [Accès au serveur](#accès-au-serveur)
- [Clé API](#clé-api)
- [Dossier](#dossier)
- [Variables d'environnement](#variables-denvironnement)
- [Configuration Laravel](#configuration-laravel)
2. [Environnements d'utilisation](#2-environnements-dutilisation)
- 2.1 [Projet local avec VPN](#21-projet-local-avec-vpn)
- 2.2 [Bureau à distance (Postman)](#22-bureau-à-distance-postman)
- 2.3 [Récapitulatif des différences](#23-récapitulatif-des-différences)
3. [Comment effectuer des requêtes](#3-comment-effectuer-des-requêtes)
- [Méthode HTTP](#méthode-http)
- [Format de l'URL](#format-de-lurl)
- [Headers obligatoires](#headers-obligatoires)
- [Exemple de requête complète](#exemple-de-requête-complète)
- [Paramètres des requêtes](#paramètres-des-requêtes)
- [Gestion des erreurs](#gestion-des-erreurs)
- [Validation des champs](#validation-des-champs)
4. [Structure de réponse](#4-structure-de-réponse)
- [Format standard](#format-standard)
- [Description des clés](#description-des-clés)
- [Exemple de réponse réussie](#exemple-de-réponse-réussie)
- [Exemple de réponse en erreur](#exemple-de-réponse-en-erreur)
- [Métadonnées spécifiques par endpoint](#métadonnées-spécifiques-par-endpoint)
5. [Tables et colonnes disponibles](#5-tables-et-colonnes-disponibles)
- [Liste des tables](#liste-des-tables)
- [Types de colonnes](#types-de-colonnes)
- [Colonnes systeme communes](#colonnes-systeme-communes)
- [Colonnes detaillees par table](#colonnes-detaillees-par-table)
- [Exploration des colonnes](#exploration-des-colonnes)
6. [Récupération de données](#6-récupération-de-données)
- 6.1 [Structure de la base de données (tables_list, column_list)](#61-structure-de-la-base-de-données)
- 6.2 [Articles (art_list, art_getstk)](#62-articles)
- 6.3 [Journaux (jnl_list)](#63-journaux)
- 6.4 [Documents (document_list, document_detail, Document_GetStatusList, Document_GetUnitPriceAndVat, Document_GetDueDate, Document_GetAttachListThumbnail, Document_GetPDF)](#64-documents)
- 6.5 [Tiers (third_list, third_GetArtHistory)](#65-tiers)
- 6.6 [Divers (getserialnumber, codes_list, custom_geninv_updatestock)](#66-divers)
7. [Envoi de données](#7-envoi-de-données)
- 7.1 [Documents (document_add, document_mod)](#71-documents)
- 7.2 [Articles (art_add, art_mod)](#72-articles)
- 7.3 [Tiers (third_add, third_mod)](#73-tiers)
- 7.4 [Divers (custom_geninv_updatestock)](#74-divers)
8. [Relations entre entités](#8-relations-entre-entités)
9. [Remarques et points d'attention](#9-remarques-et-points-dattention)
10. [Ressources externes](#10-ressources-externes)
@@ -2223,7 +2259,19 @@ Le paramètre `STKID` doit correspondre à un dépôt ayant un journal d'inventa
Les endpoints de cette section permettent de créer ou modifier des données dans le système de gestion via l'API.
### 7.1 Ajout d'un document
**Récapitulatif des opérations d'écriture par page** :
| Page | Création | Modification | Suppression |
|------|:--------:|:------------:|:-----------:|
| **Documents** | `document_add` | `document_mod` | Non disponible |
| **Articles** | `art_add` | `art_mod` | Non disponible |
| **Tiers** | `third_add` | `third_mod` | Non disponible |
| **Divers** | -- | `custom_geninv_updatestock` | Non disponible |
| **Journaux** | Non disponible | Non disponible | Non disponible |
**Remarque** : aucun endpoint de suppression n'est disponible via l'API. Les endpoints `art_del`, `third_del`, `jnl_add`, `jnl_mod`, `jnl_del` et `document_del` n'existent pas (HTTP 404).
### 7.1 Documents
#### `document_add` -- Création d'un document
@@ -2239,7 +2287,7 @@ Crée un nouveau document commercial (devis, commande, facture, etc.) dans un jo
| Paramètre | Type | Obligatoire | Description |
|-----------|------|:-----------:|-------------|
| `ThirdId` | `string` | Oui | Identifiant du tiers (champ `custid` de la table `cust`). Détermine le client ou fournisseur associé au document. |
| `Date` | `string` | Oui | Date d'encodage du document (ex : `"2026-02-20"`). |
| `Date` | `string` | Oui | Date d'encodage du document au format `YYYY-MM-DD` (ex : `"2026-02-20"`). |
| `Artid` | `array` | Oui | Tableau d'identifiants d'articles (champ `artid` de la table `art`). Chaque élément correspond à une ligne du document. |
| `Qty` | `array` | Oui | Tableau de quantités. Correspond position par position au tableau `Artid`. Chaque élément est un `string`. |
| `Saleprice` | `array` | Oui | Tableau des prix de vente unitaires. Correspond position par position au tableau `Artid`. Chaque élément est un `string`. |
@@ -2259,6 +2307,13 @@ Crée un nouveau document commercial (devis, commande, facture, etc.) dans un jo
**Correspondance des tableaux** : les tableaux `Artid`, `Qty`, `Saleprice`, `Discount`, `Vatid` et `Vatpc` fonctionnent par correspondance positionnelle. L'élément à l'index 0 de chaque tableau concerne la première ligne du document, l'élément à l'index 1 la deuxième ligne, etc.
**Métadonnées retournées** :
| Clé | Type | Description |
|-----|------|-------------|
| `rowcount` | `int` | Nombre d'éléments dans `data` (1 en cas de succès). |
| `issuccess` | `bool` | Indique si l'opération a réussi. |
**Exemple de requête** :
```json
@@ -2282,13 +2337,37 @@ Crée un nouveau document commercial (devis, commande, facture, etc.) dans un jo
}
```
---
**Exemple de réponse (succès)** :
### 7.2 Modification d'un document
```json
{
"data": {
"number": "2026/0002"
},
"metadata": { "rowcount": 1, "issuccess": true },
"error": null
}
```
**Exemple de réponse (erreur -- tiers inexistant)** :
```json
{
"data": {
"xml": "<VFPData><headererror><errorcode>001</errorcode><description>Thirdid 'INEXISTANT' does not exist !</description></headererror></VFPData>"
},
"metadata": { "rowcount": 1, "issuccess": false },
"error": ["Code: 001, Description: Thirdid 'INEXISTANT' does not exist !"]
}
```
**Remarque** : tous les tableaux (`Artid`, `Qty`, `Saleprice`, `Discount`, `Vatid`, `Vatpc`) doivent avoir la même longueur. Un décalage entre les tableaux peut provoquer des erreurs silencieuses ou des données incorrectes.
---
#### `document_mod` -- Modification d'un document existant
Modifie un document existant identifié par son numéro et son journal. Permet de mettre à jour les lignes d'articles, les prix, le tiers, ou d'ajouter des fichiers joints.
Modifie un document existant identifié par son numéro et son journal. Permet de mettre à jour les lignes d'articles, les prix, le tiers, ou d'ajouter des fichiers joints. Les lignes d'articles fournies **remplacent** les lignes existantes du document.
| | |
|---|---|
@@ -2299,7 +2378,7 @@ Modifie un document existant identifié par son numéro et son journal. Permet d
| Paramètre | Type | Obligatoire | Description |
|-----------|------|:-----------:|-------------|
| `number` | `string` | Oui | Identifiant du document à modifier. |
| `number` | `string` | Oui | Numéro du document à modifier. |
| `JNL` | `string` | Oui | Code du journal lié au document. |
| `Thirdid` | `string` | Non | Nouvel identifiant du tiers (si modification du tiers associé). |
| `Artid` | `array` | Non | Tableau d'identifiants d'articles (remplace les lignes existantes). |
@@ -2307,6 +2386,13 @@ Modifie un document existant identifié par son numéro et son journal. Permet d
| `Saleprice` | `array` | Non | Tableau des prix de vente unitaires (correspond position par position à `Artid`). |
| `Attachments` | `array` | Non | Liste de fichiers joints (même structure que `document_add`). |
**Métadonnées retournées** :
| Clé | Type | Description |
|-----|------|-------------|
| `rowcount` | `int` | Nombre d'éléments dans `data` (1 en cas de succès). |
| `issuccess` | `bool` | Indique si l'opération a réussi. |
**Exemple de requête** :
```json
@@ -2319,6 +2405,375 @@ Modifie un document existant identifié par son numéro et son journal. Permet d
}
```
**Exemple de réponse (succès)** :
```json
{
"data": {
"updated": true
},
"metadata": { "rowcount": 1, "issuccess": true },
"error": null
}
```
**Exemple de réponse (erreur -- document inexistant)** :
```json
{
"data": {
"xml": "<VFPData><headererror><errorcode>001</errorcode><description>Document not found</description></headererror></VFPData>"
},
"metadata": { "rowcount": 1, "issuccess": false },
"error": ["Code: 001, Description: Document not found"]
}
```
**Attention** : lorsque des tableaux `Artid`, `Qty` et `Saleprice` sont fournis, ils **remplacent intégralement** les lignes existantes du document. Pour ajouter une ligne sans supprimer les existantes, il faut inclure toutes les lignes (anciennes + nouvelles) dans les tableaux.
---
### 7.2 Articles
#### `art_add` -- Création d'un article
Crée un nouvel article dans le catalogue. L'identifiant de l'article (`ARTID`) doit être unique. Les autres champs sont optionnels et correspondent aux colonnes de la table `art` (160 colonnes disponibles via `column_list/art`).
| | |
|---|---|
| **URL** | `POST /{dossier}/art_add` |
| **Méthode service** | `LogisticsService::artAdd(array $params)` |
**Paramètres** :
| Paramètre | Type | Obligatoire | Description |
|-----------|------|:-----------:|-------------|
| `ARTID` | `string` | Oui | Identifiant unique de l'article à créer. Doit être unique dans la table `art`. |
| `NAME1` | `string` | Non | Nom / libellé de l'article. |
| `SALEPRICE` | `string` | Non | Prix de vente unitaire (format string, ex : `"49.99"`). |
**Remarque** : d'autres colonnes de la table `art` peuvent être passées en paramètre (en MAJUSCULES). La liste complète des colonnes est disponible via `column_list/art`.
**Métadonnées retournées** :
| Clé | Type | Description |
|-----|------|-------------|
| `rowcount` | `int` | Nombre d'éléments dans `data` (1 en cas de succès). |
| `issuccess` | `bool` | Indique si l'opération a réussi. |
**Exemple de requête** :
```json
{
"ARTID": "ART001",
"NAME1": "Clavier sans fil Bluetooth",
"SALEPRICE": "49.99"
}
```
**Exemple de réponse (succès)** :
```json
{
"data": {
"artid": "ART001"
},
"metadata": { "rowcount": 1, "issuccess": true },
"error": null
}
```
**Exemple de réponse (erreur -- ARTID déjà existant)** :
```json
{
"data": {
"xml": "<VFPData><headererror><errorcode>001</errorcode><description>Artid 'ART001' already exist ! Please use Art_Mod function</description></headererror></VFPData>"
},
"metadata": { "rowcount": 1, "issuccess": false },
"error": ["Code: 001, Description: Artid 'ART001' already exist ! Please use Art_Mod function"]
}
```
**Exemple de réponse (erreur -- ARTID manquant)** :
Requête avec body vide `{}` ou sans `ARTID` :
```
HTTP 400 -- ARTID is required and cannot be empty.
```
---
#### `art_mod` -- Modification d'un article existant
Modifie un article existant identifié par son `ARTID`. Seuls les champs fournis sont mis à jour ; les champs omis restent inchangés.
| | |
|---|---|
| **URL** | `POST /{dossier}/art_mod` |
| **Méthode service** | `LogisticsService::artMod(array $params)` |
**Paramètres** :
| Paramètre | Type | Obligatoire | Description |
|-----------|------|:-----------:|-------------|
| `ARTID` | `string` | Oui | Identifiant de l'article à modifier. Doit exister dans la table `art`. |
| `NAME1` | `string` | Non | Nouveau nom / libellé de l'article. |
| `SALEPRICE` | `string` | Non | Nouveau prix de vente unitaire (format string). |
**Remarque** : d'autres colonnes de la table `art` peuvent être passées en paramètre (en MAJUSCULES).
**Métadonnées retournées** :
| Clé | Type | Description |
|-----|------|-------------|
| `rowcount` | `int` | Nombre d'éléments dans `data` (1 en cas de succès). |
| `issuccess` | `bool` | Indique si l'opération a réussi. |
**Exemple de requête** :
```json
{
"ARTID": "ART001",
"NAME1": "Clavier Bluetooth Premium",
"SALEPRICE": "59.99"
}
```
**Exemple de réponse (succès)** :
```json
{
"data": {
"artid": "ART001"
},
"metadata": { "rowcount": 1, "issuccess": true },
"error": null
}
```
**Exemple de réponse (erreur -- ARTID inexistant)** :
```json
{
"data": {
"xml": "<VFPData><headererror><errorcode>001</errorcode><description>Artid 'INEXISTANT' does not exist !</description></headererror></VFPData>"
},
"metadata": { "rowcount": 1, "issuccess": false },
"error": ["Code: 001, Description: Artid 'INEXISTANT' does not exist !"]
}
```
---
### 7.3 Tiers
#### `third_add` -- Création d'un tiers
Crée un nouveau tiers (client ou fournisseur) dans la base de données. L'API génère automatiquement un identifiant unique au format `_@NNNNNNNN` (ex : `_@00036051`). Aucun paramètre n'est strictement obligatoire, mais il est recommandé de fournir au minimum un nom (`NAME`).
| | |
|---|---|
| **URL** | `POST /{dossier}/third_add` |
| **Méthode service** | `LogisticsService::thirdAdd(array $params)` |
**Paramètres** :
| Paramètre | Type | Obligatoire | Description |
|-----------|------|:-----------:|-------------|
| `NAME` | `string` | Non | Nom du tiers (raison sociale ou nom complet). |
| `VAT` | `string` | Non | Numéro de TVA (ex : `"BE0123456789"`). |
| `EMAIL` | `string` | Non | Adresse e-mail du tiers. |
**Remarque** : d'autres colonnes de la table `cust` peuvent être passées en paramètre (en MAJUSCULES). La liste complète des colonnes est disponible via `column_list/cust`. Attention : toutes les colonnes de `column_list/cust` ne sont pas nécessairement acceptées (voir la remarque 18 sur `third_list`).
**Métadonnées retournées** :
| Clé | Type | Description |
|-----|------|-------------|
| `rowcount` | `int` | Nombre d'éléments dans `data` (1 en cas de succès). |
| `issuccess` | `bool` | Indique si l'opération a réussi. |
**Exemple de requête** :
```json
{
"NAME": "DUPONT SPRL",
"VAT": "BE0123456789",
"EMAIL": "contact@dupont.be"
}
```
**Exemple de réponse (succès)** :
```json
{
"data": {
"thirdid": "_@00036051"
},
"metadata": { "rowcount": 1, "issuccess": true },
"error": null
}
```
**Attention** : l'endpoint `third_add` est très permissif. Un appel avec un body vide `{}` ou avec des champs vides crée tout de même un nouveau tiers avec un identifiant généré. Vérifiez les données avant l'envoi pour éviter de créer des fiches vides.
---
#### `third_mod` -- Modification d'un tiers existant
Modifie un tiers existant identifié par son `CUSTID`. Seuls les champs fournis sont mis à jour ; les champs omis restent inchangés.
| | |
|---|---|
| **URL** | `POST /{dossier}/third_mod` |
| **Méthode service** | `LogisticsService::thirdMod(array $params)` |
**Paramètres** :
| Paramètre | Type | Obligatoire | Description |
|-----------|------|:-----------:|-------------|
| `CUSTID` | `string` | Oui | Identifiant du tiers à modifier (champ `custid` de la table `cust`). Doit exister. |
| `NAME` | `string` | Non | Nouveau nom du tiers. |
| `VAT` | `string` | Non | Nouveau numéro de TVA. |
| `EMAIL` | `string` | Non | Nouvelle adresse e-mail. |
**Remarque** : d'autres colonnes de la table `cust` peuvent être passées en paramètre (en MAJUSCULES).
**Métadonnées retournées** :
| Clé | Type | Description |
|-----|------|-------------|
| `rowcount` | `int` | Nombre d'éléments dans `data` (1 en cas de succès). |
| `issuccess` | `bool` | Indique si l'opération a réussi. |
**Exemple de requête** :
```json
{
"CUSTID": "_@00036051",
"NAME": "DUPONT SA",
"EMAIL": "nouveau@dupont.be"
}
```
**Exemple de réponse (succès)** :
```json
{
"data": {
"thirdid": "_@00036051"
},
"metadata": { "rowcount": 1, "issuccess": true },
"error": null
}
```
**Exemple de réponse (erreur -- CUSTID inexistant)** :
```json
{
"data": {
"xml": "<VFPData><headererror><errorcode>001</errorcode><description>Custid 'INEXISTANT' not exist !</description></headererror></VFPData>"
},
"metadata": { "rowcount": 1, "issuccess": false },
"error": ["Code: 001, Description: Custid 'INEXISTANT' not exist !"]
}
```
**Exemple de réponse (erreur -- CUSTID manquant)** :
Requête avec body vide `{}` ou sans `CUSTID` :
```
HTTP 400 -- CUSTID is required and cannot be empty.
```
---
### 7.4 Divers
#### `custom_geninv_updatestock` -- Mise à jour du stock
Met à jour le stock d'un article dans un dépôt. Deux modes de fonctionnement sont disponibles : Inventaire (MODE=0) et Restock (MODE=1). Le mode Restock crée un mouvement de stock entrant associé à un fournisseur.
| | |
|---|---|
| **URL** | `POST /{dossier}/custom_geninv_updatestock` |
| **Méthode service** | `LogisticsService::customGeninvUpdatestock(array $params)` |
**Paramètres** :
| Paramètre | Type | Obligatoire | Description |
|-----------|------|:-----------:|-------------|
| `ARTID` | `string` | Oui | Identifiant de l'article (champ `artid` de la table `art`). |
| `STKID` | `string` | Oui | Code du dépôt / entrepôt. Valeurs obtenues via `codes_list` avec `code=STOCK` (ex : `"A"`, `"SG"`). |
| `QTY` | `string` | Oui | Quantité à ajouter au stock. Peut être négatif pour retirer du stock (ex : `"-5"`). |
| `MODE` | `string` | Oui | Mode de mise à jour : `"0"` = Inventaire (journal KI), `"1"` = Restock (journal KM). |
| `THIRDID` | `string` | Si MODE=1 | Identifiant du tiers / fournisseur (champ `custid` de la table `cust`). Obligatoire en mode Restock. |
| `TOCHECK` | `string` | Oui | Prix de contrôle. Stocké avec le mouvement mais n'affecte pas la quantité de stock. |
| `TOCHECKDETAIL` | `string` | Oui | Remarque / détail de contrôle. Texte libre stocké avec le mouvement. |
**Modes de fonctionnement** :
| Mode | Valeur | Journal | Description |
|------|--------|---------|-------------|
| Inventaire | `"0"` | KI | Ajustement d'inventaire. Nécessite un journal KI configuré pour le dépôt. |
| Restock | `"1"` | KM | Réapprovisionnement. Nécessite `THIRDID` (fournisseur) et un journal KM configuré. |
**Métadonnées retournées** :
| Clé | Type | Description |
|-----|------|-------------|
| `rowcount` | `int` | Nombre d'éléments dans `data` (1 en cas de succès). |
| `issuccess` | `bool` | Indique si l'opération a réussi. |
**Exemple de requête (mode Restock)** :
```json
{
"ARTID": "003R92572",
"STKID": "SG",
"QTY": "5",
"MODE": "1",
"THIRDID": "0100002174",
"TOCHECK": "12.50",
"TOCHECKDETAIL": "Réapprovisionnement fournisseur"
}
```
**Exemple de réponse (succès)** :
```json
{
"data": {
"custom_geninv_updatestock": "OK : Change applied - Artid : 003R92572 - Real stock received (Restock mode) : 5.00"
},
"metadata": { "rowcount": 1, "issuccess": true },
"error": null
}
```
**Exemple de réponse (erreur -- dépôt sans journal KI)** :
```json
{
"data": {
"xml": "<VFPData><headererror><errorcode>002</errorcode><description>Invalid parameter, inventory JNL not found for warehouse : A</description></headererror></VFPData>"
},
"metadata": { "rowcount": 1, "issuccess": false },
"error": ["Code: 002, Description: Invalid parameter, inventory JNL not found for warehouse : A"]
}
```
**Remarques** :
- Le paramètre `STKID` correspond à un code de dépôt obtenu via `codes_list` avec `code=STOCK`. Les dépôts disponibles dépendent de la configuration du dossier.
- Le MODE=0 (Inventaire) dépend de la configuration des journaux KI du dossier. Dans certains environnements, aucun journal KI n'est configuré pour les dépôts, ce qui rend le MODE=0 non fonctionnel.
- Le champ `QTY` peut être négatif pour retirer du stock.
- Les champs `TOCHECK` et `TOCHECKDETAIL` sont toujours envoyés (même vides). Ils servent de traçabilité et n'affectent pas la quantité de stock.
---
## 8. Relations entre entités