1. Objet

Ce guide a pour objectif de vous familiariser avec la manipulation des API REST offertes par CARL Source sur la base d’exemples concrets.

2. Vue d’ensemble

La plupart des applications encapsulent les appels aux API REST dans le langage de votre choix, mais il est important de vous familiariser avec les méthodes HTTP de l’API sous-jacente.
Nous utiliserons donc l’outil cURL pour interagir avec les API.

2.1. Prérequis

  1. La connexion entre votre poste de travail et CARL Source doit être chiffrée : en effet, des informations sensibles (mot de passe et données protégées) vont transiter par le réseau dans le cadre de ce tutoriel.
    L’URL d’accès à CARL Source doit donc commencer par https://.

Warning

Il est conseillé de privilégier pour ces échanges sécurisés, l’utilisation de TLS v1.3.
Le serveur hébergeant la solution CARL Source doit donc être configuré en conséquence.

A noter que les versions 1.0 et 1.1 de TLS sont prohibées.

 

  1. Vous devez posséder un utilisateur CARL Source valide.

 

  1. Votre mot de passe doit également être valide (i.e. ni "expiré", ni "à modifier").
    Pour vous en assurer, connectez-vous à l’application CARL Source via la page de connexion.

 

Important

Attention, les URL données en exemple contenant des crochets ([ et ]) devront impérativement encoder ces caractères (respectivement %5B et %5D) sous peine d’être rejetées.
Toutefois, les crochets seront conservés dans les exemples de ce document afin d’en faciliter la lecture.

 
 

2.2. Hello World

Commençons par nous assurer que l’outil cURL et l’API sont accessibles.
Ouvrez une fenêtre de terminal et saisissez la commande suivante (adaptez les valeurs en rouge) :

> curl https://carlsource.server.com/gmaoCS02/public/status
status: ok

La réponse est une simple ligne de texte status: ok, qui confirme que CARL Source est bien installé et accessible via l’URL saisie.

3. Authentification

L’utilisation des services nécessite généralement la transmission d’informations d’authentification.
Lors d’une demande d’accès à un service protégé, si l’identifiant ou le mot de passe fourni est invalide, l’API retourne une erreur HTTP 401 (Unauthorized) :

> curl -X GET -i https://carlsource.server.com/gmaoCS02/api/entities/v1/mr

HTTP/1.1 401 Unauthorized
{
    "errors" : [ {
        "status" : "401",
        "title" : "Unauthorized",
        "detail" : "Please provide valid authentication credentials"
    } ]
}

L’authentification est la clé permettant la lecture et l’écriture d’informations privées via l’API.

3.1. Authentification par jeton

Pour les besoins d’une application, le fait d’envoyer les informations d’identifiant et de mot de passe à chaque interaction avec l’API peut paraître lourd et augmente le risque de vol de mot de passe.

La meilleure façon de gérer ce cas de figure consiste à demander à l’application (en l’occurrence CARL Source) la création d’un jeton d’accès, puis d’inclure ce dernier dans les requêtes subséquentes.
Ce jeton remplace l’usage direct du couple "identifiant/mot de passe" et évite ainsi d’exposer ces informations sensibles à chaque appel.

CARL Source prend en charge deux mécanismes d’obtention de jeton d’accès :

  • Jeton CARL Source (type (carlsource_auth_v1)) : obtenu via le service /api/auth/v1/authenticate et transmis dans l’en-tête HTTP X-CS-Access-Token.

  • Jeton OAuth2 (type (Bearer)) : conforme à la norme RFC 6750, obtenu via le service /api/oauth2/v1/token et transmis dans l’en-tête standard Authorization: Bearer.

Dans les deux cas, le service d’authentification n’est appelé qu’une seule fois pour obtenir le jeton d’accès. Ce jeton est ensuite utilisé pour authentifier toutes les requêtes ultérieures, sans qu’il soit nécessaire de renvoyer les identifiants ou les informations d’authentification.

Exemple jeton CS
> curl -X POST -i --data "login=identifiant" --data "password=mot_de_passe" --data "origin=identifiant_de_votre_application" https://carlsource.server.com/gmaoCS02/api/auth/v1/authenticate

HTTP/1.1 200
{
    "X-CS-Access-Token":"votre_access_token",
    "token_type":"carlsource_auth_v1",
    "expires_in":86399911,
    "lang":"fr_FR"
}
Exemple jeton OAuth2
> curl -X POST https://carlsource.server.com/gmaoCS02/api/oauth2/v1/token -H "Content-Type: application/x-www-form-urlencoded" -d "grant_type=password" -d "client_id=identifiant_de_votre_application"

HTTP/1.1 200
{
    "access_token": "votre_access_token",
    "token_type": "Bearer",
    "expires_in": 3600
}
Note

La valeur des attributs origin et client_id acceptent une longueur maximale de 33 caractères.

Le fragment de JSON obtenu en retour comprend en premier lieu le jeton, qui consiste en une suite aléatoire de caractères.
CARL Source vérifie la validité d’un tel jeton lorsque ce dernier est placé dans un en-tête de requête http nommé X-CS-Access-Token.

Les informations suivantes sont également présentes dans l’en-tête :

  • Le type de jeton : il existe à ce jour deux types de jeton dans CARL Source (carlsource_auth_v1) et (bearer).
    Il est possible que des jetons de type refresh tokens soient disponibles dans le futur.

  • Le temps de validité de ce jeton (en millisecondes).
    Au-delà de ce délai, une requête embarquant ce jeton sera rejetée.
    Ce délai est configurable dans les paramètres de configuration système de CARL Source.

  • La langue de l’utilisateur ayant demandé le jeton.
    Cette information permet à l’application demandeuse de basculer au plus tôt sur la langue convenant le mieux à l’utilisateur (par exemple si celui-ci s’est connecté depuis un navigateur configuré dans une langue différente de la sienne).
    A noter que c’est la langue définie sur l’utilisateur CARL Source qui fait foi.

Note

La langue est retournée uniquement dans le cas d’un jeton (carlsource_auth_v1)

Une fois le jeton obtenu, voici la manière dont il peut être utilisé pour authentifier un appel :

Exemple jeton CARL Source
> curl -X GET -H "X-CS-Access-Token: votre_access_token" https://carlsource.server.com/gmaoCS02/api/entities/v1/mr
Exemple jeton OAuth2
> curl -X GET -H "Authorization: Bearer votre_access_token" https://carlsource.server.com/gmaoCS02/api/entities/v1/mr

3.1.1. Cas particulier du jeton OAuth2 avec JWT d’assertion

Dans le cas du mécanisme OAuth2, l’authentification du client repose sur une assertion JWT (JSON Web Token).
L’application externe construit un JWT signé pour prouver son identité à CARL Source (serveur OAuth2).
CARL Source vérifie la signature, la validité et les informations contenues dans ce JWT.
Si le jeton est valide, CARL Source renvoie un jeton d’accès OAuth2, qui sera ensuite utilisé pour consommer les APIs CARL Source.

Ce JWT d’assertion suit les spécifications des RFC 7521 et RFC 7523, et peut être signé :

  • soit avec une clé asymétrique (algorithme RSASSA-PKCS1-v1_5 + SHA-256),

  • soit avec une clé partagée (Pre-Shared Key, PSK, utilisant HMAC + SHA-256).

Sa durée de validité est limitée afin d’éviter les risques de réutilisation (replay attack).
CARL Source contrôle ainsi que l’âge du JWT ne dépasse pas la valeur maximale définie dans la configuration système.

3.2. Authentification HTTP-BASIC

Warning

L’authentification HTTP-BASIC (Basic Authentication) est déconseillée.
Veuillez privilégier l’authentification par jeton (voir section 3.1) pour toute utilisation en production.

Malgré les risques, si vous souhaitez vous authentifier de cette façon, vous devez utiliser un identifiant et un mot de passe CARL Source.

Exemple de demande d’authentification
> curl -u identifiant https://carlsource.server.com/gmaoCS02/api/auth/v1/authenticate
Enter host password for user 'identifiant':

L’option -u permet de définir un nom d’utilisateur.
A la validation de la commande, cURL demande alors le mot de passe associé.
Il est possible d’utiliser la syntaxe -u "identifiant:mot_de_passe" pour éviter l’invite, mais cela laisse une trace du mot de passe dans l’historique du terminal (ce qui n’est pas recommandé).

Il est également possible de désactiver ce mode d’authentification en cochant le paramètre système AuthBasicDisabled de la rubrique Authentification :

config auth carl

Dans ce cas les tentatives d’accès via cette méthode retourneront une erreur:

> curl -u identifiant https://carlsource.server.com/gmaoCS02/api/auth/v1/authenticate
Enter host password for user 'identifiant':

{
    "errors" : [ {
     "status" : "401",
     "title" : "Unauthorized",
     "detail" : "Please provide valid authentication credentials"
     } ]
}

3.3. Authentification et sécurité en production

Au-delà de ce tutoriel, pour lequel l’outil curl est utilisé, une application en production doit invoquer le service d’authentification à l’aide d’une bibliothèque de communication http fournie par le langage dans lequel elle est programmée.

Il convient d’être très prudent sur la façon d’invoquer ce service d’authentification, car techniquement il existe deux façons différentes de transmettre les paramètres login, password et origin au service /authenticate.

3.3.1. Authentification en production : mauvaise pratique

La première façon de faire consiste à transmettre ces informations sous la forme de paramètres dans l’URL.
Cette méthode est très fortement déconseillée pour une application en production.

Exemple de mauvaise pratique : le passage des paramètres d’authentification via l’URL
POST https://carlsource.server.com/gmaoCS02/api/auth/v1/authenticate?login=LOGIN&password=password&origin=ORIGIN

En procédant ainsi, les informations critiques d’identifiant et de mot de passe vont être potentiellement traitées comme des données non critiques et être exposées, notamment dans des fichiers de logs.
Bien que ce soit techniquement possible, cette pratique est fortement découragée.

3.3.2. Authentification en production : bonne pratique

Il est préconisé de transmettre les paramètres d’authentification en tant que données de formulaire, dans le corps de la requête, et d’ajuster le Content-Type en conséquence en utilisant application/x-www-form-urlencoded.

Exemple de bonne pratique : le passage des paramètres d’authentification via le corps de la requête
POST https://carlsource.server.com/gmaoCS02/api/auth/v1/authenticate
Content-Type: application/x-www-form-urlencoded

&login=LOGIN
&password=password
&origin=ORIGIN

4. Droits d’accès

Les droits d’accès à l’API sont pilotés par les droits positionnés sur chaque profil au niveau de CARL Source.

Un paramètre de profil global, nommé "Accès aux API de type JSON-API" et accessible depuis la catégorie "Global", autorise l’accès aux API.

Warning

Par défaut ce paramètre est positionné à la valeur 'Désactivé', ce qui bloque par conséquent l’accès aux API.

L’accès à une entité par l’API est ensuite déterminé en fonction des autorisations de Lecture/Création/Modification/Suppression sur la fonctionnalité liée à cette entité (les autres autorisations sont ignorées).
Un algorithme applique les critères suivants (dans l’ordre) afin de faire le lien entre une entité et sa fonctionnalité :

  1. Récupération de l’attribut FunctBean.entity qui indique directement si l’entité est référencée par la fonctionnalité.

  2. Si l’entité n’a pas de fonctionnalité référencée : parcours des relations entre entités ; l’entité est reliée à une autre entité dont la fonctionnalité a été identifiée. Dans ce cas, il est possible qu’une entité soit référencée par plusieurs fonctionnalités.

  3. Si, au terme de ce parcours, certaines entités sont toujours non rattachées à une fonctionnalité, on doit renseigner cette information dans ObjectInfoBean.relatedFunctionality.

Note
  • Si une entité n’est pas rattachée à une fonctionnalité, son accès par l’API est interdit (cette information est visible dans les logs lors du premier accès à l’API).

  • Certaines entités techniques ne sont pas disponibles (paramètre ObjectInfoBean.apiRestRestriction positionné à 'NOTALLOWED') ou uniquement accessibles en lecture seule (paramètre ObjectInfoBean.apiRestRestriction positionné à 'READONLY').

  • Si une entité est accessible uniquement en lecture seule, mais que le profil utilisé n’a pas d’autorisation en Lecture sur la fonctionnalité associée, alors l’entité n’est pas accessible par le profil.

Les codes HTTP suivants sont retournés en cas de droits insuffisants :

  • 403 - indique que le profil n’a pas les autorisations nécessaires sur cette entité :

    • soit vis-à-vis du paramètre global "Accès aux API de type JSON-API" (voir plus haut),

    • soit vis-à-vis de ses autorisations sur la fonctionnalité associée,

    • soit par l’absence de fonctionnalité associée.

  • 501 : indique que l’entité est uniquement accessible en lecture seule, et par conséquent que les opérations POST/PUT/PATCH/DELETE ne sont pas réalisables sur celle-ci.

5. Limite

Le paramètre de configuration ApiMaxResults indique le nombre maximum d’éléments que peut remonter une page sur un appel de l’API Rest.
La valeur maximum est fixée à 500. En effet, ce paramètre conditionne directement la mémoire consommée dans l’application; une valeur trop élevée pourrait amener rapidement à la saturation et l’arrêt de l’application.
Lorsque le nombre d’éléments retournés est supérieur à 500, il est nécessaire d’utiliser la pagination.

La pagination sert à diviser un grand ensemble de données en plusieurs "pages" plus petites, afin d’éviter de tout charger en une seule fois.
Chaque appel à l’API lit une partie des données en base (les beans), puis les transforme en entités - les objets effectivement renvoyés.
Certains filtres étant appliqués après lecture des beans et certaines entités étant issues de collections, le nombre exact d’éléments par page peut varier.

La gestion de la pagination se fait grâce aux paramètres limit et offset :

  • limit indique le nombre d’éléments désirés dans la page (ex. 100 résultats).

  • offset indique le nombre d’éléments à ignorer avant de récupérer les éléments désirés (ex. pour aller à la page suivante).

Exemples :

Page 1 : récupération des 100 premières DI
curl -X GET -H "X-CS-Access-Token: votre_access_token" "https://carlsource.server.com/gmaoCS02/api/entities/v1/mr?limit=100&offset=0"
Page 2 : récupération des 100 DI suivantes (de 101 à 200)
curl -X GET -H "X-CS-Access-Token: [red]#votre_access_token#" "https://carlsource.server.com/gmaoCS02/api/entities/v1/mr?limit=100&offset=100"
Page 3 : récupération des 100 DI suivantes (de 201 à 300)
curl -X GET -H "X-CS-Access-Token: [red]#votre_access_token#" "https://carlsource.server.com/gmaoCS02/api/entities/v1/mr?limit=100&offset=200"
Important

Avec l’option OData, les paramètres permettant de gérer la pagination sont différents; dans ce cas, les appels API doivent utiliser $top et $skip en lieu et place de limit et offset.

Exemple appel Api OData
curl -X GET -H "X-CS-Access-Token: [red]#votre_access_token#" "https://carlsource.server.com/gmaoCS02/api/odata/v1/WOPROCESS?$top=200&$skip=300

6. Scénario métier : l’API /entities

Maintenant que votre installation fonctionne et que vous savez comment accéder aux services protégés via le système d’authentification de votre choix, vous allez pouvoir interagir avec les objets métiers de CARL Source.

Ce scénario propose de créer et manipuler un concept central de CARL Source, la Demande d’intervention, via l’API /entities.

Techniquement, il s’agit d’une API REST - HATEOAS, s’appuyant sur la bibliothèque Crnk, elle-même implémentant la spécification JSON-API.

6.1. Anatomie d’un appel

Pour commencer, listons les demandes d’intervention existantes dans CARL Source.
Pour cela, il nous suffit de connaitre le code sous lequel est désignée une demande d’intervention dans CARL Source.
Ce code est 'mr' (nous y reviendrons plus tard).

Requête permettant de lister les demandes d’intervention
> curl -X GET -H "X-CS-Access-Token: votre_access_token" https://carlsource.server.com/gmaoCS02/api/entities/v1/mr
Warning

Pour être accessibles au travers de l’API /entities, en lecture/modificaton/création/suppression, les attributs doivent avoir la propriété Exporté format XML cochée ou nulle dans le dictionnaire de CARL Source.

Changement de valeur sur la propriété Exporté format XML
curl -X POST -i -H "X-CS-Access-Token: votre_access_token" https://carlsource.server.com/gmaoCS02/api/entities/v1?rebuildAPIs

Avant de l’exécuter, penchons-nous sur cette commande :

  • le premier paramètre -H 'X-CS-Access-Token" permet d’indiquer le token obtenu précédemment (voir Authentification par jeton), afin de s’authentifier à l’aide de la méthode Custom Header Token,

  • la suite de la commande invoque le service REST responsable de lister les demandes d’intervention (mr).

Décomposons cette URL :

  • https://carlsource.server.com : la première partie de l’URL correspond à l’adresse de CARL Source.

  • /gmaoCS02 : indique le contexte de l’application web CARL Source.

  • /api : spécifie que l’on souhaite solliciter une API REST de CARL Source.

  • /entities/v1/ : l’API à laquelle on s’adresse est l’API /entities, dans sa première version (/v1).

  • /mr : le type des entités auxquelles on souhaite accéder est mr, les demandes d’intervention.

Si on ne fournit pas davantage d’informations, CARL Source renvoie une liste de toutes les demandes d’intervention (au format JSON).
Voici un extrait de la réponse obtenue :

Exemple avec un extrait de réponse
> curl -X GET -H "X-CS-Access-Token: votre_access_token" https://carlsource.server.com/gmaoCS02/api/entities/v1/mr

HTTP/1.1 200
{
    "data" : [ {
        "id" : "DI-1",
        "type" : "mr",
        "attributes" : {
            "code" : "DI-001",
            "statusChangedDate" : "2018-10-19T15:31:21.495+02:00",
            "description" : "Chauffage / Climatisation salle de réunion direction",
            "expEnd" : "2018-10-20T15:31:21.495+02:00",
            "SRID" : 0,
            "amount" : 0.0,
            "creationDate" : "2018-10-19T15:31:21.495+02:00",
            "workRecept" : true,
            "workPriority" : "HIGH",
            "eqptBroken" : true,
            "statusCode" : "REQUEST"
        },
        "relationships" : {
            "address" : {
                "links" : {
                    "self" : "https://carlsource.server.com/gmaoCS02/api/entities/v1/mr/DI-1/relationships/address",
                    "related" : "https://carlsource.server.com/gmaoCS02/api/entities/v1/mr/DI-1/address"
                }
            },
            "symptom" : {
                "links" : {
                    "self" : "https://carlsource.server.com/gmaoCS02/api/entities/v1/mr/DI-1/relationships/symptom",
                    "related" : "https://carlsource.server.com/gmaoCS02/api/entities/v1/mr/DI-1/symptom"
                }
            },
            "site" : {
                "links" : {
                    "self" : "https://carlsource.server.com/gmaoCS02/api/entities/v1/mr/DI-1/relationships/site",
                    "related" : "https://carlsource.server.com/gmaoCS02/api/entities/v1/mr/DI-1/site"
                }
            },
            "risks" : {
                "links" : {
                    "self" : "https://carlsource.server.com/gmaoCS02/api/entities/v1/mr/DI-1/relationships/risks",
                    "related" : "https://carlsource.server.com/gmaoCS02/api/entities/v1/mr/DI-1/risks"
                }
            },
            "customer" : {
                "links" : {
                    "self" : "https://carlsource.server.com/gmaoCS02/api/entities/v1/mr/DI-1/relationships/customer",
                    "related" : "https://carlsource.server.com/gmaoCS02/api/entities/v1/mr/DI-1/customer"
                }
            }
        },
        "links" : {
            "self" : "https://carlsource.server.com/gmaoCS02/api/entities/v1/mr/DI-1",
            "workflow-transitions" : "https://carlsource.server.com/gmaoCS02/api/entities/v1/mr/DI-1/workflow-transitions"
        }
    },
    {
        "id" : "DI-2",
        "type" : "mr",
        ...
    } ]
}

