Partager via


API publiques Inventory Visibility

Remarque

Azure Active Directory est maintenant Microsoft Entra ID. En savoir plus

Cet article décrit les API publiques fournies par la visibilité des stocks.

L’API REST publique du complément de visibilité des stocks présente plusieurs points de terminaison d’intégration spécifiques. Elle prend en charge quatre types d’interactions :

  • Publication des modifications de stock disponibles du complément à partir d’un système externe
  • Définition ou remplacement des quantités de stock disponible dans le complément à partir d’un système externe
  • Publication des événements de réservation dans le complément à partir d’un système externe
  • Interrogation des quantités en stock actuelles à partir d’un système externe

Le tableau suivant répertorie les API actuellement disponibles :

Chemin méthode Description
/api/environment/{environmentId}/onhand Valider Créer un événement de modification de stock disponible
/api/environment/{environmentId}/onhand/bulk Valider Créer plusieurs événements de modification
/api/environment/{environmentId}/setonhand/{inventorySystem}/bulk Valider Définir/remplacer les quantités de stock disponible
/api/environment/{environmentId}/onhand/reserve Valider Créer un événement de réservation provisoire
/api/environment/{environmentId}/onhand/reserve/bulk Valider Créer plusieurs événements de réservation provisoire
/api/environment/{environmentId}/onhand/unreserve Valider Rétablir un événement de réservation provisoire
/api/environment/{environmentId}/onhand/unreserve/bulk Valider Rétablir plusieurs événements de réservation provisoire
/api/environment/{environmentId}/onhand/reserve/resyncjob Valider Nettoyage des données de réservation
/api/environment/{environmentId}/onhand/changeschedule Valider Créer un changement planifié du stock disponible
/api/environment/{environmentId}/onhand/changeschedule/bulk Valider Créer plusieurs changements disponibles avec dates
/api/environment/{environmentId}/onhand/indexquery Valider Interroger en utilisant la méthode de validation (recommandé)
/api/environment/{environmentId}/onhand Obtenir Interroger en utilisant la méthode get
/api/environment/{environmentId}/onhand/exactquery Valider Interroger avec exactitude en utilisant la méthode post
/api/environment/{environmentId}/allocation/allocate Valider Créer un événement d’affectation
/api/environment/{environmentId}/allocation/unallocate Valider Créer un événement de non affectation
/api/environment/{environmentId}/allocation/reallocate Valider Créer un événement de réaffectation
/api/environment/{environmentId}/allocation/consume Valider Créer un événement de consommation
/api/environment/{environmentId}/allocation/query Valider Résultat d’allocation de requête
/api/environment/{environmentId}/onhand/productsearch/indexquery Valider Valider la requête d’index avec recherche de produits
/api/environment/{environmentId}/onhand/productsearch/exactquery Valider Valider la requête exacte avec recherche de produits

Remarque

La partie {environmentId} du chemin d’accès est l’ID d’environnement dans Microsoft Dynamics Lifecycle Services.

L’API en masse peut renvoyer un maximum de 512 enregistrements pour chaque requête.

Authentification

Le jeton de sécurité de la plateforme est utilisé pour appeler l’API publique de visibilité des stocks. Par conséquent, vous devez générer un jeton Microsoft Entra en utilisant votre application Microsoft Entra. Vous devez ensuite utiliser le jeton Microsoft Entra pour obtenir le jeton d’accès du service de sécurité.

Pour obtenir un jeton de service de sécurité, procédez comme suit.

  1. Connectez-vous au portail Azure et utilisez-le pour trouver les valeurs clientId et clientSecret pour votre application Dynamics 365 Supply Chain Management.

  2. Récupérez un jeton Microsoft Entra (aadToken) en envoyant une requête HTTP avec les propriétés suivantes :

    • URL :https://login.microsoftonline.com/${aadTenantId}/oauth2/v2.0/token

    • Méthode :GET

    • Contenu du corps (données du formulaire) :

      Clé Valeur
      client_id ${aadAppId}
      client_secret ${aadAppSecret}
      grant_type client_credentials
      étendue 0cdb527f-a8d1-4bf8-9436-b352c68682b2/ par défaut

    Vous devriez recevoir un jeton Microsoft Entra (aadToken) en réponse. Elle doit ressembler à l’exemple ci-dessous.

    {
        "token_type": "Bearer",
        "expires_in": "3599",
        "ext_expires_in": "3599",
        "access_token": "eyJ0eX...8WQ"
    }
    
  3. Formulez une requête JavaScript Object Notation (JSON) qui ressemble à l’exemple suivant.

    {
        "grant_type": "client_credentials",
        "client_assertion_type": "aad_app",
        "client_assertion": "{Your_Microsoft EntraToken}",
        "scope": "https://inventoryservice.operations365.dynamics.com/.default",
        "context": "{$LCS_environment_id}",
        "context_type": "finops-env"
    }
    

    Notez les points suivants :

    • La valeur client_assertion doit être le jeton Microsoft Entra (aadToken) que vous avez reçu à l’étape précédente.
    • La valeur context doit être l’ID d’environnement Lifecycle Services dans lequel vous souhaitez déployer le complément.
    • Définissez toutes les autres valeurs comme indiqué dans l’exemple.
  4. Récupérez un jeton d’accès (access_token) en envoyant une requête HTTP avec les propriétés suivantes :

    • URL :https://securityservice.operations365.dynamics.com/token
    • Méthode :POST
    • En-tête HTTP : incluez la version de l’API. (La clé est Api-Version et la valeur est 1.0 .)
    • Contenu du corps : incluez la requête JSON que vous avez créée à l’étape précédente.

    Vous devriez recevoir un jeton (access_token) en réponse. Vous devez utiliser ce jeton comme jeton du porteur pour appeler l’API de visibilité des stocks. Voici un exemple.

    {
        "access_token": "{Returned_Token}",
        "token_type": "bearer",
        "expires_in": 3600
    }
    

