Ressource: articles #
Artikelstamm der EULANDA-Tabelle Artikel. Die Anlage läuft über die
EULANDA-Prozedur cn_ArNew (übernimmt den Vorlagen-Artikel .MUSTER samt
Preisen und Merkmalen, falls vorhanden). Preisfindung und Bestände sind
read-only und kommen aus den EULANDA-Funktionen - die API rechnet nie
selbst. Bilder und DMS-Dateien des Artikels: siehe Bilder und
DMS-Dateien.
Endpunkte #
| Methode | Pfad | Scope | Zweck |
|---|---|---|---|
| GET | /api/v1/articles | articles:read | Liste (Paging, Filter, q, changedSince, fields, categoryAnd/Or/Not) |
| GET | /api/v1/articles/categories | articles:read | Merkmalbaum für den Merkmal-Filter, siehe Merkmale |
| GET | /api/v1/articles/{id}/categories | articles:read | Merkmale eines Artikels |
| PUT/PATCH | /api/v1/articles/{id}/categories | articles:write | Merkmal-Zuordnung ersetzen bzw. ändern |
| GET | /api/v1/articles/{id}/service-articles | service-articles:read | Geräte-Instanzen des Artikels, siehe Serviceartikel |
| GET | /api/v1/articles/ids | articles:read | Schlüsselliste für den Lösch-Abgleich |
| GET | /api/v1/articles/{id} | articles:read | Einzelner Artikel über die Id |
| GET | /api/v1/articles/by-number/{number} | articles:read | Einzelner Artikel über die Artikelnummer |
| POST | /api/v1/articles | articles:write | Anlegen (cn_ArNew + Felder) |
| PATCH | /api/v1/articles/{id} | articles:write | Felder ändern (partiell) |
| DELETE | /api/v1/articles/{id} | articles:write | Löschen, nur wenn unbenutzt (cnf_ArCanDelete) |
| GET | /api/v1/articles/{id}/price | articles:read | Preisfindung (cn_Preis_GetVk) |
| GET | /api/v1/articles/{id}/stock | articles:read | Bestände (cnf_BestandVerfuegbarGesamt, cnf_ArLagerBestand) |
Der Vorlagen-Artikel .MUSTER ist geschützt (409
ARTICLE_TEMPLATE_PROTECTED); eine übergebene articleNumber wird über
cnf_ArUniqueArtNummer eindeutig gemacht.
Felder (Glossar Entwurf) #
| API-Feld | DB-Spalte | Typ | Schreibbar |
|---|---|---|---|
id / uid | ID / uid | int/guid | nein |
articleNumber | ArtNummer | string | ja (eindeutig via cnf_ArUniqueArtNummer) |
manufacturerNumber | ArtNummerHersteller | string | ja |
match | ArtMatch | string | ja |
barcode | Barcode | string | ja |
name / name2 / shortName | Kurztext1 / Kurztext2 / Ultrakurztext | string | ja |
longText | Langtext | string | ja |
unit / priceUnit / packagingUnit | MengenEh / PreisEh / VerpackEh | string/decimal | ja (unit validiert gegen KonMengenEh, z.B. Stk.) |
weight / volume | Gewicht / Volumen | decimal | ja |
price | Vk | decimal | ja (Basis-VK; Interpretation über isGross) |
priceNet / priceGross / isGross | VkNetto / VkBrutto / BruttoFlg | decimal/bool | nein |
currency / vatGroup / vatRate | Waehrung / MwStGr / MwstSatz | - | nein |
productGroup | WarenGr | string | ja (validiert gegen konWG) |
discountGroup | RabattGr | string | ja (validiert gegen KonRG) |
manufacturerId | HerstellerID | int | ja (validiert gegen Hersteller) |
customsTariffNumber / countryOfOrigin | WarenNr / UrsprungsLand | string | ja |
storageBin | Lagerplatz | string | ja |
minStock / maxStock / deliveryDays | StdBestandMin / StdBestandMax / BeschaffungsZeit | decimal/int | ja |
isDiscontinued / isNew / isSpecial / shopEnabled | AuslaufFlg / NeuFlg / SonderFlg / ShopFreigabeFlg | bool | ja |
serialRequired / batchRequired / stockType / status / articleType | SNPflichtFlg / ChargenPflichtFlg / LagerTyp / Status / Typ | - | nein |
createdAt / changedAt | CreateDate / ChangeDate | datetime | nein |
Einkaufspreise (EkNetto u.a.) sind bewusst nicht im Feldkatalog -
sie kommen erst mit einem eigenen, restriktiveren Scope. Die Gruppen-Felder
sind echte Fremdschlüssel: ungültige Werte lehnt die API mit 422
VALIDATION_LOOKUP_INVALID ab, bevor der SQL Server einen rohen
Constraint-Fehler wirft.
Beispiele #
Liste und Einzelabruf:
$h = @{ Authorization = "Bearer $key" }
Invoke-RestMethod 'http://localhost:8100/api/v1/articles?limit=10&fields=id,articleNumber,name,price,currency' -Headers $h
Invoke-RestMethod 'http://localhost:8100/api/v1/articles/by-number/1100' -Headers $h
curl.exe -H "Authorization: Bearer %KEY%" "http://localhost:8100/api/v1/articles?limit=10&fields=id,articleNumber,name,price,currency"
curl.exe -H "Authorization: Bearer %KEY%" "http://localhost:8100/api/v1/articles/by-number/1100"
Preisfindung für einen Kunden (3 Stück, Kundenpreise/Staffeln inklusive):
Invoke-RestMethod 'http://localhost:8100/api/v1/articles/1/price?customerId=2&quantity=3' -Headers $h
curl.exe -H "Authorization: Bearer %KEY%" "http://localhost:8100/api/v1/articles/1/price?customerId=2&quantity=3"
{
"articleId": 1, "customerId": 2, "quantity": 3.0,
"currency": "EUR", "isGross": false,
"price": 100.00, "discountPercent": 5.00, "finalPrice": 95.00,
"source": "Preisliste", "info": ""
}
Bestand:
Invoke-RestMethod 'http://localhost:8100/api/v1/articles/1/stock' -Headers $h
curl.exe -H "Authorization: Bearer %KEY%" "http://localhost:8100/api/v1/articles/1/stock"
Anlegen und ändern:
$body = @{ articleNumber = 'API-0001'; name = 'API-Testartikel'; unit = 'Stk'; price = 19.9 } | ConvertTo-Json
$article = Invoke-RestMethod 'http://localhost:8100/api/v1/articles' -Method Post -Headers $h -ContentType 'application/json' -Body $body
Invoke-RestMethod "http://localhost:8100/api/v1/articles/$($article.id)" -Method Patch -Headers $h -ContentType 'application/json' -Body (@{ isNew = $true } | ConvertTo-Json)
curl.exe -X POST -H "Authorization: Bearer %KEY%" -H "Content-Type: application/json" -d "{ \"articleNumber\": \"API-0001\", \"name\": \"API-Testartikel\", \"unit\": \"Stk\", \"price\": 19.9 }" "http://localhost:8100/api/v1/articles"
curl.exe -X PATCH -H "Authorization: Bearer %KEY%" -H "Content-Type: application/json" -d "{ \"isNew\": true }" "http://localhost:8100/api/v1/articles/123"
Fehlercodes dieser Ressource #
| HTTP | Code | Bedeutung |
|---|---|---|
| 404 | NOT_FOUND | Kein Artikel zum Schlüssel |
| 409 | ARTICLE_IN_USE | Löschen abgelehnt, Artikel wird referenziert |
| 409 | ARTICLE_TEMPLATE_PROTECTED | .MUSTER darf nicht geändert oder gelöscht werden |
| 422 | VALIDATION_LOOKUP_INVALID | Gruppe existiert nicht (productGroup/discountGroup) |
| 422 | VALIDATION_FIELD_UNKNOWN / VALIDATION_FIELD_READONLY / VALIDATION_NO_FIELDS | Body-Validierung |
Noch offen (Roadmap) #
- Lookup-Endpunkte (
/lookups/product-groupsusw.), damit Clients gültige Gruppen abfragen können. - Einkaufspreise und Lieferantenartikel mit eigenem Scope.
- Rabatt-Matrix (RabattGr x KundenGr) als Auskunfts-Endpunkt.