Add PUT /article/:sku/prices for POS price replace-all.

This commit is contained in:
seb
2026-08-01 05:17:33 +02:00
parent bdcd745c4d
commit 8a94abf1c9
5 changed files with 303 additions and 0 deletions

View File

@@ -34,6 +34,8 @@ function articleErrorStatus(error) {
if (error.message === 'Name required') return 400;
if (error.message === 'Invalid image order') return 400;
if (error.message === 'Article has children') return 400;
if (error.message === 'Invalid prices') return 400;
if (error.message === 'POS customer group required') return 400;
return 500;
}
@@ -338,6 +340,110 @@ export function register(app, basePath = '') {
}
});
/**
* @openapi
* /article/{sku}/prices:
* put:
* tags: [Article]
* summary: Replace POS prices by SKU
* description: |
* Replace-all prices for the company POS customer group.
* Each entry: `price` (net), `tax` (rate, ensured via tax.ensure), optional `minmultiplier` (default 1).
* Empty `prices` clears all POS prices. Returns the same shape as GET by SKU.
* security:
* - cookieAuth: []
* x-markdown: article/set-prices.md
* parameters:
* - in: path
* name: sku
* required: true
* schema:
* type: string
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* required: [prices]
* properties:
* prices:
* type: array
* items:
* type: object
* required: [price, tax]
* properties:
* price:
* type: number
* description: Net price
* tax:
* type: number
* description: Tax rate (e.g. 19)
* minmultiplier:
* type: number
* description: Defaults to 1; must be unique per request
* example:
* prices:
* - price: 10.5
* tax: 19
* - price: 9.9
* tax: 19
* minmultiplier: 10
* responses:
* 200:
* description: Updated article detail
* content:
* application/json:
* schema:
* type: object
* properties:
* article:
* $ref: '#/components/schemas/ArticleDetail'
* 400:
* description: Invalid prices or POS customer group required
* content:
* application/json:
* schema:
* $ref: '#/components/schemas/Error'
* 401:
* description: Unauthorized
* content:
* application/json:
* schema:
* $ref: '#/components/schemas/Error'
* 403:
* description: Not authorized
* content:
* application/json:
* schema:
* $ref: '#/components/schemas/Error'
* 404:
* description: Article not found
* content:
* application/json:
* schema:
* $ref: '#/components/schemas/Error'
*/
app.put(`${basePath}/article/:sku/prices`, async (req, res) => {
const skuParsed = parseSku(req.params.sku);
if (skuParsed.error) {
return res.status(400).json({ error: skuParsed.error });
}
if (!Array.isArray(req.body?.prices)) {
return res.status(400).json({ error: 'prices is required' });
}
try {
const article = await db.setPricesBySku(req.user.id, skuParsed.sku, req.body.prices);
res.status(200).json({ article });
} catch (error) {
const status = articleErrorStatus(error);
if (status === 500) console.error('Set article prices failed:', error);
res.status(status).json({ error: error.message });
}
});
/**
* @openapi
* /article/{sku}/image:

View File

@@ -34,3 +34,8 @@ export async function remove(googleAuthId, sku) {
const store = await getStore();
return store.article.delete(googleAuthId, sku);
}
export async function setPricesBySku(googleAuthId, sku, prices) {
const store = await getStore();
return store.article.setPricesBySku(googleAuthId, sku, prices);
}