This commit is contained in:
seb
2026-08-02 19:04:56 +02:00
parent bfb1d8762a
commit aed0857f23
21 changed files with 1953 additions and 0 deletions

View File

@@ -38,6 +38,10 @@ function articleErrorStatus(error) {
if (error.message === 'POS customer group required') return 400;
if (error.message === 'Invalid unitamount') return 400;
if (error.message === 'Unit not found') return 404;
if (error.message === 'Invalid eans') return 400;
if (error.message === 'Brand not found') return 404;
if (error.message === 'Invalid weight') return 400;
if (error.message === 'Invalid categoryIds') return 400;
return 500;
}
@@ -724,4 +728,350 @@ export function register(app, basePath = '') {
res.status(status).json({ error: error.message });
}
});
/**
* @openapi
* /article/{sku}/eans:
* put:
* tags: [Article]
* summary: Replace article EANs by SKU
* description: |
* Replace-all EANs for the article. EANs must be non-empty unique strings;
* empty array clears all EANs. Returns the same shape as GET by SKU.
* security:
* - cookieAuth: []
* x-markdown: article/set-eans.md
* parameters:
* - in: path
* name: sku
* required: true
* schema:
* type: string
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* required: [eans]
* properties:
* eans:
* type: array
* items:
* type: string
* example:
* eans: ["4001234567890"]
* responses:
* 200:
* description: Updated article detail
* content:
* application/json:
* schema:
* type: object
* properties:
* article:
* $ref: '#/components/schemas/ArticleDetail'
* 400:
* description: Invalid eans
* 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/eans`, 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?.eans)) {
return res.status(400).json({ error: 'eans is required' });
}
try {
const article = await db.setEansBySku(req.user.id, skuParsed.sku, req.body.eans);
res.status(200).json({ article });
} catch (error) {
const status = articleErrorStatus(error);
if (status === 500) console.error('Set article eans failed:', error);
res.status(status).json({ error: error.message });
}
});
/**
* @openapi
* /article/{sku}/brand:
* put:
* tags: [Article]
* summary: Set or clear article brand by SKU
* description: |
* Sets the article's `brandId` (must belong to the article's company).
* Pass `null` to clear the brand. Returns the same shape as GET by SKU.
* security:
* - cookieAuth: []
* x-markdown: article/set-brand.md
* parameters:
* - in: path
* name: sku
* required: true
* schema:
* type: string
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* required: [brandId]
* properties:
* brandId:
* type: integer
* nullable: true
* example:
* brandId: 3
* responses:
* 200:
* description: Updated article detail
* content:
* application/json:
* schema:
* type: object
* properties:
* article:
* $ref: '#/components/schemas/ArticleDetail'
* 400:
* description: Validation error
* 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 or brand not found
* content:
* application/json:
* schema:
* $ref: '#/components/schemas/Error'
*/
app.put(`${basePath}/article/:sku/brand`, async (req, res) => {
const skuParsed = parseSku(req.params.sku);
if (skuParsed.error) {
return res.status(400).json({ error: skuParsed.error });
}
const brandId = req.body?.brandId ?? null;
try {
const article = await db.setBrandIdBySku(req.user.id, skuParsed.sku, brandId);
res.status(200).json({ article });
} catch (error) {
const status = articleErrorStatus(error);
if (status === 500) console.error('Set article brand failed:', error);
res.status(status).json({ error: error.message });
}
});
/**
* @openapi
* /article/{sku}/weight:
* put:
* tags: [Article]
* summary: Set article weight by SKU
* description: |
* Sets the article's `weight`. Must be finite and `>= 0`.
* Returns the same shape as GET by SKU.
* security:
* - cookieAuth: []
* x-markdown: article/set-weight.md
* parameters:
* - in: path
* name: sku
* required: true
* schema:
* type: string
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* required: [weight]
* properties:
* weight:
* type: number
* example:
* weight: 1.5
* responses:
* 200:
* description: Updated article detail
* content:
* application/json:
* schema:
* type: object
* properties:
* article:
* $ref: '#/components/schemas/ArticleDetail'
* 400:
* description: Invalid weight
* 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/weight`, async (req, res) => {
const skuParsed = parseSku(req.params.sku);
if (skuParsed.error) {
return res.status(400).json({ error: skuParsed.error });
}
const weight = req.body?.weight;
try {
const article = await db.setWeightBySku(req.user.id, skuParsed.sku, weight);
res.status(200).json({ article });
} catch (error) {
const status = articleErrorStatus(error);
if (status === 500) console.error('Set article weight failed:', error);
res.status(status).json({ error: error.message });
}
});
/**
* @openapi
* /article/{sku}/categories:
* put:
* tags: [Article]
* summary: Replace article categories by SKU
* description: |
* Replace-all the article's category list. Each category must belong to
* the article's company; ids must be unique. Empty array removes the
* article from all categories. Returns the same shape as GET by SKU.
* security:
* - cookieAuth: []
* x-markdown: article/set-categories.md
* parameters:
* - in: path
* name: sku
* required: true
* schema:
* type: string
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* required: [categoryIds]
* properties:
* categoryIds:
* type: array
* items:
* type: integer
* example:
* categoryIds: [4, 7]
* responses:
* 200:
* description: Updated article detail
* content:
* application/json:
* schema:
* type: object
* properties:
* article:
* $ref: '#/components/schemas/ArticleDetail'
* 400:
* description: Invalid categoryIds
* 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/categories`, 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?.categoryIds)) {
return res.status(400).json({ error: 'categoryIds is required' });
}
try {
const article = await db.setCategoryIdsBySku(
req.user.id,
skuParsed.sku,
req.body.categoryIds,
);
res.status(200).json({ article });
} catch (error) {
const status = articleErrorStatus(error);
if (status === 500) console.error('Set article categories failed:', error);
res.status(status).json({ error: error.message });
}
});
}