This commit is contained in:
seb
2026-10-15 10:50:03 +02:00
parent f331625d63
commit 529b142341
13 changed files with 82 additions and 34 deletions

View File

@@ -10,14 +10,14 @@ Params: path values first, then `query:` and `body:` (`body?` = optional body).
### Reusable types
- `T1` = `{ order: T2 }`
- `T2` = `{ id: int, number: str, type: str, entityId: int|null, date: str, lines: T29[], createdAt?: str, shipping?: T37|null, shippings?: T37[], payment?: T43|null, payments?: T43[], paid?: bool, shipped?: bool, delivered?: bool, orderTotal?: num, paidTotal?: num, orderedQuantity?: num, shippedQuantity?: num, shipments?: T5[], files?: T15[] }`
- `T2` = `{ id: int, number: str, type: str, entityId: int|null, date: str, lines: T29[], externalNumber?: str|null, createdAt?: str, shipping?: T37|null, shippings?: T37[], payment?: T43|null, payments?: T43[], paid?: bool, shipped?: bool, delivered?: bool, orderTotal?: num, paidTotal?: num, orderedQuantity?: num, shippedQuantity?: num, shipments?: T5[], files?: T15[] }`
- `T3` = `{ article: T4 }`
- `T4` = `{ id: int, sku: str, name: str, slug: str, desc: str|null, seo: str|null, track_stock: bool, unitamount: num|null, weight: num|null, unit: T40, brand: T38|null, categoryIds: int[], photos: T35[], eans: str[], prices: T47[], suppliers: T17[] }`
- `T5` = `{ id: int, number: str, type: str, date: str, lines: T29[], shippings: T37[], entityId?: int|null, externalNumber?: str|null, createdAt?: str|null, lineCount?: int, packageCount?: int, files?: T15[] }`
- `T6` = `{ delivery: T7 }`
- `T7` = `{ id: int, number: str, type: str, supplierId: int|null, date: str, lines: T29[], files: T15[], externalNumber?: str|null, createdAt?: str, ledger?: T51 }`
- `T8` = `{ quote: T9 }`
- `T9` = `{ id: int, number: str, type: str, entityId: int|null, date: str, lines: T29[], createdAt?: str, positions?: int, grossTotal?: num, totalQuantity?: num, customerName?: str|null, files?: T15[] }`
- `T6` = `{ quote: T7 }`
- `T7` = `{ id: int, number: str, type: str, entityId: int|null, date: str, lines: T29[], externalNumber?: str|null, createdAt?: str, positions?: int, grossTotal?: num, totalQuantity?: num, customerName?: str|null, files?: T15[] }`
- `T8` = `{ delivery: T9 }`
- `T9` = `{ id: int, number: str, type: str, supplierId: int|null, date: str, lines: T29[], files: T15[], externalNumber?: str|null, createdAt?: str, ledger?: T51 }`
- `T10` = `{ name: str, path: str, totalSizeBytes: int, timestamp: str|null, manifest?: T11|null }`
- `T11` = `{ id: str, timestamp: str, dateKey: str, monthKey: str, dbProvider: str, files: T18, totalSizeBytes: int, durationMs: int }`
- `T12` = `{ labeltemplate: T14 }`
@@ -397,7 +397,7 @@ _none_
- Returns: `200 { deliveries: { id: int, number: str, type: str, supplierId: int|null, date: str, externalNumber?: str|null, createdAt?: str, ledger?: T51 }[] }`
#### Create delivery — `POST /delivery`
- Params: `body: { externalNumber: str, date: str, lines: T34[], supplierId?: int|null, files?: { mimetype: str, name: str, content: str, sort?: int, size?: int, hash?: str, created?: str, modified?: str, meta?: { [k]: str } }[] }`
- Returns: `201 T6`
- Returns: `201 T8`
#### Parse document (SSE) — `POST /delivery/parse`
- Params: `form: { file: str }`
- Returns: `200 SSE`
@@ -415,10 +415,10 @@ _none_
- Returns: `204 void`
#### Get delivery — `GET /delivery/{id}`
- Params: `id: int`
- Returns: `200 T6`
- Returns: `200 T8`
#### Update delivery — `PATCH /delivery/{id}`
- Params: `id: int, body: { externalNumber?: str|null, date?: str, supplierId?: int|null, lines?: T34[], files?: { mimetype: str, name: str, content: str, sort?: int, size?: int, hash?: str, created?: str, modified?: str, meta?: { [k]: str } }[] }`
- Returns: `200 T6`
- Returns: `200 T8`
#### Delete delivery file attachment — `DELETE /delivery/{id}/file/{fileId}`
- Params: `id: int, fileId: int`
- Returns: `204 void`
@@ -624,7 +624,7 @@ _none_
- Params: `query: offset?: int, limit?: int, search?: str, onlyUnpaid?: bool, onlyUndelivered?: bool, seekMonths?: int`
- Returns: `200 { orders: T2[], total: int, unfilteredTotal: int, offset: int, limit: int }`
#### Create order — `POST /order`
- Params: `body: { number: str, date: str, lines: T34[], entityId?: int|null }`
- Params: `body: { number: str, date: str, lines: T34[], entityId?: int|null, externalNumber?: str|null }`
- Returns: `201 T1`
#### Delete order — `DELETE /order/{id}`
- Params: `id: int`
@@ -633,7 +633,7 @@ _none_
- Params: `id: int`
- Returns: `200 T1`
#### Update order — `PATCH /order/{id}`
- Params: `id: int, body: { number?: str, date?: str, entityId?: int|null, lines?: T34[] }`
- Params: `id: int, body: { number?: str, date?: str, entityId?: int|null, externalNumber?: str|null, lines?: T34[] }`
- Returns: `200 T1`
#### Delete order file attachment — `DELETE /order/{id}/file/{fileId}`
- Params: `id: int, fileId: int`
@@ -763,19 +763,19 @@ _none_
#### List quotes — `GET /quote`
- Params: `query: offset?: int, limit?: int, search?: str, seekMonths?: int`
- Returns: `200 { quotes: T9[], total: int, unfilteredTotal: int, offset: int, limit: int }`
- Returns: `200 { quotes: T7[], total: int, unfilteredTotal: int, offset: int, limit: int }`
#### Create quote — `POST /quote`
- Params: `body: { number: str, date: str, lines: T34[], entityId?: int|null }`
- Returns: `201 T8`
- Params: `body: { number: str, date: str, lines: T34[], entityId?: int|null, externalNumber?: str|null }`
- Returns: `201 T6`
#### Delete quote — `DELETE /quote/{id}`
- Params: `id: int`
- Returns: `204 void`
#### Get quote — `GET /quote/{id}`
- Params: `id: int`
- Returns: `200 T8`
- Returns: `200 T6`
#### Update quote — `PATCH /quote/{id}`
- Params: `id: int, body: { number?: str, date?: str, entityId?: int|null, lines?: T34[] }`
- Returns: `200 T8`
- Params: `id: int, body: { number?: str, date?: str, entityId?: int|null, externalNumber?: str|null, lines?: T34[] }`
- Returns: `200 T6`
#### Delete quote file attachment — `DELETE /quote/{id}/file/{fileId}`
- Params: `id: int, fileId: int`
- Returns: `204 void`