L’API /entities se conforme à la norme JSON-API.
Les données JSON retournées sont toujours encapsulées dans un tableau JSON nommé data[].

Voyons la structure de chaque objet mr retourné :

  • Les attributs identifiant (id) et type d’entité (type) sont au premier niveau.

  • Les attributs métier sont regroupés dans un objet attributes.

  • Les objets et collections liés sont considérés comme des relations et regroupés dans un objet relationships.

  • Chaque relation est nommée (par exemple risks) et comprend un sous-objet links, lui-même composé de deux attributs :

    • related présente l’URL qu’il est nécessaire d’appeler si l’on souhaite récupérer le détail de cette relation,

    • self présente l’URL vers la relation elle-même (utile si l’on veut manipuler la relation elle-même et non les deux objets liés - par exemple, supprimer la relation sans supprimer aucun des deux objets liés).

  • Et enfin un objet links, qui reprend le concept du self et ajoute un attribut workflow-transitions qui nous servira à faire évoluer l’objet dans son cycle de vie (nous y reviendrons plus tard).

Structure type du JSON retourné par un service de l’API CARL Source /entities
{
    "data" : [
        {
            "id" : <identifiant>,
            "type" : <type>,
            "attributes" : {
                <liste des attributs>
            },
            "relationships" : {
                <liste des objets et collections liés avec pour chacun les URL 'self' et 'related'>
            },
            "links" : {
                "self" : <URL du service donnant le détail de cet objet>,
                "workflow-transitions" : <URL du service donnant les futurs états possibles de cet objet au sein de son cycle de vie>
            }
        },
        <les autres objets sur le même modèle>
    ]
}
Note

La commande utilisée dans ce chapitre est donnée à titre d’exemple ; elle permet de récupérer un nombre important de données.
Il est peu probable qu’une application ait besoin d’autant de données brutes ; le chapitre suivant explique comment filtrer ces données et sélectionner uniquement celles qui nous intéressent.

6.2. Lister, filtrer et sélectionner

L’API /entities de CARL Source s’appuie sur Crnk, un framework qui suit les recommandations de la spécification JSON-API. Ceci étant, tout n’est pas décrit par cette spécification.
Les aspects liés au requêtage (filtre, tri, pagination, etc.) s’appuient sur l’API QuerySpec.

6.2.1. Filtres simples

Voici quelques exemples de filtres permettant d’effectuer des recherches avec les opérateurs de base :

Tri par date de création décroissante
curl -X GET -H "X-CS-Access-Token: votre_access_token" https://carlsource.server.com/gmaoCS02/api/entities/v1/mr?sort=-creationDate
Tri par date de création décroissante, puis par description croissante
curl -X GET -H "X-CS-Access-Token: votre_access_token" https://carlsource.server.com/gmaoCS02/api/entities/v1/mr?sort=-creationDate,description
Limitation des résultats aux deux premières pages
curl -X GET -H "X-CS-Access-Token: votre_access_token" https://carlsource.server.com/gmaoCS02/api/entities/v1/mr?sort=id&page[offset]=0&page[limit]=2
Recherche exacte sur la valeur du champ 'description'
curl -X GET -H "X-CS-Access-Token: votre_access_token" https://carlsource.server.com/gmaoCS02/api/entities/v1/mr?filter[mr][description]=Chauffage / Climatisation salle de réunion direction
Recherche de type LIKE (ou «contient») sur la valeur du champ 'description'
curl -X GET -H "X-CS-Access-Token: votre_access_token" https://carlsource.server.com/gmaoCS02/api/entities/v1/mr?filter[mr][description][LIKE]=panne
Retourne uniquement la description de chaque demande d’intervention
curl -X GET -H "X-CS-Access-Token: votre_access_token" https://carlsource.server.com/gmaoCS02/api/entities/v1/mr?fields[mr]=description

6.2.2. Filtres complexes

 

Important

Attention : le format utilisé pour décrire un filtre complexe contient des caractères spéciaux (crochets et accolades). Ces caractères doivent obligatoirement être encodés; à défaut, la requête sera rejetée
Toutefois, ils seront conservés dans les exemples suivants afin d’en faciliter la lecture.

 

Il est possible d’effectuer des requêtes plus complexes en combinant les filtres avec des opérateurs logiques composites. Les opérateurs actuellement supportés sont OR et AND.

Voici quelques exemples de requêtes utilisant des filtres complexes :

Recherche des demandes d’intervention dont le code est égal à "MR01" OU dont l’identifiant est égal à "01"
curl -X GET -H "X-CS-Access-Token: votre_access_token" https://carlsource.server.com/gmaoCS02/api/entities/v1/mr?filter={"OR":[{"code":"MR01"},{"id":"01"}]}
Recherche des demandes d’intervention qui concernent un équipement en panne ET dont la priorité est haute
curl -X GET -H "X-CS-Access-Token: votre_access_token" https://carlsource.server.com/gmaoCS02/api/entities/v1/mr?filter={"AND":[{"eqptBroken":true},{"workPriority":"HIGH"}]}
Recherche des demandes d’intervention dont la date de fin souhaitée est postérieure à une valeur OU antérieure à une valeur
curl -X GET -H "X-CS-Access-Token: votre_access_token" https://carlsource.server.com/gmaoCS02/api/entities/v1/mr?filter={"OR":[{"GT":{"expEnd": "2026-01-01"}},{"LT":{"expEnd": "2026-12-31"}}]}
Recherche des demandes d’intervention qui concernent un équipement en panne OU un équipement indisponible OU dont la priorité est haute
curl -X GET -H "X-CS-Access-Token: votre_access_token" https://carlsource.server.com/gmaoCS02/api/entities/v1/mr?filter={"OR":[{"eqptBroken":true},{"eqptUnavailable":true},{"workPriority":"HIGH"}]}

Il est également possible d’imbriquer les filtres grâce aux opérateurs logiques composites. Voici un exemple :

Recherche des demandes d’intervention dont la priorité est haute OU [qui concernent un équipement en panne ET dont la date de fin souhaitée est postérieure à une valeur]
curl -X GET -H "X-CS-Access-Token: votre_access_token" https://carlsource.server.com/gmaoCS02/api/entities/v1/mr?filter={"OR":[{"workPriority":"HIGH"},{"AND":[{"eqptBroken":true},{"GT":{"expEnd": "2026-12-31"}}]}]}

 

6.3. Créer, lire, modifier et supprimer

Conformément au standard REST, les verbes HTTP suivants sont disponibles, chacun étant assigné à un rôle précis :

  • POST : création

  • GET : lecture

  • PATCH : modification

  • DELETE : suppression

6.3.1. Création

A titre d’exemple, créer une demande d’intervention revient à exécuter la commande suivante :

Requête POST créant une demande d’intervention avec une description et une priorité initialisées
curl -X POST -i -H "X-CS-Access-Token: votre_access_token" -H "Content-Type: application/vnd.api+json" \
     -d '{
        "data" : {
            "type" : "mr",
            "attributes" : {
                "description" : "Nouvelle demande",
                "workPriority" : "HIGH"
            }
        }
     }' \
     https://carlsource.server.com/gmaoCS02/api/entities/v1/mr

Conformément à la norme JSON API, le format des données soumises en JSON reprend la structure détaillée ci-dessus ({ "data" : {..}}), et un en-tête HTTP fixe le type de contenu soumis -H "Content-Type: application/vnd.api+json".
 

Tip

Les données peuvent être transmises au travers d’un fichier à l’aide de la requête suivante :
 

curl -X POST -i -H "X-CS-Access-Token: votre_access_token" -H "Content-Type: application/vnd.api+json" --data-binary "@path/to/file" https://carlsource.server.com/gmaoCS02/api/entities/v1/mr
 

Attention : le chemin d’accès au fichier doit être précédé du symbole @.

Le fichier JSON aura alors le contenu suivant :

{
    "data" : {
        "type" : "mr",
        "attributes" : {
            "description" : "Nouvelle demande",
            "workPriority" : "HIGH"
        }
    }
}

 

Le JSON décrivant la demande d’intervention venant d’être créée est reçu en réponse à cette requête, avec un code HTTP 201.
En voici un extrait :

HTTP/1.1 201
{
    "data" : {
        "id" : "166ee780a94-1486",
        "type" : "mr",
        "attributes" : {
            "code" : "000001",
            "description" : "Nouvelle demande",
            "workPriority" : "HIGH",
            "eqptBroken" : false,
            "SRID" : 0,
            "amount" : 0.0,
            "creationDate" : "2018-11-08T17:20:10.583+01:00",
            "modifyDate" : "2018-11-08T17:20:10.600+01:00",
            "expEnd" : "2018-11-08T17:20:10.585+01:00",
            "statusChangedDate" : "2018-11-08T17:20:10.584+01:00",
            "statusCode" : "REQUEST"
            ...
        },
        "relationships" : {
            "address" : {
                "links" : {
                    "self" : "https://carlsource.server.com/gmaoCS02/api/entities/v1/mr/166ee780a94-1486/relationships/address",
                    "related" : "https://carlsource.server.com/gmaoCS02/api/entities/v1/mr/166ee780a94-1486/address"
                }
            },
            "risks" : {
                "links" : {
                    "self" : "https://carlsource.server.com/gmaoCS02/api/entities/v1/mr/166ee780a94-1486/relationships/risks",
                    "related" : "https://carlsource.server.com/gmaoCS02/api/entities/v1/mr/166ee780a94-1486/risks"
                }
            },
            ...
        },
        "links" : {
            "self" : "https://carlsource.server.com/gmaoCS02/api/entities/v1/mr/166ee780a94-1486",
            "workflow-transitions" : "https://carlsource.server.com/gmaoCS02/api/entities/v1/mr/166ee780a94-1486/workflow-transitions"
        }
    }
}

La valeur de l’attribut links.self donne directement l’URL à appeler pour obtenir le détail de la demande d’intervention venant d’être créée.

6.3.2. Lecture

Pour récupérer un objet existant, il suffit d’ajouter son identifiant à la suite de l’URL :

curl -X GET -i -H "X-CS-Access-Token: votre_access_token" https://carlsource.server.com/gmaoCS02/api/entities/v1/mr/166ee780a94-1486

La réponse est alors identique à celle obtenue plus haut suite à une création : elle contient le détail de l’objet.

6.3.3. Modification

Pour modifier un objet existant, on utilise une syntaxe proche de celle de la création et de la lecture, mais avec un verbe HTTP approprié : PATCH.

curl -X PATCH -i -H "X-CS-Access-Token: votre_access_token" -H "Content-Type: application/vnd.api+json" \
     -d '{
        "data" : {
            "type" : "mr",
            "attributes" : {
                "description" : "Nouvelle demande urgente",
                "workPriority" : "VERYHIGH"
            }
        }
     }' \
     https://carlsource.server.com/gmaoCS02/api/entities/v1/mr/166ee780a94-1486

6.3.4. Suppression

Pour supprimer un objet, l’approche est similaire ; spécifier un identifiant à la fin de l’URL et utiliser un verbe HTTP approprié : DELETE.

curl -X DELETE -i -H "X-CS-Access-Token: votre_access_token" https://carlsource.server.com/gmaoCS02/api/entities/v1/mr/166ee780a94-1486

6.3.5. Synthèse

Pour résumer les différentes actions à disposition :

  • Lister : GET /api/entities/<version de l’API>/<code du type d’objet>
    + d’éventuelles options QuerySpec

  • Créer : POST /api/entities/<version de l’API>/<code du type d’objet>
    + un document JSON utilisé pour initialiser l’objet créé

  • Lire : GET /api/entities/<version de l’API>/<code du type d’objet>/<identifiant de l’objet>

  • Modifier : PATCH /api/entities/<version de l’API>/<code du type d’objet>/<identifiant de l’objet>
    + un document JSON utilisé pour modifier l’objet

  • Supprimer : DELETE /api/entities/<version de l’API>/<code du type d’objet>/<identifiant de l’objet>

6.4. Gestion du multilingue

6.4.1. Historique de la gestion du multilingue

Jusqu’en version 7.3.0, l’API /entities ne gérait pas du tout les aspects multilingues (Babylon). Cela signifie que les données manipulées par l’API étaient systématiquement les données stockées dans les tables de CARL Source (par opposition à celles stockées dans les tables de traductions), et donc exprimées dans la langue par défaut de l’application.

À partir de CARL Source 7.4.0, le paramètre de configuration système enableI18nEntitiesApi a permis d’exploiter l’API /entities dans deux modes distincts :

  • un mode dans lequel l’API supporte les capacités multilingues de CARL Source en lecture et en écriture.
    C’est le mode par défaut qui permet à l’API d’envoyer des données traduites dans la langue de l’utilisateur dans la réponse en lecture, et de créer ou modifier des traductions dans la requête en écriture.

  • un mode de compatibilité dans lequel on conserve le comportement historique de l’API en ne gérant pas du tout les aspects multilingues.
    De plus, le support du paramètre d’URI _locale (déjà présent dans plusieurs API CARL Source) est ajouté dans l’API /entities afin de pouvoir surcharger la langue de l’utilisateur connecté.

Puis, en CARL Source 7.5.0, un ensemble de nouveaux paramètres d’URI a fait son apparition afin de permettre de filtrer et trier sur des éléments traduisibles :

  • i18nFilter : à utiliser en lieu et place de filter si l’on souhaite que le filtre s’applique sur les éléments traduits.

  • _i18nSort : false par défaut. Si true, le paramètre sort peut s’appliquer à des éléments traduits.

  • _ignoreTranslations : false par défaut. Si true, les éventuelles traductions ne sont pas résolues en lecture ni en écriture.

6.4.2. Résolution de traductions et nouveaux blocs meta

Si le paramètre de configuration système enableI18nEntitiesApi est coché, les traductions sont résolues en lecture et en écriture. La langue dans laquelle la requête est effectuée est déduite :

  1. en priorité de la valeur du paramètre d’URI _locale,

  2. sinon sur la langue de l’utilisateur connecté à CARL Source lors de l’appel à l’API.

Cela signifie que si des données traduites existent dans la langue demandée, elles seront résolues et retournées dans la réponse.

Afin de savoir dans quelle langue sont exprimés les éléments retournés, et d’avoir le contexte nécessaire à l’exploitation de ces données traduites, de nouveaux blocs meta, conformes à la spécification JSON:API, ont été ajoutés à la réponse.

6.4.2.1. Blocs meta et langues des attributs en lecture

On demande le détail d’un objet de type unit et d’identifiant 100 en étant connecté avec un utilisateur français :

curl -X GET /api/entities/v1/unit/100?fields=code,description,symbol
Réponse obtenue
{
    "data": {
        "id": "CH",
        "type": "unit",
        "links": {
            "self": "https://carlsource.server.com/api/entities/v1/unit/100"
        },
        "meta": {
            "translatableAttributesLanguageMap": {
                "symbol": "fr",
                "description": "fr"
            },
            "entityLanguage": "fr",
            "codeReference": "CH"
        },
        "attributes": {
            "symbol": "ch",
            "code": "CH",
            "description": "Cheval-vapeur"
        }
    },
    "links": {
        "self": "https://carlsource.server.com/api/entities/v1/unit/100?fields=code%2Cdescription%2Csymbol"
    },
    "meta": {
        "requestLocale": "fr_FR"
    }
}

Puis le détail du même objet, avec le même utilisateur connecté, mais en spécifiant la langue anglaise :

curl -X GET /api/entities/v1/unit/100?fields=code,description,symbol&_locale=en_GB
Réponse obtenue
{
    "data" : {
        "id": "CH",
        "type": "unit",
        "links": {
            "self": "https://carlsource.server.com/api/entities/v1/unit/100"
        },
        "meta": {
            "translatableAttributesLanguageMap": {
                "symbol": "en",
                "description": "en"
            },
            "entityLanguage": "fr",
            "codeReference": "CH"
        },
        "attributes": {
            "symbol": "hp",
            "code": "CH",
            "description": "Horsepower"
        }
    },
    "links": {
        "self": "https://carlsource.server.com/api/entities/v1/unit/100?fields=code%2Cdescription%2Csymbol&_locale=en_GB"
    },
    "meta": {
        "requestLocale": "en_GB"
    }
}
6.4.2.2. Un bloc meta global pour la langue de la requête

Si l’on observe le contenu de ces deux réponses de bas en haut, on constate tout d’abord qu’un bloc meta global rappelle systématiquement la locale dans laquelle la requête a été exécutée. En effet, même si cela parait redondant dans le cas où locale est explicitement spécifiée en paramètre d’URI, ce paramètre reste optionnel et en son absence c’est la locale associée à l’utilisateur connecté qui fait foi.
Dans ce cas, la locale de la requête est implicite : il est donc bon de la rappeler dans la réponse.

6.4.2.3. Des attributs traduits dans la langue de la requête

Si l’entité sélectionnée possède des attributs traduisibles, et s’ils disposent d’une traduction dans la langue demandée, alors ceux-ci sont désormais résolus et proposés dans la réponse. Dans ce cadre, un bloc meta par entité fait son apparition et porte trois informations permettant de donner du contexte :

  • translatableAttributesLanguageMap rappelle quels sont les attributs traduisibles de l’entité, et pour chacun la langue dans laquelle sa valeur est exprimée.

  • entityLanguage permet de connaitre la langue dans laquelle l’entité a été créée.

  • codeReference est le code tel qu’il est stocké dans la table (dans la langue de l’entité donc), et qui permet de retrouver l’entité via un filter[code]=.

6.4.3. Création et modification de traductions

Si un utilisateur français crée une entité, la requête et la réponse ressemblent à ceci :

curl -X POST /api/entities/v1/unit
{
    "data": {
        "type": "unit",
        "attributes": {
            "code": "CH",
            "description": "Cheval-vapeur",
            "symbol": "ch",
            "decimal": "0"
        }
    }
}
Réponse obtenue
{
    "data": {
        "id": "100",
        "type": "unit",
        "links": {
            "self": "https://carlsource.server.com/api/entities/v1/unit/100"
        },
        "meta": {
            "translatableAttributesLanguageMap": {
                "symbol": "fr",
                "description": "fr"
            },
            "entityLanguage": "fr",
            "codeReference": "CH"
        },
        "attributes": {
            "symbol": "ch",
            "UOwner": "DEMO",
            "code": "CH",
            "modifyDate": "2026-01-16T14:38:28.128+01:00",
            "description": "Cheval-vapeur",
            "persoId": null,
            "decimal": 0
        },
        "relationships": {
            "secuPolicy": {
                "links": {
                    "self": "https://carlsource.server.com/api/entities/v1/unit/100/relationships/secuPolicy",
                    "related": "https://carlsource.server.com/api/entities/v1/unit/100/secuPolicy"
                }
            }
        }
    },
    "links": {
        "self": "https://carlsource.server.com/api/entities/v1/unit"
    },
    "meta": {
        "requestLocale": "fr_FR"
    }
}

