Hoppa till innehållet
ShopentlyLearn

Skapa · Lagerjustering — Lager

Utför ”Skapa · Lagerjustering” i ”Lager” med uppgifterna som beskrivs nedan.

POST/api/v1/inventory/stock-adjustments

Autentisering
Bearer
Tillgänglig från
STANDARD
Behörigheter som krävs
inventory.stock:update

Kodexempel

Exempel på begäran

cURL

: "${SHOPENTLY_SHOP_URL:?}"

curl --disable --globoff --fail-with-body --silent --show-error \
  --proto '=https' --connect-timeout 5 --max-time 30 \
  --request POST \
  --header "Authorization: Bearer ${SHOPENTLY_ACCESS_TOKEN:?}" \
  --header 'Idempotency-Key: example-create_adjustment_api_v1_inventory_stock_adjustments_post' \
  --header 'Content-Type: application/json' \
  --data-raw '{
  "expected_version": 0,
  "locations": [
    {
      "location_id": "example",
      "on_hand": 1
    }
  ],
  "reason": "Example",
  "target_id": "example",
  "target_type": "product",
  "warehouse_id": "example"
}' \
  --url "${SHOPENTLY_SHOP_URL%/}"/api/v1/inventory/stock-adjustments

PHP

<?php
declare(strict_types=1);