Remarque

L’URL https://securityservice.operations365.dynamics.com/token est une URL générale pour le service de sécurité. Lorsque vous appelez l’URL, la première réponse est une réponse de redirection http avec le code d’état 307 dans les en-têtes de réponse, et une entrée avec la clé « Emplacement » qui contient l’URL cible du service de sécurité. L’URL est au format suivant : https://gw.{$geo}-il101.gateway.prod.island.powerapps.com/securityservice/token. Par exemple, si votre environnement se situe aux États-Unis, l’URL peut être « https://gw.us-il101.gateway.prod.island.powerapps.com/securityservice/token. Si le code d’état de la réponse 307 n’est pas acceptable pour vous, vous pouvez créer manuellement l’URL réelle en fonction de l’emplacement de votre environnement FinOps. Le plus simple est d’ouvrir https://gw.as-il101.gateway.prod.island.powerapps.com/securityservice/token avec votre navigateur, puis de copier l’adresse dans la barre d’adresse.

Créer des événements de modification de stock disponible

Il existe deux API pour créer des événements de modification de stock disponible :

  • Créer un enregistrement : /api/environment/{environmentId}/onhand
  • Créer plusieurs enregistrements : /api/environment/{environmentId}/onhand/bulk

Le tableau suivant récapitule la signification de chaque champ dans le corps JSON.

ID champ Description
id Un ID unique pour l’événement de modification spécifique. En cas de nouvelle soumission suite à ce dysfonctionnement de service, cet ID est utilisé pour garantir que le même événement ne sera pas compté deux fois dans le système.
organizationId L’identificateur de l’organisation liée à l’événement. Cette valeur est mappée à un ID d’organisation ou de zone de données dans Supply Chain Management.
productId Identificateur du produit.
quantities Quantité selon laquelle la quantité disponible doit être modifiée. Par exemple, si 10 nouveaux livres sont ajoutés dans un rayon, cette valeur sera quantities:{ shelf:{ received: 10 }}. Si trois livres sont retirés du rayon ou vendus, cette valeur sera quantities:{ shelf:{ sold: 3 }}.
dimensionDataSource Source de données des dimensions utilisées dans l’événement et la requête de modification de publication. Si vous spécifiez la source de données, vous pouvez utiliser les dimensions personnalisées de la source de données spécifiée. La visibilité des stocks peut utiliser la configuration des dimensions pour mapper les dimensions personnalisées aux dimensions générales par défaut. Si aucune valeur dimensionDataSource n’est spécifiée, vous ne pouvez n’utiliser que les dimensions de base générales dans vos requêtes.
dimensions Paire clé-valeur dynamique. Les valeurs sont mappées à certaines des dimensions dans Supply Chain Management. Cependant, vous pouvez également ajouter des dimensions personnalisées (par exemple, Source) pour indiquer si l’événement provient de Supply Chain Management ou d’un système externe.

Remarque

Si votre règle de partitionnement des données est définie sur Par ID de produit, siteId et locationId sont des dimensions facultatives. Sinon, ce sont des dimensions obligatoires. Cette règle s’applique également aux API d’allocation, de réservation provisoire et de planification des modifications.

Les sous-sections suivantes fournissent des exemples qui montrent comment utiliser ces API.

Créer un événement de modification de stock disponible

Cette API crée un seul événement de modification de stock disponible.

Path:
    /api/environment/{environmentId}/onhand
Method:
    Post
Headers:
    Api-Version="1.0"
    Authorization="Bearer $access_token"
ContentType:
    application/json
Body:
    {
        id: string,
        organizationId: string,
        productId: string,
        dimensionDataSource: string, # Optional
        dimensions: {
            [key:string]: string,
        },
        quantities: {
            [dataSourceName:string]: {
                [key:string]: number,
            },
        },
    }

L’exemple suivant montre un exemple de contenu du corps. Dans cet exemple, l’entreprise dispose d’un système de point de vente (PDV) qui traite les transactions en magasin et donc les changements de stock. Le client a retourné un t-shirt rouge dans votre magasin. Pour refléter ce changement, vous valisez un seul événement de modification pour le produit T-shirt. Cet événement augmentera la quantité du produit T-shirt de 1.

{
    "id": "Test201",
    "organizationId": "usmf",
    "productId": "T-shirt",
    "dimensionDataSource": "pos",
    "dimensions": {
        "siteId": "1",
        "locationId": "11",
        "posMachineId": "0001",
        "colorId": "red"
    },
    "quantities": {
        "pos": {
            "inbound": 1
        }
    }
}

L’exemple suivant montre un exemple de contenu du corps sans dimensionDataSource. Dans ce cas, dimensions correspondra aux dimensions de base. Si dimensionDataSource est défini, dimensions peut être soit les dimensions de la source de données, soit les dimensions de base.

