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