$baseUrl = rtrim(getenv('SHOPENTLY_SHOP_URL') ?: '', '/');
$origin = parse_url($baseUrl);
if (!$origin || ($origin['scheme'] ?? '') !== 'https' || empty($origin['host']) ||
    isset($origin['user'], $origin['pass']) || isset($origin['user']) || isset($origin['path']) ||
    isset($origin['query']) || isset($origin['fragment'])) {
    throw new RuntimeException('SHOPENTLY_SHOP_URL must be an HTTPS origin');
}
$credential = getenv('SHOPENTLY_ACCESS_TOKEN') ?: '';
if ($credential === '' || strpbrk($credential, "\r\n") !== false) {
    throw new RuntimeException('Invalid credential');
}
$headers = ['Idempotency-Key: example-create_adjustment_api_v1_inventory_stock_adjustments_post', 'Content-Type: application/json'];
$headers[] = 'Authorization: Bearer ' . $credential;
$responseHeaders = [];
$handle = curl_init($baseUrl . '/api/v1/inventory/stock-adjustments');
curl_setopt_array($handle, [
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_HTTPHEADER => $headers,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_FOLLOWLOCATION => false,
    CURLOPT_PROTOCOLS => CURLPROTO_HTTPS,
    CURLOPT_SSL_VERIFYPEER => true,
    CURLOPT_SSL_VERIFYHOST => 2,
    CURLOPT_CONNECTTIMEOUT => 5,
    CURLOPT_TIMEOUT => 30,
    CURLOPT_HEADERFUNCTION => static function ($handle, string $line) use (&$responseHeaders): int {
        if (str_contains($line, ':')) {
            [$name, $value] = explode(':', $line, 2);
            $responseHeaders[strtolower(trim($name))] = trim($value);
        }
        return strlen($line);
    },
]);
curl_setopt($handle, CURLOPT_POSTFIELDS, '{
  "expected_version": 0,
  "locations": [
    {
      "location_id": "example",
      "on_hand": 1
    }
  ],
  "reason": "Example",
  "target_id": "example",
  "target_type": "product",
  "warehouse_id": "example"
}');
$raw = curl_exec($handle);
$status = curl_getinfo($handle, CURLINFO_RESPONSE_CODE);
$error = curl_error($handle);
curl_close($handle);
if ($raw === false) {
    throw new RuntimeException('Transport error: ' . $error);
}
if ($status < 200 || $status >= 300) {
    throw new RuntimeException('HTTP ' . $status . '; request_id=' .
        ($responseHeaders['x-request-id'] ?? '') . '; retry_after=' . ($responseHeaders['retry-after'] ?? ''));
}
$result = $raw === '' ? null : json_decode($raw, true, 512, JSON_THROW_ON_ERROR | JSON_BIGINT_AS_STRING);
echo json_encode($result, JSON_THROW_ON_ERROR | JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;

Python

from contextlib import ExitStack
import json
import os
from urllib.parse import urlsplit

import requests  # python -m pip install requests

base_url = os.environ["SHOPENTLY_SHOP_URL"].rstrip("/")
origin = urlsplit(base_url)
if origin.scheme != "https" or not origin.hostname or origin.username or origin.password or origin.path or origin.query or origin.fragment:
    raise ValueError("SHOPENTLY_SHOP_URL must be an HTTPS origin")
credential = os.environ['SHOPENTLY_ACCESS_TOKEN']
if not credential or "\r" in credential or "\n" in credential:
    raise ValueError("Invalid credential")
headers = {'Idempotency-Key': 'example-create_adjustment_api_v1_inventory_stock_adjustments_post'}
headers["Authorization"] = 'Bearer' + " " + credential
body = '{\n  "expected_version": 0,\n  "locations": [\n    {\n      "location_id": "example",\n      "on_hand": 1\n    }\n  ],\n  "reason": "Example",\n  "target_id": "example",\n  "target_type": "product",\n  "warehouse_id": "example"\n}'
if body is not None:
    headers["Content-Type"] = "application/json"

with ExitStack() as stack:
    session = stack.enter_context(requests.Session())
    files = None
    if False:
        image = stack.enter_context(open(os.environ["SHOPENTLY_IMAGE_FILE"], "rb"))
        if os.fstat(image.fileno()).st_size > 5242880:
            raise ValueError("Image exceeds 5 MiB")
        files = {"file": ("article.png", image, "image/png")}
    response = session.request(
        'POST', base_url + '/api/v1/inventory/stock-adjustments', headers=headers,
        data=body.encode("utf-8") if body is not None else None, files=files,
        timeout=(5, 30), allow_redirects=False,
    )
    if not 200 <= response.status_code < 300:
        raise RuntimeError(f"HTTP {response.status_code}; request_id={response.headers.get('X-Request-ID', '')}; retry_after={response.headers.get('Retry-After', '')}")
    if False:
        if response.headers.get("Content-Type") != "image/webp" or len(response.content) > 5242880:
            raise ValueError("Unexpected image response")
        with open(os.environ["SHOPENTLY_OUTPUT_FILE"], "xb") as output:
            output.write(response.content)
    else:
        result = response.json() if response.content else None
        print(json.dumps(result, ensure_ascii=False, indent=2))

Exempel på svar 201

JSON
{
  "data": {
    "deleted": false,
    "id": "stock_v1_WyJleGFtcGxlIiwicHJvZHVjdCIsImV4YW1wbGUiXQ",
    "version": 1
  },
  "meta": {
    "request_id": "example"
  }
}

Så fungerar det

  • Lagerposter skiljer mellan fysisk kvantitet on_hand, orderreservationer, manuella reservationer och antal tillgängliga för försäljning.
  • Använd returnerad lageridentifierare och version.
  • Produktlager och variantlager är separata mål.
  • sellable_limit med värdet -1 betyder obegränsat, medan 0 betyder att inget får säljas.
  • Obegränsad tillgänglighet visas som null i available.
  • Behandla inte null som noll.
  • Lagerjusteringar, försäljningsgränser och manuella reservationer har separata operationer och behörigheter.

Parametrar

Begärandehuvuden

Idempotency-KeySträngObligatoriskt

Unik identifierare för en logisk skrivoperation.

minLength: 1maxLength: 128
Begränsningar
pattern
"^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$"
Exempel: "example-create_adjustment_api_v1_inventory_stock_adjustments_post"

Begärans innehåll

application/json · Obligatoriskt

StockAdjustmentCreate
expected_versionHeltalObligatoriskt

Version läst före skrivningen; avvikelse gör att ändringen avvisas.

minimum: 0maximum: 9223372036854775807
Exempel: 0
locationsArray <LocationQuantity > Obligatoriskt

Lagerplatser.

minItems: 1maxItems: 100
Exempel: [{"location_id":"example","on_hand":1}]
reasonSträngObligatoriskt

Registrerad orsak till ändringen.

minLength: 1maxLength: 500
Exempel: "Example"
target_idSträngObligatoriskt

Identifierare för produkten eller varianten som operationen gäller.

Begränsningar
pattern
"^[a-z0-9][a-z0-9_-]{0,62}$"
Exempel: "example"
target_typeSträngObligatoriskt

Anger om operationen gäller en produkt eller en variant.

Begränsningar
enum
["product", "variant"]
Exempel: "product"
warehouse_idSträngObligatoriskt

Lagrets identifierare.

Begränsningar
pattern
"^[a-z0-9][a-z0-9_-]{0,62}$"
Exempel: "example"

Svar

Svar 200

dataMutationData Obligatoriskt

Innehållet i ett lyckat svar.

Fält · data
deletedBooleskt värdeObligatoriskt

Anger om borttagningen utfördes.

idSträngObligatoriskt

Resursens identifierare; bevara den som den returneras.

versionHeltal nullObligatoriskt

Resursversion för samtidighetskontroll.

metaContextPageMeta ContextMeta PageMeta RequestMeta Obligatoriskt

Metadata för svaret.

Fält · meta

ContextPageMeta

localeSträngObligatoriskt

Språk valt för denna begäran.

market_codeSträngObligatoriskt

Marknadskod returnerad av kontextendpointen.

market_idSträngObligatoriskt

Marknadsidentifierare returnerad av kontextendpointen.

paginationPagination Obligatoriskt

Metadata för markörbaserad paginering.

request_idSträngObligatoriskt

Ärendets identifierare; i svarsmetadata identifierar detta HTTP-begäran.

minLength: 1maxLength: 100

ContextMeta

localeSträngObligatoriskt

Språk valt för denna begäran.

market_codeSträngObligatoriskt

Marknadskod returnerad av kontextendpointen.

market_idSträngObligatoriskt

Marknadsidentifierare returnerad av kontextendpointen.

request_idSträngObligatoriskt

Ärendets identifierare; i svarsmetadata identifierar detta HTTP-begäran.

minLength: 1maxLength: 100

PageMeta

paginationPagination Obligatoriskt

Metadata för markörbaserad paginering.

request_idSträngObligatoriskt

Ärendets identifierare; i svarsmetadata identifierar detta HTTP-begäran.

minLength: 1maxLength: 100

RequestMeta

request_idSträngObligatoriskt

Ärendets identifierare; i svarsmetadata identifierar detta HTTP-begäran.

minLength: 1maxLength: 100

Svar 201

dataMutationData Obligatoriskt

Innehållet i ett lyckat svar.

Fält · data
deletedBooleskt värdeObligatoriskt

Anger om borttagningen utfördes.

idSträngObligatoriskt

Resursens identifierare; bevara den som den returneras.

versionHeltal nullObligatoriskt

Resursversion för samtidighetskontroll.

metaContextPageMeta ContextMeta PageMeta RequestMeta Obligatoriskt

Metadata för svaret.

Fält · meta

ContextPageMeta

localeSträngObligatoriskt

Språk valt för denna begäran.

market_codeSträngObligatoriskt

Marknadskod returnerad av kontextendpointen.

market_idSträngObligatoriskt

Marknadsidentifierare returnerad av kontextendpointen.

paginationPagination Obligatoriskt

Metadata för markörbaserad paginering.

request_idSträngObligatoriskt

Ärendets identifierare; i svarsmetadata identifierar detta HTTP-begäran.

minLength: 1maxLength: 100

ContextMeta

localeSträngObligatoriskt

Språk valt för denna begäran.

market_codeSträngObligatoriskt

Marknadskod returnerad av kontextendpointen.

market_idSträngObligatoriskt

Marknadsidentifierare returnerad av kontextendpointen.

request_idSträngObligatoriskt

Ärendets identifierare; i svarsmetadata identifierar detta HTTP-begäran.

minLength: 1maxLength: 100

PageMeta

paginationPagination Obligatoriskt

Metadata för markörbaserad paginering.

request_idSträngObligatoriskt

Ärendets identifierare; i svarsmetadata identifierar detta HTTP-begäran.

minLength: 1maxLength: 100

RequestMeta

request_idSträngObligatoriskt

Ärendets identifierare; i svarsmetadata identifierar detta HTTP-begäran.

minLength: 1maxLength: 100
Exempel på svar

HTTP-status

200
Lyckat svar Schema
201
Resurs skapad Schema
400
Ogiltig begäran
401
Autentisering krävs
403
Åtkomst nekad
404
Resursen hittades inte
409
Versionskonflikt
422
Valideringen misslyckades
429
Anropsgränsen överskreds
Övriga HTTP-statusar (7)
405
Metoden tillåts inte
413
För stor begäran
415
Formatet stöds inte
500
Serverfel
502
Fel i API-gateway
503
Tjänsten är inte tillgänglig
504
Tidsgränsen överskreds

Felkatalog: ErrorResponse

HTTP-huvuden

201

LocationSträngValfritt

Relativ URL till den skapade resursen.

401

WWW-AuthenticateSträngValfritt

Autentiseringsschema som servern kräver.

405

AllowSträngValfritt

HTTP-metoder som resursen stöder.

429, 503

Retry-AfterHeltalValfritt

Minsta väntetid före ett nytt försök, i sekunder.

minimum: 0