{
    "id": "Test202",
    "organizationId": "usmf",
    "productId": "T-shirt",
    "dimensions": {
        "siteId": "1",
        "locationId": "11",
        "colorId": "red"
    },
    "quantities": {
        "pos": {
            "inbound": 1
        }
    }
}

Créer plusieurs événements de modification

Cette API peut créer des événements de modification comme l’API d’événement unique le peut. La seule différence est que cette API peut créer plusieurs enregistrements en même temps. Par conséquent, les valeurs Path et Body diffèrent. Pour cette API, Body fournit un tableau d’enregistrements. Le nombre maximal d’enregistrements est de 512. Ainsi, l’API en bloc des modifications disponibles peut prendre en charge jusqu’à 512 événements de modification à la fois.

Par exemple, un terminal de point de vente d’un magasin de détail a traité les deux transactions suivantes :

  • Une commande de retour d’un t-shirt rouge
  • Une transaction de vente de trois t-shirts noirs

Dans ce cas, vous pouvez inclure les deux mises à jour de stock dans un seul appel d’API.

Path:
    /api/environment/{environmentId}/onhand/bulk
Method:
    Post
Headers:
    Api-Version="1.0"
    Authorization="Bearer $access_token"
ContentType:
    application/json
Body:
    [
        {
            id: string,
            organizationId: string,
            productId: string,
            dimensionDataSource: string, # Optional
            dimensions: {
                [key:string]: string,
            },
            quantities: {
                [dataSourceName:string]: {
                    [key:string]: number,
                },
            },
        },
        ...
    ]

L’exemple suivant montre un exemple de contenu du corps.

[
    {
        "id": "Test203",
        "organizationId": "usmf",
        "productId": "T-shirt",
        "dimensionDataSource": "pos",
        "dimensions": {
            "SiteId": "Site1",
            "LocationId": "11",
            "posMachineId": "0001"
            "colorId": "red"
        },
        "quantities": {
            "pos": { "inbound": 1 }
        }
    },
    {
        "id": "Test204",
        "organizationId": "usmf",
        "productId": "T-shirt",
        "dimensions": {
            "siteId": "1",
            "locationId": "11",
            "colorId": "black"
        },
        "quantities": {
            "pos": { "outbound": 3 }
        }
    }
]

Définir/remplacer les quantités de stock disponible

L’API Set on-hand remplace les données actuelles pour le produit spécifié. Cette fonctionnalité est généralement utilisée pour mettre à jour les comptages de stock. Par exemple, lors de son comptage quotidien de stock, un magasin peut constater que le stock réel disponible pour un t-shirt rouge est de 100. Ainsi, la quantité entrante du PDV doit être mise à jour sur 100, quelle que soit la quantité précédente. Vous pouvez utiliser cette API pour remplacer la valeur existante.

Path:
    /api/environment/{environmentId}/setonhand/{inventorySystem}/bulk
Method:
    Post
Headers:
    Api-Version="1.0"
    Authorization="Bearer $access_token"
ContentType:
    application/json
Body:
    [
        {
            id: string,
            organizationId: string,
            productId: string,
            dimensionDataSource: string, # Optional
            dimensions: {
                [key:string]: string,
            },
            quantities: {
                [dataSourceName:string]: {
                    [key:string]: number,
                },
            },
            modifiedDateTimeUTC: datetime,
        },
        ...
    ]

L’exemple suivant montre un exemple de contenu du corps. Le comportement de cette API diffère du comportement des API décrites dans la section Créer des événements de modification de stock disponible plus haut dans cet article. Dans cet exemple, la quantité du produit T-shirt sera définie sur 1.

[
    {
        "id": "Test204",
        "organizationId": "usmf",
        "productId": "T-shirt",
        "dimensionDataSource": "pos",
        "dimensions": {
            "SiteId": "1",
            "LocationId": "11",
            "posMachineId": "0001"
            "colorId": "red"
        },
        "quantities": {
            "pos": {
                "inbound": 100
            }
        }
    }
]

Créer des événements de réservation

Pour utiliser l’API Reserve, vous devez activer la fonctionnalité de réservation et compléter la configuration de la réservation. Pour plus d’informations (dont un exemple de flux de données et un exemple de scénario), voir Réservations de la visibilité des stocks.

Créer un événement de réservation

Une réservation peut être effectuée pour différents paramètres de source de données. Pour configurer ce type de réservation, indiquez d’abord la source de données dans le paramètre dimensionDataSource. Ensuite, dans le paramètre dimensions, spécifiez les dimensions en fonction des paramètres de dimension dans la source de données cible.

Lorsque vous appelez l’API de réservation, vous pouvez contrôler la validation de la réservation en spécifiant le paramètre booléen ifCheckAvailForReserv dans le corps de la requête. Une valeur True signifie que la validation est requise, alors qu’une valeur False signifie que la validation n’est pas requise. La valeur par défaut est True.

Si vous souhaitez créer une réservation ou annuler la réservation de quantités de stock spécifiées, définissez la quantité sur une valeur négative et définissez le paramètre ifCheckAvailForReserv sur False pour ignorer la validation. Il existe également une API d’annulation dédiée pour faire de même. La différence réside uniquement dans la manière dont les deux API sont appelées. Il est plus facile d’annuler un événement de réservation spécifique en utilisant reservationId avec l’API annuler la réservation. Pour plus d’informations, voir la section Annuler un événement de réservation.