En revanche, si c’est un utilisateur anglais qui exécute cette même requête, on obtient cette réponse :

{
    "data": {
        "id": "100",
        "type": "unit",
        "links": {
            "self": "https://carlsource.server.com/api/entities/v1/unit/100"
        },
        "meta": {
            "translatableAttributesLanguageMap": {
                "symbol": "en",
            "description": "en"
            },
            "entityLanguage": "en",
            "codeReference": "HP"
        },
        "attributes": {
            "symbol": "hp",
            "UOwner": "DEMO",
            "code": "HP",
            "modifyDate": "2026-01-16T14:48:15.065+01:00",
            "description": "Horsepower",
            "persoId": null,
            "decimal": 0
        },
        "relationships": {
            "translations": {
                "links": {
                    "self": "https://carlsource.server.com/api/entities/v1/unit/100/relationships/translations",
                    "related": "https://carlsource.server.com/api/entities/v1/unit/100/translations"
                }
            },
            "secuPolicy": {
                "links": {
                    "self": "https://carlsource.server.com/api/entities/v1/unit/100/relationships/secuPolicy",
                    "related": "https://carlsource.server.com/api/entities/v1/unit/100/secuPolicy"
                }
            }
        }
    },
    "links": {
        "self": "https://carlsource.server.com/api/entities/v1/unit?_locale=en_GB"
    },
    "meta": {
        "requestLocale": "en_GB"
    }
}

On remarque que :

  • la langue de la requête diffère entre les deux,

  • les attributs traduisibles sont exprimés en fonction de cette langue,

  • le codeReference est bien le code avec lequel l’entité a été initialement créée, et que c’est celui qui sera donc à utiliser pour faire référence à cette entité via un filtre filter[code]=.

Si l’entité a été créée par l’utilisateur français, et que l’on souhaite créer ou modifier des traductions anglaises, une requête PATCH suffit.
Si c’est un utilisateur français qui réalise cette opération, alors il faudra spécifier le paramètre d’URI _locale=en_GB.

curl -X PATCH /api/entities/v1/unit/100?_locale=en_GB
Réponse obtenue
{
    "data": {
        "id": "CH",
        "type": "unit",
        "links": {
            "self": "https://carlsource.server.com/api/entities/v1/unit/100"
        },
        "meta": {
            "translatableAttributesLanguageMap": {
                "symbol": "en",
                "description": "en"
            },
            "entityLanguage": "fr",
            "codeReference": "CH"
        },
        "attributes": {
            "symbol": "hp",
            "UOwner": "DEMO",
            "code": "CH",
            "modifyDate": "2026-01-16T13:55:43.722+01:00",
            "description": "Horsepower",
            "persoId": null,
            "decimal": 0
        },
        "relationships": {
            "translations": {
                "links": {
                    "self": "https://carlsource.server.com/api/entities/v1/unit/100/relationships/translations",
                    "related": "https://carlsource.server.com/api/entities/v1/unit/100/translations"
                }
            },
            "secuPolicy": {
                "links": {
                    "self": "https://carlsource.server.com/api/entities/v1/unit/100/relationships/secuPolicy",
                    "related": "https://carlsource.server.com/api/entities/v1/unit/100/secuPolicy"
                }
            }
        }
    },
    "links": {
        "self": "https://carlsource.server.com/api/entities/v1/unit/100?_locale=en_GB"
    },
    "meta": {
        "requestLocale": "en_GB"
    }
}

6.4.4. Le filtrage multilingue

Le filtrage a évolué en plusieurs étapes dont voici le détail.

Jusqu’en CARL Source 7.2, pour une requête comprenant un filtre tel que filter[code][EQ]=SOME_CODE :

  • La locale n’était jamais prise en compte, et la recherche se faisait uniquement sur la table principale (i.e. toujours en langue principale et jamais dans les tables de traductions).

  • La section attributes contenait les valeurs non traduites telles que stockées dans la table principale.

À partir de CARL Source 7.4, pour une requête comprenant un filtre tel que filter[code][EQ]=SOME_CODE :

  • La recherche se fait uniquement sur la table principale.

  • Si le paramètre de configuration système enableI18nEntitiesApi est coché, la section attributes contient les valeurs traduites.

  • Si le paramètre de configuration système enableI18nEntitiesApi est coché, mais si la requête inclut le paramètre _ignoreTranslations=true, alors la section attributes contient les valeurs non traduites telles que stockées dans la table principale (mode de compatibilité à la requête près).

  • Si le paramètre de configuration système enableI18nEntitiesApi est décoché, la section attributes contient les valeurs non traduites telles que stockées dans la table principale (mode de compatibilité global).

À partir de CARL Source 7.5, pour une requête comprenant un filtre tel que i18nFilter[code][EQ]=SOME_CODE :

  • La recherche se fait sur les valeurs traduites.

  • La section attributes contient les valeurs traduites.

Warning

Pour rester dans le comportement historique (avant CARL Source 7.3) sans support multilingue, on peut intervenir à deux niveaux :

  1. Au niveau global, en décochant le paramètre de configuration système enableI18nEntitiesApi.

  2. À la requête près, en ajoutant le paramètre d’URI _ignoreTranslations=true.

6.4.5. Le tri multilingue

Contrairement au filtrage, et conformément à la spécification JSON:API, le tri ne peut pas s’appuyer sur un nouveau paramètre : c’est toujours le paramètre sort qui s’en charge. De ce fait, en l’état son comportement est conforme à l’historique : il ne tient pas compte des traductions.
En revanche, un nouveau paramètre permet de faire en sorte que sort gère le multilingue : ajouter le paramètre _i18nSort=true active le tri sur l’attribut traduisible.

  • Le paramètre filter devient i18nFilter si l’on souhaite qu’il s’applique à des valeurs traduites

  • En revanche, le paramètre sort reste sort et il faut ajouter _i18nSort=true si l’on souhaite qu’il s’applique à des valeurs traduites

Exemples

Soient les données de la fonctionnalité animal, exécutées par un utilisateur français.

  • Code : A

  • Description : abeille

  • Traduction de description : bee

 

  • Code : B

  • Description : baleine

  • Traduction de description : whale

 

  • Code : C

  • Description : chien

  • Traduction de description : dog

curl -X GET /api/entities/v1/animal
  • A, abeille

  • B, baleine

  • C, chien

curl -X GET /api/entities/v1/animal?_locale=en_GB
  • A, bee

  • B, whale

  • C, dog

curl -X GET /api/entities/v1/animal?filter[description][LIKE]=h&_locale=en_GB

*

curl -X GET /api/entities/v1/animal?i18nFilter[description][LIKE]=h&_locale=en_GB
  • B, whale

  • C, chien

curl -X GET /api/entities/v1/animal?_ignoreI18n=true&_locale=enGB
  • A, abeille

  • B, baleine

  • C, chien

curl -X GET /api/entities/v1/animal?sort=description&_locale=enGB
  • A, bee

  • B, whale

  • C, dog

curl -X GET /api/entities/v1/animal?sort=description&_i18nSort=true&_locale=enGB
  • A, bee

  • C, dog

  • B, whale

6.5. Les API sortant du cas standard

6.5.1. L’API des relevés de mesure /entities/v1/measurereading

L’ajout des relevés de mesure ne peut être pris en charge par l’API standard car il comporte une particularité.
En effet, le calcul de la variation en fonction de la mesure (et inversement) est un traitement particulier qui n’entre pas dans un cas standard d’ajout d’une entité.

Une API a été réalisée spécifiquement pour l’ajout d’un relevé de mesure : se reporter au chapitre Scénario d’ajout des relevés de mesure : l’API /measure-readings pour une explication détaillée.

6.6. Interagir avec le cycle de vie

Au-delà des interactions CRUD (créer, lire, modifier, supprimer), l’API /entities permet de faire évoluer l’état des objets métier le long de leur cycle de vie.
Dans CARL Source, les objets métier les plus centraux disposent d’un cycle de vie : il s’agit d’une succession d’états reliés entre eux par des transitions.

Exemple : par défaut, à sa création, une demande d’intervention est positionnée à l’état Attente prise en compte.
À partir de cet état, différentes transitions sont disponibles, menant chacune vers un nouvel état :

  • La transition Accepter la demande d’intervention mène vers l’état Attente réalisation.

  • La transition Transférer la demande d’intervention boucle sur l’état courant Attente prise en compte.

  • La transition Refuser la demande d’intervention mène vers l’état Refusé.

  • La transition Demander un complément d’information mène vers l’état Attente information.

  • La transition Clôturer la demande mène vers l’état Soldé.

Reprenons la demande d’intervention créée précédemment.
Son identifiant est 166ee780a94-1486 et elle se trouve à l’état Attente prise en compte (correspondant à un attribut "statusCode" positionné à la valeur "REQUEST").

Si l’on cherche à consulter les données relatives à cette demande d’intervention (via la commande suivante) :

curl -X GET -H "X-CS-Access-Token: votre_access_token" https://carlsource.server.com/gmaoCS02/api/entities/v1/mr/166ee780a94-1486

On obtient en retour les informations suivantes :

{
    "data" : {
        "id" : "166ee780a94-1486",
        "type" : "mr",
        "attributes" : {
            "code" : "000005",
            "description" : "Nouvelle demande",
            "workPriority" : "HIGH",
            "statusCode" : "REQUEST"
            ...
        },
        "relationships" : {
            ...
        },
        "links" : {
            "self" : "https://carlsource.server.com/gmaoCS02/api/entities/v1/mr/166ee780a94-1486",
            "workflow-transitions" : "https://carlsource.server.com/gmaoCS02/api/entities/v1/mr/166ee780a94-1486/workflow-transitions"
        }
    }
}

La rubrique links nous fournit un lien (URL) via la propriété «workflow-transitions».
L’appel de cette URL permet d’obtenir la liste de toutes les transitions pouvant être jouées à partir de l’état courant de la demande d’intervention :

curl -X GET -H "X-CS-Access-Token: votre_access_token" https://carlsource.server.com/gmaoCS02/api/entities/v1/mr/166ee780a94-1486/workflow-transitions

La liste des transitions pouvant être conséquente, il est possible d’utiliser les capacités de filtrage évoquées plus tôt afin de restreindre la liste aux transitions qui nous intéressent.

Dans cet exemple, on souhaite jouer la transition Accepter la demande d’intervention pour que l’état de la demande d’intervention bascule à Attente réalisation : nous avons donc besoin du code correspondant à cet état "cible".
Ce code peut être obtenu par le biais de la sous-fonctionnalité Workflows d’états de CARL Source (cf. Codes des transitions et des états) : en l’occurrence, le code correspondant à l’état Attente réalisation est AWAITINGREAL.
Nous pouvons maintenant restreindre la liste des transitions à celles dont le nextStepCode vaut AWAITINGREAL :

curl -X GET -H "X-CS-Access-Token: votre_access_token" https://carlsource.server.com/gmaoCS02/api/entities/v1/mr/166ee780a94-1486/workflow-transitions?filter[nextStepCode]=AWAITINGREAL
Réponse obtenue :
HTTP/1.1 200
{
    "data" : [ {
        "id" : "M1B:com.carl.xnet.system.status.TransitionParameters",
        "type" : "workflow-transitions",
        "attributes" : {
            "nextStepCode" : "AWAITINGREAL",
            "transitionParameters" : null
        },
        "relationships" : {
            "transition" : {
                "links" : {
                    "self" : "https://carlsource.server.com/gmaoCS02/api/entities/v1/workflow-transitions/M1B:com.carl.xnet.system.status.TransitionParameters/relationships/transition",
                    "related" : "https://carlsource.server.com/gmaoCS02/api/entities/v1/workflow-transitions/M1B:com.carl.xnet.system.status.TransitionParameters/transition"
                }
            }
        },
        "links" : {
            "self" : "https://carlsource.server.com/gmaoCS02/api/entities/v1/workflow-transitions/M1B:com.carl.xnet.system.status.TransitionParameters"
        }
    },
    {
        "id" : "M1:com.carl.xnet.system.status.TransitionParameters",
        "type" : "workflow-transitions",
        "attributes" : {
            "nextStepCode" : "AWAITINGREAL",
            "transitionParameters" : null
        },
        "relationships" : {
            "transition" : {
                "links" : {
                    "self" : "https://carlsource.server.com/gmaoCS02/api/entities/v1/workflow-transitions/M1:com.carl.xnet.system.status.TransitionParameters/relationships/transition",
                    "related" : "https://carlsource.server.com/gmaoCS02/api/entities/v1/workflow-transitions/M1:com.carl.xnet.system.status.TransitionParameters/transition"
                }
            }
        },
        "links" : {
            "self" : "https://carlsource.server.com/gmaoCS02/api/entities/v1/workflow-transitions/M1:com.carl.xnet.system.status.TransitionParameters"
        }
    } ]
}

On constate dans la réponse ci-dessus que deux transitions permettent de faire passer la demande d’intervention à l’état Attente réalisation.
L’API nous donne les moyens de connaitre le détail de chaque transition via relationships.transition.links.related :

  • /api/entities/v1/workflow-transitions/M1B:com.carl.xnet.system.status.TransitionParameters/transition

  • /api/entities/v1/workflow-transitions/M1:com.carl.xnet.system.status.TransitionParameters/transition

Appel du détail de la première transition (M1B:com.carl.xnet.system.status.TransitionParameters) :

curl -X GET -H "X-CS-Access-Token: votre_access_token" https://carlsource.server.com/gmaoCS02/api/entities/v1/api/entities/v1/workflow-transitions/M1B:com.carl.xnet.system.status.TransitionParameters/transition
Réponse obtenue :
HTTP/1.1 200
{
    "data" : {
        "id" : "M1B",
        "type" : "mrreqawaintingrealtransition",
        "attributes" : {
            "ordering" : 1,
            "description" : "Accepter la DI",
            "automatic" : true,
            "pageId" : null,
            "transitionFamily" : null
        },
        "relationships" : {
            "msgTemplate" : {
                "links" : {
                    "self" : "https://carlsource.server.com/gmaoCS02/api/entities/v1/mrreqawaintingrealtransition/M1B/relationships/msgTemplate",
                    "related" : "https://carlsource.server.com/gmaoCS02/api/entities/v1/mrreqawaintingrealtransition/M1B/msgTemplate"
                }
            },
            "nextStep" : {
                "links" : {
                    "self" : "https://carlsource.server.com/gmaoCS02/api/entities/v1/mrreqawaintingrealtransition/M1B/relationships/nextStep",
                    "related" : "https://carlsource.server.com/gmaoCS02/api/entities/v1/mrreqawaintingrealtransition/M1B/nextStep"
                }
            },
            "step" : {
                "links" : {
                    "self" : "https://carlsource.server.com/gmaoCS02/api/entities/v1/mrreqawaintingrealtransition/M1B/relationships/step",
                    "related" : "https://carlsource.server.com/gmaoCS02/api/entities/v1/mrreqawaintingrealtransition/M1B/step"
                }
            }
        },
        "links" : {
            "self" : "https://carlsource.server.com/gmaoCS02/api/entities/v1/mrreqawaintingrealtransition/M1B"
        }
    }
}

Le détail de la transition nous indique que celle-ci est automatique ("automatic" : true) : elle peut donc être appelée sans paramètre.
=> Appliquons cette transition à notre demande d’intervention.

Pour réaliser cette transition d’état, il est nécessaire d’effectuer un POST de la transition sur l’URL de workflow-transitions de notre demande d’intervention :

curl -X POST -H "X-CS-Access-Token: votre_access_token" -H "Content-Type: application/vnd.api+json, Accept: application/vnd.api+json" \
     -d '{
        "data" : {
            "id" : "M1B:com.carl.xnet.system.status.TransitionParameters",
            "type" : "workflow-transitions",
            "attributes" : {
                "nextStepCode" : "AWAITINGREAL",
                "transitionParameters" : null
            },
            "relationships" : {
                "transition" : {
                    "links" : {
                        "self" : "https://carlsource.server.com/gmaoCS02/api/entities/v1/workflow-transitions/M1B:com.carl.xnet.system.status.TransitionParameters/relationships/transition",
                        "related" : "https://carlsource.server.com/gmaoCS02/api/entities/v1/workflow-transitions/M1B:com.carl.xnet.system.status.TransitionParameters/transition"
                    }
                }
            },
            "links" : {
                "self" : "https://carlsource.server.com/gmaoCS02/api/entities/v1/workflow-transitions/M1B:com.carl.xnet.system.status.TransitionParameters"
            }
        }
    }' \
    https://carlsource.server.com/gmaoCS02/api/entities/v1/mr/166ee780a94-1486/workflow-transitions

Nous ne nous intéresserons pas au JSON retourné (il s’agit uniquement du détail de la transition jouée).
En revanche, si l’on demande à nouveau le détail de la demande d’intervention, on peut constater que son attribut statusCode est passé de REQUEST à AWAITINGREAL :

curl -X GET -H "X-CS-Access-Token: votre_access_token" https://carlsource.server.com/gmaoCS02/api/entities/v1/mr/166ee780a94-1486?fields[mr]=code,description,statusCode
Réponse obtenue :
HTTP/1.1 200
{
    "data" : {
        "id" : "166ee780a94-1486",
        "type" : "mr",
        "attributes" : {
            "code" : "000001",
            "description" : "Nouvelle demande urgente",
            "statusCode" : "AWAITINGREAL"
        },
        "links" : {
            "self" : "https://carlsource.server.com/gmaoCS02/api/entities/v1/mr/166ee780a94-1486",
            "workflow-transitions" : "https://carlsource.server.com/gmaoCS02/api/entities/v1/mr/166ee780a94-1486/workflow-transitions"
        }
    }
}

6.7. Le dictionnaire CARL Source

L’API /entities de CARL Source est autodescriptive : les objets JSON retournés dans la réponse HTTP incluent des URL directement invocables afin de pouvoir "naviguer" dans un graphe d’objet tout en le découvrant.
Il y a toutefois des limites : il est nécessaire de connaitre le code du type d’objet que l’on souhaite manipuler (mr dans nos exemples).
De même, s’il est possible de découvrir les transitions disponibles à partir de l’état courant d’un objet, les codes des états dans lesquels un objet peut se trouver ne sont pas fournis par l’API.

Ces codes sont disponibles depuis la fonctionnalité Dictionnaire de CARL Source, et sa sous-fonctionnalité Workflows d’états (menu Système).

6.7.1. Codes des types d’objets

Les objets du dictionnaire décrivent tous les objets de CARL Source, quels que soient leur type, mais tous ne sont pas manipulables par l’API /entities : seuls sont manipulables les objets de catégorie Entité (objectType = BEAN) - cela représente plus de 500 objets.

Note

Quelques rares exceptions sont à noter - certains objets particulièrement techniques (propres au fonctionnement interne de CARL Source) sont :

  • soit exclus des objets manipulables,

  • soit accessibles uniquement en lecture seule (cf. la valeur de l’attribut apiRestriction sur les objets du dictionnaire).

À partir de ces objets, retrouver le code du type d’objet à utiliser avec l’API s’avère très simple : il s’agit de la valeur du code de l’objet, en minuscule.

