openapi: 3.0.0
info:
version: v1.2
title: 'VAS - Skladové zásoby'
description: |
Služba pro práci se skladovými zásobami. Nejedná se přímo o sklad, protože neřeší všechny procesy, např. inventuru, u které je nutné,
si zkontrolovat, jestli nad produkty neprobíhá balení atd. Na službu lze pohlížet spíše jako na databázi zásob, která se interně stará
o stav zásob (na ceste, rezervace, probíhá balení atd.). Služba se řídí tímto **[stavovým diagramem](https://drive.google.com/file/d/1XgWU6xCi3zmDnBav_mbCzPUTaK8oEo9Q/view?usp=sharing)**
(pokud nelze otevřít, případně vidíte jen náhled, řekni Marcelovi)
# TODO
* vyhledat TOTO v textu
* Description u parametu nedávat k objektu componenty
* Označit default hodnoty
## Vlastnosti služby
* podpora více skladů
* podpora více klientů v rámci skladu (případ, vlastník skladu expeduje pro více klientů)
* podpora seriových čísel a datum spotřeby
# Procesy se skladovými zásobami
Ve stavovém diagramu je vidět celý životní cyklus zásoby a jakými stavy procházi. Důležité pro práci ze servisou je pochopit
dva objekty `Inbound a Outbound identification`. Každý vznik nebo zánik zásoby je spojen identifikací popisujíci, jak se zásoba
ve skladu vytvořila nebo zanikla. Pro jednoduchost si lze inbound a outbound identification představit jako dokument,
který přichází se zbožím při naskladnění (inbound) - může to být dodací list nebo objednávka od dodavatele, v případě vyskladnění (outbound)
většinou objednávka od klienta (ale může to být i soupiska zboží, který chcete převést na jiný sklad atd.).
V diagramu je naznačené, při kterých přechodech inbound a outbound dokumenty vznikají.
## Příklad z praxe
Vašek má eshop, který implementuje sklad za pomocí této service. Vašek ze svého eshopu může objednávat zboží přímo u svého
dodavatele. U dodavatele objedná 1000ks ponožek a ten mu potvrdí, že objednávka přijde za 3 dny a předá mu dvě trackovací čísla balíku.
Tato informace se do service zapíše jako Inbound, kde `identifier` bude číslo objednávky. Vzhledem k tomu, že zboží je ještě na cestě,
vloží se ve stavu `pending`. Do obecného pole `data` můžeme uložit trackovací čísla balíčků.
Eshop nyní ví, že bude mít za 3 dny skladem 1000 položek, takže je nabídne k prodeji. Příjde první objednávka na 5ks.
Tato informace se do skladu zapíše jako Outbound, kde `identifier` bude číslo objednávky, stav `oredered` a `allowPending: true`, která
zajistí, že i když nejsou položky skladem, tak dojde k jejich předobjednání - stav `pre_ordered`.
Za 3 dny přijede zásilka se zbožím a Vašek v administraci eshopu zaklikne, že objednávka dorazila. Eshop provede PATCH inbound se statusem
"accepted". Zásoby, které jsou spojeny s nějakou objednávkou (outbound) automaticky přejdou do stavu `ordered`, zbytek do stavu `in_stock`.
Vaškova přítelkyně Eva obstarává expedici zásilek. V eshopu si zaklikne, že jde expedovat objednávku. Eshop tuto informaci promítne do
skladu jako PATCH outbound a pošle požadovanou zásobu dle objednávky do stavu `preparing` (implementačně lze doplňovat podstavy dle libosti,
např. completing -> packing atd., systém s informací nijak neoperuje).
Když Eva přes eshop objedná pro všechny objednávky dopravu, pošle se do service PATCH outbound do stavu `shipped`
## Jak zjistit stav zásob
TODO
## Jak provést inventuru?
TODO
## Jak udělat Inbound, pokud v zásilce nepřišly všechny položky?
TODO
## Jak zjistit po přijmu Inbound, které objednávky byly novým příjmem zboží pokryty
TODO - toto je z Rakety viz Andrej... o tomto se musíme více pobavit
# Implementační detaily
## Authorizace
Pro autorizaci se používá VAS api key (je přidělen jednotlivím
projektům). Klíč je předáván v každém požadavku v hlavičce `Auth`.
Server (IP adresa) ze kterého se komunikuje musí být také povolena. Toto
vše lze získat/nastavit v [administraci
services](https://admin.services.viaaurea.eu).
## Query object
**Zde je popis věcí co nedokážu teď zapsat do dockumentace v openapi
(pokud zjistíte jak, tak dokumentaci upravte nebo mi dejte vědět).**
Tento objekt slouží pro filtraci. Je předáván buď v těle požadavku, nebo
v cestě jako parametry. Popis jednotlivích klíčů je
[níže](#klíče-objektu-query-a-jejich-význam).
Je možno předávat jak pole hodnot, tak samotnou hodnotu.
**path**
```
?query[sku][]=PEN_001&query[sku][]=PEN_002&query[inboundId]=40
```
**body**
```
{
"query": {
"sku": [
"PEN_001",
"PEN_002"
],
"inboundId": 40
}
}
```
#### Klíče objektu query a jejich význam
Klíče použijte v objektu `query`.
| klíč | význam | využití |
| --- | --- | --- |
| `sku` | SKU produktu |
| `stockId` | Unikátní id skladové zásoby |
| `inboundId` | Unikátní id dokumentu naskladnění |
| `outboundId` | Unikátní id dokumentu vyskladnění |
| `client` | Identifikátor klienta |
| `warehouse` | Identifikátor skladu |
| `status` | Stav skladové zásoby/naskladnění |
| `subStatus` | Substav skladové zásoby |
| `subStatus` | Substav skladové zásoby |
| `serialNumber` | Sériové číslo skladové zásoby |
| `lockedTo` | Rezervace skladové zásoby platná do |
| `lockingKey` | Klíč rezervace skladové zásoby |
| `process` | Skladové zásoby s příznakem `process` |
| `processLabel` | Skladové zásoby se štítkem |
| `processDate` | Skladové zásoby se štítkem |
### Paginator object
Tento objekt slouží pro stránkování. Je předáván buď v těle požadavku, nebo v cestě jako
parametry.
**path**
```
?paginator[page]=1&paginator[itemsPerPage]=40
```
**body**
```
{
"paginator": {
"page": 1,
"itemsPerPage": 40
}
}
```
#### Klíče objektu paginator a jejich význam
Klíče použijte v objektu `paginator`.
| parametr | význam |
| --- | --- |
| `itemsPerPage` | Počet záznamů na stránku |
| `page` | požadovaná strana |
termsOfService: 'https://www.viaaurea.cz/vas'
contact:
name: 'Via Aurea s.r.o.'
email: 'vas@viaaurea.cz'
url: 'https://www.viaaurea.cz'
license:
name: Apache 2.0
url: 'https://www.apache.org/licenses/LICENSE-2.0.html'
servers:
- url: 'https://localhost:8443/' # local na portu 8443
description: 'Vývojový server na localhostu (docker)'
- url: 'https://stock.services.viaaurea.eu/stock' # OSTRÝ SERVER!!!
description: 'Ostrý server'
- url: 'https://stock.services.viaaurea.cz/stock' # vývoj - není zprovozněno
description: 'Vývojový server (Brno) - není ještě zprovozněný'
tags:
- name: Inbound
description: 'Naskladnění skladových zásob'
- name: Outbound
description: 'Vyskladnění skladových zásob'
- name: Stock
description: 'Skladové zásoby'
- name: Reservation
description: 'Rezervace skladových zásob'
- name: Process
description: 'Zpracovávání skladových zásob'
- name: Movement
description: 'Pohyby skladových zásob'
- name: Inventory
description: 'Úpravy skladových zásob inventurou'
paths:
# INBOUND
/api/inbounds/:
post:
description: 'Vytvoření požadavku na naskladnění zásob.'
operationId: addInbound
tags:
- Inbound
security:
- Auth: []
requestBody:
description: 'Naskladní skladových zásob do stavu. Stavy můžou být `accepted` (zásoby budou k dispozici ihned),
`pending` (na zásoby čekám a budou akceptovány později), `denied` (odmítnuté zásoby).'
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/NewInbound'
responses:
201:
description: Inbound odpověď
content:
application/json:
schema:
$ref: '#/components/schemas/InboundResponse'
422:
$ref: '#/components/responses/UnprocessableEntity'
401:
$ref: '#/components/responses/Unauthorized'
403:
$ref: '#/components/responses/Forbidden'
default:
description: unexpected error
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
get:
description: 'Seznam dokumentů pro naskladnění'
operationId: getInboundList
tags:
- Inbound
security:
- Auth: [ ]
parameters:
- $ref: '#/components/parameters/QueryInQuery'
- $ref: '#/components/parameters/PaginatorInQuery'
responses:
200:
description: 'Dokumenty naskladnění'
content:
application/json:
schema:
$ref: '#/components/schemas/InboundListResponse'
401:
$ref: '#/components/responses/Unauthorized'
403:
$ref: '#/components/responses/Forbidden'
404:
$ref: '#/components/responses/NotFound'
'/api/inbounds/{inboudId}/':
get:
description: 'Detail dokumentu pro naskladnění'
operationId: getInbound
tags:
- Inbound
security:
- Auth: []
parameters:
- $ref: '#/components/parameters/InboundId'
responses:
# 201:
# $ref: '#/components/schemas/InboundResponse'
200:
description: 'Dokument naskladnění'
content:
application/json:
schema:
$ref: '#/components/schemas/InboundResponse'
401:
$ref: '#/components/responses/Unauthorized'
403:
$ref: '#/components/responses/Forbidden'
404:
$ref: '#/components/responses/NotFound'
422:
$ref: '#/components/responses/UnprocessableEntity'
patch:
description: 'Aktualizace požadavku na naskladnění zásob.'
operationId: updateInbound
tags:
- Inbound
security:
- Auth: []
parameters:
- $ref: '#/components/parameters/InboundId'
requestBody:
description: |
Upraví skladové zásoby do požadovaného stavu. Stavy můžou být `accepted` (zásoby budou k dispozici ihned),
`pending` (na zásoby čekám a budou akceptovány později), `denied` (odmítnuté zásoby).
Je-li v požadavku objekt `items`, tak se naskladnění upraví podle nového stavu.
* Chybějící položka bude zrušena.
* Rušené zásoby budou převedeny do stavu `not_arrived`.
* Přidané položky budou vytvořeny.
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/UpdateInbound'
responses:
200:
description: ''
content:
application/json:
schema:
$ref: '#/components/schemas/InboundResponse'
400:
$ref: '#/components/responses/BadRequestError'
401:
$ref: '#/components/responses/Unauthorized'
403:
$ref: '#/components/responses/Forbidden'
404:
$ref: '#/components/responses/NotFound'
422:
$ref: '#/components/responses/UnprocessableEntity'
# OUTBOUND
/api/outbounds/:
post:
description: 'Vytvoří dokument vyskladnění. Probíhá rezervace požadovaných skladových zásob.'
operationId: addOutbound
tags:
- Outbound
security:
- Auth: []
requestBody:
description: '...'
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/NewOutbound'
responses:
201:
description: '...'
content:
application/json:
schema:
$ref: '#/components/schemas/OutboundResponse'
400:
description: 'Nedostatečné skladové zásoby pro vytvoření dokumentu'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
401:
$ref: '#/components/responses/Unauthorized'
403:
$ref: '#/components/responses/Forbidden'
422:
$ref: '#/components/responses/UnprocessableEntity'
get:
description: 'Seznam dokumentů pro vyskladnění'
operationId: getOutboundList
tags:
- Outbound
security:
- Auth: []
parameters:
- $ref: '#/components/parameters/QueryInQuery'
- $ref: '#/components/parameters/PaginatorInQuery'
responses:
200:
$ref: '#/components/responses/OutboundListResponse'
401:
$ref: '#/components/responses/Unauthorized'
403:
$ref: '#/components/responses/Forbidden'
404:
$ref: '#/components/responses/NotFound'
'/api/outbounds/{outboudId}/':
get:
description: 'Detail dokumentu pro vyskladnění'
operationId: getOutbound
tags:
- Outbound
security:
- Auth: []
parameters:
- $ref: '#/components/parameters/OutboundId'
responses:
200:
$ref: '#/components/responses/OutboundResponse'
401:
$ref: '#/components/responses/Unauthorized'
403:
$ref: '#/components/responses/Forbidden'
404:
$ref: '#/components/responses/NotFound'
422:
$ref: '#/components/responses/UnprocessableEntity'
patch:
description: 'Aktualizace požadavku na vyskladnění.'
operationId: updateOutbound
tags:
- Outbound
security:
- Auth: []
parameters:
- $ref: '#/components/parameters/OutboundId'
requestBody:
description: |
Upraví skladové zásoby do požadovaného stavu podle stavového diagramu.
Je-li součástí požadavku objekt `items`, tak jsou položky upraveny podle objektu. Položky vždy zpět naskladní
a poté provede nové vyskladnění. Není-li dostatek zboží, tak se úprava neuskuteční.
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/UpdateOutbound'
responses:
200:
$ref: '#/components/responses/OutboundResponse'
400:
$ref: '#/components/responses/BadRequest'
401:
$ref: '#/components/responses/Unauthorized'
403:
$ref: '#/components/responses/Forbidden'
404:
$ref: '#/components/responses/NotFound'
422:
$ref: '#/components/responses/UnprocessableEntity'
# MOVEMENT
/api/movements/{sku}/:
get:
description: 'Pohyby produktu na skladu'
operationId: getMovement
tags:
- Movement
security:
- Auth: [ ]
parameters:
- $ref: '#/components/parameters/Sku'
- $ref: '#/components/parameters/QueryInQuery'
- $ref: '#/components/parameters/PaginatorInQuery'
responses:
200:
$ref: '#/components/responses/MovementsResponse'
401:
$ref: '#/components/responses/Unauthorized'
403:
$ref: '#/components/responses/Forbidden'
422:
$ref: '#/components/responses/UnprocessableEntity'
# STOCK
# /api/stocks/{stockId}/:
# get:
# description: 'todo neni implementovano'
# operationId: getStock
#
# security:
# - Auth: []
# parameters:
# - $ref: '#/components/parameters/StockId'
#
# responses:
# 200:
# description: 'todo'
# content:
# application/json:
# schema:
# $ref: '#/components/schemas/StockItems'
/api/stocks/:
patch:
description: 'Požadavek na změny stavů skladových zásob pro stavového diagramu. Skladové zásoby se filtrují na základě
objektu `query` v těle požadavku. Filtrovat lze podle `stockId`, `lockingKey`, `inboundId` nebo `outboundId`'
operationId: updateStock
tags:
- Stock
security:
- Auth: []
requestBody:
description: 'Požadavek obsahuje filtrační objekt `query` a data pro samotné skladové zásoby.'
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/UpdateStock'
responses:
200:
$ref: '#/components/responses/UpdateStockResponse'
400:
$ref: '#/components/responses/BadRequest'
401:
$ref: '#/components/responses/Unauthorized'
403:
$ref: '#/components/responses/Forbidden'
422:
$ref: '#/components/responses/UnprocessableEntity'
/api/stocks/aggregate/:
get:
description: 'Pohled na skladové jednotky podle `sku`, `client` a `warehouse`.'
operationId: getAggregateStock
tags:
- Stock
security:
- Auth: []
parameters:
- $ref: '#/components/parameters/QueryInQuery'
- $ref: '#/components/parameters/PaginatorInQuery'
responses:
200:
description: 'Agregovaná data'
content:
application/json:
schema:
properties:
data:
type: object
allOf:
- $ref: '#/components/schemas/ResponseDate'
properties:
items:
allOf:
- $ref: '#/components/schemas/AggregateItems'
401:
$ref: '#/components/responses/Unauthorized'
403:
$ref: '#/components/responses/Forbidden'
422:
$ref: '#/components/responses/UnprocessableEntity'
# STOCK - RESERVATION
/api/stocks/reservation/:
post:
description: 'Vytvoří rezervaci skladových zásob pod daným klíčem'
operationId: addReservation
tags:
- Reservation
security:
- Auth: []
requestBody:
description: 'Požadavek na rezervaci skladových zásob'
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/NewReservation'
responses:
200:
$ref: '#/components/responses/NewReservation'
401:
$ref: '#/components/responses/Unauthorized'
403:
$ref: '#/components/responses/Forbidden'
422:
$ref: '#/components/responses/UnprocessableEntity'
/api/stocks/reservation/{lockingKey}:
delete:
description: 'Zrušení rezervace skladových zásob na základě klíče'
operationId: deleteReservation
tags:
- Reservation
security:
- Auth: []
parameters:
- $ref: '#/components/parameters/LockingKey'
responses:
200:
$ref: '#/components/responses/DeleteReservation'
500:
$ref: '#/components/responses/ErrorReservation'
# STOCK - PROCESS
/api/stocks/process/:
post:
description: '//todo popis!!!! Označení položek příznakem process'
operationId: addProcces
tags:
- Process
security:
- Auth: []
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/NewReservation'
responses:
200:
$ref: '#/components/responses/NewReservation'
400:
$ref: '#/components/responses/NewReservation'
/api/stocks/process/{processKey}:
delete:
description: 'Zrušerní procesu nad skladovými zásobami na základě klíče'
operationId: cancelProcess
tags:
- Process
security:
- Auth: []
parameters:
- $ref: '#/components/parameters/ProcessKey'
responses:
200:
$ref: '#/components/responses/DeleteProcess'
500:
$ref: '#/components/responses/ErrorProcess'
/api/stocks/inventory/{sku}:
post:
description: 'Inventura'
operationId: inventory
tags:
- Inventory
security:
- Auth: []
parameters:
- $ref: '#/components/parameters/Sku'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/NewReservation'
responses:
200:
$ref: '#/components/responses/NewReservation'
400:
$ref: '#/components/responses/NewReservation'
components:
schemas:
# inbounds
UpdateInbound:
type: object
allOf:
- $ref: '#/components/schemas/InboundStatus'
- $ref: '#/components/schemas/Force'
- $ref: '#/components/schemas/Data'
- $ref: '#/components/schemas/DeniedNote'
properties:
items:
type: array
items:
type: object
required:
- sku
- qty
properties:
sku:
type: string
maxLength: 255
description: Identifikace skladoch zásob SKU
qty:
type: number
format: int32
minimum: 0
description: Množství naskladňovaných zásob. Pro vytváření minimum 1, pro úpravy i 0.
purchasePrice:
type: number
format: float
minimum: 0
description: Nákupní cena (za jednotku)
currency:
type: string
description: Měna
NewInbound:
description: 'Objekt pro vytvoření dokumentu o naskladění skladových zásob'
required:
- warehouse
- client
# - status
- items
allOf:
- $ref: '#/components/schemas/Name'
- $ref: '#/components/schemas/Warehouse'
- $ref: '#/components/schemas/Client'
- $ref: '#/components/schemas/Identifier'
- $ref: '#/components/schemas/Data'
- $ref: '#/components/schemas/InboundStatus'
properties:
items:
type: array
items:
type: object
required:
- sku
- qty
properties:
sku:
type: string
maxLength: 255
description: Identifikace skladoch zásob SKU
qty:
type: number
format: float
minimum: 0
description: Množství naskladňovaných zásob. Pro vytváření minimum 1, pro úpravy i 0.
type:
type: string
description: |
Typ naskladnění/vyskladnění - po kusech (na skladněno bude tolik kusů co je qty), nebo počástech
(na skladněnaq bude jedna položka s qty, ze které se pak bude postupně "ukrajovat"). Odečítat lze až do
miliótin (z metru milimetry). Výchozí hodnota je `piece`.
enum:
- partial
- piece
purchasePrice:
type: number
format: float
minimum: 0
description: Nákupní cena (za jednotku)
currency:
type: string
description: Měna
# outbounds
UpdateOutbound:
type: object
required:
- status
allOf:
- $ref: '#/components/schemas/OutboundStatus'
- $ref: '#/components/schemas/SubStatus'
- $ref: '#/components/schemas/Data'
- $ref: '#/components/schemas/AllowPending'
- $ref: '#/components/schemas/RemovalFromStorage'
properties:
items:
allOf:
- $ref: '#/components/schemas/OutboundItems'
NewOutbound:
type: object
allOf:
- $ref: '#/components/schemas/Warehouse'
- $ref: '#/components/schemas/Client'
- $ref: '#/components/schemas/OutboundStatus'
- $ref: '#/components/schemas/Identifier'
- $ref: '#/components/schemas/Name'
- $ref: '#/components/schemas/Data'
- $ref: '#/components/schemas/AllowPending'
- $ref: '#/components/schemas/RemovalFromStorage'
properties:
items:
allOf:
- $ref: '#/components/schemas/OutboundItems'
# description: 'Objekt pro vytvoření dokumentu o vyskladění skladových zásob'
# required:
# - status
# - warehouse
# - client
# - items
# allOf:
# - $ref: '#/components/schemas/Warehouse'
# - $ref: '#/components/schemas/Client'
# - $ref: '#/components/schemas/OutboundStatus'
# - $ref: '#/components/schemas/Identifier'
# - $ref: '#/components/schemas/Name'
# - $ref: '#/components/schemas/Data'
# - $ref: '#/components/schemas/AllowPending'
# - $ref: '#/components/schemas/RemovalFromStorage'
# properties:
# items:
# allOf:
# - $ref: '#/components/schemas/OutboundItems'
NewReservation:
type: object
description: 'Objekt pro vytvoření rezervace skladových zásob'
required:
- warehouse
- client
- lockedTo
- lockingKey
- items
allOf:
- $ref: '#/components/schemas/Warehouse'
- $ref: '#/components/schemas/Client'
- $ref: '#/components/schemas/LockedTo'
- $ref: '#/components/schemas/LockingKey'
properties:
items:
allOf:
- $ref: '#/components/schemas/OutboundItems'
# základní odpověď po naskladnění
InboundResponse:
description: Odpověď po vytvoření nebo úpravě inbound
properties:
data:
type: object
allOf:
- $ref: '#/components/schemas/InboundId'
- $ref: '#/components/schemas/ResponseDate'
properties:
inbound:
allOf:
- $ref: '#/components/schemas/Inbound'
properties:
items:
allOf:
- $ref: '#/components/schemas/StockItems'
canceledPreOrder:
description: Outbound ID zrušených předpobjednávek. Vzniklo úpravou inboundu (změna položek, nebo zrušení předobjednávek).
type: array
items:
type: number
format: int32
InboundListResponse:
description: Seznam dokumentů naskladění
properties:
data:
type: object
allOf:
- $ref: '#/components/schemas/ResponseDate'
properties:
items:
type: array
items:
allOf:
- $ref: '#/components/schemas/Inbound'
properties:
countItems:
type: number
format: int32
description: 'Počet skladových zásob tohoto dokumentu'
# entita inbound
Inbound:
description: Objekt naskladění (inbound)
type: object
allOf:
- $ref: '#/components/schemas/InboundId'
- $ref: '#/components/schemas/InboundStatus'
- $ref: '#/components/schemas/Client'
- $ref: '#/components/schemas/Warehouse'
- $ref: '#/components/schemas/Identifier'
- $ref: '#/components/schemas/Name'
- $ref: '#/components/schemas/Description'
- $ref: '#/components/schemas/Data'
- $ref: '#/components/schemas/InboundDate'
- $ref: '#/components/schemas/DeniedNote'
- $ref: '#/components/schemas/DeniedDate'
OutboundResponse:
description: Odpověď po vytvoření nebo úpravě outbound
properties:
data:
type: object
allOf:
- $ref: '#/components/schemas/OutboundId'
- $ref: '#/components/schemas/ResponseDate'
- $ref: '#/components/schemas/ResponseMessage'
properties:
outbound:
allOf:
- $ref: '#/components/schemas/Outbound'
properties:
items:
allOf:
- $ref: '#/components/schemas/StockItems'
OutboundListResponse:
description: Seznam dokumentů naskladění
properties:
data:
type: object
allOf:
- $ref: '#/components/schemas/ResponseDate'
properties:
items:
type: array
items:
allOf:
- $ref: '#/components/schemas/Outbound'
properties:
countItems:
type: number
format: int32
description: 'Počet skladových zásob tohoto dokumentu'
# entita inbound
Outbound:
description: Objekt naskladění (inbound)
type: object
allOf:
- $ref: '#/components/schemas/OutboundId'
- $ref: '#/components/schemas/Client'
- $ref: '#/components/schemas/Warehouse'
- $ref: '#/components/schemas/Identifier'
- $ref: '#/components/schemas/Data'
# stavy naskladnění - Inbound
InboundStatus:
description: 'Stav naskladění'
required:
- status
properties:
status:
type: string
enum:
- pending
- accepted
- denied
description: 'Stav pro naskladění
- `pending` Čeká, zásoby jsou k dispozici pro předobjednávky (`pre_ordered`)
- `accepted` Akceptováno, zásoby jsou k dispozici (`in_stock`|`ordered`)
- `denied` Odmítnuto, zásoby jsou odepsány (`discarded`)'
UpdateStock:
type: object
required:
- status
- query
allOf:
- $ref: '#/components/schemas/OutboundStatus'
- $ref: '#/components/schemas/SubStatus'
- $ref: '#/components/schemas/Data'
properties:
query:
type: object
properties:
stockId:
oneOf:
- type: number
- type: array
items:
type: number
outboundId:
oneOf:
- type: number
- type: array
items:
type: number
inboundId:
oneOf:
- type: number
- type: array
items:
type: number
lockingKey:
oneOf:
- type: string
- type: array
items:
type: string
# položky StockItem
StockItems:
type: array
items:
type: object
allOf:
- $ref: '#/components/schemas/StockItem'
# položka StockItem
StockItem:
description: 'Popis skladové jednotky'
type: object
allOf:
- $ref: '#/components/schemas/StockId'
- $ref: '#/components/schemas/Sku'
- $ref: '#/components/schemas/Qty'
- $ref: '#/components/schemas/StockStatus'
- $ref: '#/components/schemas/SubStatus'
- $ref: '#/components/schemas/Client'
- $ref: '#/components/schemas/Warehouse'
- $ref: '#/components/schemas/InboundId'
- $ref: '#/components/schemas/OutboundId'
- $ref: '#/components/schemas/ExpirationDate'
- $ref: '#/components/schemas/PurchasePrice'
- $ref: '#/components/schemas/Currency'
- $ref: '#/components/schemas/SerialNumber'
- $ref: '#/components/schemas/LockedTo'
- $ref: '#/components/schemas/LockingKey'
- $ref: '#/components/schemas/Data'
- $ref: '#/components/schemas/Process'
- $ref: '#/components/schemas/ProcessLabel'
- $ref: '#/components/schemas/ProcessDate'
- $ref: '#/components/schemas/InStockDate'
- $ref: '#/components/schemas/ReservedDate'
- $ref: '#/components/schemas/PreparingDate'
- $ref: '#/components/schemas/OrderedDate'
- $ref: '#/components/schemas/ReadyForCarrierDate'
- $ref: '#/components/schemas/ShippedDate'
- $ref: '#/components/schemas/DiscardedDate'
- $ref: '#/components/schemas/ReturnedDate'
OutboundItems:
type: array
items:
type: object
allOf:
- $ref: '#/components/schemas/Sku'
- $ref: '#/components/schemas/QtyIn'
- $ref: '#/components/schemas/Method'
MovementItems:
description: 'Položky pohybů skladových zásob'
type: array
items:
type: object
allOf:
- $ref: '#/components/schemas/MovementItem'
MovementItem:
description: 'Položka pohybu skladové zásoby'
type: object
allOf:
- $ref: '#/components/schemas/MovementDate'
- $ref: '#/components/schemas/Sku'
- $ref: '#/components/schemas/QtyAbsolute'
- $ref: '#/components/schemas/QtyRelative'
- $ref: '#/components/schemas/Client'
- $ref: '#/components/schemas/Warehouse'
- $ref: '#/components/schemas/InboundId'
- $ref: '#/components/schemas/OutboundId'
- $ref: '#/components/schemas/MovementNote'
- $ref: '#/components/schemas/CountsBefore'
AggregateItems:
description: 'Položky skladových zásob agregovaných podle `sku`, `client` a `warehouse`'
type: array
items:
type: object
allOf:
- $ref: '#/components/schemas/AggregateItem'
AggregateItem:
description: 'Položka skladové zásoby agregované podle `sku`, `client` a `warehouse`'
type: object
allOf:
- $ref: '#/components/schemas/Sku'
- $ref: '#/components/schemas/Qty'
- $ref: '#/components/schemas/StockStatus'
- $ref: '#/components/schemas/Client'
- $ref: '#/components/schemas/Warehouse'
MovementResponse:
description: 'Pohyb skladové zásoby'
properties:
data:
type: object
allOf:
- $ref: '#/components/schemas/ResponseDate'
properties:
items:
allOf:
- $ref: '#/components/schemas/MovementItems'
meta:
type: object
properties:
paginator:
type: object
allOf:
- $ref: '#/components/schemas/Paginator'
query:
type: object
allOf:
- $ref: '#/components/schemas/Query'
# ================================================================================
# základní property
# ================================================================================
Client:
properties:
client:
type: string
maxLength: 64
description: Identifikátor klienta - je míněn klient skladu nikoli příjemce zboží.
Parametr má význam v případě, že je nutné vést zásoby ruzných klientů nebo eshopu.
Pokud je service používána jen pro jeden eshop, posílejte vždy stejnou hodnotu, např. 1
TOTO (co tak dát 1 default?)
Warehouse:
properties:
warehouse:
type: string
maxLength: 255
description: 'Identifikátor skladu - service umožňuje spravovat data nad více sklady'
Identifier:
properties:
identifier:
type: string
maxLength: 255
description: Vaše identifikace inbound nebo outbound dokumentu - většinou číslo objednávky nebo
jiného dokumentu, podle kterého došlo k naskladnění nebo výdeji zásob
Name:
properties:
name:
type: string
maxLength: 255
description: 'Název inbound nebo outbound identifikace - systém s informací interně nepracuje, je na uživateli co zde vloží, např. "Objednávka"'
Description:
properties:
description:
type: string
maxLength: 255
description: 'Popis'
Data:
properties:
data:
type: string
maxLength: 65000
description: 'Doplňující data ve formátu JSON (string). System s nimi nepracuje, jsou to uživatelská data, např. pro uložení trackovací čísel balíků.'
InboundDate:
properties:
inboundDate:
type: string
format: date-time
description: 'Datum naskladění ve formátu ISO 8601'
DeniedDate:
properties:
deniedDate:
type: string
format: date-time
description: 'Datum odmítnutí naskladění ve formátu ISO 8601'
DeniedNote:
properties:
deniedNote:
type: string
maxLength: 255
description: 'Poznámka pro odmítnutní naskladnění'
StockId:
properties:
stockId:
type: number
format: int32
description: 'Unikátní identifikátor skladové zásoby'
Sku:
type: object
properties:
sku:
type: string
maxLength: 255
description: 'Stock Keeping Unit - jedinečný kód produktu z pohledu skladu'
example: 'SKODA-ENYAQ'
Qty:
properties:
qty:
type: number
format: int32
description: 'Počet kusů.'
QtyIn:
properties:
qty:
type: number
format: int32
minimum: 0
description: 'Počet kusů. Pro vytváření je minimum 1, pro úpravy 0 (rušení).'
StockStatus:
properties:
status:
type: string
enum:
- pending
- pre_ordered
- in_stock
- reserved
- ordered
- preparing
- ready_for_carrier
- shipped
- returned
- discarded
description: 'Stav skladové zásoby viz. stavový diagram služby'
OutboundStatus:
properties:
status:
type: string
enum:
- ordered
- preparing
- shipped
- ready_for_carrier
- return_pending
- returned_discarded
- returned_stocked
- discarded
- in_stock
description: 'Stav skladové zásoby. Převod do `in_stock` značí uvolnění zásob do skladu, třeba při zrušení objednávky.
TODO: jak se počítá, položky outboundu mohou mít ruzne stavy? Co pre_ordered?'
SubStatus:
properties:
subStatus:
type: string
maxLength: 255
description: 'Uživatesky definovaný stav - systém s ním nepracuje'
Type:
properties:
type:
type: string
enum:
- piece
- partial
description: 'Určuje jak bude skladová zásoba vyskladňovat.
* `piece` Po celých kusech. Volte, když je prodáván jeden celý kus SKU.
* `partial` Po částech. Volte, když je prodávána část SKU. Například po litrech. (tato možnost není ještě implementována)'
OutboundId:
properties:
outboundId:
type: number
format: int32
description: 'Unikátní identifikátor vyskladění'
InboundId:
properties:
inboundId:
type: number
format: int32
description: 'Unikátní identifikátor naskladění'
ExpirationDate:
properties:
expirationDate:
type: string
format: date-time
description: 'Datum expirace zboží. Slouží pro metody vyskladění (FEFO). Formát ISO 8601'
PurchasePrice:
properties:
purchasePrice:
type: number
format: float
description: 'Nákupní cena SKU (za jednotku)'
Currency:
properties:
currency:
type: string
maxLength: 3
description: 'Kód měny ve formátu ISO 4217'
SerialNumber:
properties:
serialNumber:
type: string
maxLength: 255
description: 'Sériové číslo - unikátní číslo jednoho konkrétního kusu zboží'
LockedTo:
properties:
lockedTo:
type: string
format: date-time
description: 'Platnost zámku pro rezervaci skladové jednotky'
LockingKey:
properties:
lockingKey:
type: string
maxLength: 255
description: Klíč zámku pro rezervaci skladové zásoby. Pomocí tohoto klíče je možné rezervované zásoby vyskladnit.
Jako klíč může být jakýkoli string, implementačně se nabízí sessionID uživatele nebo ID košíku atd.
Process:
properties:
process:
type: boolean
description: Indikuje, že nad zásobou probíha nějaky proces, který znemožňuje vyskladnění položky.
Procesem může být např. inventura nebo přeorganizace zboží v rámci skladu. .'
ProcessLabel:
properties:
processLabel:
type: string
maxLength: 255
description: 'Uživatelský popis zámku, např. Inventura nebo Kontrola záruční doby atd.'
ProcessDate:
properties:
processDate:
type: string
format: date-time
description: 'Datum vzniku zámku ve formátu ISO 8601'
ProcessKey:
properties:
processKey:
type: string
maxLength: 255
description: Klíč procesu pro skladové zásoby. Pomocí tohoto klíče je možné zrušit proces nad zásobami.
Jako klíč může být jakýkoli string, implementačně se nabízí id inventury. Klíč musí být unikátní.
InStockDate:
description: 'Datum přechodu skladové jednotky do stavu `in_stock`'
properties:
inStockDate:
type: string
format: date-time
description: Datum naskladnění skladové zásoby (přechod skladové jednotky do stavu `in_stock`).
Slouží pro metody vyskladění (FIFO/LIFO). Formát 8601'
ReservedDate:
properties:
reservedDate:
type: string
format: date-time
description: 'Datum vzniku rezervace na skladovou jednotku ve formátu ISO 8601'
PreparingDate:
properties:
preparingDate:
type: string
format: date-time
description: 'Datum přechodu skladové jednotky do stavu `prepering` ve formátu ISO 8601'
OrderedDate:
properties:
orderedDate:
type: string
format: date-time
description: 'Datum přechodu skladové jednotky do stavu `ordered` ve formátu ISO 8601'
ReadyForCarrierDate:
properties:
readyForCarrierDate:
type: string
format: date-time
description: 'Datum přechodu skladové jednotky do stavu `ready_for_carrier` ve formátu ISO 8601'
ShippedDate:
properties:
shippedDate:
type: string
format: date-time
description: 'Datum přechodu skladové jednotky do stavu `shipped` ve formátu ISO 8601'
DiscardedDate:
properties:
discardedDate:
type: string
format: date-time
description: 'Datum přechodu skladové jednotky do stavu `discarded` ve formátu ISO 8601'
ReturnedDate:
properties:
returnedDate:
type: string
format: date-time
description: 'Datum přechodu skladové jednotky do stavu `returned` ve formátu ISO 8601'
AllowPending:
properties:
allowPending:
type: boolean
description: 'Umožní vyskladnit skladové zásoby, které jsou ještě ve stavu `pending` (nejsou na skladě a jsou teprv očekávány). Tyto
zásoby mají pak stav `pre_ordered`. Výchozí hodnota `false`.'
RemovalFromStorage:
properties:
removalFromStorage:
type: string
enum:
- fully
- partly
description: 'Umožní objednávku vyskladnit částečně.
Vyskladní i přestože není skladová zásoba A skladem (není požadované mnozžství) a B skladem je.
Výsledkem je vyskladěnní všech kusů B a žádného kusu A. Výchozí hodnota je `fully`'
Method:
properties:
method:
type: string
enum:
- fifo
- lifo
- fefo
description: 'Metoda použitá pro výběr skladových zásob'
Force:
properties:
force:
type: boolean
description: 'Příznak vynucení přechodu'
ResponseDate:
properties:
date:
type: string
format: date-time
description: 'Datum odpovědi ve formátu ISO 8601'
ResponseMessage:
properties:
message:
type: string
description: 'Popis odpovědi'
TransitionsData:
description: ''
properties:
notPossibleTransition:
type: array
description: 'Položky, které nelze převést do požadovaného stavu'
items:
$ref: '#/components/schemas/StockItem'
canBeTransition:
type: array
description: 'Položky, které lze převést do požadovaného stavu'
items:
$ref: '#/components/schemas/StockItem'
# jiné.. zatím z ukázek pet
Error:
required:
- code
- message
properties:
code:
type: integer
format: int32
message:
type: string
MovementDate:
description: 'Datum pohybu ve formátu ISO 8601'
properties:
date:
type: string
format: date-time
description: 'Datum pohybu ve formátu ISO 8601'
QtyAbsolute:
description: 'Absolutní změna skladových zásob'
properties:
qtyAbsolute:
type: number
format: float
description: 'Absolutní změna skladových zásob. Například při inventuře'
QtyRelative:
description: 'Relativní změna skladových zásob'
properties:
qtyRelative:
type: number
format: float
description: 'Relativní změna skladových zásob'
MovementNote:
description: 'Popis pohybu'
properties:
note:
type: string
description: 'Popis pohybu'
CountsBefore:
properties:
countsBefore:
type: string
description: 'Počty skladových zásob před pohybem skladové zásoby'
Paginator:
type: object
properties:
itemsPerPage:
type: number
format: int32
description: 'Počet záznamů na stránku'
page:
type: number
format: int32
description: 'Nastavená stránka'
count:
type: number
format: int32
description: 'Celkový počet záznamů'
Query:
description: 'Použitá filtrace'
type: array
items:
type: array
items:
type: string
# Odpovědi // todo!!! ostatní
responses:
OutboundResponse:
description: 'Odpověď pro dokument vyskladění'
content:
application/json:
schema:
$ref: '#/components/schemas/OutboundResponse'
OutboundListResponse:
description: 'Odpověď pro dokumenty vyskladění'
content:
application/json:
schema:
$ref: '#/components/schemas/OutboundListResponse'
MovementsResponse:
description: 'Pohyby daného produktu'
content:
application/json:
schema:
$ref: '#/components/schemas/MovementResponse'
UpdateStockResponse:
description: 'Úprava skladových zásob'
content:
application/json:
schema:
properties:
data:
type: object
properties:
date:
$ref: '#/components/schemas/ResponseDate'
message:
$ref: '#/components/schemas/ResponseMessage'
items:
$ref: '#/components/schemas/StockItems'
# 422
UnprocessableEntity:
description: 'Validační chyby'
content:
application/json:
schema:
properties:
error:
type: object
properties:
message:
type: string
description: 'Popis chyby'
details:
type: object
description: 'Detail validačních chyb'
# 400
BadRequest:
description: 'Špatný požadavek. Požadavek nelze vykonat.'
content:
application/json:
schema:
properties:
data:
allOf:
- $ref: '#/components/schemas/ResponseMessage'
- $ref: '#/components/schemas/TransitionsData'
# 400
BadRequestError:
description: 'Špatný požadavek. Požadavek nelze vykonat.'
content:
application/json:
schema:
properties:
error:
allOf:
- $ref: '#/components/schemas/ResponseMessage'
properties:
code:
description: 'Kód chyby'
type: number
enum:
- 400
# 401
Unauthorized:
description: 'Klient není autorizován. K autorizaci použijte klíč předaný v hlavičkách `Auth`'
content:
application/json:
schema:
properties:
error:
type: object
allOf:
- $ref: '#/components/schemas/ResponseMessage'
properties:
code:
type: number
enum:
- 401
description:
type: string
# 403
Forbidden:
description: 'Přístup zakázán'
content:
application/json:
schema:
properties:
error:
type: object
allOf:
- $ref: '#/components/schemas/ResponseMessage'
properties:
code:
type: number
enum:
- 403
description:
type: string
# 404
NotFound:
description: 'Zdroj nebyl nalezen'
content:
application/json:
schema:
properties:
error:
type: 'object'
allOf:
- $ref: '#/components/schemas/ResponseMessage'
properties:
code:
description: 'Kód chyby'
type: number
enum:
- 404
# 200
NewReservation:
description: 'Vytvoří rezervace'
content:
application/json:
schema:
properties:
data:
type: object
allOf:
- $ref: '#/components/schemas/ResponseDate'
- $ref: '#/components/schemas/ResponseMessage'
properties:
error:
description: 'Případné chyby v rezervaci'
type: object
allOf:
- $ref: '#/components/schemas/ResponseMessage'
properties:
code:
type: number
items:
type: array
items:
allOf:
- $ref: '#/components/schemas/Sku'
- $ref: '#/components/schemas/Qty'
reservation:
description: 'Rezervované skladové položky'
type: object
properties:
items:
type: array
items:
$ref: '#/components/schemas/StockItem'
# 200
DeleteReservation:
description: 'Zrušení rezervace na základě klíče'
content:
application/json:
schema:
properties:
data:
type: object
allOf:
- $ref: '#/components/schemas/ResponseDate'
- $ref: '#/components/schemas/ResponseMessage'
- $ref: '#/components/schemas/LockingKey'
# 200
DeleteProcess:
description: 'Zrušení procesu na základě klíče'
content:
application/json:
schema:
properties:
data:
type: object
allOf:
- $ref: '#/components/schemas/ResponseDate'
- $ref: '#/components/schemas/ResponseMessage'
- $ref: '#/components/schemas/ProcessKey'
# 500
ErrorProcess:
description: 'Chyba při rušení procesu'
content:
application/json:
schema:
allOf:
- $ref: '#/components/schemas/ResponseDate'
properties:
error:
type: object
allOf:
- $ref: '#/components/schemas/ResponseMessage'
# 500
ErrorReservation:
description: 'Chyba při rušení rezervace'
content:
application/json:
schema:
allOf:
- $ref: '#/components/schemas/ResponseDate'
properties:
error:
type: object
allOf:
- $ref: '#/components/schemas/ResponseMessage'
# Security - Authorizace
securitySchemes:
Auth:
type: apiKey
in: header
name: Auth
description: 'Authorizační klíč projektu'
# Parametry
parameters:
InboundId:
name: inboudId
in: path
description: 'Unikátní id dokumentu naskladění'
required: true
schema:
$ref: '#/components/schemas/InboundId'
OutboundId:
name: outboudId
in: path
description: 'Unikátní id dokumentu vyskladnění'
required: true
schema:
$ref: '#/components/schemas/OutboundId'
StockId:
name: stockId
in: path
description: 'Unikátní id skladové zásoby'
required: true
schema:
$ref: '#/components/schemas/StockId'
LockingKey:
name: lockingKey
in: path
description: 'Klíč rezervace'
required: true
schema:
$ref: '#/components/schemas/LockingKey'
ProcessKey:
name: processKey
in: path
description: 'Klíč procesu'
required: true
schema:
$ref: '#/components/schemas/ProcessKey'
Sku:
name: sku
in: path
description: 'Identifikace produktu'
required: true
schema:
$ref: '#/components/schemas/Sku'
# todo nevim jak zapsat ?query[sku]=SKU&query[inboundId]=40
QueryInQuery:
description: 'Filtrační podmínky.
- `query[sku]`
- `query[inboundId]`
'
name: query
in: query
explode: true
style: form
schema:
type: array
items:
properties:
id:
description: name of the field to be filtered
type: string
value:
description: value of the filter
type: string
PaginatorInQuery:
description: 'Objekt pro stránkování.
- `paginator[page]` požadovaná strana
- `paginator[itemsPerPage]` počet položek na stránku'
name: paginator
in: query
schema:
properties:
page:
type: number
format: int32
itemsPerPage:
type: number
format: int32