Path:
    /api/environment/{environmentId}/onhand/reserve
Method:
    Post
Headers:
    Api-Version="1.0"
    Authorization="Bearer $access_token"
ContentType:
    application/json
Body:
    {
        id: string,
        organizationId: string,
        productId: string,
        dimensionDataSource: string,
        dimensions: {
            [key:string]: string,
        },
        quantityDataSource: string, # optional
        quantities: {
            [dataSourceName:string]: {
                [key:string]: number,
            },
        },
        modifier: string,
        quantity: number,
        ifCheckAvailForReserv: boolean,
    }

L’exemple suivant montre un exemple de contenu du corps.

{
    "id": "reserve-0",
    "organizationId": "SCM_IV",
    "productId": "iv_contoso_product",
    "quantity": 1,
    "quantityDataSource": "iv",
    "modifier": "softReservOrdered",
    "ifCheckAvailForReserv": true,
    "dimensions": {
        "siteId": "iv_contoso_site",
        "locationId": "iv_contoso_location",
        "colorId": "red",
        "sizeId": "small"
    }
}

L’exemple suivant montre une réponse réussie.

{
    "reservationId": "RESERVATION_ID",
    "id": "ohre~id-822-232959-524",
    "processingStatus": "success",
    "message": "",
    "statusCode": 200
}

Créer plusieurs événements de réservation

Cette API est une version en bloc de l’API d’événement unique.

Path:
    /api/environment/{environmentId}/onhand/reserve/bulk
Method:
    Post
Headers:
    Api-Version="1.0"
    Authorization="Bearer $access_token"
ContentType:
    application/json
Body:
    [
        {
            id: string,
            organizationId: string,
            productId: string,
            dimensionDataSource: string,
            dimensions: {
                [key:string]: string,
            },
            quantityDataSource: string, # optional
            quantities: {
                [dataSourceName:string]: {
                    [key:string]: number,
                },
            },
            modifier: string,
            quantity: number,
            ifCheckAvailForReserv: boolean,
        },
        ...
    ]

Annuler des événements de réservation

L’API Annuler la réservation sert d’opération d’annulation pour les événements de réservation. Elle fournit un moyen d’annuler un événement de réservation spécifié par reservationId ou pour diminuer la quantité de réservation.

Annuler un événement de réservation

Lorsqu’une réservation est créée, un reservationId est inclus dans le corps de la réponse. Vous devez fournir le même reservationId pour annuler la réservation, et inclure le même organizationId, productId et le dimensions utilisés pour l’appel de l’API de réservation. Enfin, spécifiez une valeur OffsetQty qui représente le nombre d’éléments à libérer de la réservation précédente. Une réservation peut être entièrement ou partiellement annulée en fonction de la condition OffsetQty spécifiée. Par exemple, si 100 unités d’éléments ont été réservées, vous pouvez spécifier OffsetQty: 10 pour annuler la réservation 10 du montant initialement réservé.

Path:
    /api/environment/{environmentId}/onhand/unreserve
Method:
    Post
Headers:
    Api-Version="1.0"
    Authorization="Bearer $access_token"
ContentType:
    application/json
Body:
    {
        id: string,
        organizationId: string,
        productId: string,
        reservationId: string,
        dimensions: {
            [key:string]: string,
        },
        OffsetQty: number
    }

Le code suivant montre un exemple de contenu du corps.

{
    "id": "unreserve-0",
    "organizationId": "SCM_IV",
    "productId": "iv_contoso_product",
    "reservationId": "RESERVATION_ID",
    "dimensions": {
        "siteid":"iv_contoso_site",
        "locationid":"iv_contoso_location",
        "ColorId": "red",
        "SizeId": "small"
    },
    "OffsetQty": 1
}

Le code suivant montre un exemple de corps de réponse réussie.

{
    "reservationId": "RESERVATION_ID",
    "totalInvalidOffsetQtyByReservId": 0,
    "id": "ohoe~id-823-11744-883",
    "processingStatus": "success",
    "message": "",
    "statusCode": 200
}

Note

Dans le corps de la réponse, lorsque OffsetQty est inférieur ou égal à la quantité réservée, processingStatus est « Succès » et totalInvalidOffsetQtyByReservId est 0.

Si la condition OffsetQty est supérieure au montant réservé, processingStatus est « partialSuccess » et totalInvalidOffsetQtyByReservId est la différence entre OffsetQty et le montant réservé.

Par exemple, si la réservation a une quantité de 10, et OffsetQty a une valeur de 12, totalInvalidOffsetQtyByReservId est 2.

Annuler plusieurs événements de réservation

Cette API est une version en bloc de l’API d’événement unique.

Path:
    /api/environment/{environmentId}/onhand/unreserve/bulk
Method:
    Post
Headers:
    Api-Version="1.0"
    Authorization="Bearer $access_token"
ContentType:
    application/json
Body:
    [      
        {
            id: string,
            organizationId: string,
            productId: string,
            reservationId: string,
            dimensions: {
                [key:string]: string,
            },
            OffsetQty: number
        }
        ...
    ]

Nettoyage des données de réservation

L’API nettoyer les données de réservation est utilisée pour nettoyer les données de réservation historiques. Le corps doit être une liste de sources de données. Si la liste est vide, toutes les sources de données seront nettoyées.