Quelques exemples :

  • Pour l’objet du dictionnaire Intervention, le code vaut WO : le code à utiliser dans l’API est donc wo.
    => Exemple : https://carlsource.server.com/gmaoCS02/api/entities/v1/wo liste les interventions définies dans CARL Source.

  • Pour l’objet du dictionnaire Client, le code vaut CUSTOMER : le code à utiliser dans l’API est donc customer.
    => Exemple : https://carlsource.server.com/gmaoCS02/api/entities/v1/customer liste les clients définis dans CARL Source.

  • Pour l’objet du dictionnaire Centre de coût, le code vaut COSTCENTER : le code à utiliser dans l’API est donc costcenter.
    => Exemple : https://carlsource.server.com/gmaoCS02/api/entities/v1/costcenter liste les centres de coût définis dans CARL Source.

  • Pour l’objet du dictionnaire Intervenant, le code vaut TECHNICIAN : le code à utiliser dans l’API est donc technician.
    => Exemple : https://carlsource.server.com/gmaoCS02/api/entities/v1/technician liste les intervenants définis dans CARL Source.

  • etc.

6.7.2. Codes des transitions et des états

Nous avons vu que les transitions d’un objet entre deux états (via la propriété workflow-transitions) pouvaient facilement être découvertes via les URL retournées par l’API.
En revanche, les différents états possibles pour un objet CARL Source ne peuvent pas être découverts de la même manière.
Afin d’avoir une vue de ces différents états, il est nécessaire de consulter la sous-fonctionnalité du Workflows d’états depuis le dictionnaire CARL Source.

Cela permet par exemple de saisir qu’une demande d’intervention dont l’attribut statusCode vaut REQUEST :

  • est en Attente de prise en compte,

  • que l’état suivant le plus probable est AWAITINGREAL (Attente réalisation),

  • et que l’on peut parvenir à ce nouvel état en appliquant la transition Accepter la DI.

7. Scénario IIOT : Faire interagir les objets connectés avec CARL Source

Ce chapitre explique comment faire interagir les objets connectés avec CARL Source.

Note

Dans les requêtes qui suivent, les valeurs en rouge sont à modifier en fonction de votre configuration ou de vos besoins.
Les requêtes ont été définies sur la base d’une Authentification HTTP-BASIC. Pour une authentification par jeton, il sera nécessaire de les adapter en suivant la procédure d'Authentification par jeton.

7.1. Contexte

7.1.1. L’appairage entre un capteur et un point de mesure

Un capteur peut être associé à un ou plusieurs points de mesure CARL Source. Pour cela, une entité a été créée sous le nom de SensorPairing.
Cette entité représente l’appairage entre un capteur et un point de mesure. Cela signifie donc qu’un appairage doit avoir 1 point de mesure, et un point de mesure peut avoir 0 ou 1 appairage.
L’ensemble des appairages représente ainsi les différentes associations d’un capteur aux points de mesure de CARL Source.

L’entité SensorPairing contient les attributs suivants :

Attribut Type Obligatoire ? Description

description

Alphanumérique

Non

Description

databaseName

Alphanumérique

Oui

Nom de la base de données dans laquelle le capteur est géré

measurement

Alphanumérique

Oui

Nom de la mesure dans laquelle le capteur est géré

sensorTags

Liste de SensorTag

Oui

Liste des tags

field

Alphanumérique

Oui

Mesure

dateOfPairing

Date

Oui

Date d’appairage

measurePoint

MeasurePoint

Oui

Point de mesure associé

7.1.2. Les tags associés à un appairage

Un appairage doit avoir 1 ou plusieurs tags. Une entité SensorTag a donc été créée pour remplir ce rôle.
Cette entité est constituée d’une combinaison clé/valeur et est associée à un appairage. Elle contient les attributs suivants :

Attribut Type Obligatoire ? Description

tagKey

Alphanumérique

Oui

Clé

tagValue

Alphanumérique

Oui

Valeur

sensorPairing

SensorPairing

Oui

Appairage associé

Par défaut, lors de la création d’un appairage, deux tags sont créés automatiquement. Ceux-ci représentent le point de mesure et l’équipement associés :

Clé Valeur

MEASURE_POINT

id CARL Source du point de mesure

EQUIPMENT

id CARL Source de l’équipement

7.2. Créer, lire, modifier et supprimer un appairage de capteur

7.2.1. Création

Requête POST créant un appairage entre un capteur et un point de mesure
curl -X POST -H "X-CS-Access-Token: votre_access_token" -H "Content-Type: application/vnd.api+json" \
     -d '{
        "data": {
            "type": "sensorpairing",
            "attributes": {
                "description": "mon premier appairage",
                "databaseName": "nom de la base",
                "measurement": "nom de la mesure",
                "field": "mesure",
                "dateOfPairing": "2019-12-10T19:10:00.000+02:00"
            },
            "relationships": {
                "measurePoint": {
                    "data": {
                        "type": "measurepoint",
                        "id": "measurepoint_id"
                    }
                }
            }
        }
     }' \
     https://carlsource.server.com/gmaoCS02/api/entities/v1/sensorpairing

Le JSON décrivant l’appairage venant d’être créé est reçu en réponse à cette requête, avec un code HTTP 201.

Note

Les deux tags MEASURE_POINT et EQUIPMENT ont également été créés.

7.2.2. Lecture

7.2.2.1. Lister tous les appairages
Requête GET récupérant la liste de tous les appairages
curl -X GET -H "X-CS-Access-Token: votre_access_token" https://carlsource.server.com/gmaoCS02/api/entities/v1/sensorpairing/
7.2.2.2. Lister tous les appairages entre un capteur et ses points de mesure
Requête GET récupérant la liste de tous les appairages d’un capteur (récupère uniquement l’id des appairages)
curl -X GET -H "X-CS-Access-Token: votre_access_token" https://carlsource.server.com/gmaoCS02/api/entities/v1/sensortag?fields=sensorPairing&filter[tagKey]=SENSOR&filter[tagValue]=sensor_name
Requête GET récupérant la liste de tous les appairages d’un capteur (en incluant dans le résultat la totalité des attributs de chaque appairage)
curl -X GET -H "X-CS-Access-Token: votre_access_token" https://carlsource.server.com/gmaoCS02/api/entities/v1/sensortag?include=sensorPairing&filter[tagKey]=SENSOR&filter[tagValue]=sensor_name
7.2.2.3. Lister tous les points de mesure d’un capteur

Ici, le point de mesure n’est pas directement lié au tag : il faut l’inclure à la requête en passant par l’appairage.
Dans le résultat obtenu la liste des points de mesure du capteur se situera donc dans la balise "included": [...].

Requête GET récupérant la liste de tous points de mesure d’un capteur
curl -X GET -H "X-CS-Access-Token: votre_access_token" https://carlsource.server.com/gmaoCS02/api/entities/v1/sensortag?include=sensorPairing.measurePoint&filter[tagKey]=SENSOR&filter[tagValue]=intensity
7.2.2.4. Récupérer le détail d’un appairage
Requête GET récupérant un appairage existant
curl -X GET -H "X-CS-Access-Token: votre_access_token" https://carlsource.server.com/gmaoCS02/api/entities/v1/sensorpairing/pairing_id
7.2.2.5. Récupérer le point de mesure d’un appairage
Requête GET récupérant le point de mesure d’un appairage
curl -X GET -H "X-CS-Access-Token: votre_access_token" https://carlsource.server.com/gmaoCS02/api/entities/v1/sensorpairing/pairing_id/relationships/measurePoint

7.2.3. Modification

La syntaxe est proche de celle de la création, il suffit de faire pointer l’url sur l’id de l’appairage et d’utiliser uniquement les attributs/relations à modifier.
Exemple :

Requête PATCH modifiant un appairage existant
curl -X PATCH -H "X-CS-Access-Token: votre_access_token" -H "Content-Type: application/vnd.api+json" \
     -d '{
        "data": {
            "type": "sensorpairing",
            "attributes": {
                "description": "mon premier appairage modifié",
                "field": "mesure2",
                "dateOfPairing": "2019-12-10T20:10:00.000+02:00"
            }
        }
     }' \
     https://carlsource.server.com/gmaoCS02/api/entities/v1/sensorpairing/pairing_id

7.2.4. Suppression

Requête DELETE supprimant un appairage existant
curl -X DELETE -H "X-CS-Access-Token: votre_access_token" https://carlsource.server.com/gmaoCS02/api/entities/v1/sensorpairing/pairing_id

7.3. Créer, lire, modifier et supprimer un tag associé à un appairage de capteur

7.3.1. Création

Requête POST créant un tag sur un appairage
curl -X POST -H "X-CS-Access-Token: votre_access_token" -H "Content-Type: application/vnd.api+json" \
     -d '{
        "data": {
            "type": "sensortag",
            "attributes": {
              "tagKey": "SENSOR",
              "tagValue": "engine_temp"
            },
            "relationships": {
                "sensorPairing": {
                    "data": {
                        "type": "sensorpairing",
                        "id": "pairing_id"
                    }
                }
            }
        }
     }' \
     https://carlsource.server.com/gmaoCS02/api/entities/v1/sensortag

Le JSON décrivant le tag venant d’être créé est reçu en réponse à cette requête, avec un code HTTP 201.

7.3.2. Lecture

7.3.2.1. Lister tous les tags
Requête GET récupérant la liste de tous les tags
curl -X GET -H "X-CS-Access-Token: votre_access_token" https://carlsource.server.com/gmaoCS02/api/entities/v1/sensortag/
7.3.2.2. Lister tous les tags filtrés par clé
Requête GET récupérant la liste de tous les tags filtrés par la clé MEASURE_POINT
curl -X GET -H "X-CS-Access-Token: votre_access_token" https://carlsource.server.com/gmaoCS02/api/entities/v1/sensortag?fields=tagKey,tagValue,sensorPairing&filter[tagKey]=MEASURE_POINT
7.3.2.3. Lister tous les tags d’un appairage
Requête GET récupérant la liste de tous les tags d’un appairage
curl -X GET -H "X-CS-Access-Token: votre_access_token" https://carlsource.server.com/gmaoCS02/api/entities/v1/sensorpairing/pairing_id/sensorTags?fields=tagKey,tagValue
7.3.2.4. Récupérer le détail d’un tag
Requête GET récupérant le tag existant
curl -X GET -H "X-CS-Access-Token: votre_access_token" https://carlsource.server.com/gmaoCS02/api/entities/v1/sensortag/tag_id

7.3.3. Modification

La syntaxe est proche de celle de la création, il suffit de faire pointer l’url sur l’id du tag et d’utiliser uniquement les attributs/relations à modifier.
Exemple :

Requête PATCH modifiant un tag existant
curl -X PATCH -H "X-CS-Access-Token: votre_access_token" -H "Content-Type: application/vnd.api+json" \
     -d '{
        "data": {
            "type": "sensortag",
            "attributes": {
              "tagValue": "intensity"
            }
        }
     }' \
     https://carlsource.server.com/gmaoCS02/api/entities/v1/sensortag/tag_id

7.3.4. Suppression

Requête DELETE supprimant un tag existant
curl -X DELETE -H "X-CS-Access-Token: votre_access_token" https://carlsource.server.com/gmaoCS02/api/entities/v1/sensortag/tag_id

7.4. Créer et lire un relevé de mesure via un appairage de capteur

7.4.1. Création

Requête POST créant un relevé de mesure depuis un appairage
curl -X POST -H "X-CS-Access-Token: votre_access_token" -H "Content-Type: application/vnd.api+json" \
     -d '{
        "data": {
            "measure": 3, OU "variation": 3,
            "measuredAt": "2023-04-17T15:07:06",
            "sensorPairing": {
                "id": "pairing_id"
            }
        }
     }' \
     https://carlsource.server.com/gmaoCS02/api/measure-readings/v1/add

Le JSON décrivant l’appairage venant d’être créé est reçu en réponse à cette requête, avec un code HTTP 201.

Note

La valeur de l’attribut "Origine" est fixée à 3 (IOT).
La valeur de l’attribut "Description" reprend la concaténation des tags de l’appairage.
Exemple : MEASURE_POINT=measurepoint_id;EQUIPMENT=equipment_id;SENSOR=intensity;...

Les deux tags MEASURE_POINT et EQUIPMENT ont également été créés.

Tip

Il est également possible d’ajouter une liste de relevés de mesure.
Pour une explication détaillée : se reporter au chapitre Scénario d’ajout des relevés de mesure : l’API /measure-readings.

7.4.2. Lecture

7.4.2.1. Lister tous les relevés de mesure d’un capteur

Dans l’exemple ci-dessous, nous listons tous les relevés de mesure du capteur "intensity".
La variable "fields" affiche uniquement les champs demandés pour optimiser le résultat aux attributs utiles, mais elle peut être retirée de la requête.

Requête GET récupérant la liste de tous les relevés de mesure d’un capteur
curl -X GET -H "X-CS-Access-Token: votre_access_token" https://carlsource.server.com/gmaoCS02/api/entities/v1/measurereading?fields=measure,variation,dateMeasure,description,measurePoint,sensorPairing&filter[measurereading][description][LIKE]=SENSOR=intensity
Note

Cette requête peut être adaptée afin de filtrer les relevés de mesure en fonction des tags d’appairage concaténés dans la description des relevés.
Pour cela, il suffit de remplacer SENSOR=intensity par MEASURE_POINT=measurepoint_id, ou encore EQUIPMENT=equipment_id, etc.

7.4.2.2. Lister tous les relevés de mesure d’un appairage
Requête GET récupérant la liste de tous les relevés de mesure d’un appairage
curl -X GET -H "X-CS-Access-Token: votre_access_token" https://carlsource.server.com/gmaoCS02/api/entities/v1/measurereading?filter[sensorPairing.id]=pairing_id
7.4.2.3. Lister tous les relevés de mesure d’un point de mesure
Requête GET récupérant la liste de tous les relevés de mesure d’un point de mesure
curl -X GET -H "X-CS-Access-Token: votre_access_token" https://carlsource.server.com/gmaoCS02/api/entities/v1/measurereading?filter[measurePoint.id]=measurepoint_id
7.4.2.4. Récupérer le détail d’un relevé de mesure
Requête GET récupérant le relevé de mesure existant
curl -X GET -H "X-CS-Access-Token: votre_access_token" https://carlsource.server.com/gmaoCS02/api/entities/v1/measurereading/measurereading_id

8. Scénario d’utilisation des documents liés : l’API /ui/v1/documents

L’API /ui/v1/documents a été créée en premier lieu pour être utilisée par les IHM de l’application, d’où son emplacement dans /ui/v1.
Elle peut néanmoins être utilisée dans un contexte hors IHM par une application externe.

8.1. Modèle de données

8.1.1. Nom de classe Java™ des entités

Contrairement aux APIs génériques de type JSON:API qui permettent de manipuler les entités, cette API nécessite que l’on précise directement le nom de la classe Java™ du type d’entité sur laquelle on veut manipuler les documents.
Pour obtenir ce nom de classe de façon simple vous pouvez interroger l’application via un appel JSON-API.

Exemple pour obtenir le nom de classe Java™ pour l’entité Intervention dont le code est WO
curl -X GET -H "X-CS-Access-Token: votre_access_token" \
    https://carlsource.server.com/gmaoCS02/api/entities/v1/objectinfo?"filter[code]=WO&fields=typeName"
Réponse obtenue
{
  "data": [
    {
      "id": "WO",
      "type": "objectinfo",
      "links": {
        "self": "https://carlsource.server.com/gmaoCS02/api/entities/v1/objectinfo/WO"
      },
      "attributes": {
        "typeName": "com.carl.xnet.works.backend.bean.WOBean"
      }
    }
  ],
  "links": {
    "self": "code=WO&fields=typeName"
  }
}

8.1.2. Types de documents liés

Dans l’application CARL Source, les documents liés à une entité sont classés par type de document : un contrat, un schéma technique, une icône, un fond de plan de bâtiment. Le type n’est pas un type de format de fichier (PNG, JPEG, PDF, Word, etc.) mais une catégorie liée à leur usage.

Ces types de documents sont accessibles depuis la fonctionnalité "Type de documents" du module "Système". C’est le code du type de document qui est utilisé dans l’API des documents liés.

8.2. Upload (téléversement) d’un document lié

L’API /ui/v1/documents/entity/upload/<entity-class-name>/<entity-id> permet de téléverser un nouveau document et de le lier à l’entité dont on donne le type (nom de classe Java™) et l’identifiant. Le contenu de la requête est au format multipart/form-data, identique à ce qui est utilisé par un navigateur pour envoyer un fichier.

Exemple pour ajouter un document PDF à l’intervention d’identifiant 17c30872770-7c :
curl -X POST -H "X-CS-Access-Token: votre_access_token" \
    -F "type=DOC" \
    -F "description=Nouveau document" \
    -F "file=@NouveauDoc.pdf" \
    https://carlsource.server.com/gmaoCS02/api/ui/v1/documents/entity/upload/com.carl.xnet.works.backend.bean.WOBean/17c30872770-7c
Réponse obtenue
{
    "data": [
        {
            "type": "documents",
            "id": "17c30872770-3336",
            "attributes": {
                "fileName": "NouveauDoc.pdf",
                "code": "DOC-00005",
                "description": "Nouveau document",
                "type": "DOC"
            },
            "links": {
                "download": "https://carlsource.server.com/gmaoCS02/download/servlet/NouveauDoc.pdf?docid\u003d17c30872770-3337\u0026version\u003d0"
            }
        }
    ]
}

Paramètres supplémentaires :

  • code (facultatif) : le code du document lié qui sera créé. Par défaut c’est la codification automatique qui est utilisée, mais il est possible de le définir. Exemple : code=CONTRAT-0001.

Important

Le lien download retourné par l’API ne doit pas être utilisé actuellement pour le téléchargement du document.
Il retourne une valeur dépréciée utilisée uniquement par les IHM de CARL Source et sera remplacé à terme par un lien différent.
Pour effectuer le téléchargement du document lié, il faut utiliser l’API de téléchargement précisée ci-après.

8.3. Download (téléchargement) d’un document lié

Pour télécharger un document lié, il est nécessaire d’utiliser l’API /ui/v1/documents/download/<document-id>.

Exemple pour télécharger le document ajouté ci-dessus et dont l’identifiant est 17c30872770-3336
curl -X GET -H "X-CS-Access-Token: votre_access_token" --output "doc.pdf" \
    https://carlsource.server.com/gmaoCS02/api/ui/v1/documents/download/17c30872770-3336

8.4. Lister les documents liés à une entité

Pour récupérer la liste des documents liés à une entité, on utilise l’API /ui/v1/documents/entity/<entity-class-name>/<entity-id>.

Exemple pour lister les documents liés à l’intervention d’identifiant 17c30872770-7c
curl -X GET -H "X-CS-Access-Token: votre_access_token" \
    https://carlsource.server.com/gmaoCS02/api/ui/v1/documents/entity/com.carl.xnet.works.backend.bean.WOBean/17c30872770-7c