View File

@@ -10,14 +10,14 @@ Params: path values first, then `query:` and `body:` (`body?` = optional body).
### Reusable types
- `T1` = `{ order: T2 }`
- `T2` = `{ id: int, number: str, type: str, entityId: int|null, date: str, lines: T23[], createdAt?: str, shipping?: T31|null, shippings?: T31[], payment?: T37|null, payments?: T37[], paid?: bool, shipped?: bool, delivered?: bool, orderTotal?: num, paidTotal?: num, orderedQuantity?: num, shippedQuantity?: num, shipments?: T5[], files?: T13[] }`
- `T2` = `{ id: int, number: str, type: str, entityId: int|null, date: str, lines: T23[], externalNumber?: str|null, createdAt?: str, shipping?: T31|null, shippings?: T31[], payment?: T37|null, payments?: T37[], paid?: bool, shipped?: bool, delivered?: bool, orderTotal?: num, paidTotal?: num, orderedQuantity?: num, shippedQuantity?: num, shipments?: T5[], files?: T13[] }`
- `T3` = `{ article: T4 }`
- `T4` = `{ id: int, sku: str, name: str, slug: str, desc: str|null, seo: str|null, track_stock: bool, unitamount: num|null, weight: num|null, unit: T34, brand: T32|null, categoryIds: int[], photos: T29[], eans: str[], prices: T39[], suppliers: T14[] }`
- `T5` = `{ id: int, number: str, type: str, date: str, lines: T23[], shippings: T31[], entityId?: int|null, externalNumber?: str|null, createdAt?: str|null, lineCount?: int, packageCount?: int, files?: T13[] }`
- `T6` = `{ delivery: T7 }`
- `T7` = `{ id: int, number: str, type: str, supplierId: int|null, date: str, lines: T23[], files: T13[], externalNumber?: str|null, createdAt?: str, ledger?: T43 }`
- `T8` = `{ quote: T9 }`
- `T9` = `{ id: int, number: str, type: str, entityId: int|null, date: str, lines: T23[], createdAt?: str, positions?: int, grossTotal?: num, totalQuantity?: num, customerName?: str|null, files?: T13[] }`
- `T6` = `{ quote: T7 }`
- `T7` = `{ id: int, number: str, type: str, entityId: int|null, date: str, lines: T23[], externalNumber?: str|null, createdAt?: str, positions?: int, grossTotal?: num, totalQuantity?: num, customerName?: str|null, files?: T13[] }`
- `T8` = `{ delivery: T9 }`
- `T9` = `{ id: int, number: str, type: str, supplierId: int|null, date: str, lines: T23[], files: T13[], externalNumber?: str|null, createdAt?: str, ledger?: T43 }`
- `T10` = `{ labeltemplate: T12 }`
- `T11` = `{ attachment: T13, fileUrl: str }`
- `T12` = `{ id: int, name: str, width: num, height: num, dpi: int, type: str, content: T19, thumb?: str|null }`
@@ -315,16 +315,16 @@ _none_
- Returns: `200 { deliveries: { id: int, number: str, type: str, supplierId: int|null, date: str, externalNumber?: str|null, createdAt?: str, ledger?: T43 }[] }`
#### Create delivery — `POST /delivery`
- Params: `body: { externalNumber: str, date: str, lines: T28[], supplierId?: int|null, files?: { mimetype: str, name: str, content: str, sort?: int, size?: int, hash?: str, created?: str, modified?: str, meta?: { [k]: str } }[] }`
- Returns: `201 T6`
- Returns: `201 T8`
#### Delete delivery — `DELETE /delivery/{id}`
- Params: `id: int`
- Returns: `204 void`
#### Get delivery — `GET /delivery/{id}`
- Params: `id: int`
- Returns: `200 T6`
- Returns: `200 T8`
#### Update delivery — `PATCH /delivery/{id}`
- Params: `id: int, body: { externalNumber?: str|null, date?: str, supplierId?: int|null, lines?: T28[], files?: { mimetype: str, name: str, content: str, sort?: int, size?: int, hash?: str, created?: str, modified?: str, meta?: { [k]: str } }[] }`
- Returns: `200 T6`
- Returns: `200 T8`
#### Delete delivery file attachment — `DELETE /delivery/{id}/file/{fileId}`
- Params: `id: int, fileId: int`
- Returns: `204 void`
@@ -428,7 +428,7 @@ _none_
- Params: `query: offset?: int, limit?: int, search?: str, onlyUnpaid?: bool, onlyUndelivered?: bool, seekMonths?: int`
- Returns: `200 { orders: T2[], total: int, unfilteredTotal: int, offset: int, limit: int }`
#### Create order — `POST /order`
- Params: `body: { number: str, date: str, lines: T28[], entityId?: int|null }`
- Params: `body: { number: str, date: str, lines: T28[], entityId?: int|null, externalNumber?: str|null }`
- Returns: `201 T1`
#### Delete order — `DELETE /order/{id}`
- Params: `id: int`
@@ -437,7 +437,7 @@ _none_
- Params: `id: int`
- Returns: `200 T1`
#### Update order — `PATCH /order/{id}`
- Params: `id: int, body: { number?: str, date?: str, entityId?: int|null, lines?: T28[] }`
- Params: `id: int, body: { number?: str, date?: str, entityId?: int|null, externalNumber?: str|null, lines?: T28[] }`
- Returns: `200 T1`
#### Delete order file attachment — `DELETE /order/{id}/file/{fileId}`
- Params: `id: int, fileId: int`
@@ -522,19 +522,19 @@ _none_
#### List quotes — `GET /quote`
- Params: `query: offset?: int, limit?: int, search?: str, seekMonths?: int`
- Returns: `200 { quotes: T9[], total: int, unfilteredTotal: int, offset: int, limit: int }`
- Returns: `200 { quotes: T7[], total: int, unfilteredTotal: int, offset: int, limit: int }`
#### Create quote — `POST /quote`
- Params: `body: { number: str, date: str, lines: T28[], entityId?: int|null }`
- Returns: `201 T8`
- Params: `body: { number: str, date: str, lines: T28[], entityId?: int|null, externalNumber?: str|null }`
- Returns: `201 T6`
#### Delete quote — `DELETE /quote/{id}`
- Params: `id: int`
- Returns: `204 void`
#### Get quote — `GET /quote/{id}`
- Params: `id: int`
- Returns: `200 T8`
- Returns: `200 T6`
#### Update quote — `PATCH /quote/{id}`
- Params: `id: int, body: { number?: str, date?: str, entityId?: int|null, lines?: T28[] }`
- Returns: `200 T8`
- Params: `id: int, body: { number?: str, date?: str, entityId?: int|null, externalNumber?: str|null, lines?: T28[] }`
- Returns: `200 T6`
#### Delete quote file attachment — `DELETE /quote/{id}/file/{fileId}`
- Params: `id: int, fileId: int`
- Returns: `204 void`

