Przejdź do głównej zawartości

API pakowania

Wszystko poniżej żyje pod /api/_action/p2lab-stockly/packaging/ i uwierzytelnia się jak każde inne wywołanie Admin API. Przykłady zakładają token w nagłówku Authorization.

GET packaging/resolve?productIds=<oddzielone przecinkami> Uprawnienie: p2lab_stockly_packaging_profile:read · najwyżej 100 identyfikatorów na wywołanie

Endpoint, którego potrzebuje większość integracji. Odpowiada, jakie wartości zostaną użyte dla artykułu i który poziom je dostarczył.

{
"products": [
{
"productId": "0191f1…",
"packagingWeightKg": 0.06,
"packagingWeightSource": "profile",
"ownBox": false,
"ownBoxSource": "global",
"dimensionsMm": [300, 200, 100],
"dimensionsSource": "product",
"dunnageFactor": 1.15,
"preferredMaterialId": "0191f2…",
"winningProfileId": "0191f3…",
"matchedProfileIds": ["0191f3…", "0191f4…"],
"rankCollision": false,
"estimated": true
}
]
}
PoleUwagi
*Sourceproduct, parent, profile, global, none
dimensionsMm[długość, szerokość, wysokość], albo null, gdy nikt nie wie
matchedProfileIdsnajpierw zwycięzca, potem reguły, które przegrał
rankCollisiondwie reguły o równej randze go zgarnęły; odpowiedź jest stabilna, ale arbitralna
estimatedco najmniej jedna wartość jest odziedziczona lub założona, a nie zmierzona

Typowy błąd. packagingWeightKg: null przy packagingWeightSource: "none" znaczy, że nikt nic nie zapisał. Nie renderuj tego jako 0,00 kg; to rozróżnienie jest powodem, dla którego to pole istnieje.

GET packaging/coverage?page=1&limit=50 Uprawnienie: p2lab_stockly_packaging_profile:read

{
"summary": {
"total": 4812,
"missingDimensions": 3140,
"missingWeight": 210,
"ready": 1672,
"materials": 8,
"profiles": 5,
"hasGlobalProfile": true
},
"gaps": [
{
"productId": "0191f1…",
"productNumber": "SW10001",
"name": "Farba ścienna, biała, 5 l",
"shipments": 412,
"hasWeight": true,
"hasDimensions": false,
"hasOwnRow": false
}
]
}

gaps jest posortowane malejąco po shipments z ostatniego półrocza. To właśnie ta kolejność jest użyteczna: zamienia zadanie poprawienia pięciu tysięcy artykułów w poprawienie tych czterdziestu, które wyjeżdżają codziennie.

hasGlobalProfile: false warto alarmować. Bez reguły zbiorczej artykuły poza wszystkimi profilami nie dostają żadnych danych o pakowaniu.

GET packaging/collisions?limit=50 Uprawnienie: p2lab_stockly_packaging_profile:read

{
"collisions": [
{
"productId": "0191f1…",
"productNumber": "SW10001",
"name": "Farba ścienna, biała, 5 l",
"matchRank": 100,
"profiles": [
{ "id": "0191f3…", "name": "Farby 5 l" },
{ "id": "0191f4…", "name": "Towar delikatny" }
]
}
]
}

Normalnie pusta. Niepusta lista znaczy, że dwie reguły o tej samej randze zgarniają ten sam artykuł, więc zwycięzcę rozstrzyga porównanie wewnętrzne, a nie sklep.

GET packaging/variance?limit=50&minVarianceKg=0.05 Uprawnienie: p2lab_stockly_parcel:read

{
"variance": [
{
"productId": "0191f1…",
"productNumber": "SW10001",
"name": "Farba ścienna, biała, 5 l",
"parcels": 37,
"avgVarianceKg": 0.42,
"maxVarianceKg": 0.61,
"avgEstimatedKg": 5.9
}
]
}

Liczone są wyłącznie paczki zawierające jeden rodzaj artykułu; w pudle mieszanym różnicy nie da się przypisać żadnemu z nich. Wartość dodatnia znaczy, że pudło okazało się cięższe niż przewidywano.

Świadomie nie ma tu endpointu zapisu: dane pakowania to zwykły DAL, więc standardowe Admin API załatwia sprawę mniejszym nakładem nauki i mniejszą liczbą rzeczy do zepsucia.

POST /api/p2lab-stockly-packaging-material
{
"code": "K30",
"label": "Karton 300x200x150",
"type": "box",
"innerLengthMm": 300,
"innerWidthMm": 200,
"innerHeightMm": 150,
"tareKg": 0.28,
"maxPayloadKg": 20,
"active": true
}
POST /api/p2lab-stockly-packaging-profile
{
"name": "Farby 5 l",
"matchType": "property",
"matchId": "<id opcji property_group_option>",
"matchRank": 100,
"packagingWeightKg": 0.06
}
POST /api/p2lab-stockly-product-packaging
{
"productId": "0191f1…",
"packagingWeightKg": 0.12,
"ownBox": true
}
  • Jeden wiersz na artykuł w p2lab_stockly_product_packaging. Klucz unikalny tego pilnuje, a właściwym zapisem jest upsert po productId.
  • Pomiń pole, zamiast wysyłać 0 albo false, chyba że taka wartość jest zamierzona. Pominięcie dziedziczy; wartość rozstrzyga.
  • matchType: null to wiersz globalny. Trzymaj dokładnie jeden.
  • Równe wartości matchRank są legalne i raportowane, a nie odrzucane; patrz konflikty. Nadawaj różne rangi.