Réponse obtenue
{
    "data": [
        {
            "type": "documents",
            "id": "17c30872770-3ca5",
            "attributes": {
                "fileName": "Photo.jpg",
                "code": "DOC-00008",
                "description": "Photo.jpg",
                "type": "IMG"
            },
            "links": {
                "download": "https://carlsource.server.com/gmaoCS02/download/servlet/Photo.jpg?..."
            }
        },
        {
            "type": "documents",
            "id": "17c30872770-3ca4",
            "attributes": {
                "fileName": "Manuel technique.pdf",
                "code": "DOC-00007",
                "description": "Manuel technique.pdf",
                "type": "PLAN"
            },
            "links": {
                "download": "https://carlsource.server.com/gmaoCS02/download/servlet/Manuel+technique.pdf?..."
            }
        },
        {
            "type": "documents",
            "id": "17c30872770-3ca6",
            "attributes": {
                "fileName": "Contrat.pdf",
                "code": "DOC-00009",
                "description": "Contrat.pdf",
                "type": "DOC"
            },
            "links": {
                "download": "https://carlsource.server.com/gmaoCS02/download/servlet/Contrat.pdf?..."
            }
        }
    ],
    "meta": {
        "isEntityDocumentable": true,
        "numberOfDocumentsInWidget": 3,
        "hasMoreResults": false,
        "canUploadDocuments": true,
        "canReadDocuments": true
    },
    "included": [
        {
            "type": "document-type",
            "id": "DOC",
            "attributes": {
                "code": "DOC",
                "description": "Textes, contrats"
            }
        },
        ...
    ]
}

La réponse fournit également (via les rubriques meta et included) un certain nombre d’informations supplémentaires utiles pour une IHM :

  • l’entité supporte les documents liés,

  • l’utilisateur peut téléverser ou télécharger des documents liés pour cette entité,

  • ainsi que la liste des types de documents avec leurs libellés.

Important

Comme précisé plus haut pour l’API d’upload (téléversement) d’un document lié, il ne faut pas tenir compte du lien download et ne pas l’utiliser car ce dernier est amené à évoluer.

Paramètres de filtre supplémentaires :

  • type (facultatif) : une liste de types de documents séparés par des virgules. Exemple : type=IMG,ICON.

  • pictureType (facultatif) : un booléen permettant de filtrer les résultats en fonction de la caractérisation des types de documents comme étant (ou non) des images (cf. la fonctionnalité "Type de documents" du module "Système"). Exemple : pictureType=true.

9. Scénario d’import d’équipements : l’API /import-equipment

L’API /import-equipment permet d’importer en masse des équipements dans CARL Source, puis de les mettre à jour après un import initial.
Cette API ayant un lien avec les fonctions d’import d’équipements pour les cartes, plans de bâtiments, puis pour le BIM, elle est située avec les APIs REST dédiées au SIG : /gis/v1/import-equipment.

L’import se réalise en deux temps :

  1. Utilisation des APIs REST pour importer les descriptions des équipements dans la table de référence : CSGI_IMP_EQUIPMENT;

  2. Utilisation du traitement d’import d’équipements GISIMPORTJOB, dans la fonctionnalité CARL Source des traitements automatiques.

9.1. Droit d’utilisation de l’API

L’utilisation de cette API nécessite que l’utilisateur avec lequel est invoquée l’API dispose des droits de profil requis. L’API est contrôlée par le droit de profil : Equipements / Import d’équipements.

9.2. Insérer, modifier, ou supprimer des descriptions d’équipements dans la table d’import

L’API /gis/v1/import-equipment/apply-batch-operations permet de modifier en lot la table d’import.

Cette API permet d’envoyer, dans une requête POST au format JSON (Media-Type: application/json), une liste d’opérations à réaliser sur la table d’import.

Exemple de contenu envoyé dans le corps de la requête POST
[
    {
        "action": "CREATE",
        "equipment": {"id":"1", "structureId":"MATERIAL", "projectGuid":"18"}
    },
    {
        "action": "DELETE",
        "equipment": {"id":"2"}
    }
]

Les actions disponibles pour la description d’équipement sont les suivantes :

Action Description

CREATE

La ligne d’import est créée (SYNCH_DATE = now) avec les valeurs fournies. La version est mise à 0.

UPDATE

La ligne d’import est mise à jour (SYNCH_DATE = now) avec les valeurs fournies. La version est incrémentée.

SYNC

La ligne d’import est marquée comme étant mise à jour (SYNCH_DATE = now). La version est incrémentée.

DELETE

La ligne d’import est marquée pour suppression (SYNCH_DELETE = true). La version est incrémentée.

Les champs correspondants pour la description d’équipement sont les suivants :

Champs Type (Format ou Longueur) Opération Description

id

Alphanumérique (33)

CREATE, UPDATE, SYNC, DELETE

Identifiant de l’équipement dans la table d’import

code

Alphanumérique (20)

CREATE

Code de l’équipement à importer (identifiant métier)

projectGuid

Alphanumérique (40)

CREATE

Identifiant (GUID) du projet BIM

description

Alphanumérique (60)

CREATE, UPDATE

Description de l’équipement à importer (libellé)

structureId

Alphanumérique (40)

CREATE, UPDATE

Identifiant du type de structure

parentId

Alphanumérique (33)

CREATE, UPDATE

Identifiant de l’équipement parent dans la table d’import

ifcClass

Alphanumérique (255)

CREATE, UPDATE

Classe IFC

attributes

Alphanumérique (JSON)

CREATE, UPDATE

Attributs d’objet génériques (par exemple issus de l’IFC)

patternCode

Alphanumérique (20)

CREATE, UPDATE

Code d’un article ou d’un modèle pour l’équipement

capacity, levelNumber

Numérique (nombre entier)

CREATE, UPDATE

Capacité d’accueil, Numéro d’étage

sul, area, groundArea

Numérique

CREATE, UPDATE

Surface utile, Surface de plancher, Surface de terrain

use, erpClass, erpCategory

Alphanumérique (255)

CREATE, UPDATE

Usage, Classification ERP, Catégorie ERP

pathDwf, pathDwg

Alphanumérique (255)

CREATE, UPDATE

Chemin relatif du DWF dans la bibliothèque, Nom du DWG d’origine

geom

Alphanumérique (EWKT)

CREATE, UPDATE

Géométrie (point, ligne, ou polygone)

xtrabool01, xtrabool02, xtrabool03

Booléen

CREATE, UPDATE

Champs booléens libres

xtradate01, xtradate02, xtradate03

Alphanumérique (date-heure ISO8601)

CREATE, UPDATE

Champs dates-heures libres

xtranum01, xtranum02, xtranum03

Numérique

CREATE, UPDATE

Champs numériques libres

xtratxt01, xtratxt02, xtratxt03, xtratxt04, xtratxt05, xtratxt06, xtratxt07, xtratxt08, xtratxt09, xtratxt10

Alphanumérique (255)

CREATE, UPDATE

Champs textes libres

Warning

L’usage de cette API nécessite que l’utilisateur dispose de tous les droits de Création, Modification, Suppression dans le droit de profil : Equipements / Import d’équipements.
Même si vous ne souhaitez réaliser qu’un seul type d’opération, il est nécessaire que l’utilisateur dispose bien des 3 droits pour que l’accès à l’API soit autorisé.

Requête POST insérant la description d’un équipement dans la table d’import
curl -X POST -H "X-CS-Access-Token: votre_access_token" -H "Content-Type: application/json"  --data-binary "@path/to/file" https://carlsource.server.com/gmaoCS02/api/gis/v1/import-equipment/apply-batch-operations
Exemple de contenu du fichier JSON
[
    {
        "action": "CREATE",
        "equipment": {
            "id":"1254",
            "code":"B2",
            "description":"Bat 2",
            "structureId":"BUILDING",
            "ifcClass":"IFCBUILDING",
            "projectGuid":"GUID2",
            "area":1200,
            "attributes":"{attr1:0}"
        }
    },
    {
        "action": "UPDATE",
        "equipment": {
            "id":"125",
            "description":"Bat 1 - new description",
            "structureId":"BUILDING",
            "area":1750
        }
    },
    {
        "action": "SYNC",
        "equipment": {
            "id":"12"
        }
    },
    {
        "action": "DELETE",
        "equipment": {
            "id":"123"
        }
    }
]
Important

Une fois la requête exécutée avec succès, il est nécessaire de lancer dans CARL Source le traitement d’import d’équipements GISIMPORTJOB à partir de la fonctionnalité "Traitements automatiques".

9.3. Récupérer les descriptions des équipements déjà présents dans la table d’import

L’API /gis/v1/import-equipment/stream-equipments/{bimprojectguid} permet de récupérer toutes les lignes de la table d’import associées à un projet référencé par son bimprojectguid.

Le résultat est retourné au format ndjson (Media-Type: application/x-ndjson) : chaque enregistrement est converti au format JSON sur une seule ligne, et chaque ligne est séparée par le caractère : \n.

Requête GET récupérant le contenu de la table d’import pour le projet GUID1
curl -X GET -H "X-CS-Access-Token: votre_access_token" https://carlsource.server.com/gmaoCS02/api/gis/v1/import-equipment/stream-equipments/GUID1
Réponse obtenue
HTTP/1.1 200

{"id": "1","code": "B1","description": "New building","area": 1200.0,"structureId": "BUILDING","attributes": "{attr1:0}","ifcClass": "IFCBUILDING"}
{"id": "2","code": "B2","description": "Building 2","area": 900.0,"structureId": "BUILDING","attributes": "{attr1:0}","ifcClass": "IFCBUILDING"}
Warning

L’usage de cette API nécessite que l’utilisateur dispose du droit de Lecture dans le droit de profil : Equipements / Import d’équipements.

10. Scénario d’utilisation des indicateurs : l’API /ui/v1/indicators

L’API /ui/v1/indicators permet de récupérer la valeur d’un indicateur tout en permettant de faire varier les valeurs des critères de cet indicateur.

10.1. Création d’un indicateur

Pour être utilisable, cette API nécessite la création d’un indicateur. Il est possible de créer aussi bien un indicateur de type filtre que de type requête. A noter qu’il sera possible de faire varier la valeur des critères sur un indicateur de type filtre.

Le filtre peut être créé depuis un écran de recherche de CARL Source (éventuellement complété d’un filtre avancé) en utilisant l’action Transformer en indicateur.

Dans la suite de ce scénario, on crée un indicateur qui s’appuie sur le bean de recherche MRSELBean. Cet indicateur comporte un critère de filtre sur le statut (qui fait partie du bean de recherche) ainsi que deux critères personnalisés : un premier sur le champ xtraTxt01 et un autre sur le champ externalEntityId.
A noter qu’il est possible de modifier la description du filtre (qui correspondra à la valeur utilisée pour identifier le filtre dans les requêtes API) dans l’écran d’édition des filtres avancés. Mais il n’est pas possible ensuite de modifier cette description dans l’écran d’édition de l’indicateur.

10.2. Récupération des informations sur l’indicateur

Cette partie s’appuie sur les API des entités au format JSON:API en utilisant le type indicator.
Ici, on récupère les informations sur l’indicateur en partant de son code et en incluant également ses critères :

curl -X GET -H "X-CS-Access-Token: votre_access_token" \
    https://carlsource.server.com/gmaoCS02/api/entities/v1/indicator?include=criteria&filter[code]=IND_MR_CUSTOM
Réponse obtenue (les parties "links", "relationships", ainsi que certains attributs sont exclus de cet exemple par souci de brièveté) :
{
  "data": [
    {
      "id": "17c57530346-f01",
      "type": "indicator",
      "attributes": {
        "code": "IND_MR_CUSTOM",
        "description": "Texte pour IND_MR_CUSTOM",
        "type": "FILTER",
        "targetForm": "MR_SELId",
        "dataBean": "com.carl.xnet.works.backend.bean.MRBean",
        "searchBean": "com.carl.xnet.works.backend.search.MRSELBean"
      }
    }
  ],
  "included": [
    {
      "id": "17c57530346-dee",
      "type": "indicatorcriterion",
      "attributes": {
        "criterion": "status",
        "description": "status",
        "criterionValue": "[REQUEST,WAITINFO,AWAITINGREAL]",
      }
    },
    {
      "id": "17c57530346-def",
      "type": "indicatorcriterion",
      "attributes": {
        "description": "xtraTxt01",
        "criterionValue": "123456",
        "operator": 6,
        "property": "xtraTxt01"
      }
    },
    {
      "id": "17c57530346-df1",
      "type": "indicatorcriterion",
      "attributes": {
        "description": "externalEntityId",
        "criterionValue": "12",
        "operator": 6,
        "property": "eqpt.externalEntityId",
      }
    }
  ]
}

10.3. Récupération de la valeur de cet indicateur avec les critères par défaut

L’appel suivant permet de récupérer la valeur courante de l’indicateur sans modifier les valeurs des critères de l’indicateur.
A noter qu’un recalcul est forcé à chaque appel (même si l’indicateur a une information de rafraîchissement différente de 0).

curl -X POST -i -H "X-CS-Access-Token: votre_access_token" -H "Content-Type: application/vnd.api+json" \
-d '{
    "code": "IND_MR_CUSTOM"
    }' \
https://carlsource.server.com/gmaoCS02/api/ui/v1/indicators/values
Réponse obtenue :
{
  "data": [
    {
      "type": "com.carl.xnet.analyse.backend.bean.indicator",
      // l’identifiant est retourné, que l’on passe le code ou l’identifiant en paramètre
      "id": "17c57530346-f01",
      "attributes": {
        "values": [
          {
            "value": 42.0
          }
        ]
      }
    }
  ]
}
Note

Il est possible de passer l’identifiant de l’indicateur au lieu de son code en remplaçant le paramètre code par id.

10.4. Récupération de la valeur de cet indicateur avec un critère modifié

On peut ensuite modifier la valeur d’un critère de filtre (ici : externalEntityId).
Dans l’exemple suivant, on passe deux valeurs différentes dans le même appel :

curl -X POST -i -H "X-CS-Access-Token: votre_access_token" -H "Content-Type: application/vnd.api+json" \
-d '{
    "code": "IND_MR_CUSTOM",
    "filters":[
    {
        "filterId": "1",
        "criteria": [
        {
            "name": "externalEntityId",
            "value":"first entity"
        }
        ]
    },
    {
        "filterId": "2",
        "criteria": [
        {
            "name": "externalEntityId",
            "value":"other entity"
        }
        ]
    }
    ]
}' \
https://carlsource.server.com/gmaoCS02/api/ui/v1/indicators/values
Réponse obtenue :
{
  "data": [
    {
      "type": "com.carl.xnet.analyse.backend.bean.indicator",
      "id": "17c57530346-f01",
      "attributes": {
        "values": [
          {
            "filterId": "1",
            "value": 10.0
          },
          {
            "filterId": "2",
            "value": 21.0
          }
        ]
      }
    }
  ]
}

Dans ce cas, la réponse obtenue indique l’identifiant du filtre passé en paramètre ainsi que la valeur associée.

Note

Si la requête de l’indicateur est complexe (ex : table chargée, critère de filtre non indexé), il faut éviter de demander trop de valeurs en une seule fois : cela entraînerait un temps de réponse important.
C’est à l’application cliente de trouver le bon compromis entre "nombre de valeurs" et "nombre de requêtes".
A noter que le nombre de valeurs demandées en une seule commande est limité par le paramètre système ApiMaxResults.

10.5. Récupération de la valeur de cet indicateur avec plusieurs critères modifiés

Il est également possible de faire varier plusieurs critères de filtre.
Par exemple :

curl -X POST -i -H "X-CS-Access-Token: votre_access_token" -H "Content-Type: application/vnd.api+json" \
-d '{
    "code": "IND_MR_CUSTOM",
    "filters":[
    {
        "filterId": "1",
        "criteria": [
        {
            "name": "externalEntityId",
            "value":"first entity"
        },
        {
            "name": "xtraTxt01",
            "value":"a value for xtraTxt01"
        }
        ]
    }
    ]
}' \
https://carlsource.server.com/gmaoCS02/api/ui/v1/indicators/values
Réponse obtenue :
{
  "data": [
    {
      "type": "com.carl.xnet.analyse.backend.bean.indicator",
      "id": "17c57530346-f01",
      "attributes": {
        "values": [
          {
            "filterId": "1",
            "value": 13.0
          }
        ]
      }
    }
  ]
}

11. Scénario d’ajout des relevés de mesure : l’API /measure-readings

L’API /measure-readings permet d’ajouter un ou plusieurs relevés de mesure.

11.1. Droits d’utilisation de l’API

L’utilisation de cette API nécessite que l’utilisateur avec lequel est invoquée l’API dispose des droits de profil requis.
L’API est contrôlée par le droit de profil : Equipements / Relevé de mesure.

11.2. Insérer / Lire des relevés de mesure

11.2.1. Insérer un relevé de mesure

L’API /measure-readings/v1/add permet d’envoyer, dans une requête POST au format JSON (Media-Type: application/json), un relevé de mesure à un point de mesure.

Exemple de contenu envoyé dans le corps de la requête POST
curl -X POST -H "X-CS-Access-Token: votre_access_token" -H "Content-Type: application/vnd.api+json" \
-d '{
    "data": {
        "origin": "AUTO",
        "measure": 10000, OU "variation": 10,
        "measuredAt": "2023-04-17T15:07:06",
        "measurePoint": {
            "id": "6" OU "code": "CPT-KM-02"
        }
    }
}' \
https://carlsource.server.com/gmaoCS02/api/measure-readings/v1/add

Les champs correspondants pour la description du relevé de mesure sont les suivants :

Champs Type (Format ou Longueur) Description Obligatoire / Facultatif

origin

Alphanumérique

Code de l’origine du relevé de mesure (MANUAL, AUTO, IOT)

Obligatoire si measurePoint est renseigné.
Facultatif (car sera forcé à IOT) si sensorPairing est renseigné.

measure

Numérique

Valeur de la mesure

Obligatoire si variation non renseignée.
Ne pas renseigner si variation est renseignée.

variation

Numérique

Variation du relevé de mesure

Obligatoire si measure non renseignée.
Ne pas renseigner si measure est renseignée.

measuredAt

Date

Date de la mesure

Obligatoire

correction

Booléen

S’il s’agit d’une correction

Facultatif

repercussion

Booléen

S’il s’agit d’une répercussion

Facultatif

description

Alphanumérique (60)

Description du relevé de mesure

Facultatif

measurePoint

Point de mesure de référence

Obligatoire si sensorPairing non renseigné.
Ne pas renseigner si sensorPairing est renseigné.

sensorPairing

Appairage de capteur de référence

Obligatoire si measurePoint non renseigné.
Ne pas renseigner si measurePoint est renseigné.

Warning

L’utilisation de measure ou variation est obligatoire pour que le relevé de mesure soit ajouté, mais les deux attributs ne doivent pas être renseignés simultanément.

L’utilisation de measurePoint ou sensorPairing est obligatoire pour que le relevé de mesure soit ajouté, mais les deux références ne doivent pas être renseignées simultanément (car sensorPairing contient measurePoint).

Les champs correspondants pour la description du point de mesure de référence sont les suivants :

Champs Type (Format ou Longueur) Description

code

Alphanumérique (20)

Code du point de mesure (ne pas renseigner si id est spécifié)

id

Alphanumérique (33)

Id du point de mesure (ne pas renseigner si code est spécifié)

Warning

L’utilisation de code ou id est obligatoire pour que le relevé de mesure puisse avoir un point de mesure de référence, mais les deux attributs ne peuvent pas être renseignés simultanément.

Les champs correspondants pour la description de l’appairage de capteur de référence sont les suivants :

Champs Type (Format ou Longueur) Description

id

Alphanumérique (33)

Id de l’appairage de capteur

Réponse obtenue
HTTP/1.1 201 Created
{
    "data": {
        "id": "18ad0a4654d-8",
        "variation": 0.0,
        "measure": 10000.0,
        "measuredAt": "2023-04-17T15:07:06.000",
        "correction": false,
        "repercussion": false,
        "origin": "AUTO",
        "measurePoint": {
            "id": "6"
        },
        "modifyDate": "2023-09-26T10:41:53.996",
        "noChrono": false
    }
}

