> ## Documentation Index
> Fetch the complete documentation index at: https://api-docs.useopenwrench.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Purchasing flow

# Le flux d'achats : demandes vers commandes vers réceptions

> Parcourez le cycle de vie des achats de l'API Équipes internes de bout en bout : lire les demandes d'achat approuvées, émettre des bons de commande, associer les postes et enregistrer les réceptions.

Ce guide parcourt le cycle de vie des achats de bout en bout avec l'API Équipes internes : les techniciens émettent des **demandes d'achat** (DA), votre système d'achats les transforme en **bons de commande** (BC) avec un vendeur, et les marchandises arrivent comme **réceptions** qui mettent à jour le stock. Il suppose que vous avez une clé d'API partenaire (voir l'[introduction](/partners-api/introduction)).

Tous les exemples supposent :

```bash theme={null}
export BASE="https://api.useopenwrench.com/api/external"
export KEY="<partner-api-key>"      # en-tête X-API-KEY
export SECRET="<shared-secret>"     # en-tête OW-KEY
```

## Vocabulaire des statuts

**Demandes d'achat** : `requested`, `denied`, `cancelled`, `approved`, `orderInProgress`, `ordered`, `partially_ordered`, `fulfilled`, `partially_fulfilled`. Le statut d'une DA est recalculé à partir de ses postes à mesure qu'ils sont associés à des BC, donc la plupart des mouvements se produisent automatiquement.

**Bons de commande** : `new`, `ordered`, `received`, `partially_received`, `cancelled`, `closed`.

## 1. Lire les demandes d'achat approuvées

```bash theme={null}
# Le carnet de commandes à passer
curl -H "X-API-KEY: $KEY" -H "OW-KEY: $SECRET" \
  "$BASE/v1/partners/inventory/purchase_requests?status=approved"

# Une DA avec ses postes de pièces et d'équipement
curl -H "X-API-KEY: $KEY" -H "OW-KEY: $SECRET" \
  "$BASE/v1/partners/inventory/purchase_requests/601"
```

Tout paramètre de requête autre que les paramètres de pagination agit comme un filtre d'égalité sur les colonnes de l'entité (`status=approved`, `stockLocationId=42`), toujours à l'intérieur de la portée de votre entreprise.

Pour une liste de travail multi-DA, interrogez les postes directement :

```bash theme={null}
curl -H "X-API-KEY: $KEY" -H "OW-KEY: $SECRET" \
  "$BASE/v1/partners/inventory/purchase_request_line_items?status=approved"
curl -H "X-API-KEY: $KEY" -H "OW-KEY: $SECRET" \
  "$BASE/v1/partners/inventory/purchase_request_line_items/count_by?status=approved"
```

Les statuts de DA peuvent aussi être définis directement lorsque votre flux d'approbation vit à l'extérieur d'OpenWrench : `PATCH .../purchase_requests/{id}/{status}` pour tout statut du vocabulaire, et `PATCH .../purchase_requests/{id}/cancelled` pour annuler (seulement depuis `requested` ou `approved`; sinon `400`).

## 2. Créer le bon de commande

`POST /v1/partners/inventory/purchase_orders` crée le BC avec ses postes en un seul appel. Requis : `status` (typiquement `new`), `partEquipmentVendorId`, `currencyId` et `createdByEmail`. `totalCost` est requis à moins que les paramètres d'inventaire de votre entreprise ne marquent le coût du BC comme non obligatoire (il est obligatoire par défaut). `supplierCompanyId` et `supplierFacilityId` sont dérivés de votre clé.

```bash theme={null}
curl -X POST "$BASE/v1/partners/inventory/purchase_orders" \
  -H "X-API-KEY: $KEY" -H "OW-KEY: $SECRET" \
  -H "Content-Type: application/json" \
  -d '{
    "status": "new",
    "partEquipmentVendorId": 44,
    "currencyId": "USD",
    "createdByEmail": "purchasing@example.com",
    "stockLocationId": 7,
    "totalBeforeTax": 620.00,
    "tax": 52.70,
    "totalCost": 672.70,
    "incomingLineItems": [
      {
        "isEquipmentLine": false,
        "partId": 210,
        "partQuantity": 2,
        "partUomId": 1,
        "partCost": 310.00,
        "partCurrencyId": "USD",
        "prLineItemIds": [8801, 8802]
      }
    ]
  }'
```

Chaque poste définit `isEquipmentLine` et ensuite soit les champs `part*` soit les champs `equipment*`. `prLineItemIds` enregistre quelles lignes de DA le poste de BC exécute. Passer un `id` de premier niveau remplace les champs modifiables d'un BC existant au lieu d'en créer un nouveau.

### Associer des postes de DA

Si vous n'avez pas relié les DA via `prLineItemIds` au moment de la création, associez-les explicitement :

```bash theme={null}
curl -X PATCH -H "X-API-KEY: $KEY" -H "OW-KEY: $SECRET" \
  "$BASE/v1/partners/inventory/purchase_request_line_items/associate_po_line_item/8801,8802/9902"
```

Chaque poste de DA listé passe à `orderInProgress` avec son `associatedPurchaseOrderLineItemId` défini, et le statut de chaque DA parent est recalculé. Les ids que votre clé ne peut pas lire sont **silencieusement ignorés** (l'appel peut retourner une liste vide), alors vérifiez les éléments retournés contre ce que vous avez envoyé.

### Réviser les postes

`POST /v1/partners/inventory/purchase_order_line_items/bulk` prend un **tableau JSON** de postes, tous référençant le même `supplierPurchaseOrderId`, et a une sémantique de remplacement :

<Warning>
  Tous les postes existants **non reçus** du BC sont d'abord supprimés, puis les postes soumis sont créés. Envoyez à chaque fois l'ensemble complet des lignes ouvertes prévues. Le statut de la ligne n'est pas modifiable ici : les nouvelles lignes commencent comme `new`, et une ligne resoumise avec son `id` conserve son statut.
</Warning>

Les listes d'ids de pièces/équipement/demandes d'achat du BC sont recalculées et la notification de bon de commande est renvoyée. `supplierFacilityId`/`supplierCompanyId` par poste proviennent de votre clé; les éléments sans permission d'écriture sont silencieusement ignorés.

## 3. Marquer la commande passée

```bash theme={null}
curl -X PATCH -H "X-API-KEY: $KEY" -H "OW-KEY: $SECRET" \
  "$BASE/v1/partners/inventory/purchase_orders/350/ordered"
```

Cela définit le BC à `ordered` et envoie la commande au vendeur par courriel. La réponse de succès est l'enveloppe de chaîne de confirmation (`"type": "Email"`, `"data": "Email has been sent"`), et **non** le BC; récupérez à nouveau le BC pour son nouvel état. Pour interrompre plutôt, `PATCH .../purchase_orders/{id}/cancel` (qui retourne le BC mis à jour).

## 4. Enregistrer les réceptions à mesure que les marchandises arrivent

`PUT /v1/partners/inventory/purchase_order_receipts` enregistre une réception sur un poste de BC. Sur cet endpoint, `updatedBy` et `supplierFacilityId` **doivent être fournis dans le corps**; ils ne sont pas dérivés de la clé.

```bash theme={null}
curl -X PUT "$BASE/v1/partners/inventory/purchase_order_receipts" \
  -H "X-API-KEY: $KEY" -H "OW-KEY: $SECRET" \
  -H "Content-Type: application/json" \
  -d '{
    "receiptNumber": "RCPT-1042",
    "purchaseOrderId": 350,
    "purchaseOrderLineItemId": 9902,
    "receivedQuantity": 2,
    "pricePerQuantity": 310.00,
    "updatedBy": "warehouse@example.com",
    "supplierFacilityId": 12
  }'
```

Règles :

* `receiptNumber`, `purchaseOrderId`, `purchaseOrderLineItemId`, `receivedQuantity`, `updatedBy` et `supplierFacilityId` sont requis.
* `receivedQuantity` doit être non nulle; **une valeur négative enregistre un retour**.
* Mettre à jour une réception ajuste les quantités et coûts reçus sur le poste de BC et les fiches de stock à l'emplacement de destination.
* Pour l'équipement sérialisé, envoyez une entrée par unité dans `equipmentPerStockLocationReceiptValues`, `assetReceiptValues` ou `receiptValuesWithoutId`. La longueur du tableau doit égaler `receivedQuantity`, ces tableaux ne peuvent pas accompagner un retour, et les numéros de série ou d'actif déjà utilisés sont rejetés.
* Les métadonnées de facture du vendeur (`invoiceNumber`, `invoiceCurrency`, `invoiceTotal`, `exchangeRate`, `invoiceTotalPostExchange`) peuvent être capturées sur la réception.

Relisez une réception avec `GET /v1/partners/inventory/purchase_order_receipts/{id}`.

## Idempotence et gestion des erreurs

* Les créations ne sont pas idempotentes : réessayer une création de BC en dépassement de délai peut dupliquer la commande. Utilisez l'endpoint de liste avec un filtre (par exemple sur vos références externes de style `receiptNumber`) pour vérifier avant de réessayer.
* Les problèmes de permission apparaissent comme `400` (avec l'enveloppe d'erreur standard), et les ids silencieusement ignorés sur les endpoints en lot et d'association signifient qu'un appel « réussi » peut avoir fait moins que ce que vous avez demandé. Réconciliez toujours la charge utile de réponse contre votre requête.
* Les [endpoints de catalogue](/partners-api/catalog-and-stock) fournissent les valeurs `partId`, `equipmentTypeId`, `partEquipmentVendorId` et `stockLocationId` dont ce flux a besoin.
* Chaque modification de bon de commande, de ligne ou de réception effectuée via ces endpoints est consignée dans le journal d'audit du bon de commande dans OpenWrench, attribuée au contact associé à votre clé d'API.