Path:
    /api/environment/{environmentId}/onhand/reserve/resyncjob
Method:
    Post
Headers:
    Api-Version="1.0"
    Authorization="Bearer $access_token"
ContentType:
    application/json
Body:
    [      
        "iv",
        "pos"
    ]

Interroger le stock disponible

Utilisez l’API Query on-hand pour récupérer les données de stock disponible actuelles pour vos produits. Vous pouvez utiliser cette API chaque fois que vous devez connaître le stock, par exemple pour consulter les niveaux de stock des produits sur votre site Web d’e-commerce ou pour vérifier la disponibilité des produits dans les régions ou dans les magasins et entrepôts à proximité. L’API prend actuellement en charge l’interrogation de jusqu’à 5000 éléments individuels par valeur productID. Plusieurs valeurs siteID et locationID peuvent également être spécifiées dans chaque requête. Lorsque votre règle de partitionnement des données est définie sur Par emplacement, la limite maximale est définie par l’équation suivante :

NumOf(SiteID) × NumOf(LocationID) <= 10 000.

Interroger en utilisant la méthode post

L’API de requête par post est disponible en deux versions. Le tableau suivant présente les différences.

API version 1.0 API version 2.0
Ne peut interroger qu’un seul ID d’organisation. Peut interroger plusieurs ID d’organisation.
Peut interroger jusqu’à 10 000 combinaisons de sites et d’entrepôts. Peut interroger plus de 10 000 combinaisons d’ID d’organisation, de sites et d’entrepôts. Peut renvoyer des résultats sur plusieurs pages.

Les sous-sections suivantes montrent comment utiliser chaque version de l’API.

Requête par post API version 1.0

Path:
    /api/environment/{environmentId}/onhand/indexquery
Method:
    Post
Headers:
    Api-Version="1.0"
    Authorization="Bearer $access_token"
ContentType:
    application/json
Body:
    {
        dimensionDataSource: string, # Optional
        filters: {
            organizationId: string[],
            productId: string[],
            siteId: string[],
            locationId: string[],
            [dimensionKey:string]: string[],
        },
        groupByValues: string[],
        returnNegative: boolean,
    }

Dans le corps de cette requête, dimensionDataSource est un paramètre facultatif. S’il n’est pas défini, filters sera traité comme dimensions de base.

Le paramètre returnNegative contrôle si les résultats contiennent des entrées négatives.

Interroger les données stockées par emplacement

Cette section s’applique lorsque votre règle de partitionnement des données est définie sur Par emplacement.

  • organizationId doit être un groupe contenant exactement une valeur.
  • productId peut contenir une ou plusieurs valeurs. S’il s’agit d’un tableau vide, le système renverra tous les produits des sites et emplacements spécifiés. Dans ce cas, siteId et locationId ne doivent pas être vides.
  • siteId et locationId sont utilisés pour le partitionnement. Vous pouvez spécifier plusieurs valeurs siteId et locationId dans une requête Requête en main. Si les deux tableaux sont vides, le système renverra tous les sites et emplacements des produits spécifiés. Dans ce cas, productId ne doit pas être vide.

Nous vous recommandons d’utiliser le paramètre groupByValues d’une manière cohérente avec la configuration de votre index. Pour plus d’informations, voir Configuration de la hiérarchie d’index disponible.

Interroger les données stockées par ID de produit

Cette section s’applique lorsque votre règle de partitionnement des données est définie sur Par ID de produit. Dans ce cas, deux filters champs sont requis : organizationId, productId.

  • organizationId doit être un groupe contenant exactement une valeur.
  • productId doit être un groupe contenant au moins une valeur.

Contrairement au stockage des données par emplacement, si vous ne spécifiez pas de valeurs pour siteId et locationId, les informations de stock pour chaque ID produit seront regroupées sur tous les sites et/ou emplacements.

Remarque

Si vous avez activé les fonctionnalités de planification des changements de stock disponible et de disponibilité à la vente (DAV), votre requête peut également inclure le paramètre booléen QueryATP, qui contrôle si les résultats de la requête incluent des informations DAV. Pour plus d’informations et des exemples, voir Plannings de changement du stock disponible et disponibilité à la vente de la Inventory Visibility.

L’exemple suivant montre un exemple de contenu du corps. Il montre que vous pouvez interroger le stock disponible à partir de plusieurs emplacements (entrepôts).

{
    "dimensionDataSource": "pos",
    "filters": {
        "organizationId": ["usmf"],
        "productId": ["T-shirt"],
        "siteId": ["1"],
        "locationId": ["11","12","13"],
        "colorId": ["red"]
    },
    "groupByValues": ["colorId", "sizeId"],
    "returnNegative": true
}

L’exemple suivant montre comment interroger tous les produits d’un site et d’un emplacement spécifiques.

{
    "filters": {
        "organizationId": ["usmf"],
        "productId": [],
        "siteId": ["1"],
        "locationId": ["11"],
    },
    "groupByValues": ["colorId", "sizeId"],
    "returnNegative": true
}

Requête par post API version 2.0

Path:
    /api/environment/{environmentId}/onhand/indexquery?pageNumber={pageNumber}&pageSize={pageSize}
Method:
    Post
Headers:
    Api-Version="2.0"
    Authorization="Bearer $access_token"
