Add quote and order HTTP APIs on manifest documents.
Expose store-backed CRUD for quotes and sales orders with shared ManifestLine shapes, entityId customers, and documented date semantics.
This commit is contained in:
70
docs/api/routes/order/create.md
Normal file
70
docs/api/routes/order/create.md
Normal file
@@ -0,0 +1,70 @@
|
||||
# `POST /order`
|
||||
|
||||
Protected. Requires a valid session cookie (`credentials: 'include'`).
|
||||
|
||||
Create order
|
||||
|
||||
Creates a sales order with header and lines in one transaction.
|
||||
`date` is the document date (expected delivery).
|
||||
`entityId` must be a company customer (not Lieferanten/POS), or null.
|
||||
Each line requires `sku`, `amount`, `net`, and `tax` (rate); `rebate` defaults to `0`.
|
||||
|
||||
|
||||
## Body (JSON)
|
||||
|
||||
```json
|
||||
{
|
||||
"number": "O-2026-001",
|
||||
"date": "2026-09-15",
|
||||
"entityId": 1,
|
||||
"lines": [
|
||||
{
|
||||
"sku": "1",
|
||||
"amount": 10,
|
||||
"net": 99.5,
|
||||
"tax": 19
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Response `201`
|
||||
|
||||
Created order
|
||||
|
||||
```json
|
||||
{
|
||||
"order": {
|
||||
"id": 1,
|
||||
"number": "…",
|
||||
"type": "order",
|
||||
"entityId": 1,
|
||||
"date": "2026-08-10T00:00:00.000Z",
|
||||
"lines": [
|
||||
{
|
||||
"id": 1,
|
||||
"articleId": 1,
|
||||
"sku": "…",
|
||||
"amount": 1,
|
||||
"net": 1,
|
||||
"rebate": 1,
|
||||
"tax": 1,
|
||||
"comment": "…"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Errors
|
||||
|
||||
| Status | Description |
|
||||
|--------|-------------|
|
||||
| 400 | Invalid order, invalid lines, or no company selected — `{"error":"…"}` |
|
||||
| 401 | Unauthorized — `{"error":"…"}` |
|
||||
| 403 | Not authorized — `{"error":"…"}` |
|
||||
| 404 | Company, entity, or article not found — `{"error":"…"}` |
|
||||
|
||||
---
|
||||
|
||||
_Generated from `@openapi` JSDoc. Do not edit by hand — run `npm run docs:api`._
|
||||
32
docs/api/routes/order/delete.md
Normal file
32
docs/api/routes/order/delete.md
Normal file
@@ -0,0 +1,32 @@
|
||||
# `DELETE /order/{id}`
|
||||
|
||||
Protected. Requires a valid session cookie (`credentials: 'include'`).
|
||||
|
||||
Delete order
|
||||
|
||||
Deletes the sales order (`manifestarticle` rows cascade).
|
||||
|
||||
## Path parameters
|
||||
|
||||
| Param | Required | Type | Description |
|
||||
|-------|----------|------|-------------|
|
||||
| `id` | yes | integer | |
|
||||
|
||||
## Response `204`
|
||||
|
||||
Deleted
|
||||
|
||||
_No content_
|
||||
|
||||
## Errors
|
||||
|
||||
| Status | Description |
|
||||
|--------|-------------|
|
||||
| 400 | No company selected or invalid id — `{"error":"…"}` |
|
||||
| 401 | Unauthorized — `{"error":"…"}` |
|
||||
| 403 | Not authorized — `{"error":"…"}` |
|
||||
| 404 | Order not found — `{"error":"…"}` |
|
||||
|
||||
---
|
||||
|
||||
_Generated from `@openapi` JSDoc. Do not edit by hand — run `npm run docs:api`._
|
||||
54
docs/api/routes/order/get.md
Normal file
54
docs/api/routes/order/get.md
Normal file
@@ -0,0 +1,54 @@
|
||||
# `GET /order/{id}`
|
||||
|
||||
Protected. Requires a valid session cookie (`credentials: 'include'`).
|
||||
|
||||
Get order
|
||||
|
||||
Returns a sales order with lines for the selected company.
|
||||
|
||||
## Path parameters
|
||||
|
||||
| Param | Required | Type | Description |
|
||||
|-------|----------|------|-------------|
|
||||
| `id` | yes | integer | |
|
||||
|
||||
## Response `200`
|
||||
|
||||
Order
|
||||
|
||||
```json
|
||||
{
|
||||
"order": {
|
||||
"id": 1,
|
||||
"number": "…",
|
||||
"type": "order",
|
||||
"entityId": 1,
|
||||
"date": "2026-08-10T00:00:00.000Z",
|
||||
"lines": [
|
||||
{
|
||||
"id": 1,
|
||||
"articleId": 1,
|
||||
"sku": "…",
|
||||
"amount": 1,
|
||||
"net": 1,
|
||||
"rebate": 1,
|
||||
"tax": 1,
|
||||
"comment": "…"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Errors
|
||||
|
||||
| Status | Description |
|
||||
|--------|-------------|
|
||||
| 400 | No company selected or invalid id — `{"error":"…"}` |
|
||||
| 401 | Unauthorized — `{"error":"…"}` |
|
||||
| 403 | Not authorized — `{"error":"…"}` |
|
||||
| 404 | Order or company not found — `{"error":"…"}` |
|
||||
|
||||
---
|
||||
|
||||
_Generated from `@openapi` JSDoc. Do not edit by hand — run `npm run docs:api`._
|
||||
40
docs/api/routes/order/list.md
Normal file
40
docs/api/routes/order/list.md
Normal file
@@ -0,0 +1,40 @@
|
||||
# `GET /order`
|
||||
|
||||
Protected. Requires a valid session cookie (`credentials: 'include'`).
|
||||
|
||||
List orders
|
||||
|
||||
Lists sales orders (`manifest` rows with `type = 'order'`)
|
||||
for the authenticated user's selected company.
|
||||
|
||||
|
||||
## Response `200`
|
||||
|
||||
Order list
|
||||
|
||||
```json
|
||||
{
|
||||
"orders": [
|
||||
{
|
||||
"id": 1,
|
||||
"number": "…",
|
||||
"type": "order",
|
||||
"entityId": 1,
|
||||
"date": "2026-08-10T00:00:00.000Z"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Errors
|
||||
|
||||
| Status | Description |
|
||||
|--------|-------------|
|
||||
| 400 | No company selected — `{"error":"…"}` |
|
||||
| 401 | Unauthorized — `{"error":"…"}` |
|
||||
| 403 | Not authorized — `{"error":"…"}` |
|
||||
| 404 | Company not found — `{"error":"…"}` |
|
||||
|
||||
---
|
||||
|
||||
_Generated from `@openapi` JSDoc. Do not edit by hand — run `npm run docs:api`._
|
||||
66
docs/api/routes/order/update.md
Normal file
66
docs/api/routes/order/update.md
Normal file
@@ -0,0 +1,66 @@
|
||||
# `PATCH /order/{id}`
|
||||
|
||||
Protected. Requires a valid session cookie (`credentials: 'include'`).
|
||||
|
||||
Update order
|
||||
|
||||
Patches header fields that are present. If `lines` is present, replaces
|
||||
all lines; if omitted, leaves lines unchanged. Returns the full order.
|
||||
`date` is the document date (expected delivery).
|
||||
|
||||
|
||||
## Path parameters
|
||||
|
||||
| Param | Required | Type | Description |
|
||||
|-------|----------|------|-------------|
|
||||
| `id` | yes | integer | |
|
||||
|
||||
## Body (JSON)
|
||||
|
||||
```json
|
||||
{
|
||||
"number": "O-2026-001b",
|
||||
"lines": []
|
||||
}
|
||||
```
|
||||
|
||||
## Response `200`
|
||||
|
||||
Updated order
|
||||
|
||||
```json
|
||||
{
|
||||
"order": {
|
||||
"id": 1,
|
||||
"number": "…",
|
||||
"type": "order",
|
||||
"entityId": 1,
|
||||
"date": "2026-08-10T00:00:00.000Z",
|
||||
"lines": [
|
||||
{
|
||||
"id": 1,
|
||||
"articleId": 1,
|
||||
"sku": "…",
|
||||
"amount": 1,
|
||||
"net": 1,
|
||||
"rebate": 1,
|
||||
"tax": 1,
|
||||
"comment": "…"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Errors
|
||||
|
||||
| Status | Description |
|
||||
|--------|-------------|
|
||||
| 400 | Invalid order, invalid lines, invalid id, or no company selected — `{"error":"…"}` |
|
||||
| 401 | Unauthorized — `{"error":"…"}` |
|
||||
| 403 | Not authorized — `{"error":"…"}` |
|
||||
| 404 | Order, entity, article, or company not found — `{"error":"…"}` |
|
||||
|
||||
---
|
||||
|
||||
_Generated from `@openapi` JSDoc. Do not edit by hand — run `npm run docs:api`._
|
||||
70
docs/api/routes/quote/create.md
Normal file
70
docs/api/routes/quote/create.md
Normal file
@@ -0,0 +1,70 @@
|
||||
# `POST /quote`
|
||||
|
||||
Protected. Requires a valid session cookie (`credentials: 'include'`).
|
||||
|
||||
Create quote
|
||||
|
||||
Creates a quote with header and lines in one transaction.
|
||||
`date` is the document date (valid-until).
|
||||
`entityId` must be a company customer (not Lieferanten/POS), or null.
|
||||
Each line requires `sku`, `amount`, `net`, and `tax` (rate); `rebate` defaults to `0`.
|
||||
|
||||
|
||||
## Body (JSON)
|
||||
|
||||
```json
|
||||
{
|
||||
"number": "Q-2026-001",
|
||||
"date": "2026-08-31",
|
||||
"entityId": 1,
|
||||
"lines": [
|
||||
{
|
||||
"sku": "1",
|
||||
"amount": 10,
|
||||
"net": 99.5,
|
||||
"tax": 19
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Response `201`
|
||||
|
||||
Created quote
|
||||
|
||||
```json
|
||||
{
|
||||
"quote": {
|
||||
"id": 1,
|
||||
"number": "…",
|
||||
"type": "quote",
|
||||
"entityId": 1,
|
||||
"date": "2026-08-10T00:00:00.000Z",
|
||||
"lines": [
|
||||
{
|
||||
"id": 1,
|
||||
"articleId": 1,
|
||||
"sku": "…",
|
||||
"amount": 1,
|
||||
"net": 1,
|
||||
"rebate": 1,
|
||||
"tax": 1,
|
||||
"comment": "…"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Errors
|
||||
|
||||
| Status | Description |
|
||||
|--------|-------------|
|
||||
| 400 | Invalid quote, invalid lines, or no company selected — `{"error":"…"}` |
|
||||
| 401 | Unauthorized — `{"error":"…"}` |
|
||||
| 403 | Not authorized — `{"error":"…"}` |
|
||||
| 404 | Company, entity, or article not found — `{"error":"…"}` |
|
||||
|
||||
---
|
||||
|
||||
_Generated from `@openapi` JSDoc. Do not edit by hand — run `npm run docs:api`._
|
||||
32
docs/api/routes/quote/delete.md
Normal file
32
docs/api/routes/quote/delete.md
Normal file
@@ -0,0 +1,32 @@
|
||||
# `DELETE /quote/{id}`
|
||||
|
||||
Protected. Requires a valid session cookie (`credentials: 'include'`).
|
||||
|
||||
Delete quote
|
||||
|
||||
Deletes the quote (`manifestarticle` rows cascade).
|
||||
|
||||
## Path parameters
|
||||
|
||||
| Param | Required | Type | Description |
|
||||
|-------|----------|------|-------------|
|
||||
| `id` | yes | integer | |
|
||||
|
||||
## Response `204`
|
||||
|
||||
Deleted
|
||||
|
||||
_No content_
|
||||
|
||||
## Errors
|
||||
|
||||
| Status | Description |
|
||||
|--------|-------------|
|
||||
| 400 | No company selected or invalid id — `{"error":"…"}` |
|
||||
| 401 | Unauthorized — `{"error":"…"}` |
|
||||
| 403 | Not authorized — `{"error":"…"}` |
|
||||
| 404 | Quote not found — `{"error":"…"}` |
|
||||
|
||||
---
|
||||
|
||||
_Generated from `@openapi` JSDoc. Do not edit by hand — run `npm run docs:api`._
|
||||
54
docs/api/routes/quote/get.md
Normal file
54
docs/api/routes/quote/get.md
Normal file
@@ -0,0 +1,54 @@
|
||||
# `GET /quote/{id}`
|
||||
|
||||
Protected. Requires a valid session cookie (`credentials: 'include'`).
|
||||
|
||||
Get quote
|
||||
|
||||
Returns a quote with lines for the selected company.
|
||||
|
||||
## Path parameters
|
||||
|
||||
| Param | Required | Type | Description |
|
||||
|-------|----------|------|-------------|
|
||||
| `id` | yes | integer | |
|
||||
|
||||
## Response `200`
|
||||
|
||||
Quote
|
||||
|
||||
```json
|
||||
{
|
||||
"quote": {
|
||||
"id": 1,
|
||||
"number": "…",
|
||||
"type": "quote",
|
||||
"entityId": 1,
|
||||
"date": "2026-08-10T00:00:00.000Z",
|
||||
"lines": [
|
||||
{
|
||||
"id": 1,
|
||||
"articleId": 1,
|
||||
"sku": "…",
|
||||
"amount": 1,
|
||||
"net": 1,
|
||||
"rebate": 1,
|
||||
"tax": 1,
|
||||
"comment": "…"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Errors
|
||||
|
||||
| Status | Description |
|
||||
|--------|-------------|
|
||||
| 400 | No company selected or invalid id — `{"error":"…"}` |
|
||||
| 401 | Unauthorized — `{"error":"…"}` |
|
||||
| 403 | Not authorized — `{"error":"…"}` |
|
||||
| 404 | Quote or company not found — `{"error":"…"}` |
|
||||
|
||||
---
|
||||
|
||||
_Generated from `@openapi` JSDoc. Do not edit by hand — run `npm run docs:api`._
|
||||
40
docs/api/routes/quote/list.md
Normal file
40
docs/api/routes/quote/list.md
Normal file
@@ -0,0 +1,40 @@
|
||||
# `GET /quote`
|
||||
|
||||
Protected. Requires a valid session cookie (`credentials: 'include'`).
|
||||
|
||||
List quotes
|
||||
|
||||
Lists quotes (`manifest` rows with `type = 'quote'`)
|
||||
for the authenticated user's selected company.
|
||||
|
||||
|
||||
## Response `200`
|
||||
|
||||
Quote list
|
||||
|
||||
```json
|
||||
{
|
||||
"quotes": [
|
||||
{
|
||||
"id": 1,
|
||||
"number": "…",
|
||||
"type": "quote",
|
||||
"entityId": 1,
|
||||
"date": "2026-08-10T00:00:00.000Z"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Errors
|
||||
|
||||
| Status | Description |
|
||||
|--------|-------------|
|
||||
| 400 | No company selected — `{"error":"…"}` |
|
||||
| 401 | Unauthorized — `{"error":"…"}` |
|
||||
| 403 | Not authorized — `{"error":"…"}` |
|
||||
| 404 | Company not found — `{"error":"…"}` |
|
||||
|
||||
---
|
||||
|
||||
_Generated from `@openapi` JSDoc. Do not edit by hand — run `npm run docs:api`._
|
||||
66
docs/api/routes/quote/update.md
Normal file
66
docs/api/routes/quote/update.md
Normal file
@@ -0,0 +1,66 @@
|
||||
# `PATCH /quote/{id}`
|
||||
|
||||
Protected. Requires a valid session cookie (`credentials: 'include'`).
|
||||
|
||||
Update quote
|
||||
|
||||
Patches header fields that are present. If `lines` is present, replaces
|
||||
all lines; if omitted, leaves lines unchanged. Returns the full quote.
|
||||
`date` is the document date (valid-until).
|
||||
|
||||
|
||||
## Path parameters
|
||||
|
||||
| Param | Required | Type | Description |
|
||||
|-------|----------|------|-------------|
|
||||
| `id` | yes | integer | |
|
||||
|
||||
## Body (JSON)
|
||||
|
||||
```json
|
||||
{
|
||||
"number": "Q-2026-001b",
|
||||
"lines": []
|
||||
}
|
||||
```
|
||||
|
||||
## Response `200`
|
||||
|
||||
Updated quote
|
||||
|
||||
```json
|
||||
{
|
||||
"quote": {
|
||||
"id": 1,
|
||||
"number": "…",
|
||||
"type": "quote",
|
||||
"entityId": 1,
|
||||
"date": "2026-08-10T00:00:00.000Z",
|
||||
"lines": [
|
||||
{
|
||||
"id": 1,
|
||||
"articleId": 1,
|
||||
"sku": "…",
|
||||
"amount": 1,
|
||||
"net": 1,
|
||||
"rebate": 1,
|
||||
"tax": 1,
|
||||
"comment": "…"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Errors
|
||||
|
||||
| Status | Description |
|
||||
|--------|-------------|
|
||||
| 400 | Invalid quote, invalid lines, invalid id, or no company selected — `{"error":"…"}` |
|
||||
| 401 | Unauthorized — `{"error":"…"}` |
|
||||
| 403 | Not authorized — `{"error":"…"}` |
|
||||
| 404 | Quote, entity, article, or company not found — `{"error":"…"}` |
|
||||
|
||||
---
|
||||
|
||||
_Generated from `@openapi` JSDoc. Do not edit by hand — run `npm run docs:api`._
|
||||
Reference in New Issue
Block a user