11.2.2. Insérer une liste de relevés de mesure

L’API /measure-readings/v1/add-all permet d’envoyer, dans une requête POST au format JSON (Media-Type: application/json), une liste de relevés de mesure à un ou plusieurs points de mesure.

Note

Cette liste permet d’ajouter des relevés de mesure sur différents points de mesure.
Les relevés de mesure peuvent ne pas être ordonnés car le traitement les triera via l’attribut measuredAt.

Exemple de contenu envoyé dans le corps de la requête POST
curl -X POST -H "X-CS-Access-Token: votre_access_token" -H "Content-Type: application/vnd.api+json" \
    -d '{
        "data":[
            {
                "origin": "AUTO",
                "variation": 5,
                "measuredAt": "2023-05-18T15:59:06",
                "measurePoint": {
                    "code": "CPT-KM-02"
                }
            },
            {
                "origin": "MANUAL",
                "measure": 10,
                "measuredAt": "2023-05-18T16:57:06",
                "measurePoint": {
                    "id": "12"
                }
            },
            {
                "origin": "AUTO",
                "measure": 11000,
                "measuredAt": "2023-05-18T15:57:06",
                "measurePoint": {
                    "code": "CPT-KM-02"
                }
            }
        ]
}' \
https://carlsource.server.com/gmaoCS02/api/measure-readings/v1/add-all
Note

Les champs à renseigner sont identiques à ceux de l’API /measure-readings/v1/add.
La différence réside dans l’action à appeler (add-all) et dans la mise en forme du contenu : data entre crochets [ ].

Réponse obtenue
HTTP/1.1 201 Created
{
    "data": [
        {
            "id": "18ad0e3e436-4e4",
            "variation": 0.0,
            "measure": 10.0,
            "measuredAt": "2023-05-18T16:57:06.000",
            "correction": false,
            "repercussion": false,
            "origin": "MANUAL",
            "measurePoint": {
                "id": "12"
            },
            "modifyDate": "2023-09-26T15:11:51.219",
            "noChrono": false
        },
        {
            "id": "18ad0e3e436-4e6",
            "variation": 1000.0,
            "measure": 11000.0,
            "measuredAt": "2023-05-18T15:57:06.000",
            "correction": false,
            "repercussion": false,
            "origin": "AUTO",
            "measurePoint": {
                "id": "6"
            },
            "modifyDate": "2023-09-26T15:11:51.317",
            "noChrono": false
        },
        {
            "id": "18ad0e3e436-4e7",
            "variation": 5.0,
            "measure": 11005.0,
            "measuredAt": "2023-05-18T15:59:06.000",
            "correction": false,
            "repercussion": false,
            "origin": "AUTO",
            "measurePoint": {
                "id": "6"
            },
            "modifyDate": "2023-09-26T15:11:51.342",
            "noChrono": false
        }
    ]
}

11.2.3. Lire des relevés de mesure

L’API /entities/v1/measurereading permet de retourner, dans une requête GET, les relevés de mesure.

Comme décrit dans le chapitre Lister, filtrer et sélectionner, il est possible d’affiner cette recherche en filtrant, en triant et sélectionnant les attributs à afficher.

Voici un exemple :

Affiche les attributs "dateMeasure, measure, variation, description, origin" des relevés du point de mesure ayant pour id "6", triés par date de mesure croissant
https://carlsource.server.com/gmaoCS02/api/entities/v1/measurereading?filter[measurePoint.id]=6&sort=dateMeasure&fields=dateMeasure,measure,variation,description,origin
Clé Valeur Description

filter[measurePoint.id]

6

Recherche les relevés de mesure du point de mesure ayant pour id : 6

sort

dateMeasure

Trie les relevés de mesure par date de mesure croissant

fields

dateMeasure,measure,variation,description,origin

Affiche uniquement les champs définis

Réponse obtenue
{
    "data": [
        {
            "id": "4",
            "type": "measurereading",
            "links": {
                "self": "http://localhost:8380/xnet/api/entities/v1/measurereading/4"
            },
            "attributes": {
                "origin": 1,
                "description": null,
                "variation": 10000.0,
                "measure": 10000.0,
                "dateMeasure": "2007-12-10T00:00:00.000+01:00"
            }
        },
        {
            "id": "18ad0e3e436-442",
            "type": "measurereading",
            "links": {
                "self": "http://localhost:8380/xnet/api/entities/v1/measurereading/18ad0e3e436-442"
            },
            "attributes": {
                "origin": 2,
                "description": null,
                "variation": 0.0,
                "measure": 10000.0,
                "dateMeasure": "2023-04-17T15:07:06.000+02:00"
            }
        },
        {
            "id": "18ad0e3e436-4e6",
            "type": "measurereading",
            "links": {
                "self": "http://localhost:8380/xnet/api/entities/v1/measurereading/18ad0e3e436-4e6"
            },
            "attributes": {
                "origin": 2,
                "description": null,
                "variation": 1000.0,
                "measure": 11000.0,
                "dateMeasure": "2023-05-18T15:57:06.000+02:00"
            }
        },
        {
            "id": "18ad0e3e436-4e7",
            "type": "measurereading",
            "links": {
                "self": "http://localhost:8380/xnet/api/entities/v1/measurereading/18ad0e3e436-4e7"
            },
            "attributes": {
                "origin": 2,
                "description": null,
                "variation": 5.0,
                "measure": 11005.0,
                "dateMeasure": "2023-05-18T15:59:06.000+02:00"
            }
        }
    ],
    "links": {
        "self": "measurePoint.id=6&sort=dateMeasure&fields=dateMeasure%2Cmeasure%2Cvariation%2Cdescription%2Corigin"
    }
}

12. Manipulation des réservations avec l’API /reserves

L’API /reserves permet de manipuler une ou plusieurs réservations (création, mise à jour, recherche, suppression).

12.1. Droits d’utilisation de l’API

L’utilisation de cette API nécessite que l’utilisateur avec lequel est invoquée l’API dispose des droits de profil requis.
L’API est contrôlée par les droits de profil : Travaux / Intervention et Stock / Réservations.

12.2. Créer une ou plusieurs réservations

12.2.1. Créer une réservation

L’API /reserves/v1/add permet d’envoyer, dans une requête POST au format JSON (Media-Type: application/json), une réservation.

Note

La création d’une réservation est possible uniquement si l’intervention est à l’état "Validée".

La création d’une réservation est impossible si la date spécifiée est antérieure à la date de début de l’intervention.

Si la date de réservation spécifiée est située après la date de fin de l’intervention, la date de fin de l’intervention sera automatiquement mise à jour avec la date de la réservation.

Exemple de contenu envoyé dans le corps de la requête POST
curl -X POST -H "X-CS-Access-Token: votre_access_token" -H "Content-Type: application/vnd.api+json" \
-d '{
"data": {
      "quantity": 1,
      "reserveDate" : "2024-01-05T09:12:55.835+01:00",
      "description" : "Test de création de réservation avec l’API REST",
        "item": {
            "code": "FILTRE-AIR-D20"
            }
        ,
        "wo": {
            "code": "DEV-WO-017-2006"
        },
        "actor": {
            "code": "DEMO"
        },
         "warehouse": {
            "code": "MAG2"
        }
    }’\
https://carlsource.server.com/gmaoCS02/api/reserves/v1/add

Les champs correspondants pour la description d’une réservation sont les suivants :

Champs Type (Format ou Longueur) Description Obligatoire / Facultatif

item

Alphanumérique

Code ou id de l’article

Obligatoire

quantity

Numérique

Nombre d’articles à réserver

Obligatoire

warehouse

Alphanumérique

Code ou id du magasin de la réservation

Obligatoire

wo

Alphanumérique

Intervention porteuse de la réservation

Obligatoire

reserveDate

Date

Date de la réservation

Facultatif. Date du jour par défaut.

actor

Alphanumérique

Code ou id de l’acteur

Facultatif. Acteur connecté par défaut.

description

Alphanumérique (60)

Description de la réservation

Facultatif

Réponse obtenue
HTTP/1.1 201 Created
{
    "data": {
        "id": "1917e380cdc-ac",
        "item": {
            "id": "FILTRE-AIR-D20",
            "code": "FILTRE-AIR-D20"
        },
        "quantity": 1.0,
        "reserveDate": "2024-01-05T09:12:55.835+01:00",
        "wo": {
            "id": "DEV17",
            "code": "DEV-WO-017-2006"
        },
        "actor": {
            "id": "14",
            "code": "DEMO"
        },
        "description": "Test de création de réservation avec l’API REST"
    }
}

12.2.2. Créer une liste de réservations

L’API /reserves/v1/add-all permet d’envoyer, dans une requête POST au format JSON (Media-Type: application/json), une liste de réservations.

Note

Cette liste permet d’ajouter des réservations sur une ou plusieurs interventions, magasins ou articles. Il n’est pas obligatoire de créer la liste avec le même magasin, article ou intervention. Chaque réservation peut donc contenir des données indépendantes des autres réservations.

Si l’API rencontre une erreur fonctionnelle (ex : donnée obligatoire non renseignée ou tentative de création sur une intervention non valide), c’est l’intégralité de la liste qui est rejetée.

Exemple de contenu envoyé dans le corps de la requête POST
curl -X POST -H "X-CS-Access-Token: votre_access_token" -H "Content-Type: application/vnd.api+json" \
-d '{
"data":[
        {
            "quantity": 1,
            "reserveDate": "2023-12-11T10:50:46.841+01:00",
            "description": "Test création de réservation 1",
            "item": {
                "code": "FILTRE-AIR-D20"
            },
            "wo": {
                "code": "DEV-WO-017-2006"
            },
            "actor": {
                "code": "DEMO"
            },
            "warehouse": {
                "code": "MAG2"
            }
        },
        {
            "quantity": 2,
            "reserveDate": "2023-12-11T10:50:46.841+01:00",
            "description": "Test création de réservation 2",
            "item": {
                "code": "FILTRE-AIR-D20"
            },
            "wo": {
                "code": "DEV-WO-017-2006"
            },
            "actor": {
                "code": "DEMO"
            },
            "warehouse": {
                "code": "MAG2"
            }
        },
         {
            "quantity": 3,
            "reserveDate": "2023-12-11T10:50:46.841+01:00",
            "description": "Test création de réservation 3",
            "item": {
                "code": "ITEM1"
            },
            "wo": {
                "code": "DEV-WO-017-2006"
            },
            "actor": {
                "code": "DEMO"
            },
            "warehouse": {
                "code": "MAG1"
            }
        }
    ]
}’\
Note

Les champs à renseigner sont identiques à ceux de l’API /reserves/v1/add.
La différence réside :

  • dans l’action à appeler : add-all

  • et dans la mise en forme du contenu : data entre crochets [ ].

Réponse obtenue
HTTP/1.1 201 Created
{
    "data": [
        {
            "id": "1917e380cdc-1eb",
            "item": {
                "id": "FILTRE-AIR-D20",
                "code": "FILTRE-AIR-D20"
            },
            "quantity": 1.0,
            "reserveDate": "2023-12-11T10:50:46.841+01:00",
            "wo": {
                "id": "DEV17",
                "code": "DEV-WO-017-2006"
            },
            "actor": {
                "id": "14",
                "code": "DEMO"
            },
            "description": "Test création de réservation 1"
        },
        {
            "id": "1917e380cdc-1ed",
            "item": {
                "id": "FILTRE-AIR-D20",
                "code": "FILTRE-AIR-D20"
            },
            "quantity": 2.0,
            "reserveDate": "2023-12-11T10:50:46.841+01:00",
            "wo": {
                "id": "DEV17",
                "code": "DEV-WO-017-2006"
            },
            "actor": {
                "id": "14",
                "code": "DEMO"
            },
            "description": "Test création de réservation 2"
        },
        {
            "id": "1917e380cdc-1ef",
            "item": {
                "id": "ITEM1",
                "code": "ITEM1"
            },
            "warehouse": {
                "id": "WAREHOUSE1",
                "code": "MAG1"
            },
            "quantity": 3.0,
            "reserveDate": "2023-12-11T10:50:46.841+01:00",
            "wo": {
                "id": "DEV17",
                "code": "DEV-WO-017-2006"
            },
            "actor": {
                "id": "14",
                "code": "DEMO"
            },
            "description": "Test création de réservation 3"
        }
    ]
}

12.3. Mettre à jour une réservation

L’API /reserves/v1/update/<reserve-id> permet de mettre à jour une réservation.

Exemple de contenu envoyé dans le corps de la requête PATCH pour mettre à jour le magasin et la description de la réservation portant l’identifiant '1917e380cdc-1eb'
curl -X POST -H "X-CS-Access-Token: votre_access_token" -H "Content-Type: application/vnd.api+json" \
-d '{
      "data":  {
      "quantity": 1,
      "reserveDate" : "2024-01-05T09:12:55.835+01:00",
      "description" : "Réservation mise à jour par DEMO vers MAG1",
        "item": {
            "code": "FILTRE-AIR-D20"
        }
        ,
        "wo": {
            "code": "DEV-WO-017-2006"
        },
        "actor": {
            "code": "DEMO"
        },
         "warehouse": {
            "code": "MAG1"
        }
    }
} ‘ \
https://carlsource.server.com/gmaoCS02/api/reserves/v1/update/1917e380cdc-ac
Réponse obtenue
HTTP/1.1 200 OK
{
    "data": {
        "id": "1917e380cdc-ac",
        "item": {
            "id": "FILTRE-AIR-D20",
            "code": "FILTRE-AIR-D20"
        },
        "warehouse": {
            "id": "WAREHOUSE1",
            "code": "MAG1"
        },
        "quantity": 1.0,
        "reserveDate": "2024-01-05T09:12:55.835+01:00",
        "wo": {
            "id": "DEV17",
            "code": "DEV-WO-017-2006"
        },
        "actor": {
            "id": "14",
            "code": "DEMO"
        },
        "description": "Réservation mise à jour par DEMO vers MAG1"
    }
}

12.4. Mettre à jour une liste de réservations

L’API /reserves/v1/update-all permet de mettre à jour une liste de réservations.

Note

En plus des attributs obligatoires, il est nécessaire de fournir l’id de la réservation que l’on souhaite mettre à jour dans la liste.

Exemple de contenu envoyé dans le corps de la requête PATCH
{
    "data": [
        {
            "id": "1917e380cdc-1eb",
            "item": {
                "code": "ITEM1"
            },
            "quantity": 2.0,
            "reserveDate": "2023-12-11T10:50:46.841+01:00",
            "wo": {
                "code": "DEV-WO-017-2006"
            },
            "actor": {
                "code": "DEMO"
            },
            "description": "Mise à jour de la réservation 1"
        },
        {
            "id": "1917e380cdc-1ed",
            "item": {
                "code": "FILTRE-AIR-D20"
            },
            "quantity": 2.0,
            "reserveDate": "2023-12-11T10:50:46.841+01:00",
            "wo": {
                "code": "DEV-WO-018-2006"
            },
            "actor": {
                "code": "DEMO"
            },
            "description": "Mise à jour de la réservation 2"
        },
        {
            "id": "1917e380cdc-1ef",
            "item": {
                "code": "ITEM1"
            },
            "warehouse": {
                "code": "MAG1"
            },
            "quantity": 2.0,
            "reserveDate": "2023-12-11T10:50:46.841+01:00",
            "wo": {
                "code": "DEV-WO-017-2006"
            },
            "actor": {
                "code": "DEMO"
            },
            "description": "Mise à jour de la réservation 3"
        }
    ]
}
Réponse obtenue
{
    "data": [
        {
            "id": "1917e380cdc-1eb",
            "item": {
                "id": "FILTRE-AIR-D20",
                "code": "FILTRE-AIR-D20"
            },
            "quantity": 2.0,
            "reserveDate": "2023-12-11T10:50:46.841+01:00",
            "wo": {
                "id": "DEV17",
                "code": "DEV-WO-017-2006"
            },
            "actor": {
                "id": "14",
                "code": "DEMO"
            },
            "description": "Mise à jour de la réservation 1"
        },
        {
            "id": "1917e380cdc-1ed",
            "item": {
                "id": "FILTRE-AIR-D20",
                "code": "FILTRE-AIR-D20"
            },
            "quantity": 2.0,
            "reserveDate": "2023-12-11T10:50:46.841+01:00",
            "wo": {
                "id": "DEV18",
                "code": "DEV-WO-018-2006"
            },
            "actor": {
                "id": "14",
                "code": "DEMO"
            },
            "description": "Mise à jour de la réservation 2"
        },
        {
            "id": "1917e380cdc-1ef",
            "item": {
                "id": "ITEM1",
                "code": "ITEM1"
            },
            "warehouse": {
                "id": "WAREHOUSE1",
                "code": "MAG1"
            },
            "quantity": 2.0,
            "reserveDate": "2023-12-11T10:50:46.841+01:00",
            "wo": {
                "id": "DEV17",
                "code": "DEV-WO-017-2006"
            },
            "actor": {
                "id": "14",
                "code": "DEMO"
            },
            "description": "Mise à jour de la réservation 3"
        }
    ]
}

12.5. Retrouver les réservations liées à une entité (article, intervention ou magasin)

L’API /reserves/v1/<entityType>/<entityId> permet de rechercher des réservations liées aux entités wo, item et warehouse.

Exemple de requête GET pour rechercher les réservations liées à l’intervention 'DEV-WO-018-2006'
https://carlsource.server.com/gmaoCS02/api/reserves/v1/wo/DEV18
Réponse obtenue
{
    "data": [
        {
            "id": "1917e380cdc-1ed",
            "item": {
                "id": "FILTRE-AIR-D20",
                "code": "FILTRE-AIR-D20"
            },
            "quantity": 2.0,
            "reserveDate": "2023-12-11T10:50:46.841+01:00",
            "wo": {
                "id": "DEV18",
                "code": "DEV-WO-018-2006"
            },
            "actor": {
                "id": "14",
                "code": "DEMO"
            },
            "description": "Mise à jour de la réservation 2"
        }
    ]
}
Entité de recherche Description

item

Article lié à la réservation

wo

Intervention liée à la réservation

warehouse

Magasin lié à la réservation

12.6. Suppression d’une réservation

L’API /reserves/v1/delete/<reserveId> permet la suppression d’une réservation.

Exemple de requête DEL pour supprimer la réservation portant l’identifiant '1917e380cdc-1ed'
https://carlsource.server.com/gmaoCS02/api/reserves/v1/delete/1917e380cdc-1ed

13. Scénario de mise à jour des états des factures : l’API /energy-meter-invoices

13.1. Droits d’utilisation de l’API

L’utilisation de cette API nécessite que l’utilisateur avec lequel est invoquée l’API dispose des droits de profil requis.
L’API est contrôlée par le droit de profil : Equipements / Suivi facturation énergie.

13.2. Mise à jour des états des factures

L’API /energy-meter-invoices/v1/update-status permet d’envoyer, dans une requête POST au format JSON (Media-Type: application/json), une liste de factures à mettre à jour.