ContentType:
    application/json
Body:
    # Same as version 1.0

Le format de requête pour l’API version 2.0 est similaire à celui de la version 1.0, mais prend également en charge deux paramètres facultatifs : pageNumber et pageSize, qui permettent au système de diviser un seul résultat volumineux en plusieurs des documents plus petits. Les résultats sont triés par entrepôt (locationId) et les paramètres sont utilisés comme suit pour diviser les résultats en pages :

  • pageSize établit le nombre d’entrepôts (locationId valeurs) renvoyés dans chaque page.
  • pageNumber établit le numéro de page renvoyé.

Une requête de ce format renvoie les données d’inventaire disponibles à partir du numéro d’entrepôt ({pageNumber} − 1) × {pageSize} et inclut les données pour le prochain {pageSize} entrepôts.

L’API version 2.0 répond avec un document qui utilise la structure suivante :

{
    Value: { # Response same as Api-Version=1.0 }
    nextLink: onhand/indexquery?pageNumber={pageNumber+1}&pageSize={pageSize}
}

Lorsque la requête atteint le dernier entrepôt (locationId), la nextLink valeur est une chaîne vide.

L’API version 2.0 vous permet également de spécifier plusieurs ID d’organisation dans votre demande. Pour ce faire, incluez une liste d’ID d’organisation séparés par des virgules dans le organizationId filtre de votre document de demande. Par exemple, "organizationId": ["org1", "org2", "org3"].

Interroger en utilisant la méthode get

Path:
    /api/environment/{environmentId}/onhand
Method:
    Get
Headers:
    Api-Version="1.0"
    Authorization="Bearer $access_token"
ContentType:
    application/json
Query(Url Parameters):
    groupBy
    returnNegative
    [Filters]

Voici un exemple d’URL pour get. Cette requête get est exactement la même que l’exemple post fourni précédemment.

/api/environment/{environmentId}/onhand?organizationId=SCM_IV&productId=iv_contoso_product&siteId=iv_contoso_site&locationId=iv_contoso_location&colorId=red&groupBy=colorId,sizeId&returnNegative=true

Le système ne prend pas en charge l’interrogation d’inventaire sur plusieurs ID d’organisation avec la méthode GET.

Requête exacte disponible

Les requêtes exactes disponibles ressemblent aux requêtes disponibles classiques à la différence qu’elle vous permettent de spécifier une hiérarchie de mappage entre un site et un emplacement. Par exemple, vous avez les deux sites suivants :

  • Site 1, qui est mappé à l’emplacement A
  • Site 2, qui est mappé à l’emplacement B

Pour une requête de stock disponible classique, si vous spécifiez "siteId": ["1","2"] et "locationId": ["A","B"], Inventory Visibility interroge automatiquement le résultat des sites et emplacements suivants :

  • Site 1, emplacement A
  • Site 1, emplacement B
  • Site 2, emplacement A
  • Site 2, emplacement B

Comme vous le constatez, la requête de stock disponible standard ne voit pas que l’emplacement A n’existe que sur le site 1 et que l’emplacement B n’existe que sur le site 2. Par conséquent, il effectue des requêtes redondantes. Pour prendre en charge ce mappage hiérarchique, vous pouvez utiliser une requête exacte disponible et spécifier les mappages d’emplacement dans le corps de la requête. Dans ce cas, vous interrogez et recevez des résultats uniquement pour site 1, emplacement A et site 2, emplacement B.

Requête de requête exacte disponible à l’aide de la méthode post

L’API de requête exacte disponible par post est disponible en deux versions. Le tableau suivant présente les différences.

API version 1.0 API version 2.0
Ne peut interroger qu’un seul ID d’organisation. Peut interroger plusieurs ID d’organisation.

Requête exacte disponible par post-API version 1.0

Path:
    /api/environment/{environmentId}/onhand/exactquery
Method:
    Post
Headers:
    Api-Version="1.0"
    Authorization="Bearer $access_token"
ContentType:
    application/json
Body:
    {
        dimensionDataSource: string, # Optional
        filters: {
            organizationId: string[],
            productId: string[],
            dimensions: string[],
            values: string[][],
        },
        groupByValues: string[],
        returnNegative: boolean,
    }

Dans le corps de cette requête, dimensionDataSource est un paramètre facultatif. S’il n’est pas défini, dimensions dans filters sera traité comme dimensions de base. Il y a quatre champs obligatoires pour filters : organizationId, productId, dimensions et values.

  • organizationId ne doit contenir qu’une seule valeur, mais c’est tout de même un tableau.
  • productId peut contenir une ou plusieurs valeurs. Si c’est un tableau vide, tous les produits seront renvoyés.
  • Dans le groupe dimensions, siteId et locationId sont obligatoires si et seulement si votre règle de partitionnement des données est définie sur Par emplacement. Dans ce cas, ils peuvent apparaître avec d’autres éléments dans n’importe quel ordre.
  • values peut contenir un ou plusieurs tuples distincts de valeurs correspondant à dimensions.

dimensions dans filters sera ajouté automatiquement à groupByValues.

Le paramètre returnNegative contrôle si les résultats contiennent des entrées négatives.

L’exemple suivant montre un exemple de contenu du corps.

{
    "dimensionDataSource": "pos",
    "filters": {
        "organizationId": ["SCM_IV"],
        "productId": ["iv_contoso_product"],
        "dimensions": ["siteId", "locationId", "colorId"],
        "values" : [
            ["iv_contoso_site", "iv_contoso_location", "red"],
            ["iv_contoso_site", "iv_contoso_location", "blue"],
        ]
    },
    "groupByValues": ["colorId", "sizeId"],
    "returnNegative": true
}

L’exemple suivant montre comment interroger tous les produits de plusieurs sites et emplacements.

{
    "filters": {
        "organizationId": ["SCM_IV"],
        "productId": [],
        "dimensions": ["siteId", "locationId"],
        "values" : [
            ["iv_contoso_site_1", "iv_contoso_location_1"],
            ["iv_contoso_site_2", "iv_contoso_location_2"],
        ]
    },
    "groupByValues": ["colorId", "sizeId"],
    "returnNegative": true
}

Requête exacte disponible via l’API post-version 2.0

Path:
    /api/environment/{environmentId}/onhand/exactquery
Method:
    Post
Headers:
    Api-Version="2.0"
    Authorization="Bearer $access_token"
ContentType:
    application/json
Body:
    {
        dimensionDataSource: string, # Optional
        filters: {
            productId: string[],
            keys: string[],
            values: string[][],
        },
        groupByValues: string[],
        returnNegative: boolean,
    }

La version 2.0 de l’API diffère de la version 1.0 des manières suivantes :

  • La filters section comporte désormais un keys champ au lieu d’un dimensions champ. Le keys champ fonctionne comme le dimensions champ de la version 1.0, mais peut désormais également inclure organizationId. Vous pouvez spécifier les clés dans n’importe quel ordre.
  • La filters section ne prend plus en charge le organizationId champ. Au lieu de cela, vous pouvez inclure organizationId parmi les dimensions dans le keys champ (par exemple, keys: ["organizationId", "siteId", "locationId"]) et définir les valeurs d’ID d’organisation à la position correspondante dans le values champ (par exemple, values: ["SCM_IV", "iv_contoso_site_1", "iv_contoso_location_1"]).

Les autres champs sont identiques à la version 1.0 de l’API.

Requête avec recherche de produit

Les API de requête disponibles suivantes ont été améliorées pour prendre en charge la recherche de produits :

Remarque

Lorsque vous validez une requête Inventory Visibility qui utilise la recherche de produits, utilisez le paramètre de requête productSearch (avec un objet à l’intérieur ProductAttributeQuery) pour rechercher ou filtrer par ID de produit. Les API les plus récentes ne prennent plus en charge l’ancien paramètre de requête productid dans le corps de la requête.

Conditions préalables

Avant de pouvoir commencer à utiliser les API de recherche de produits, votre système doit répondre aux exigences suivantes :

Contrat de recherche de produit

Le contrat de recherche de produit définit les règles de communication avec les API de recherche de produits. Il fournit une manière standardisée de décrire les capacités et le comportement des fonctionnalités de recherche de produits. Par conséquent, les utilisateurs peuvent plus facilement comprendre, interagir avec et créer des applications qui utilisent les API Inventory Visibility.

L’exemple suivant montre un exemple de contrat.

{
    "productFilter": {
        "logicalOperator": "And",
        "conditions": [
            {
                "conditionOperator": "Contains",
                "productName": [
                    "Deluxe"
                ],
            },
        ],
        "subFilters": [
            {
                "conditions": [
                    {
                        "conditionOperator": "IsExactly",
                        "productType": [
                            "Item"
                        ]
                    }
                ]
            }
        ]
    },
    "attributeFilter": {
        "logicalOperator": "Or",
        "conditions": [
            {
                "attributeName": "Weight Limit",
                "attributeTypeName":"PoundDomain",
                "attributeArea": " ProductAttribute",
                "attributeValues": [
                    "370"
                ],
                "conditionOperator": "GreaterEqual"
            }
        ],
        "subFilters": [
            {
                "conditions": [
                    {
                        "attributeName": "Weight Limit",
                        "attributeTypeName":"PoundDomain",
                        "attributeArea": " ProductAttribute",
                        "attributeValues": [
                            "330"
                        ],
                        "conditionOperator": "LessEqual"
                    }
                ]
            }
        ]
    },
}

La table suivante décrit les champs utilisés dans le contrat.

ID champ Description
logicalOperator Les valeurs possibles sont And et Or. Utilisez ce champ pour connecter plusieurs conditions ou conditions et sous-filtres. Notez que subFilters est en fait un objet productFilter ou attributeFilter. Vous pouvez donc avoir subFilters à l’intérieur subFilters.
conditionOperator Les valeurs possibles sont IsExactly, IsNot, Contains, DoesNotContain, BeginsWith, IsOneOf, GreaterEqual, LessEqual et Between.
ProductFilter Utilisez ce champ pour filtrer les produits par informations relatives au produit. Par exemple, vous pouvez modifier productName dans le contrat par Company, itemNumber, productSearchName, productType, productName, productDescription, inventoryUnitSymbol, salesUnitSymbol, ou purchaseUnitSymbol pour répondre aux besoins de votre entreprise.
AttributeFilter Utilisez ce champ pour filtrer les produits par informations relatives à l’attribut.
attributeArea Les valeurs possibles sont ProductAttribute, DimensionAttribute et BatchAttribute.
Path:
    /api/environment/{environmentId}/onhand/productsearch/indexquery
Method:
    Post
Headers:
    Api-Version="1.0"
    Authorization="Bearer $access_token"
ContentType:
    application/json
Body:
    {
        productSearch: {ProductAttributeQuery contract object inherited from Product Search}
            dimensionDataSource: string, # Optional
            filters: {
                organizationId: string[],
                siteId: string[],
                locationId: string[],
                [dimensionKey:string]: string[],
            },
            groupByValues: string[],
            returnNegative: boolean,
    }

L’exemple suivant montre un exemple de contenu du corps.

{
    "productSearch": {
        "productFilter": {
            "conditions": [
                {
                    "conditionOperator": "contains",
                    "productName": [
                        "speaker cable"
                    ],
                },
            ],
        },
    },
    "returnNegative": true, 
    "filters": 
    {
        "organizationId": ["usmf"], 
        "siteId": ["1"], 
        "locationId": ["13"],
    },
    "groupByValues": ["colorid"],
}

L’exemple suivant montre une réponse réussie.

[
    {
        "productId": "M0030",
        "dimensions": {
            "ColorId": "White",
            "siteid": "1",
            "locationid": "13"
        },
        "quantities": {
            "fno": {
                "arrived": 0,
                "availordered": 20,
                "onorder": 5,
                "ordered": 20,
                "physicalinvent": 0,
                "reservordered": 0,
                "reservphysical": 0,
                "orderedsum": 20,
                "softreserved": 0
            },
            "iv": {
                "ordered": 0,
                "softreserved": 0,
                "softreservphysical": 0,
                "softreservordered": 0,
                "total ordered": 20,
                "total on order": 5,
                "availabletoreserve": 20,
                "totalavailable": 20,
                "totalordered": 20,
                "totalonorder": 5
            },
            "pos": {
                "inbound": 0,
                "outbound": 0
            },
            "@iv": {
                "@allocated": 0
            }
        }
    },
    {
        "productId": "M0030",
        "dimensions": {
            "ColorId": "Black",
            "siteid": "1",
            "locationid": "13"
        },
        "quantities": {
            "fno": {
                "arrived": 0,
                "availordered": 3,
                "ordered": 3,
                "physicalinvent": 0,
                "reservordered": 0,
                "reservphysical": 0,
                "orderedsum": 3,
                "softreserved": 0
            },
            "iv": {
                "ordered": 0,
                "softreserved": 0,
                "softreservphysical": 0,
                "softreservordered": 0,
                "total ordered": 3,
                "availabletoreserve": 3,
                "totalavailable": 3,
                "totalordered": 3
            },
            "pos": {
                "inbound": 0,
                "outbound": 0
            },
            "@iv": {
                "@allocated": 0
            }
        }
    }
]
Path:
    /api/environment/{environmentId}/onhand/productsearch/exactquery
Method:
    Post
Headers:
    Api-Version="1.0"
    Authorization="Bearer $access_token"
ContentType:
    application/json
Body:
    {
        productSearch: {ProductAttributeQuery contract object inherited from Product Search}
            dimensionDataSource: string, # Optional
            filters: {
                organizationId: string[],
                dimensions: string[],
                values: string[][],
            },
            groupByValues: string[],
            returnNegative: boolean,
    }

L’exemple suivant montre un exemple de contenu du corps.

{
    "productSearch": {
        "productFilter": {
            "conditions": [
                {
                    "conditionOperator": "contains",
                    "productName": [
                        "speaker cable"
                    ],
                },
            ],
        },
    },
    "filters": {
        "organizationId": ["usmf"],
        "dimensions": ["siteId", "locationId", "colorid"],
        "values" : [
            ["1", "13", "Black"],
        ]
    },
    "groupByValues": [],
    "returnNegative": true
}

L’exemple suivant montre une réponse réussie.

[
    {
        "productId": "M0030",
        "dimensions": {
            "ColorId": "Black",
            "siteid": "1",
            "locationid": "13"
        },
        "quantities": {
            "fno": {
                "arrived": 0,
                "availordered": 3,
                "ordered": 3,
                "physicalinvent": 0,
                "reservordered": 0,
                "reservphysical": 0,
                "orderedsum": 3,
                "softreserved": 0
            },
            "iv": {
                "ordered": 0,
                "softreserved": 0,
                "softreservphysical": 0,
                "softreservordered": 0,
                "total ordered": 3,
                "availabletoreserve": 3,
                "totalavailable": 3,
                "totalordered": 3
            },
            "pos": {
                "inbound": 0,
                "outbound": 0
            },
            "@iv": {
                "@allocated": 0
            }
        }
    }
]

Disponible à la vente

Vous pouvez configurer la Inventory Visibility pour vous permettre de planifier les futurs changements de stock et de calculer les quantités DAV. Le DAV correspond à la quantité d’un article qui est disponible et peut être promise à un client dans le courant d’une période à venir. L’utilisation du calcul de la DAV peut augmenter considérablement votre capacité de traitement des commandes. Pour plus d’informations sur l’activation de cette fonctionnalité et sur l’interaction avec la Inventory Visibility via son API une fois la fonctionnalité activée, consultez Plannings de changement du stock disponible et disponibilité à la vente de la Inventory Visibility.

Allocation

Les API liées à l’allocation sont situées dans Allocation de la visibilité des stocks.