View File

@@ -17,6 +17,7 @@ Each line requires `sku` or `name`, `amount`, `net`, and `taxrate` (rate); `pu`
| `number` | yes | string | |
| `date` | yes | string | Document date / expected delivery |
| `entityId` | no | integer | Customer entity (manifest.entity_id) |
| `externalNumber` | no | string | External customer reference number (manifest.external_number) |
| `lines` | yes | ManifestLineInput[] | |
```json
@@ -48,6 +49,7 @@ Created order
"number": "…",
"type": "order",
"entityId": 1,
"externalNumber": "…",
"date": "2026-08-10T00:00:00.000Z",
"createdAt": "2026-08-10T00:00:00.000Z",
"lines": [

View File

@@ -23,6 +23,7 @@ Order
"number": "…",
"type": "order",
"entityId": 1,
"externalNumber": "…",
"date": "2026-08-10T00:00:00.000Z",
"createdAt": "2026-08-10T00:00:00.000Z",
"lines": [

View File

@@ -32,6 +32,7 @@ Order list
"number": "…",
"type": "order",
"entityId": 1,
"externalNumber": "…",
"date": "2026-08-10T00:00:00.000Z",
"createdAt": "2026-08-10T00:00:00.000Z",
"lines": [

View File

@@ -22,6 +22,7 @@ all lines; if omitted, leaves lines unchanged. Returns the full order.
| `number` | no | string | |
| `date` | no | string | Document date / expected delivery |
| `entityId` | no | integer | |
| `externalNumber` | no | string | External customer reference number (manifest.external_number) |
| `lines` | no | ManifestLineInput[] | |
```json
@@ -42,6 +43,7 @@ Updated order
"number": "…",
"type": "order",
"entityId": 1,
"externalNumber": "…",
"date": "2026-08-10T00:00:00.000Z",
"createdAt": "2026-08-10T00:00:00.000Z",
"lines": [

View File

@@ -17,6 +17,7 @@ Each line requires `sku` or `name`, `amount`, `net`, and `taxrate` (rate); `pu`
| `number` | yes | string | |
| `date` | yes | string | Document date / valid-until |
| `entityId` | no | integer | Customer entity (manifest.entity_id) |
| `externalNumber` | no | string | External customer reference number (manifest.external_number) |
| `lines` | yes | ManifestLineInput[] | |
```json
@@ -48,6 +49,7 @@ Created quote
"number": "…",
"type": "quote",
"entityId": 1,
"externalNumber": "…",
"date": "2026-08-10T00:00:00.000Z",
"createdAt": "2026-08-10T00:00:00.000Z",
"positions": 1,

View File

@@ -23,6 +23,7 @@ Quote
"number": "…",
"type": "quote",
"entityId": 1,
"externalNumber": "…",
"date": "2026-08-10T00:00:00.000Z",
"createdAt": "2026-08-10T00:00:00.000Z",
"positions": 1,

View File

@@ -29,6 +29,7 @@ Quote list
"number": "…",
"type": "quote",
"entityId": 1,
"externalNumber": "…",
"date": "2026-08-10T00:00:00.000Z",
"createdAt": "2026-08-10T00:00:00.000Z",
"positions": 1,

View File

@@ -22,6 +22,7 @@ all lines; if omitted, leaves lines unchanged. Returns the full quote.
| `number` | no | string | |
| `date` | no | string | Document date / valid-until |
| `entityId` | no | integer | |
| `externalNumber` | no | string | External customer reference number (manifest.external_number) |
| `lines` | no | ManifestLineInput[] | |
```json
@@ -42,6 +43,7 @@ Updated quote
"number": "…",
"type": "quote",
"entityId": 1,
"externalNumber": "…",
"date": "2026-08-10T00:00:00.000Z",
"createdAt": "2026-08-10T00:00:00.000Z",
"positions": 1,

View File

@@ -957,6 +957,10 @@
* type: integer
* nullable: true
* description: Customer (manifest.entity_id)
* externalNumber:
* type: string
* nullable: true
* description: External reference number (manifest.external_number)
* date:
* type: string
* format: date-time
@@ -1006,6 +1010,10 @@
* type: integer
* nullable: true
* description: Customer (manifest.entity_id)
* externalNumber:
* type: string
* nullable: true
* description: External customer reference number (manifest.external_number)
* date:
* type: string
* format: date-time

View File

@@ -171,6 +171,10 @@ export function register(app, basePath = '') {
* type: integer
* nullable: true
* description: Customer entity (manifest.entity_id)
* externalNumber:
* type: string
* nullable: true
* description: External customer reference number (manifest.external_number)
* lines:
* type: array
* items:
@@ -292,7 +296,7 @@ export function register(app, basePath = '') {
return res.status(400).json({ error: selected.error });
}
const { number, date, createdAt, entityId, lines } = req.body ?? {};
const { number, date, createdAt, entityId, externalNumber, lines } = req.body ?? {};
if (entityId !== undefined && entityId !== null && (typeof entityId !== 'number' || !Number.isInteger(entityId) || entityId <= 0)) {
return res.status(400).json({ error: 'Invalid entityId' });
}
@@ -303,6 +307,7 @@ export function register(app, basePath = '') {
date,
createdAt,
entityId,
externalNumber: externalNumber !== undefined && externalNumber !== null ? String(externalNumber) : externalNumber,
lines,
});
res.status(201).json({ order });
@@ -397,6 +402,10 @@ export function register(app, basePath = '') {
* entityId:
* type: integer
* nullable: true
* externalNumber:
* type: string
* nullable: true
* description: External customer reference number (manifest.external_number)
* lines:
* type: array
* items:
@@ -534,6 +543,11 @@ export function register(app, basePath = '') {
}
patch.entityId = body.entityId;
}
if (Object.prototype.hasOwnProperty.call(body, 'externalNumber')) {
patch.externalNumber = body.externalNumber !== null && body.externalNumber !== undefined
? String(body.externalNumber)
: null;
}
if (Object.prototype.hasOwnProperty.call(body, 'lines')) {
patch.lines = body.lines;
}

View File

@@ -157,6 +157,10 @@ export function register(app, basePath = '') {
* type: integer
* nullable: true
* description: Customer entity (manifest.entity_id)
* externalNumber:
* type: string
* nullable: true
* description: External customer reference number (manifest.external_number)
* lines:
* type: array
* items:
@@ -273,7 +277,7 @@ export function register(app, basePath = '') {
return res.status(400).json({ error: selected.error });
}
const { number, date, createdAt, entityId, lines } = req.body ?? {};
const { number, date, createdAt, entityId, externalNumber, lines } = req.body ?? {};
if (entityId !== undefined && entityId !== null && (typeof entityId !== 'number' || !Number.isInteger(entityId) || entityId <= 0)) {
return res.status(400).json({ error: 'Invalid entityId' });
}
@@ -284,6 +288,7 @@ export function register(app, basePath = '') {
date,
createdAt,
entityId,
externalNumber: externalNumber !== undefined && externalNumber !== null ? String(externalNumber) : externalNumber,
lines,
});
res.status(201).json({ quote });
@@ -378,6 +383,10 @@ export function register(app, basePath = '') {
* entityId:
* type: integer
* nullable: true
* externalNumber:
* type: string
* nullable: true
* description: External customer reference number (manifest.external_number)
* lines:
* type: array
* items:
@@ -515,6 +524,11 @@ export function register(app, basePath = '') {
}
patch.entityId = body.entityId;
}
if (Object.prototype.hasOwnProperty.call(body, 'externalNumber')) {
patch.externalNumber = body.externalNumber !== null && body.externalNumber !== undefined
? String(body.externalNumber)
: null;
}
if (Object.prototype.hasOwnProperty.call(body, 'lines')) {
patch.lines = body.lines;
}