Exemple de contenu envoyé dans le corps de la requête POST
curl -X POST -H "X-CS-Access-Token: votre_access_token" -H "Content-Type: application/vnd.api+json" \
-d ' {
	"data":[
		{	"invoiceNumber" : "110",
			"status" : "PAID",
			"energyMeter" : {
						"id" : "nrj1" OU "code" : "ENERGY_01"
					}
		},
		{
			"invoiceNumber" : "111",
			"status" : "TOPAY",
			"energyMeter" : {
				"id" : "nrj1" OU "code" : "ENERGY_01"
			}
		}
	]
}' \
https://carlsource.server.com/gmaoCS02/api/energy-meter-invoice/v1/update-status

Les champs correspondants pour la description de la facture sont les suivants :

Champs Type (Format ou Longueur) Description Obligatoire / Facultatif

invoiceNumber

Alphanumérique

Numéro de la facture

Obligatoire

status

Alphanumérique

Etat

Obligatoire

Les champs correspondants pour la description d’un point énergie sont les suivants :

Champs Type (Format ou Longueur) Description

code

Alphanumérique

Code du point énergie (ne pas renseigner si id est spécifié)

id

Alphanumérique

Identifiant du point énergie (ne pas renseigner si code est spécifié)

L’utilisation de code ou id est obligatoire pour que la facture puisse avoir un point énergie de référence, mais les deux attributs ne peuvent pas être renseignés simultanément.

Réponse obtenue
HTTP/1.1 201 Created
{
"data":[
        {
            "invoiceNumber" : "110",
            "status" : "PAID",
            "energyMeter" : {
                "id" : "nrj1"
            }
        },
        {
            "invoiceNumber" : "111",
            "status" : "TOPAY",
            "energyMeter" : {
                "id" : "nrj1"
            }
        }
    ]
}

L’API /link-equipments permet d’ajouter, de déplacer, de modifier ou de clôturer un ou plusieurs liens dans l’arborescence.

L’utilisation de cette API nécessite que l’utilisateur avec lequel est invoquée l’API dispose des droits de profil requis.
L’API est contrôlée par le droit de profil : Equipements / Arborescence du parc équipements.

  • Lorsque le lien existe déjà, si la date de fin est renseignée : droit "Supprimer le lien courant".

  • Lorsque le lien existe entre les deux équipements : droit "Modifier les informations sur liens".

  • Lorsque le lien existe pour cette jonction : droit "Modifier les informations sur liens".

Note

Toutes ces différentes actions sur les liens sont régies par deux appels uniquement :

  • /link-equipments/v1/add pour la gestion d’un seul lien

  • /link-equipments/v1/add-all pour la gestion d’une liste de liens

C’est l’utilisation des attributs qui composent le corps de cette API qui permet de définir s’il s’agit de la création, du déplacement, de la modification ou de la clôture du lien.

Exemples d’utilisation :

  • Création : Si aucun lien n’existe, l’ajout d’un père, d’un fils, et d’une date de début crée le lien dans l’arborescence.

  • Déplacement : L’appel à la même API que précédemment en modifiant le père ou le fils déplace le lien dans l’arborescence.

  • Clôture : L’ajout d’une date de fin clôture le lien dans l’arborescence.

L’API /link-equipments/v1/add permet d’envoyer, dans une requête POST au format JSON (Media-Type: application/json), un lien sur l’arborescence.

Exemple de contenu envoyé dans le corps de la requête POST
curl -X POST -H "X-CS-Access-Token: votre_access_token" -H "Content-Type: application/vnd.api+json" \
-d '{
    "data": {
        "linkBegin":"2024-09-11T12:00:00",
        "description":"Lien API Rest",
        "ordering":1,
        "junction": {
            "id":"LOCATIONMATERIAL"
        },
        "parent": {
            "id":"ALLEMAGNE"
        },
        "child": {
            "code":"CEAU"
        }
    }
}' \
https://carlsource.server.com/gmaoCS02/api/link-equipments/v1/add

Les champs correspondants pour la description du lien sur l’arborescence sont les suivants :

Champs Type (Format ou Longueur) Description Obligatoire / Facultatif

linkBegin

Date

Date de début de validité du lien

Obligatoire, uniquement dans le cas des liens datés.

linkEnd

Date

Date de fin de validité du lien

Facultatif

ordering

Numérique

Ordre des nœuds d’une branche d’arborescence

Facultatif

description

Alphanumérique

Description du lien

Facultatif

  • linkBegin : ce champ est requis uniquement si la structure enfant est de type "liens datés".
    Par exemple, un lien entre un point de structure et un matériel nécessite une date, tandis qu’un lien entre deux points de structure n’en requiert aucune.

Un lien nécessite l’utilisation des entités de référence suivantes :

Champs Description Obligatoire / Facultatif

junction

Description des liens entre structures

Obligatoire

parent

Equipement parent du lien

Facultatif

child

Equipement enfant du lien

Obligatoire

Les champs correspondants pour la description des entités de référence du lien sont les suivants :

Champs Type (Format ou Longueur) Description

code

Alphanumérique (20)

Code de l’entité de référence

id

Alphanumérique (33)

Id de l’entité de référence

Warning

L’utilisation de code ou id est obligatoire pour une entité de référence.

Réponse obtenue
HTTP/1.1 201 Created
{
    "data": [
        {
            "id": "19368f7c674-3",
            "junction": {
                "id": "LOCATIONMATERIAL"
            },
            "parent": {
                "id": "ALLEMAGNE",
                "code": "ALLEMAGNE"
            },
            "child": {
                "id": "9",
                "code": "CEAU"
            },
            "linkBegin": "2024-09-11T12:00:00.000",
            "linkEnd": "2200-12-31T01:00:00.000",
            "description": "lien API Rest",
            "ordering": 1
        }
    ]
}

L’API /link-equipments/v1/add-all permet d’envoyer, dans une requête POST au format JSON (Media-Type: application/json), une liste de liens sur l’arborescence.

Note

Cette liste permet de gérer des liens sur différents équipements.
Les liens peuvent être transmis de manière non-ordonnée car le traitement les triera via l’attribut linkBegin.

Exemple de contenu envoyé dans le corps de la requête POST
curl -X POST -H "X-CS-Access-Token: votre_access_token" -H "Content-Type: application/vnd.api+json" \
    -d '{
        "data": [
            {
            "junction": {
                "id":"LOCATIONMATERIAL"
            },
            "parent": {
                "id":"ALLEMAGNE"
            },
            "child": {
                "code":"BALL"
            },
            "linkBegin":"2024-09-11T12:00:00",
            "description":"Création du lien",
            "ordering":1
        },
        {
            "junction": {
                "id":"LOCATIONMATERIAL"
            },
            "parent": {
                "id":"FRANCE"
            },
            "child": {
                "code":"BALL"
            },
            "linkBegin":"2024-09-11T13:00:00",
            "description":"Déplacement du lien",
            "ordering":1
        },
        {
            "junction": {
                "id":"LOCATIONMATERIAL"
            },
            "parent": {
                "id":"FRANCE"
            },
            "child": {
                "code":"BALL"
            },
            "linkBegin":"2024-09-11T14:00:00",
            "description":"Modification de la date du lien existant",
            "ordering":1
        },
        {
            "junction": {
                "id":"LOCATIONMATERIAL"
            },
            "parent": {
                "id":"FRANCE"
            },
            "child": {
                "code":"BALL"
            },
            "linkBegin":"2024-09-11T15:00:00",
            "linkEnd":"2024-09-12T15:00:00",
            "description":"Clôture du lien",
            "ordering":1
        }
    ]
}' \
https://carlsource.server.com/gmaoCS02/api/link-equipments/v1/add-all

L’exemple ci-dessus illustre les cas de figure suivants :

  • Déplacement du lien du père "ALLEMAGNE" vers le père "FRANCE" (cf. "Déplacement du lien" dans le code)

Warning

Le déplacement d’un lien entraîne la clôture du lien existant et la création du nouveau lien dans l’arborescence - cf. "Réponse obtenue" plus bas.

  • Modification de la date du lien en cours (cf. les deux premières occurrences d’utilisation de l’attribut linkBegin)

  • Clôture du lien en cours (cf. occurrence d’utilisation de l’attribut linkEnd)

Note

Les champs à renseigner sont identiques à ceux de l’API /link-equipments/v1/add.
La différence réside dans l’action à appeler (add-all) et dans la mise en forme du contenu : data entre crochets [ ].

Réponse obtenue
HTTP/1.1 201 Created
{
    "data": [
        {
            "id": "19368f7c674-18",
            "junction": {
                "id": "LOCATIONMATERIAL"
            },
            "parent": {
                "id": "ALLEMAGNE",
                "code": "ALLEMAGNE"
            },
            "child": {
                "id": "2",
                "code": "BALL"
            },
            "linkBegin": "2024-09-11T12:00:00.000",
            "linkEnd": "2200-12-31T01:00:00.000",
            "description": "Création du lien",
            "ordering": 1
        },
        {
            "id": "19368f7c674-18",
            "junction": {
                "id": "LOCATIONMATERIAL"
            },
            "parent": {
                "id": "ALLEMAGNE",
                "code": "ALLEMAGNE"
            },
            "child": {
                "id": "2",
                "code": "BALL"
            },
            "linkBegin": "2024-09-11T12:00:00.000",
            "linkEnd": "2024-09-11T12:59:59.999",
            "description": "Création du lien",
            "ordering": 1
        },
        {
            "id": "19368f7c674-19",
            "junction": {
                "id": "LOCATIONMATERIAL"
            },
            "parent": {
                "id": "FRANCE",
                "code": "FRANCE"
            },
            "child": {
                "id": "2",
                "code": "BALL"
            },
            "linkBegin": "2024-09-11T13:00:00.000",
            "linkEnd": "2200-12-31T01:00:00.000",
            "description": "Déplacement du lien",
            "ordering": 1
        },
        {
            "id": "19368f7c674-19",
            "junction": {
                "id": "LOCATIONMATERIAL"
            },
            "parent": {
                "id": "FRANCE",
                "code": "FRANCE"
            },
            "child": {
                "id": "2",
                "code": "BALL"
            },
            "linkBegin": "2024-09-11T14:00:00.000",
            "linkEnd": "2200-12-31T01:00:00.000",
            "description": "Modification de la date du lien existant",
            "ordering": 1
        },
        {
            "id": "19368f7c674-19",
            "junction": {
                "id": "LOCATIONMATERIAL"
            },
            "parent": {
                "id": "FRANCE",
                "code": "FRANCE"
            },
            "child": {
                "id": "2",
                "code": "BALL"
            },
            "linkBegin": "2024-09-11T15:00:00.000",
            "linkEnd": "2024-09-12T15:00:00.000",
            "description": "Clôture du lien",
            "ordering": 1
        }
    ]
}

Analyse de la réponse obtenue :

  • Création : La réponse n°1 correspond à la création du lien.

  • Déplacement :

    • La réponse n°2 correspond à la clôture de ce lien (même id) car le déplacement d’un lien clôture le lien actuel pour en créer un nouveau.

    • La réponse n°3 correspond à la création du nouveau lien suite à la demande de déplacement.

  • Modification : La réponse n°4 correspond à la modification du lien en cours.

  • Clôture : La réponse n°5 correspond à la clôture du lien dans l’arborescence.

Warning

Si une erreur survient lors du traitement de l’API, aucune modification n’est prise en compte.

L’API /entities/v1/linkequipment permet de retourner, dans une requête GET, les liens équipement.

Comme décrit dans le chapitre Lister, filtrer et sélectionner, il est possible d’affiner cette recherche en filtrant, en triant et sélectionnant les attributs à afficher.

Exemple
https://carlsource.server.com/gmaoCS02/api/entities/v1/linkequipment?filter[child.code]=BALL&sort=linkBegin

15. Scénario de manipulation des inventaires : l’API /inventories

L’API /inventories permet de créer un ou plusieurs inventaires.

15.1. Droits d’utilisation de l’API

L’utilisation de l’API nécessite que l’utilisateur dispose des droits de profils requis. L’API est contrôlée par le droit de création d’inventaire : Stock/Inventaire.

15.2. Créer un ou plusieurs inventaires

15.2.1. Créer un inventaire

L’API /inventories/v1/add permet d’envoyer dans une requête POST au format JSON (Media-Type: application/json), un mouvement d’inventaire.

Exemple
curl -X POST -H "X-CS-Access-Token: votre_access_token" -H "Content-Type: application/vnd.api+json" \
-d '{
"data": {
	"movementQuantity": 11.0,
	"description": "Test de création d’inventaire avec l’API REST",
	"item": {
		"code": "ITEM1"
		},
	"location": {
		"code": "A1C10"
		},
	"actor": {
		"code": "DEMO"
		},
	"warehouse": {
		"code": "MAG1"}
		}
	}'https://carlsource.server.com/gmaoCS02/api/inventories/v1/add

Les champs correspondants pour la description d’un inventaire sont les suivants :

Champs Type (Format ou Longueur) Description Obligatoire / Facultatif

item

Alphanumérique

Code ou id de l’article

Obligatoire

movementQuantity

Numérique

Quantité inventoriée

Obligatoire

warehouse

Alphanumérique

Code ou id du magasin de la réservation

Obligatoire. Peut-être facultatif si l’article a déjà été inventorié dans un seul magasin.

location

Alphanumérique

Intervention porteuse de la réservation

Facultatif

movementDate

Date Date de l’inventaire

Facultatif. Date du jour par défaut.

actor

Alphanumérique

Code ou id de l’acteur

Facultatif. Acteur connecté par défaut.

description

Alphanumérique

Description de l’inventaire

Facultatif

materialMoved

Alphanumérique

Code ou id du matériel

Obligatoire pour l’inventaire d’un article sérialisé

batchNum

Alphanumérique

Numéro de lot associé

Facultatif

movementType

Alphanumérique

Code ou id du type de mouvement

Facultatif. Mouvement de type Inventaire par défaut.

inventoryId

Réponse obtenue
HTTP/1.1 201 Created
{
   "data":{
		"id":"19759fe5d1c-1",
		"actor":{
			"id":"14",
			"code":"DEMO"
		},
		"item":{
			"id":"ITEM1",
			"code":"ITEM1"
		},
		"movementQuantity":11.0,
		"movementDate":"2025-06-10T15:21:58.311+02:00",
		"location":{
			"id":"LOCATION1",
			"code":"A1C10"
	},
		"warehouse":{
			"id":"WAREHOUSE1",
			"code":"MAG1"
			},
		"description":"Test de création d’inventaire avec l’API REST",
            "movementType":{
			   "id":"INVENTORY",
			   "code":"INVENTAIRE"}
	}
}

15.2.2. Créer une liste d’inventaire

L’ API/inventories/v1/add-all permet d’envoyer dans une requête POST au format JSON (Media-Type :application/json), une liste d’inventaire.

Note

Si l’API rencontre une erreur fonctionnelle, comme une donnée obligatoire non renseignée c’est toute la liste qui est rejetée.

Exemple de contenu envoyé dans le corps de la requête POST
curl -X POST -H "X-CS-Access-Token: votre_access_token" -H "Content-Type: application/vnd.api+json" \
    -d    '{
    "data": [
    {
        "movementQuantity": 4.0,
        "description": "Test de création de plusieurs inventaires avec l’API REST. Inventaire 1",
        "item": {
            "code": "ITEM1"
        },
        "location": {
            "code": "A1C10"
        },
        "actor": {
            "code": "DEMO"
        },
        "warehouse": {
            "code": "MAG1"
        }
    },
    {
        "movementQuantity": 3.0,
        "description": "Test de création de plusieurs inventaires avec l’API REST. Inventaire 2",
        "item": {
            "code": "ITEM1"
        },
        "location": {
            "code": "A2C03"
        },
        "actor": {
            "code": "DEMO"
        },
        "warehouse": {
            "code": "MAG2"
        }
    }
    ]
}’\https://carlsource.server.com/gmaoCS02/api/inventories/v1/add-all
Note

Les champs à renseigner sont identiques à l’API inventories/v1/add.
La différence réside dans l’action à appeler add-all, et dans la mise en forme du contenu :
data entre crochets [ … ].

Réponse obtenue
HTTP/1.1 201 Created
{
     "data": [
    {
      "id": "19759fe5d1c-57",
      "actor": {
        "id": "14",
        "code": "DEMO"
      },
      "item": {
        "id": "ITEM1",
        "code": "ITEM1"
      },
      "movementQuantity": 4.0,
      "movementDate": "2025-06-10T15:42:02.225+02:00",
      "location": {
        "id": "LOCATION1",
        "code": "A1C10"
      },
      "warehouse": {
        "id": "WAREHOUSE1",
        "code": "MAG1"
      },
      "description": "Test de création de plusieurs inventaires avec l’API REST. Inventaire 1",
      "movementType": {
        "id": "INVENTORY",
        "code": "INVENTAIRE"
      }
    },
    {
      "id": "19759fe5d1c-5a",
      "actor": {
        "id": "14",
        "code": "DEMO"
      },
      "item": {
        "id": "ITEM1",
        "code": "ITEM1"
      },
      "movementQuantity": 3.0,
      "movementDate": "2025-06-10T15:42:02.292+02:00",
      "location": {
        "id": "LOCATION4",
        "code": "A2C03"
      },
      "warehouse": {
        "id": "WAREHOUSE2",
        "code": "MAG2"
      },
      "description": "Test de création de plusieurs inventaires avec l’API REST. Inventaire 2",
      "movementType": {
        "id": "INVENTORY",
        "code": "INVENTAIRE"
      }
    }
  ]
}

16. Import de factures externes : l’API /invoices

16.1. Présentation générale

Cette API REST permet d’importer des factures externes dans CARL Source, conformément à la norme EN16931 et aux besoins spécifiques du SI. Elle s’adresse aux clients souhaitant automatiser l’intégration de leurs factures électroniques (e-factures) dans CARL Source.

16.1.1. Import des données de facturation

  • Endpoint : /api/invoices/v1/add

  • Méthode HTTP : POST

  • Type de contenu attendu (Content-type) : application/json

  • Authentification : Requise

16.1.2. Import des données de facturation et du fichier représentant la facture

  • Endpoint : /api/invoices/v1/add

  • Méthode HTTP : POST

  • Type de contenu attendu (Content-type) : multipart/form-data

  • Authentification : Requise

16.1.3. Droits d’utilisation

Les droits d’accès aux APIs sont conditionnés par les paramètres de module suivants (Menu Système, fonctionnalité Paramètres des modules) :

  • Achats / INVOICE_IMPORT_ENABLED | Activer l’import de e-factures : doit être coché

  • Achats / INVOICE_IMPORT_FORMAT | Format de l’import de e-factures : doit valoir "CARL Source"

Ainsi que par le droit de profil suivant :

  • Achats / Factures / Autoriser la création de factures par API d’import d’e-factures : doit être coché

16.2. Fonctionnement de l’API

16.2.1. Étapes de traitement

  1. Validation des données :

    • Les champs obligatoires sont renseignés (voir ci-dessous).

    • Le type de facture est contrôlé (certains types comme 384/CORRECTED ou 389/SELF_BILLED ne sont pas supportés pour l’instant).

    • Les règles métier garantissant la cohérence des données fournies (commande, devise, etc.) sont contrôlées.

  2. Réalisation de l’import :

    • Si la facture n’existe pas, elle est créée.

    • Si elle existe et est toujours à l’état "En préparation", elle est mise à jour.

    • Si la commande associée n’est pas trouvée, le mode "pré-facture" doit être autorisé afin que la facture soit tout de même créée en tant que "pré-facture" (brouillon).

    • Si la facture de référence n’est pas trouvée, le mode "pré-facture" doit être autorisé afin que l’avoir soit tout de même créée en tant que "pré-avoir" (brouillon).

