Files
logisticsAPI/documentation/documentation_api_logistics.md
Marvin dfe20e79d7 Enhance Documents page functionality and update API documentation
- Added a new `$results` property to the Documents page to allow users to specify the maximum number of results returned by the `document_list` endpoint, defaulting to ~108.
- Updated the `searchDocuments` method to include the `results` parameter in API requests, ensuring it is sent as a string.
- Modified the documents.blade.php view to include an input field for the `results` parameter, with appropriate placeholder text and guidance.
- Improved the documentation for the `document_list` endpoint to clarify the behavior of the `results` parameter and its interaction with `thirdid`.
- Updated the `Document_GetPDF` section to reflect its functionality and correct usage of the `LAYOUT` parameter.
- Added a new test to verify that the `results` parameter is correctly sent to the API.
- Overall, enhanced the user experience and API interaction for document management.
2026-02-23 11:24:57 +01:00

1364 lines
57 KiB
Markdown

# Documentation API Logistics (Flex/ESI Gescom)
Dernière mise à jour : 2026-02-23
---
## Table des matières
1. [Pré-requis](#1-pré-requis)
2. [Environnements d'utilisation](#2-environnements-dutilisation)
3. [Comment effectuer des requêtes](#3-comment-effectuer-des-requêtes)
4. [Structure de réponse](#4-structure-de-réponse)
5. [Tables et colonnes disponibles](#5-tables-et-colonnes-disponibles)
6. [Récupération de données](#6-récupération-de-données)
7. [Envoi de données](#7-envoi-de-données)
8. [Endpoints non fonctionnels](#8-endpoints-non-fonctionnels)
9. [Relations entre entités](#9-relations-entre-entités)
10. [Remarques et points d'attention](#10-remarques-et-points-dattention)
11. [Ressources externes](#11-ressources-externes)
---
## 1. Pré-requis
### Connexion VPN
L'API Logistics est hébergée sur l'infrastructure ESI Cloud. Pour y accéder depuis un poste de travail local (hors du réseau ESI), une connexion VPN vers ESI Cloud est obligatoire. Sans cette connexion VPN, le serveur n'est pas joignable. Contactez votre administrateur réseau pour obtenir les identifiants et la configuration du VPN.
### Accès au serveur
L'API Logistics est hébergée sur un serveur privé. Les informations de connexion sont les suivantes :
| Élément | Valeur |
|---------|--------|
| Serveur | TSE-10-TEST |
| Hôte | `tse-10-test.esiweb.pro` (public) / `tse-10-test.esi.local` (réseau privé) |
| Port HTTP | 5186 |
| Port HTTPS | 7126 |
L'accès au serveur nécessite soit une connexion au réseau privé (via VPN), soit l'utilisation de l'hôte public avec le port adéquat.
### Clé API
Toutes les requêtes sont protégées par une clé API. Cette clé doit être transmise dans le header HTTP `X-API-KEY` de chaque requête. Sans clé valide, l'API retourne une erreur d'authentification.
### Dossier
Chaque requête cible un dossier comptable spécifique. Le nom du dossier est inclus dans l'URL de la requête. Le nom du dossier **doit impérativement être en minuscules** dans toutes les URLs (exemple : `esigescom`, et non `EsiGescom`).
### Variables d'environnement
L'application Laravel utilise les variables d'environnement suivantes pour se connecter à l'API. Elles doivent être configurées dans le fichier `.env` :
| Variable | Description | Exemple |
|----------|-------------|---------|
| `LOGISTICS_API_BASE_URL` | URL de base du serveur API | `http://tse-10-test.esi.local` |
| `LOGISTICS_API_KEY` | Clé d'authentification API | `YOUR_API_KEY` |
| `LOGISTICS_API_FOLDER` | Nom du dossier comptable (minuscules) | `esigescom` |
| `LOGISTICS_API_TIMEOUT` | Timeout total de la requête en secondes | `300` |
| `LOGISTICS_API_CONNECT_TIMEOUT` | Timeout de connexion en secondes | `10` |
| `LOGISTICS_API_RETRY_TIMES` | Nombre de tentatives en cas d'échec de connexion | `3` |
| `LOGISTICS_API_RETRY_SLEEP_MS` | Délai entre les tentatives en millisecondes | `500` |
### Configuration Laravel
Les variables d'environnement sont lues par le fichier de configuration `config/logistics.php` :
| Clé de config | Variable .env | Défaut |
|---------------|---------------|--------|
| `logistics.base_url` | `LOGISTICS_API_BASE_URL` | - |
| `logistics.api_key` | `LOGISTICS_API_KEY` | - |
| `logistics.folder` | `LOGISTICS_API_FOLDER` | - |
| `logistics.timeout` | `LOGISTICS_API_TIMEOUT` | `30` |
| `logistics.connect_timeout` | `LOGISTICS_API_CONNECT_TIMEOUT` | `10` |
| `logistics.retry.times` | `LOGISTICS_API_RETRY_TIMES` | `3` |
| `logistics.retry.sleep_ms` | `LOGISTICS_API_RETRY_SLEEP_MS` | `500` |
Le service `App\Services\LogisticsService` utilise ces valeurs pour configurer automatiquement les appels HTTP (URL, headers, timeouts, retry). En cas d'échec de connexion, le service effectue un retry automatique selon la configuration.
---
## 2. Environnements d'utilisation
L'API Logistics peut être interrogée depuis deux environnements distincts. Selon l'environnement utilisé, l'URL de base et les conditions d'accès diffèrent.
### 2.1 Projet local avec VPN
Dans ce scénario, le développeur travaille sur son poste local (par exemple avec Laravel Herd) et communique avec le serveur Logistics à distance via le VPN ESI Cloud.
| Élément | Valeur |
|---------|--------|
| Connexion VPN | Obligatoire (VPN vers ESI Cloud) |
| URL de base | `http://tse-10-test.esi.local` |
| Format d'URL complet | `http://tse-10-test.esi.local/{dossier}/{endpoint}` |
Exemple de configuration `.env` pour un projet local :
```
LOGISTICS_API_BASE_URL=http://tse-10-test.esi.local
LOGISTICS_API_KEY=votre-cle-api
LOGISTICS_API_FOLDER=esigescom
```
### 2.2 Bureau à distance (Postman)
Dans ce scénario, l'utilisateur se connecte au serveur via une connexion de bureau à distance (Remote Desktop) et utilise Postman directement depuis cette session. Étant déjà sur le réseau interne, aucun VPN n'est nécessaire et le serveur est accessible directement.
| Élément | Valeur |
|---------|--------|
| Connexion VPN | Non requise (connexion directe via bureau à distance) |
| URL de base | `http://tse-10-test.esiweb.pro` |
| Format d'URL complet | `http://tse-10-test.esiweb.pro/{dossier}/{endpoint}` |
Pour obtenir un accès au bureau à distance et à l'application Logistics, contactez **Claudi Dewandre**.
### 2.3 Récapitulatif des différences
| Critère | Projet local (VPN) | Bureau à distance (Postman) |
|---------|--------------------|-----------------------------|
| VPN ESI Cloud | Obligatoire | Non requis |
| Outil | Application Laravel, cURL, Postman local | Postman sur le serveur distant |
| URL de base | `http://tse-10-test.esi.local` | `http://tse-10-test.esiweb.pro` |
| Accès requis | Identifiants VPN + clé API | Accès bureau à distance + accès Logistics (contacter Claudi Dewandre) + clé API |
---
## 3. Comment effectuer des requêtes
### Méthode HTTP
**Tous les endpoints utilisent la méthode POST**, y compris les opérations de lecture. Aucun endpoint ne répond aux méthodes GET, PUT, PATCH ou DELETE.
### Format de l'URL
L'URL de chaque requête suit le schéma suivant :
```
POST {base_url}/{dossier}/{endpoint}
```
Où :
- `{base_url}` est l'URL de base du serveur (ex : `http://tse-10-test.esi.local`)
- `{dossier}` est le nom du dossier comptable en minuscules (ex : `esigescom`)
- `{endpoint}` est le nom de l'endpoint (ex : `art_list`, `document_detail`)
### Headers obligatoires
| Header | Valeur | Description |
|--------|--------|-------------|
| `X-API-KEY` | `<votre clé API>` | Clé d'authentification (obligatoire) |
| `Content-Type` | `application/json` | Type de contenu du body (obligatoire si body présent) |
### Exemple de requête complète
```http
POST /esigescom/art_list HTTP/1.1
Host: tse-10-test.esiweb.pro:5186
X-API-KEY: votre-cle-api
Content-Type: application/json
```
### Paramètres des requêtes
Les paramètres sont transmis dans le body de la requête au format JSON. Certains endpoints n'exigent aucun paramètre (body vide ou `{}`). Les paramètres peuvent être de différents types :
| Type | Description | Exemple |
|------|-------------|---------|
| `string` | Chaîne de caractères | `"ART001"` |
| `int` | Nombre entier | `10` |
| `array` | Tableau de valeurs | `["ART001", "ART002"]` |
**Attention** : certains paramètres qui représentent des nombres doivent être transmis au format `string` (ex : `QTY` dans `Document_GetUnitPriceAndVat` doit être `"2"` et non `2`).
### Gestion des erreurs
Le service `LogisticsService` de l'application gère automatiquement :
- **Retry automatique** : en cas d'échec de connexion (`ConnectionException`), le service retente automatiquement selon la configuration (`retry.times` et `retry.sleep_ms`).
- **Logging** : chaque requête (réussie ou échouée) est enregistrée dans la table `api_request_logs` avec l'endpoint, les paramètres, le code de statut et la réponse.
- **Exceptions** : en cas d'erreur, une `LogisticsApiException` est levée avec un message explicite en français.
- **Traduction des erreurs** : la classe `App\Support\ApiErrorTranslator` normalise le champ `error` de la réponse API (qui peut être `null`, une chaîne ou un tableau de chaînes) et ajoute une explication en français aux messages d'erreur connus (ex : "Search terms are required" est enrichi de "Le champ de recherche est obligatoire.").
### Validation des champs
Avant chaque appel API, les pages Filament vérifient que les champs obligatoires sont remplis. Si un champ requis est vide, un message d'erreur en français est affiché et l'appel API n'est pas effectué. Les règles de validation sont basées sur la documentation fournisseur (`documentation/WEB-A-1 (3).md`). Cette validation côté client évite des appels API inutiles et fournit un retour immédiat à l'utilisateur.
---
## 4. Structure de réponse
### Format standard
Tous les endpoints retournent un objet JSON avec la même structure :
```json
{
"data": "<résultat de la requête>",
"metadata": {
"rowcount": 0,
"issuccess": true
},
"error": null
}
```
### Description des clés
| Clé | Type | Description |
|-----|------|-------------|
| `data` | `mixed` | Le résultat de la requête. Peut être un tableau d'objets, un objet unique, une chaîne, ou `null`. |
| `metadata` | `object` | Informations sur la requête. Contient toujours `rowcount` et `issuccess`. Peut contenir d'autres clés selon l'endpoint. |
| `metadata.rowcount` | `int` | Nombre d'éléments retournés dans `data`. |
| `metadata.issuccess` | `bool` | `true` si la requête a réussi, `false` sinon. |
| `error` | `string`, `array` ou `null` | Message d'erreur en cas d'échec. Peut être une chaîne, un tableau de chaînes, ou `null` si la requête a réussi. L'application normalise ce champ via `ApiErrorTranslator`. |
### Exemple de réponse réussie
```json
{
"data": [
{ "artid": "ART001", "name1": "Chaise bureau" },
{ "artid": "ART002", "name1": "Chaise visiteur" }
],
"metadata": {
"rowcount": 2,
"issuccess": true
},
"error": null
}
```
### Exemple de réponse en erreur
```json
{
"data": null,
"metadata": {
"rowcount": 0,
"issuccess": false
},
"error": "Invalid API key"
}
```
### Métadonnées spécifiques par endpoint
Certains endpoints retournent des clés supplémentaires dans `metadata` :
| Endpoint | Clés supplémentaires | Description |
|----------|---------------------|-------------|
| `tables_list` | `tableCount`, `folderType`, `endpoint` | Nombre total de tables, type de base de données (ex : `DBF`), nom de l'endpoint |
| `column_list` | `columnCount`, `tableName` | Nombre de colonnes retournées, nom de la table interrogée |
---
## 5. Tables et colonnes disponibles
### Liste des tables
L'API expose 16 tables. Chacune correspond à un domaine fonctionnel de la gestion commerciale :
| Table | Colonnes | Description |
|-------|----------|-------------|
| `art` | 160 | **Articles** : références produits du catalogue. Contient l'identifiant, le nom, la description, les prix, les unités, les catégories, etc. |
| `attach` | 13 | **Fichiers attachés** : pièces jointes associées aux documents (factures, bons de commande, etc.). |
| `barcode` | 12 | **Codes-barres** : codes-barres associés aux articles pour l'identification et le scan. |
| `category` | 10 | **Catégories** : catégories de classification pour organiser les articles. |
| `codes` | 50 | **Codes système** : codes de configuration internes au système de gestion. |
| `cust` | 216 | **Tiers/Clients** : fiches tiers (clients, fournisseurs). Contient l'identifiant, le nom, l'adresse, les conditions commerciales, les coordonnées, etc. |
| `docdet` | 82 | **Lignes de documents** : lignes de détail des documents commerciaux. Chaque ligne référence un article avec sa quantité, son prix, sa TVA, etc. |
| `dochead` | 212 | **En-têtes de documents** : en-têtes des documents commerciaux (devis, commandes, factures). Contient le tiers, la date, le journal, le statut, les totaux, etc. |
| `docpay` | 22 | **Paiements** : paiements associés aux documents (montant, date, mode de paiement). |
| `file` | 17 | **Fichiers** : fichiers système gérés par l'application. |
| `hist` | 50 | **Historique** : historique des opérations effectuées dans le système. |
| `incodes` | 24 | **Codes internes** : codes internes paramétrables, utilisés pour les listes de valeurs, les types, etc. |
| `jnl` | 155 | **Journaux** : journaux comptables et commerciaux. Chaque journal regroupe des documents du même type (ventes, achats, etc.). |
| `pers` | 78 | **Personnes/Contacts** : fiches de contacts associées aux tiers ou à l'entreprise. |
| `price` | 28 | **Tarifs** : grilles de prix et conditions tarifaires par article, client ou catégorie. |
| `stk` | 20 | **Stock** : quantités en stock par article et par emplacement. |
### Types de colonnes
Chaque colonne d'une table possède un type de données identifié par un code à une lettre :
| Code | Label | Description |
|------|-------|-------------|
| `C` | Caractère | Chaîne de caractères (texte libre, identifiants, noms, etc.) |
| `N` | Numérique | Nombre entier ou décimal (quantités, prix, montants, etc.) |
| `T` | Date/Heure | Timestamp combinant date et heure |
| `D` | Date | Date seule (sans composante horaire) |
| `L` | Logique | Booléen (`true`/`false`) |
| `M` | Mémo | Texte long (champs de description étendus, remarques, etc.) |
### Exploration des colonnes
Pour connaître les colonnes disponibles dans une table, utiliser les endpoints `tables_list` et `column_list/{tablename}` décrits dans la section 6.
**Remarque importante** : l'API retourne les colonnes en double dans la réponse de `column_list`. L'application effectue une déduplication automatique côté client.
---
## 6. Récupération de données
Tous les endpoints de cette section servent à lire des données depuis l'API. Ils utilisent la méthode POST et retournent des données dans la clé `data` de la réponse.
### 6.1 Structure de la base de données
#### `tables_list` -- Liste des tables
Retourne la liste de toutes les tables accessibles dans le dossier comptable. Utile pour découvrir la structure de la base de données.
| | |
|---|---|
| **URL** | `POST /{dossier}/tables_list` |
| **Méthode service** | `LogisticsService::tablesList()` |
**Paramètres** : aucun.
**Exemple de requête** :
```json
{}
```
**Exemple de réponse** :
```json
{
"data": [
{ "name": "art", "columnCount": 160 },
{ "name": "attach", "columnCount": 13 },
{ "name": "barcode", "columnCount": 12 },
{ "name": "category", "columnCount": 10 },
{ "name": "codes", "columnCount": 50 },
{ "name": "cust", "columnCount": 216 },
{ "name": "docdet", "columnCount": 82 },
{ "name": "dochead", "columnCount": 212 },
{ "name": "docpay", "columnCount": 22 },
{ "name": "file", "columnCount": 17 },
{ "name": "hist", "columnCount": 50 },
{ "name": "incodes", "columnCount": 24 },
{ "name": "jnl", "columnCount": 155 },
{ "name": "pers", "columnCount": 78 },
{ "name": "price", "columnCount": 28 },
{ "name": "stk", "columnCount": 20 }
],
"metadata": { "tableCount": 16, "folderType": "DBF", "endpoint": "tables_list", "rowcount": 16, "issuccess": true },
"error": null
}
```
---
#### `column_list/{tablename}` -- Colonnes d'une table
Retourne la liste des colonnes d'une table donnée, avec leur type, leur longueur et leur précision. Indispensable pour connaître les champs utilisables dans le paramètre `select` des autres endpoints.
| | |
|---|---|
| **URL** | `POST /{dossier}/column_list/{tablename}` |
| **Méthode service** | `LogisticsService::columnList(string $table)` |
**Paramètres** :
| Paramètre | Emplacement | Type | Obligatoire | Description |
|-----------|-------------|------|:-----------:|-------------|
| `tablename` | URL | `string` | Oui | Nom de la table (issu de `tables_list`). Exemple : `art`, `cust`, `dochead`. |
**Exemple de requête** :
```
POST /esigescom/column_list/stk
```
**Exemple de réponse** :
```json
{
"data": [
{ "name": "ARTID", "dataType": "C", "length": 20, "precision": 0 },
{ "name": "STOCK", "dataType": "N", "length": 10, "precision": 2 },
{ "name": "DEPOT", "dataType": "C", "length": 10, "precision": 0 }
],
"metadata": { "columnCount": 3, "tableName": "stk", "rowcount": 3, "issuccess": true },
"error": null
}
```
**Remarque** : l'API retourne chaque colonne en double. L'application effectue une déduplication automatique.
---
### 6.2 Articles
Les articles sont les références produits du catalogue. Ils sont stockés dans la table `art`.
#### `art_list` -- Recherche d'articles
Retourne une liste d'articles correspondant aux critères de recherche. L'API retourne un maximum fixe de **5 résultats** par appel, cette limite n'est pas configurable.
| | |
|---|---|
| **URL** | `POST /{dossier}/art_list` |
| **Méthode service** | `LogisticsService::artList(array $params)` |
**Paramètres** :
| Paramètre | Type | Obligatoire | Description |
|-----------|------|:-----------:|-------------|
| `search` | `string` | Oui | Filtre de recherche textuel. Recherche dans les colonnes `artid` et `name1` de la table `art`. **Ce paramètre est obligatoire** : un appel sans `search` retourne une erreur "Search terms are required", même si `barcode` est fourni. |
| `select` | `string` | Non | Liste des colonnes à retourner, séparées par des virgules. Les noms de colonnes disponibles sont ceux de la table `art` (obtenables via `column_list/art`). Si omis, un jeu de colonnes par défaut est retourné. |
| `results` | `int` | Non | **Sans effet.** Ce paramètre est accepté par l'API mais n'influence pas le nombre de résultats retournés. L'API retourne toujours un maximum de 5 résultats, quelle que soit la valeur de `results` (testé avec 1, 3, 5, 10, 20, en int et en string). |
| `barcode` | `string` | Non | **Sans effet observable.** Ce paramètre est accepté par l'API mais ne modifie pas les résultats. Les données retournées sont strictement identiques avec ou sans `barcode`. Le paramètre `search` reste obligatoire même si `barcode` est fourni. |
**Métadonnées retournées** :
L'endpoint `art_list` retourne des métadonnées spécifiques dans la clé `metadata` :
| Clé | Type | Description |
|-----|------|-------------|
| `rowCount` | `int` | Nombre de résultats retournés. |
| `source` | `string` | Type de base de données (ex : `DBF`). |
| `executionTimeMs` | `int` | Temps d'exécution de la requête en millisecondes. |
| `searchColumns` | `string` | Colonnes utilisées pour la recherche (ex : `artid,name1`). |
| `selectColumns` | `string` | Colonnes demandées dans le paramètre `select`. |
| `searchTerms` | `string` | Termes de recherche utilisés. |
**Exemple de requête** :
```json
{
"search": "chaise",
"select": "artid,name1,saleprice"
}
```
**Exemple de réponse** :
```json
{
"data": [
{ "artid": "003R92572", "name1": "Papier A4 80g", "saleprice": 12.50 },
{ "artid": "003R92573", "name1": "Papier A4 90g", "saleprice": 14.00 },
{ "artid": "003R98703", "name1": "Papier A3 80g", "saleprice": 18.75 },
{ "artid": "003R98711", "name1": "Papier A3 90g", "saleprice": 21.00 },
{ "artid": "003R98718", "name1": "Papier A4 100g", "saleprice": 16.50 }
],
"metadata": {
"rowCount": 5,
"source": "DBF",
"executionTimeMs": 720,
"searchColumns": "artid,name1",
"selectColumns": "artid,name1,saleprice",
"searchTerms": "papier"
},
"error": null
}
```
**Attention** : les noms de colonnes dans `select` doivent correspondre exactement aux noms retournes par `column_list/art` (ex : `name1`, pas `artname`). L'API ignore silencieusement les noms de colonnes invalides sans emettre d'erreur, ce qui peut donner l'impression que le parametre `select` ne fonctionne pas.
---
#### `art_getstk` -- Stock d'un article
Retourne les informations de stock pour un article donné. Permet de vérifier la disponibilité d'un article dans les différents dépôts.
| | |
|---|---|
| **URL** | `POST /{dossier}/art_getstk` |
| **Méthode service** | `LogisticsService::artGetStock(string $artId)` |
**Paramètres** :
| Paramètre | Type | Obligatoire | Description |
|-----------|------|:-----------:|-------------|
| `ARTID` | `string` | Oui | Identifiant unique de l'article (champ `artid` de la table `art`). |
**Exemple de requête** :
```json
{
"ARTID": "ART001"
}
```
---
### 6.3 Journaux
Les journaux regroupent les documents commerciaux par type (ventes, achats, retours, etc.). Ils sont stockés dans la table `jnl`.
#### `jnl_list` -- Liste des journaux
Retourne la liste des journaux correspondant au type demandé. Un journal contient un ou plusieurs documents.
| | |
|---|---|
| **URL** | `POST /{dossier}/jnl_list` |
| **Méthode service** | `LogisticsService::jnlList(array $params)` |
**Paramètres** :
| Paramètre | Type | Obligatoire | Description |
|-----------|------|:-----------:|-------------|
| `TYPE` | `string` | Oui | Code de type de journal (1 ou 2 caractères). Voir la section "Codes de type" ci-dessous. |
| `select` | `string` | Non | Colonnes à retourner, séparées par des virgules (colonnes de la table `jnl`). Insensible à la casse. Si omis, seule la colonne `jnl` est retournée par défaut. |
| `results` | `string` | Non | Nombre maximum de résultats. **Doit être au format string** (ex : `"50"`), pas un nombre. Un entier provoque une erreur HTTP 400. La limite par défaut (sans ce paramètre) est de 30 résultats. Contrairement à `art_list` et `third_list`, ce paramètre fonctionne réellement pour `jnl_list`. |
**Codes de type de journal** :
La colonne `TYPE` de la table `jnl` contient un code à 2 caractères suivant le schéma `[Domaine][TypeDocument]` :
| Domaine (1er caractère) | Signification |
|---|---|
| `C` | Client |
| `S` | Supplier / Fournisseur |
| `K` | stocK / Inventaire |
| Type document (2e caractère) | Signification |
|---|---|
| `O` | Order / Commande |
| `D` | Delivery / Livraison (note d'envoi) |
| `I` | Invoice / Facture |
| `C` | Credit note / Note de crédit |
| `P` | Proposal / Offre de prix (pro forma) |
| `A` | Achat |
| `M` | Mouvement (stock) |
Le paramètre `TYPE` accepte 1 ou 2 caractères :
- **1 caractère** : filtre tous les journaux dont le code de type contient ce caractère (première ou deuxième position). Exemples :
- `TYPE=C` retourne tous les journaux client (CO, CD, CI, CC, CP, CA, CM) -- 42 résultats dans le dossier de test.
- `TYPE=I` retourne toutes les factures (CI, KI) -- 26 résultats.
- `TYPE=O` retourne toutes les commandes (CO, SO) -- 7 résultats.
- `TYPE=D` retourne toutes les livraisons (CD, SD) -- 5 résultats.
- `TYPE=S` retourne tous les journaux fournisseur (SD, SO) -- 2 résultats.
- `TYPE=K` retourne tous les journaux inventaire (KI, KM) -- 2 résultats.
- `TYPE=P` retourne toutes les offres de prix (CP) -- 3 résultats.
- `TYPE=A` retourne tous les journaux d'achat (CA) -- 2 résultats.
- **2 caractères** : correspondance exacte sur le code de type. Exemples :
- `TYPE=CO` retourne uniquement les commandes client -- 6 résultats.
- `TYPE=CI` retourne uniquement les factures client -- 25 résultats.
- `TYPE=CC` retourne uniquement les notes de crédit client -- 1 résultat.
**Métadonnées retournées** :
| Clé | Type | Description |
|-----|------|-------------|
| `rowCount` | `int` | Nombre de résultats retournés. |
| `source` | `string` | Type de base de données (ex : `DBF`). |
| `unlimited` | `bool` | Indique si la requête est sans limite (toujours `false` dans les tests). |
**Colonnes utiles de la table `jnl`** :
| Colonne | Type | Description |
|---------|------|-------------|
| `JNL` | `C(8)` | Code unique du journal (ex : `03VEN`, `01COM`). |
| `NAME` | `C(40)` | Nom du journal (ex : `FACTURE CLIENT`). |
| `NAME1` | `C(40)` | Nom alternatif 1 (ex : `FACTURE 03VEN`). |
| `NAME2` | `C(40)` | Nom alternatif 2 (ex : `FAKTUUR`). |
| `TYPE` | `C(2)` | Code de type (ex : `CI`, `CO`, `SD`). |
| `NUMBER` | `N(8)` | Dernier numéro de document dans ce journal. |
| `JNLORDER` | `C(8)` | Journal de commande lié. |
| `JNLINV` | `C(8)` | Journal de facturation lié. |
| `JNLCRED` | `C(8)` | Journal de note de crédit lié. |
| `JNLMVT` | `C(8)` | Journal de mouvement de stock lié. |
| `STKID` | `C(2)` | Identifiant de stock associé. |
| `STATUSINIT` | `C(2)` | Statut initial des documents créés dans ce journal. |
**Exemple de requête** :
```json
{
"TYPE": "C",
"select": "JNL,NAME,TYPE,NUMBER",
"results": "50"
}
```
**Exemple de réponse** :
```json
{
"data": [
{ "jnl": "01COM", "name": "COMMANDE", "type": "CO", "number": 25100123 },
{ "jnl": "03VEN", "name": "FACTURE CLIENT", "type": "CI", "number": 25105451 },
{ "jnl": "04NCV", "name": "NOTE DE CREDIT CLIENT", "type": "CC", "number": 25400010 }
],
"metadata": {
"rowCount": 3,
"source": "DBF",
"unlimited": false
},
"error": null
}
```
---
### 6.4 Documents
Les documents commerciaux (devis, commandes, factures, avoirs, etc.) constituent le coeur du système. Chaque document possède un en-tête (`dochead`) et une ou plusieurs lignes de détail (`docdet`). Un document appartient à un journal et est associé à un tiers.
#### `document_list` -- Liste des documents
Retourne une liste de documents, éventuellement filtrée par tiers. Permet de consulter les documents commerciaux associés à un client. Les documents sont retournés triés par date décroissante (les plus récents en premier).
| | |
|---|---|
| **URL** | `POST /{dossier}/document_list` |
| **Méthode service** | `LogisticsService::documentList(array $params)` |
**Paramètres** :
| Paramètre | Type | Obligatoire | Description |
|-----------|------|:-----------:|-------------|
| `select` | `string` | Non | Colonnes à retourner, séparées par des virgules (colonnes de la table `dochead`). Si omis, seule la colonne `thirdid` est retournée par défaut. Colonnes utiles : `jnl`, `number`, `thirdid`, `date`, `status`, `topay`. |
| `thirdid` | `string` | Non | Identifiant du tiers (champ `custid` de la table `cust`). Si fourni, seuls les documents de ce tiers sont retournés. |
| `results` | `string` | Non | Nombre maximum de résultats à retourner. Accepte les formats string et int. La limite par défaut (sans ce paramètre) est d'environ 108 résultats. **Attention** : ce paramètre n'a d'effet que lorsqu'un `thirdid` est également fourni. Sans `thirdid`, l'API ignore `results` et retourne tous les documents disponibles (jusqu'à sa limite par défaut). |
**Métadonnées retournées** :
| Clé | Type | Description |
|-----|------|-------------|
| `rowCount` | `int` | Nombre de résultats retournés. |
| `source` | `string` | Type de base de données (ex : `DBF`). |
| `unlimited` | `bool` | Indique si la requête est sans limite (observé toujours `false`). |
**Exemple de requête** :
```json
{
"select": "jnl,number,thirdid,date,status,topay",
"thirdid": "_@00025009",
"results": "20"
}
```
**Exemple de réponse** :
```json
{
"data": [
{
"jnl": "03VEN",
"number": 25105397,
"thirdid": "_@00025009",
"date": "2025-07-01T00:00:00",
"status": "",
"topay": 18958.28
}
],
"metadata": { "rowCount": 1, "source": "DBF", "unlimited": false },
"error": null
}
```
**Remarque** : un appel sans aucun paramètre (body vide `{}`) retourne une erreur HTTP 400. Au minimum, le paramètre `select` ou `thirdid` doit être fourni.
---
#### `document_detail` -- Détail d'un document
Retourne le détail complet d'un document spécifique : l'en-tête (informations générales du document), toutes les lignes de détail (articles, quantités, prix) dans un tableau `detail`, et les fichiers attachés dans un tableau `attach`.
| | |
|---|---|
| **URL** | `POST /{dossier}/document_detail` |
| **Méthode service** | `LogisticsService::documentDetail(string $jnl, string $number)` |
**Paramètres** :
| Paramètre | Type | Obligatoire | Description |
|-----------|------|:-----------:|-------------|
| `jnl` | `string` | Oui | Code du journal auquel appartient le document (ex : `03VEN`, `01COM`). |
| `number` | `string` | Oui | Numéro du document dans le journal (ex : `25105397`). |
**Métadonnées retournées** :
| Clé | Type | Description |
|-----|------|-------------|
| `detailRowCount` | `int` | Nombre de lignes de détail. |
| `attachRowCount` | `int` | Nombre de fichiers attachés. |
| `source` | `string` | Type de base de données (ex : `DBF`). |
| `isSuccess` | `bool` | Succès de la requête. |
| `jnl` | `string` | Code du journal (écho du paramètre). |
| `number` | `string` | Numéro du document (écho du paramètre). |
| `totalExecutionTimeMs` | `float` | Temps d'exécution en millisecondes. |
**Structure de la réponse `data`** :
La réponse contient directement les champs de l'en-tête du document au premier niveau, plus deux tableaux `detail` et `attach` :
| Champ en-tête | Type | Description |
|---------------|------|-------------|
| `jnl` | `string` | Code du journal. |
| `number` | `int` | Numéro du document. |
| `type` | `string` | Type de document (ex : `CI` = facture client, `CO` = commande). |
| `date` | `string` | Date du document (format ISO `YYYY-MM-DDT00:00:00`). |
| `thirdid` | `string` | Identifiant du tiers. |
| `thirdname` | `string` | Nom du tiers. |
| `thirdaddr` | `string` | Adresse du tiers. |
| `thirdzip` | `string` | Code postal du tiers. |
| `thirdcity` | `string` | Ville du tiers. |
| `thirdcount` | `string` | Code pays du tiers (ex : `BE`). |
| `thirdvat` | `string` | Numéro de TVA du tiers. |
| `topay` | `float` | Montant total TTC. |
| `payed` | `float` | Montant déjà payé. |
| `status` | `string` | Statut du document (code de `Document_GetStatusList`). |
| `paydelay` | `string` | Code de délai de paiement. |
| `datepay` | `string` | Date d'échéance de paiement (format ISO). |
| `basis1` / `basis2` / `basis3` | `float` | Bases de calcul TVA (par taux). |
| `vatid1` / `vatid2` / `vatid3` | `string` | Identifiants de taux TVA. |
| `vatpc1` / `vatpc2` / `vatpc3` | `float` | Pourcentages TVA. |
| `vatamt1` / `vatamt2` / `vatamt3` | `float` | Montants TVA. |
| `yourref` | `string` | Référence du client. |
| `note` | `string` | Remarques sur le document. |
| `agent` | `string` | Agent commercial. |
| `vcs` | `string` | Communication structurée (VCS). |
| `time` | `string` | Horodatage de création (format ISO avec heure). |
| `docheadid` | `string` | Identifiant interne unique de l'en-tête. |
| Champ ligne (`detail[]`) | Type | Description |
|--------------------------|------|-------------|
| `docdetid` | `string` | Identifiant interne unique de la ligne. |
| `artid` | `string` | Identifiant de l'article. |
| `artname` | `string` | Nom de l'article. |
| `artdesc` | `string` | Description de l'article. |
| `qty` | `float` | Quantité. |
| `unitprice` | `float` | Prix unitaire HT. |
| `discount` | `float` | Remise (en pourcentage). |
| `amount` | `float` | Montant HT de la ligne (qty x unitprice - discount). |
| `vatid` | `string` | Code TVA. |
| `vatpc` | `float` | Pourcentage TVA. |
| `amtvatinc` | `float` | Montant TTC de la ligne. |
| `lineorder` | `int` | Ordre de la ligne dans le document. |
| `barcode` | `string` | Code-barres de l'article. |
| `status` | `string` | Statut de la ligne. |
**Exemple de requête** :
```json
{
"jnl": "03VEN",
"number": "25105397"
}
```
**Exemple de réponse** (simplifié) :
```json
{
"data": {
"jnl": "03VEN",
"number": 25105397,
"type": "CI",
"date": "2025-07-01T00:00:00",
"thirdid": "_@00025009",
"thirdname": "LGTECH SPRL",
"topay": 18958.28,
"status": "",
"detail": [
{
"artid": "DI21",
"artname": "SQL SERVEUR 2022 STANDARD CORE",
"qty": 4,
"unitprice": 3917,
"amount": 15668,
"vatid": "21",
"vatpc": 21,
"lineorder": 2
}
],
"attach": []
},
"metadata": {
"detailRowCount": 2,
"attachRowCount": 0,
"source": "DBF",
"isSuccess": true,
"jnl": "03VEN",
"number": "25105397",
"totalExecutionTimeMs": 24.96
},
"error": null
}
```
---
#### `Document_GetStatusList` -- Statuts disponibles d'un journal
Retourne la liste des statuts disponibles pour les documents d'un journal donné. Les statuts varient selon le type de journal. Utile pour connaître les états possibles d'un document (ouverte, envoyée, comptabilisée, soldée, etc.).
| | |
|---|---|
| **URL** | `POST /{dossier}/Document_GetStatusList` |
| **Méthode service** | `LogisticsService::documentGetStatusList(string $jnl)` |
**Paramètres** :
| Paramètre | Type | Obligatoire | Description |
|-----------|------|:-----------:|-------------|
| `jnl` | `string` | Oui | Code du journal dont on veut connaître les statuts (ex : `03VEN`, `01COM`, `02NEV`). |
**Exemple de requête** :
```json
{
"jnl": "03VEN"
}
```
**Exemple de réponse** :
```json
{
"data": [
{ "code": "GE", "desc": "Générée" },
{ "code": "SE", "desc": "Envoyée au client" },
{ "code": "AC", "desc": "Comptabilisée" },
{ "code": "PA", "desc": "Payée" }
],
"metadata": { "rowcount": 4, "issuccess": true },
"error": null
}
```
**Statuts observés par type de journal** :
| Journal | Type | Statuts |
|---------|------|---------|
| `03VEN` (Facture client) | `CI` | GE (Générée), SE (Envoyée au client), AC (Comptabilisée), PA (Payée) |
| `01COM` (Commande) | `CO` | OP (Ouverte), OS (Commandée aux fournisseurs), PR (Client Prévenu), MB (Marchandise bloquée en magasin), CL (Soldée) |
| `02NEV` (Note d'envoi) | `CD` | OP (Ouverte), TI (A facturer), IN (Facturée) |
| `04NCV` (Note de crédit) | `CC` | GE (Générée), SE (Envoyée au client), AC (Comptabilisée) |
| `11COMF` (Commande fournisseur) | -- | OP (Ouverte), SE (Envoyée au fournisseur), PD (Partiellement livrée), CL (Soldée) |
| `09OFFRE` (Offre de prix) | `CP` | (vide) -- pas de statuts configurés |
---
#### `Document_GetUnitPriceAndVat` -- Prix unitaire et TVA
Retourne le prix unitaire et la TVA applicable pour un article dans un contexte précis (journal, tiers, date, quantité). Utile pour calculer le montant d'une ligne de document avant création. Le prix retourné est le prix configuré dans le système pour cet article/tiers/journal ; il peut être `0.00` si aucun prix n'est configuré.
| | |
|---|---|
| **URL** | `POST /{dossier}/Document_GetUnitPriceAndVat` |
| **Méthode service** | `LogisticsService::documentGetUnitPriceAndVat(array $params)` |
**Paramètres** :
| Paramètre | Type | Obligatoire | Description |
|-----------|------|:-----------:|-------------|
| `ARTID` | `string` | Oui | Identifiant de l'article (champ `artid` de la table `art`). |
| `QTY` | `string` | Oui | Quantité demandée. **Doit impérativement être au format string** (ex : `"2"`). Un entier provoque une erreur HTTP 400. |
| `JNL` | `string` | Oui | Code du journal (ex : `03VEN`). |
| `THIRDID` | `string` | Oui | Identifiant du tiers (champ `custid` de la table `cust`). |
| `DATE` | `string` | Oui | Date de référence pour le calcul du prix. **Format obligatoire : `YYYY-MM-DD`** (ex : `"2025-07-01"`). Tout autre format (DD/MM/YYYY, etc.) retourne une erreur HTTP 400 "Invalid date format. Expected format: YYYY-MM-DD". |
**Structure de la réponse `data`** :
| Champ | Type | Description |
|-------|------|-------------|
| `unitprice` | `string` | Prix unitaire HT (ex : `"3917.00"`, `"0.00"`). |
| `discount` | `string` | Remise applicable (ex : `"10.00"`, `"."` si aucune remise). |
| `vatid` | `string` | Code de taux TVA (ex : `"21"`). |
| `vatpc` | `string` | Pourcentage TVA (ex : `"21.00"`). |
**Exemple de requête** :
```json
{
"ARTID": "DI21",
"QTY": "4",
"JNL": "03VEN",
"THIRDID": "_@00025009",
"DATE": "2025-07-01"
}
```
**Exemple de réponse** :
```json
{
"data": {
"unitprice": "0.00",
"discount": ".",
"vatid": "21",
"vatpc": "21.00"
},
"metadata": { "rowcount": 4, "issuccess": true },
"error": null
}
```
---
#### `Document_GetDueDate` -- Echeance de paiement
Calcule la date d'échéance de paiement à partir d'un code de délai de paiement et d'une date de départ. Utile pour déterminer automatiquement la date limite de paiement d'un document.
| | |
|---|---|
| **URL** | `POST /{dossier}/Document_GetDueDate` |
| **Méthode service** | `LogisticsService::documentGetDueDate(string $payDelay, string $date)` |
**Paramètres** :
| Paramètre | Type | Obligatoire | Description |
|-----------|------|:-----------:|-------------|
| `paydelay` | `string` | Oui | Code de délai de paiement. Les valeurs valides proviennent de `codes_list` avec `code=PAYDELAY`. Voir le tableau ci-dessous. |
| `date` | `string` | Oui | Date de départ à partir de laquelle calculer l'échéance. **Format obligatoire : `YYYY-MM-DD`** (ex : `"2025-07-01"`). Tout autre format retourne une erreur HTTP 400 "Invalid date format. Expected format: YYYY-MM-DD". |
**Codes de délai de paiement disponibles** (obtenus via `codes_list` avec `code=PAYDELAY`) :
| Code (`paydelay`) | Description | Exemple : date=2025-07-01 |
|-------------------|-------------|---------------------------|
| `30` | 30 jours date de facture | 2025-08-01 |
| `30F` | 30 jours fin de mois | 2025-08-30 |
| `45F` | 45 jours fin de mois | 2025-08-31 |
| `50` | 50 jours date de facture | 2025-08-20 |
| `60` | 60 jours date de facture | 2025-09-01 |
| `60F` | 60 jours fin de mois | 2025-08-31 |
| `75F` | 75 jours fin de mois | 2025-09-30 |
| `90` | 90 jours date de facture | 2025-10-01 |
| `90F` | 90 jours fin de mois | 2025-09-30 |
| `0F` | 0 jours fin de mois (fin du mois courant) | 2025-07-31 |
**Structure de la réponse `data`** :
| Champ | Type | Description |
|-------|------|-------------|
| `duedate` | `string` | Date d'échéance calculée (format `YYYY-MM-DD`). |
**Exemple de requête** :
```json
{
"paydelay": "30",
"date": "2025-07-01"
}
```
**Exemple de réponse** :
```json
{
"data": { "duedate": "2025-08-01" },
"metadata": { "rowcount": 1, "issuccess": true },
"error": null
}
```
---
#### `Document_GetAttachListThumbnail` -- Miniatures des annexes
Retourne les miniatures des fichiers images attachés à un document. Seuls les fichiers de type image sont concernés ; les autres types de fichiers ne sont pas retournés. Si le document n'a pas d'images attachées, l'API retourne une erreur spécifique (code 004).
| | |
|---|---|
| **URL** | `POST /{dossier}/Document_GetAttachListThumbnail` |
| **Méthode service** | `LogisticsService::documentGetAttachListThumbnail(string $jnl, string $number)` |
**Paramètres** :
| Paramètre | Type | Obligatoire | Description |
|-----------|------|:-----------:|-------------|
| `JNL` | `string` | Oui | Code du journal du document (ex : `03VEN`). |
| `NUMBER` | `string` | Oui | Numéro du document (ex : `25105397`). |
**Codes d'erreur spécifiques** :
| Code | Description |
|------|-------------|
| `003` | Document non trouvé (`Document {JNL} {NUMBER} not found.`). |
| `004` | Aucune image trouvée (`Error - no image found !`). Le document existe mais n'a pas de fichier image attaché. |
**Exemple de requête** :
```json
{
"JNL": "03VEN",
"NUMBER": "25105397"
}
```
**Exemple de réponse en erreur (pas d'image)** :
```json
{
"data": {
"xml": "<VFPData><headererror><errorcode>004</errorcode><description>Error - no image found !</description></headererror></VFPData>"
},
"metadata": { "rowcount": 1, "issuccess": false },
"error": ["Code: 004, Description: Error - no image found !"]
}
```
---
#### `Document_GetPDF` -- Generation de PDF
Genere un fichier PDF pour un document donne et le retourne en base64. Le PDF contient la mise en page complete du document (en-tete, lignes de detail, totaux, informations tiers, etc.).
| | |
|---|---|
| **URL** | `POST /{dossier}/Document_GetPDF` |
| **Methode service** | `LogisticsService::documentGetPdf(string $jnl, string $number, string $layout)` |
**Parametres** :
| Parametre | Type | Obligatoire | Description |
|-----------|------|:-----------:|-------------|
| `JNL` | `string` | Oui | Code du journal (ex : `03VEN`). |
| `NUMBER` | `string` | Oui | Numero du document (ex : `25105397`). |
| `LAYOUT` | `string` | Oui | Identifiant numerique de la mise en page du PDF. **Doit etre une valeur numerique sous forme de string** (ex : `"0"`, `"1"`, `"2"`). Toute valeur textuelle (ex : `"default"`, `"FACTURE"`, `"A4"`) provoque une erreur "Valeur, type ou nombre d'arguments de fonction, non valide". Dans les tests, toutes les valeurs numeriques (`0` a `10`, y compris `-1`) retournent le meme PDF, ce qui suggere qu'une seule mise en page est configuree dans le dossier de test. La valeur `"1"` est recommandee par defaut. |
**Structure de la reponse `data`** :
| Champ | Type | Description |
|-------|------|-------------|
| `pdf` | `string` | Contenu du fichier PDF encode en base64. Pour obtenir le fichier PDF, decoder cette chaine en base64. |
**Exemple de requete** :
```json
{
"JNL": "03VEN",
"NUMBER": "25105397",
"LAYOUT": "1"
}
```
**Exemple de reponse** :
```json
{
"data": {
"pdf": "JVBERi0xLjMNCiX..."
},
"metadata": { "rowcount": 1, "issuccess": true },
"error": null
}
```
---
### 6.5 Tiers
Les tiers (clients, fournisseurs) sont les entités commerciales avec lesquelles l'entreprise interagit. Ils sont stockés dans la table `cust`.
#### `third_list` -- Recherche de tiers
Retourne une liste de tiers correspondant au filtre de recherche. Permet de trouver un client ou fournisseur par son nom, son identifiant ou d'autres critères.
| | |
|---|---|
| **URL** | `POST /{dossier}/third_list` |
| **Méthode service** | `LogisticsService::thirdList(array $params)` |
**Paramètres** :
| Paramètre | Type | Obligatoire | Description |
|-----------|------|:-----------:|-------------|
| `search` | `string` | Oui | Filtre de recherche. **Ce paramètre est obligatoire** : un appel sans filtre retourne une erreur. |
| `select` | `string` | Non | Colonnes à retourner, séparées par des virgules (colonnes de la table `cust`). |
| `results` | `int` | Non | **Sans effet.** Ce paramètre est accepté mais n'influence pas le nombre de résultats. L'API retourne toujours un maximum de 10 résultats (testé avec 3, 10, 20). |
**Exemple de requête** :
```json
{
"search": "Dupont",
"select": "custid,custname,city"
}
```
---
#### `third_GetArtHistory` -- Historique des articles d'un tiers
Retourne l'historique complet des articles présents dans les documents associés à un tiers. Permet d'analyser les achats ou ventes passés d'un client/fournisseur.
| | |
|---|---|
| **URL** | `POST /{dossier}/third_GetArtHistory` |
| **Méthode service** | `LogisticsService::thirdGetArtHistory(string $thirdId)` |
**Paramètres** :
| Paramètre | Type | Obligatoire | Description |
|-----------|------|:-----------:|-------------|
| `thirdid` | `string` | Oui | Identifiant du tiers (champ `custid` de la table `cust`). |
**Exemple de requête** :
```json
{
"thirdid": "CUST001"
}
```
---
### 6.6 Divers
#### `getserialnumber` -- Numéro de série du dossier
Retourne le numéro de série du dossier comptable. Identifie de manière unique l'installation du logiciel de gestion.
| | |
|---|---|
| **URL** | `POST /{dossier}/getserialnumber` |
| **Méthode service** | `LogisticsService::getSerialNumber()` |
**Paramètres** : aucun.
**Exemple de requête** :
```json
{}
```
---
#### `codes_list` -- Données par code interne
Retourne les données associées à un code interne. Les codes proviennent de la table `incodes` et servent à stocker des listes de valeurs paramétrables (types de documents, catégories, etc.).
| | |
|---|---|
| **URL** | `POST /{dossier}/codes_list` |
| **Méthode service** | `LogisticsService::codesList(array $params)` |
**Paramètres** :
| Paramètre | Type | Obligatoire | Description |
|-----------|------|:-----------:|-------------|
| `code` | `string` | Oui | Début du code interne à rechercher (de la table `incodes`). Le filtre s'applique par préfixe. |
**Exemple de requête** :
```json
{
"code": "PAY"
}
```
**Remarque** : les valeurs retournées contiennent des champs `vala1`, `vala2`, etc. dont la signification précise dépend du code recherché.
---
## 7. Envoi de données
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
#### `document_add` -- Création d'un document
Crée un nouveau document commercial (devis, commande, facture, etc.) dans un journal. Le document est composé d'un en-tête (tiers, date, journal) et d'une ou plusieurs lignes d'articles.
| | |
|---|---|
| **URL** | `POST /{dossier}/document_add` |
| **Méthode service** | `LogisticsService::documentAdd(array $params)` |
**Paramètres** :
| 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"`). |
| `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`. |
| `JNL` | `string` | Oui | Code du journal dans lequel créer le document (ex : `"VEN"` pour ventes). |
| `Discount` | `array` | Non | Tableau des réductions de prix (en pourcentage ou montant). Correspond position par position au tableau `Artid`. |
| `Vatid` | `array` | Non | Tableau des identifiants de code TVA. Correspond position par position au tableau `Artid`. |
| `Vatpc` | `array` | Non | Tableau des pourcentages de TVA. Correspond position par position au tableau `Artid`. |
| `Attachments` | `array` | Non | Liste de fichiers joints au document. Voir la structure ci-dessous. |
**Structure d'un élément `Attachments`** :
| Clé | Type | Description |
|-----|------|-------------|
| `FileName` | `string` | Nom du fichier avec extension (ex : `"facture.pdf"`). |
| `FileDesc` | `string` | Description du fichier (ex : `"Bon de commande signé"`). |
| `FileContentBase64` | `string` | Contenu du fichier encodé en base64. |
**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.
**Exemple de requête** :
```json
{
"ThirdId": "CUST001",
"Date": "2026-02-20",
"Artid": ["ART001", "ART002"],
"Qty": ["2", "5"],
"Saleprice": ["10.00", "25.50"],
"JNL": "VEN",
"Discount": ["0", "10"],
"Vatid": ["TVA21", "TVA21"],
"Vatpc": ["21", "21"],
"Attachments": [
{
"FileName": "bon.pdf",
"FileDesc": "Bon de commande",
"FileContentBase64": "JVBERi0xLjQK..."
}
]
}
```
---
### 7.2 Modification d'un document
#### `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.
| | |
|---|---|
| **URL** | `POST /{dossier}/document_mod` |
| **Méthode service** | `LogisticsService::documentMod(array $params)` |
**Paramètres** :
| Paramètre | Type | Obligatoire | Description |
|-----------|------|:-----------:|-------------|
| `number` | `string` | Oui | Identifiant 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). |
| `Qty` | `array` | Non | Tableau de quantités (correspond position par position à `Artid`). |
| `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`). |
**Exemple de requête** :
```json
{
"number": "2026/0001",
"JNL": "VEN",
"Artid": ["ART001", "ART003"],
"Qty": ["3", "1"],
"Saleprice": ["10.00", "50.00"]
}
```
---
## 8. Endpoints non fonctionnels
Les endpoints suivants ont été identifiés mais ne fonctionnent pas dans l'état actuel ou nécessitent des paramètres dont les valeurs attendues sont inconnues.
### `custom_geninv_updatestock` -- Mise à jour de l'inventaire
| | |
|---|---|
| **URL** | `POST /{dossier}/custom_geninv_updatestock` |
| **Méthode service** | `LogisticsService::customGeninvUpdatestock(array $params)` |
| **Statut** | Non fonctionnel |
**Paramètres connus** :
| Paramètre | Type | Description |
|-----------|------|-------------|
| `ARTID` | `string` | Identifiant de l'article. |
| `STKID` | `string` | Identifiant du stock. **Valeur attendue inconnue**. |
| `QTY` | `string` | Quantité à mettre à jour. |
| `TOCHECK` | `string` | Signification inconnue (possiblement un prix). |
| `TOCHECKDETAIL` | `string` | Signification inconnue (possiblement des remarques). |
| `MODE` | `string` | Mode d'opération. Signification inconnue. |
**Problème** : la valeur attendue pour `STKID` est inconnue, et la signification de plusieurs paramètres (`TOCHECK`, `TOCHECKDETAIL`, `MODE`) reste à clarifier auprès du fournisseur.
---
## 9. Relations entre entités
Les entités du système de gestion sont liées entre elles selon le schéma suivant :
```
Tiers (cust)
|
+-- possède un ou plusieurs --> Documents (dochead / docdet)
|
+-- appartient à un --> Journal (jnl)
|
+-- contient un ou plusieurs --> Articles (art)
|
+-- peut avoir des --> Fichiers attachés (attach)
|
+-- peut avoir des --> Paiements (docpay)
```
**Description des relations** :
- Un **tiers** (`cust`) est un client ou fournisseur. Il peut être associé à plusieurs documents commerciaux.
- Un **journal** (`jnl`) regroupe plusieurs documents du même type (ventes, achats, retours, etc.). Chaque document appartient à un seul journal.
- Un **document** est composé d'un en-tête (`dochead`) contenant les informations générales (tiers, date, journal, statut, totaux) et de lignes de détail (`docdet`) contenant les articles.
- Un **article** (`art`) est une référence produit du catalogue. Chaque ligne de document fait référence à un article avec une quantité, un prix unitaire et une TVA.
- Le **stock** (`stk`) contient les quantités en stock par article. Il est consultable via l'endpoint `art_getstk`.
- Les **fichiers attachés** (`attach`) sont des pièces jointes associées aux documents (factures PDF, bons de commande scannés, etc.).
- Les **paiements** (`docpay`) enregistrent les règlements associés aux documents.
- Les **codes internes** (`incodes`) sont des tables de référence paramétrables utilisées pour les listes déroulantes, les types, les catégories, etc.
---
## 10. Remarques et points d'attention
1. **Dossier en minuscules** : le nom du dossier dans les URLs doit toujours être en minuscules. Exemple : `esigescom`, pas `EsiGescom`. Le non-respect de cette règle provoque une erreur.
2. **Méthode POST uniquement** : tous les endpoints utilisent la méthode POST, y compris pour les opérations de lecture. N'utilisez pas GET, PUT ou DELETE.
3. **Paramètres numériques en string** : plusieurs paramètres qui représentent des nombres doivent être transmis au format `string`. Le paramètre `QTY` dans `Document_GetUnitPriceAndVat` (`"2"`, pas `2`) et le paramètre `results` dans `jnl_list` (`"50"`, pas `50`) provoquent une erreur HTTP 400 s'ils sont envoyés comme entiers. Toujours caster en string les valeurs numériques en cas de doute.
4. **Paramètre `search` obligatoire pour `third_list`** : l'endpoint `third_list` exige le paramètre `search`. Un appel sans ce paramètre retourne une erreur.
5. **Paramètre `results`** : le comportement de ce paramètre varie selon l'endpoint. Pour `art_list`, il n'a **aucun effet** (toujours 5 résultats maximum). Pour `third_list`, il n'a **aucun effet** non plus (toujours 10 résultats maximum). En revanche, pour `jnl_list` et `document_list`, le paramètre `results` **fonctionne réellement** et limite le nombre de résultats retournés. Pour `jnl_list`, la limite par défaut est de 30, et le paramètre doit être au format string. Pour `document_list`, la limite par défaut est d'environ 108 résultats. **Attention** : pour `document_list`, le paramètre `results` n'a d'effet que lorsqu'un `thirdid` est également fourni. Sans `thirdid`, l'API ignore `results` et retourne tous les documents disponibles.
6. **Paramètre `TYPE` obligatoire pour `jnl_list`** : l'endpoint `jnl_list` exige le paramètre `TYPE`. Le filtre accepte 1 caractère (filtre large : `C` pour tous les journaux client) ou 2 caractères (filtre exact : `CI` pour les factures client uniquement). Un appel sans ce paramètre retourne une erreur.
7. **Format du champ `error`** : le champ `error` de la réponse API peut être `null`, une chaîne ou un tableau de chaînes. L'application normalise ce champ automatiquement via `ApiErrorTranslator`.
8. **Paramètre `select`** : permet de choisir les colonnes à retourner. Les noms de colonnes disponibles pour chaque table s'obtiennent via `column_list/{tablename}`. Si omis, un jeu de colonnes par défaut est retourné. **Attention** : les noms de colonnes doivent correspondre exactement à ceux retournés par `column_list` (ex : `name1`, pas `artname`). L'API ignore silencieusement les noms de colonnes invalides sans émettre d'erreur.
9. **Casse des paramètres** : la casse des noms de paramètres varie selon les endpoints. Par exemple, l'identifiant du tiers peut être `thirdid`, `Thirdid` ou `THIRDID` selon l'endpoint. Respectez la casse documentée pour chaque endpoint.
10. **Fichiers attachés en base64** : lors de l'ajout ou la modification de documents, les fichiers joints doivent être encodés en base64 dans le champ `FileContentBase64`. Seul le contenu du fichier est encodé, pas le nom ni la description.
11. **Déduplication des colonnes** : l'endpoint `column_list` retourne chaque colonne en double. L'application effectue une déduplication automatique, mais si vous interrogez l'API directement, vous devez gérer ce doublon.
12. **Correspondance positionnelle des tableaux** : dans `document_add` et `document_mod`, les tableaux `Artid`, `Qty`, `Saleprice`, `Discount`, `Vatid` et `Vatpc` fonctionnent par correspondance positionnelle. Assurez-vous que tous les tableaux ont la même longueur.
13. **Timeout** : certaines requêtes peuvent être lentes selon le volume de données. Le timeout par défaut est configuré à 300 secondes. En cas de timeout, vérifiez la configuration `LOGISTICS_API_TIMEOUT`.
14. **Format de date obligatoire** : les endpoints qui acceptent un paramètre de date (`DATE`, `date`) exigent le format **`YYYY-MM-DD`** (ex : `"2025-07-01"`). Tout autre format (DD/MM/YYYY, MM/DD/YYYY, etc.) retourne une erreur HTTP 400 avec le message "Invalid date format. Expected format: YYYY-MM-DD". Les dates dans les réponses API utilisent le format ISO `YYYY-MM-DDT00:00:00` (avec composante horaire).
15. **`Document_GetPDF` et parametre `LAYOUT`** : le parametre `LAYOUT` de l'endpoint `Document_GetPDF` doit etre une **valeur numerique sous forme de string** (ex : `"1"`). Les valeurs textuelles (`"default"`, `"FACTURE"`, `"A4"`, etc.) provoquent une erreur. La valeur `"1"` est recommandee par defaut.
16. **Codes de délai de paiement** : les valeurs valides pour `paydelay` (utilisé dans `Document_GetDueDate`) sont obtenues via l'endpoint `codes_list` avec `code=PAYDELAY`. Les codes courants sont : `30`, `30F`, `45F`, `50`, `60`, `60F`, `75F`, `90`, `90F`, `0F`. Le suffixe `F` indique un calcul "fin de mois" (l'échéance tombe le dernier jour du mois de calcul).
17. **Modes de paiement** : les valeurs valides pour les modes de paiement sont obtenues via `codes_list` avec `code=PAYMODE`. Les codes courants sont : `CAS` (Cash), `VIR` (Virement), `BC` (Bancontact), `CBEF` (Cash BEF).
---
## 11. Ressources externes
- [Documentation Postman](https://documenter.getpostman.com/view/40440561/2sB2qaj2Pz)