16.2.2. Codes de retour

  • 200 : Import effectué avec succès

  • 400 : Paramètres d’entrée invalides

  • 403 : Droits insuffisants

  • 500 : Erreur interne

16.3. Structure des données attendues

16.3.1. Exemple de payload JSON

{
  "data": {
    "invoiceNumber": "FAC-2026-001",
    "invoiceIssueDate": "2026-04-17T10:00:00+02:00",
    "invoiceTypeCode": "380",
    "invoiceStatus": "EN_ATTENTE",
    "buyerReference": "ACH-12345",
    "purchaseOrderReference": "PO-2026-001",
    "deliveryCode": "BL-2026-001",
    "precedingInvoiceReference": null,
    "sellerReference": "VEND-98765",
    "supplierReference": "FOUR-54321",
    "invoiceReference": "REF-2026-001",
    "invoiceCurrencyCode": "EUR",
    "invoiceTotalAmountWithVAT": 1200.50,
    "invoiceTotalVATAmount": 200.08,
    "invoiceTotalAmountWithoutVAT": 1000.42
  }
}

16.3.2. Description des champs principaux

Champ Obligatoire Description

invoiceNumber

Oui (1)

Numéro unique de la facture externe

invoiceIssueDate

Oui

Date d’émission de la facture (format ISO 8601)

invoiceTypeCode

Non (2)

Code type de facture (380, 381, 384, 389)

invoiceStatus

Oui

Statut interne de la facture dans le SI appelant

buyerReference

Non

Références sur l’acheteur

purchaseOrderReference

Non (3)

Référence de la commande associée

deliveryCode

Non (3)

Numéro de BL client (obligatoire si mode BL activé)

precedingInvoiceReference

Non

Référence de facture d’origine (obligatoire pour 381)

sellerReference

Non

Référence du vendeur

supplierReference

Non

Référence du fournisseur

invoiceReference

Non

Référence de la facture d’origine pour les avoirs

invoiceCurrencyCode

Oui

Code de la devise (format ISO 4217)

invoiceTotalAmountWithVAT

Oui

Montant total TTC

invoiceTotalVATAmount

Oui

Montant total TVA

invoiceTotalAmountWithoutVAT

Oui

Montant total HT

(1) Obligatoire ou non selon le cas métier (pré-facture possible)

(2) Obligatoire pour certaines règles métier (ex : 381 avec precedingInvoiceReference)

(3) Le caractère obligatoire dépend du mode de facturation (commande ou BL - uniquement commande pour l’instant)

16.4. Points d’attention

  • Type de facture :

    • Les factures de type 384 (Rectificative) ne sont pas prises en compte.

    • Les factures de type 389 (Auto-facturation) sont pour l’instant refusées par l’API.

  • Pré-facture :

    • Si aucune commande n’est trouvée, le mode "pré-facture" doit être activé côté configuration pour que la facture soit importée. Dans le cas contraire la facture n’est pas importée.

16.5. Bonnes pratiques

  • Toujours renseigner les champs obligatoires.

  • Vérifier la configuration du module Achat et du profil de l’utilisateur invoquant l’API côté CARL Source.

  • Utiliser les bons codes de types de facture selon la norme EN16931. Si le type n’est pas renseigné, le traitement utilise le type 380 - facture commerciale - par défaut.

  • En cas d’erreur, consulter le message retourné dans le corps de la réponse http, mais aussi côté serveur dans les logs applicatifs de CARL Source.

  • Lors de la phase de mise en place, il peut être pratique d’utiliser une authentification BASIC pour mener les tests.
    Nous encourageons toutefois fortement l’utilisation de tokens OAuth2 pour un passage en exploitation.

16.6. Exemple d’appel avec curl

Voici un exemple d’appel à l’API d’import de factures externes en utilisant curl. À noter : les environnements CARL Source en SaaS sont protégés et - pour des raisons de sécurité - rejettent les requêtes ne spécifiant aucun user-agent ou spécifiant un user-agent contenant "curl".

Exemple d’import des données de facturation
curl -X POST \
  https://carlsource.server.com/gmaoCS02/api/invoices/v1/add \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer votre_access_token" \
  --user-agent "Mozilla/5.0" \
  --data-binary @- <<'EOF'
{
  "data": {
    "invoiceNumber": "FAC-2026-001",
    "invoiceIssueDate": "2026-04-17T10:00:00+02:00",
    "invoiceTypeCode": "380",
    "invoiceStatus": "EN_ATTENTE",
    "buyerReference": "ACH-12345",
    "purchaseOrderReference": "PO-2026-001",
    "deliveryCode": "BL-2026-001",
    "precedingInvoiceReference": null,
    "sellerReference": "VEND-98765",
    "supplierReference": "FOUR-54321",
    "invoiceReference": "REF-2026-001",
    "invoiceCurrencyCode": "EUR",
    "invoiceTotalAmountWithVAT": 1200.50,
    "invoiceTotalVATAmount": 200.08,
    "invoiceTotalAmountWithoutVAT": 1000.42
  }
}
EOF
  • Remplacez la valeur en rouge carlsource.server.com/gmaoCS02 par l’URL et le contexte de votre instance CARL Source.

  • Remplacez votre_access_token par un token d’authentification valide.

  • Note : pour simplifier les tests, il est possible de remplacer -H "Authorization: Bearer votre_access_token" \ par -u identifiant:mot_de_passe en utilisant un couple login / mot de passe valide.

16.6.1. Exemple avec upload de fichier PDF (multipart/form-data)

Voici un exemple d’appel à l’API d’import de factures externes avec un fichier PDF joint, en utilisant curl :

Exemple avec upload de fichier PDF (multipart/form-data)
DTO=$(cat <<'EOF'
{
  "data": {
    "invoiceNumber": "FAC-2026-001",
    "invoiceIssueDate": "2026-04-17T10:00:00+02:00",
    "invoiceTypeCode": "380",
    "invoiceStatus": "EN_ATTENTE",
    "buyerReference": "ACH-12345",
    "purchaseOrderReference": "PO-2026-001",
    "deliveryCode": "BL-2026-001",
    "precedingInvoiceReference": null,
    "sellerReference": "VEND-98765",
    "supplierReference": "FOUR-54321",
    "invoiceReference": "REF-2026-001",
    "invoiceCurrencyCode": "EUR",
    "invoiceTotalAmountWithVAT": 1200.50,
    "invoiceTotalVATAmount": 200.08,
    "invoiceTotalAmountWithoutVAT": 1000.42
  }
}
EOF
)

curl -X POST \
  https://carlsource.server.com/gmaoCS02/api/invoices/v1/add \
  -H "Authorization: Bearer votre_access_token" \
  --user-agent "Mozilla/5.0" \
  -F "dto=$DTO;type=application/json" \
  -F 'pdf=@/chemin/vers/facture.pdf;type=application/pdf'
  • La partie dto doit être envoyée avec le type de contenu application/json.

  • La partie pdf correspond au fichier PDF à joindre (paramètre required = false : l’envoi du PDF est optionnel).

  • Remplacez la valeur en rouge carlsource.server.com/gmaoCS02 par l’URL et le contexte de votre instance CARL Source.

  • Remplacez votre_access_token par un token d’authentification valide.

  • Remplacez /chemin/vers/facture.pdf par le chemin local vers votre fichier PDF.

17. Echange de données

17.1. Droits d’utilisation

Les droits d’accès aux APIs sont conditionnés par les droits de profil suivants :

  • Echange de données / Interface d’échange / Import : pour les APIs commençant par "api/exchange/v1/import/"

  • Echange de données / Interface d’échange / Export : pour les APIs commençant par "api/exchange/v1/export/"

  • Echange de données / Historique des échanges / Lecture : pour l’API "api/exchange/v1/executions/"

17.2. Export synchrone

Cette API permet d’effectuer un export de données via une interface en mode synchrone. Son résultat correspond au contenu du fichier généré.

  • Signature : api/exchange/v1/export/synchronous/interface/<code de l’interface>

  • Méthode HTTP : POST

  • Corps de message (optionnel) au format JSON avec les propriétés suivantes :

Propriété Obligatoire Définition

customFilterCode

Non

Code du filtre personnalisé

evalParameters

Non

Objet JSON contenant la liste des codes d’attributs sur lesquels appliquer un filtrage, ainsi que l’expression du filtre.
Exemple : {"xtraTxt01": "texte", "xtraNum01": 20} pour retrouver les entités dont l’attribut “xtraTxt01” vaut "texte" et l’attribut “xtraNum01” vaut 20.

Exemple de corps de message :

{
  "customFilterCode": "WO_02",
  "evalParameters": {
    "code": "CTRL*"
  }
}

Exemple d’utilisation de l’API via cURL :

Exécution de l’interface 'USER_OUT' en écrivant le résultat dans le fichier "user_out.xml"
curl -X POST https://carlsource.server.com/gmaoCS02/api/exchange/v1/export/synchronous/interface/USER_OUT \
     -u identifiant:mot_de_passe \
     -o user_out.xml
Utilisation d’un filtre permettant d’exporter les utilisateurs dont le code se termine par "MO" :
curl -X POST https://carlsource.server.com/gmaoCS02/api/exchange/v1/export/synchronous/interface/USER_OUT \
     -u identifiant:mot_de_passe \
     -H 'Content-Type: application/json' \
     -d '{"evalParameters": {"code": "*MO"}}' \
     -o user_out_filtered.xml

17.3. Export asynchrone

Cette API permet d’effectuer un export de données via une interface et/ou un système externe en mode asynchrone.

  • Signatures :

    • Export via une interface : api/exchange/v1/export/asynchronous/interface/<code de l’interface>

    • Export via un système externe : api/exchange/v1/export/asynchronous/external-system/<code du système externe>

    • Export via une interface dans un système externe : api/exchange/v1/export/asynchronous/external-system/<code du système externe>/interface/<code de l’interface>

  • Méthode HTTP : POST

  • Corps de message (optionnel) au format JSON : voir le corps de message du chapitre Export synchrone

  • Réponse au format JSON encapsulée dans la propriété data :

Propriété Obligatoire Définition

messageId

Oui

Identification de l’historique d’échange (voir Suivi des échanges asynchrones)

Exemple d’utilisation de l’API via cURL :

Exécution de l’interface 'USER_OUT' (l’option '-s' permettant d’afficher uniquement le contenu de la réponse) :
curl -s -X POST https://carlsource.server.com/gmaoCS02/api/exchange/v1/export/asynchronous/interface/USER_OUT \
     -H "X-CS-Access-Token: votre_access_token"
Réponse obtenue :
{"data":{"messageId":"0217d44f-c142-46a8-ae17-dd07b04289cf"}}
Exécution de l’interface 'USER_OUT' dans le système externe 'EXT_SYST_XML' avec l’utilisation d’un filtre permettant d’exporter les utilisateurs dont le code se termine par "MO" :
curl -s -X POST https://carlsource.server.com/gmaoCS02/api/exchange/v1/export/asynchronous/external-system/EXT_SYST_XML/interface/USER_OUT \
     -u identifiant:mot_de_passe \
     -H 'Content-Type: application/json' \
     -d '{"evalParameters": {"code": "*MO"}}'
Réponse obtenue :
{"data":{"messageId":"aa72e3dd-00eb-4559-b183-81afead5056e"}}

17.4. Import synchrone

Cette API permet d’effectuer un import de données via une interface et/ou un système externe en mode synchrone.

  • Signatures :

    • Import via une interface : api/exchange/v1/import/synchronous/interface/<code de l’interface>

    • Import via un système externe : api/exchange/v1/import/synchronous/external-system/<code du système externe>

    • Import via une interface dans un système externe : api/exchange/v1/import/synchronous/external-system/<code du système externe>/interface/<code de l’interface>

  • Méthode HTTP : POST

  • Corps de message (optionnel dans le cas d’une utilisation d’un système externe) : contenu de l’échange à importer

  • Réponse au format JSON encapsulée dans la propriété data :

Propriété Obligatoire Définition

status

Oui

Valeur true ou false indiquant la réussite ou l’échec de l’import

errors

Oui

Liste des erreurs remontées durant l’import

Exemples de réponses :

Import réussi :
{
    "data": {
        "status": true,
        "errors": []
    }
}
Import en erreur :
{
    "data": {
        "status": false,
        "errors": [
            "Erreur lors de la validation (costCenter):org.postgresql.util.PSQLException: ERREUR: valeur trop longue pour le type character varying(60) Sur l’élément principal numéro 2 de tag 'costCenter' [srcPos='2' code='SUIVI-PLOMB']\n"
        ]
    }
}

Exemple d’utilisation de l’API via cURL :

Exécution de l’interface 'COSTCENTER_IN_CSV' en fournissant le fichier "costcenter_in.csv" :
curl -s -X POST https://carlsource.server.com/gmaoCS02/api/exchange/v1/import/synchronous/interface/COSTCENTER_IN_CSV \
     -u identifiant:mot_de_passe \
     -d @costcenter_in.csv
Réponse obtenue :
{"data":{"status":true,"errors":[]}}
Exécution de l’interface 'COSTCENTER_IN_CSV' dans le système externe 'EXT_SYST_XML' :
curl -s -X POST https://carlsource.server.com/gmaoCS02/api/exchange/v1/import/synchronous/external-system/EXT_SYS_XML/interface/COSTCENTER_IN_CSV \
     -H "X-CS-Access-Token: votre_access_token" \
Réponse obtenue :
{"data":{"status":true,"errors":[]}}

17.5. Import asynchrone

Cette API permet d’effectuer un import de données via une interface et/ou un système externe en mode asynchrone.

  • Signatures :

    • Import via une interface : api/exchange/v1/import/asynchronous/interface/<code de l’interface>

    • Import via un système externe : api/exchange/v1/import/asynchronous/external-system/<code du système externe>

    • Import via une interface dans un système externe : api/exchange/v1/export/asynchronous/external-system/<code du système externe>/interface/<code de l’interface>

  • Méthode HTTP : POST

  • Corps de message (optionnel dans le cas d’une utilisation d’un système externe) : contenu de l’échange à importer

  • Réponse au format JSON encapsulée dans la propriété data :

Propriété Obligatoire Définition

messageId

Oui

Identification de l’historique d’échange (voir Suivi des échanges asynchrones)

Exemple d’utilisation de l’API via cURL :

Exécution de l’interface 'COSTCENTER_IN_CSV' en fournissant le fichier "costcenter_in.csv" :
curl -s -X POST https://carlsource.server.com/gmaoCS02/api/exchange/v1/import/asynchronous/interface/COSTCENTER_IN_CSV \
     -H "X-CS-Access-Token: votre_access_token" \
     -d @costcenter_in.csv
Réponse obtenue :
{"data":{"messageId":"f2a666e0-70b4-4d26-bf4d-9d950c3cb27b"}}
Exécution de l’interface 'COSTCENTER_IN_CSV' dans le système externe 'EXT_SYST_XML' :
curl -s -X POST https://carlsource.server.com/gmaoCS02/api/exchange/v1/import/asynchronous/external-system/EXT_SYS_XML/interface/COSTCENTER_IN_CSV \
     -H "X-CS-Access-Token: votre_access_token" \
Réponse obtenue :
{"data":{"messageId":"ed122f53-85b0-4303-9f27-2a9b0741ea17"}}

17.6. Suivi des échanges asynchrones

Cette API permet de connaître l’état d’un échange asynchrone.

  • Signature : api/exchange/v1/executions/<messageId>

  • Méthode HTTP : GET

  • Réponse au format JSON encapsulée dans la propriété data :

Propriété Définition

messageId

Identifiant correspondant à l’échange déclenché (contenu dans la réponse des APIs asynchrones)

execStatus

Code du résultat de l’exécution (voir liste de valeurs 'EXCHANGESTATUS')

processStep

Etape de l’échange

processedElements

Nombre d’éléments traités

errorCode

Code d’erreur pour les échanges de données (voir liste de valeurs 'EXCHANGEERROR')

rejectedElements

Nombre d’éléments rejetés

id

Identifiant de l’historique d’échange

links

Objet JSON contenant un lien (propriété self) vers le détail complet de l’historique d’échange

Exemple de réponse :
{
    "data": {
        "messageId": "ed122f53-85b0-4303-9f27-2a9b0741ea17",
        "processStep": "IMPORTATION",
        "execStatus": "OK",
        "processedElements": 1,
        "rejectedElements": 0,
        "id": "19324b43129-53a",
        "links": {
            "self": "https://carlsource.server.com/gmaoCS02/api/entities/v1/interfaceexecution/19324b43129-53a"
        }
    }
}

Exemple d’utilisation de l’API via cURL :

Demande du suivi d’une exécution d’échange ayant pour identifiant "4ddd58d5-8a24-4541-ba15-facddefcb07b" durant laquelle une erreur s’est produite :
curl -s -X POST https://carlsource.server.com/gmaoCS02/api/exchange/v1/executions/4ddd58d5-8a24-4541-ba15-facddefcb07b \
     -H "X-CS-Access-Token: votre_access_token" \
Réponse obtenue :
{
    "data":{
        "messageId":"4ddd58d5-8a24-4541-ba15-facddefcb07b",
        "processStep":"UPLOAD",
        "execStatus":"WARNING",
        "processedElements":0,
        "rejectedElements":0,
        "errorCode":"TECH001",
        "id":"19324b43129-66a",
        "links":{
            "self":"https://carlsource.server.com/gmaoCS02/api/entities/v1/interfaceexecution/19324b43129-66a"
        }
    }
}

18. Conclusion

Vous disposez à présent des informations nécessaires pour prendre en main cette API et interagir avec les objets de CARL Source :

  • s’authentifier,

  • lister, créer, lire, modifier, et supprimer des objets métier,

  • faire évoluer ces objets le long de leur cycle de vie avec les workflow-transitions.

 


Avis de marques déposées

Nous avons apporté tous nos efforts pour garantir l’exactitude des informations au moment de la publication de ce document.
CARL Source étant en constante évolution, CARL Berger-Levrault ne peut être tenu responsable des éventuels manques ou erreurs de ce document.
Si vous relevez une incohérence ou une erreur, merci de contacter le service support de CARL Berger-Levrault.
 
Toute reproduction, en tout ou en partie, sous quelque forme que ce soit, est formellement interdite sans l’autorisation préalable de CARL Berger-Levrault.
 
Toutes les marques et noms de produits mentionnés dans ce document sont les propriétés de leurs détenteurs respectifs telles que répertoriées ci-dessous :

  • Android™ et Google Chrome® sont des marques déposées de Google LLC

  • ArcGIS® est une marque déposée d’Environmental Systems Research Institute.

  • Elasticsearch® est une marque déposée d’Elasticsearch B.V. aux États-Unis et dans d’autres pays.

  • Firefox® est une marque déposée de Mozilla Foundation.

  • Java™ et Oracle® sont des marques déposées d’Oracle Corporation.

  • PostgreSQL® est une marque déposée de The PostgreSQL Community Association of Canada.

  • Safari® est une marque d’Apple Inc., déposée aux États-Unis et dans d’autres pays.

  • Azure®, SQL Server®, Microsoft Edge® et Windows® sont des marques déposées de Microsoft Corporation.

  • Tomcat® est une marque déposée de l’Apache Software Foundation aux États-Unis et dans d’autres pays.