This commit is contained in:
seb
2026-10-20 23:25:47 +02:00
parent 70c7d5eff2
commit 07206674c1
5 changed files with 33 additions and 41 deletions

View File

@@ -59,7 +59,7 @@ export const article = {
return http(`/api/article/${encodeURIComponent(sku)}/history${qs ? `?${qs}` : ''}`); return http(`/api/article/${encodeURIComponent(sku)}/history${qs ? `?${qs}` : ''}`);
}, },
/** POST /api/article → 201 { article } */ /** POST /api/article → 201 { sku } */
create({ categoryId, name, track_stock }) { create({ categoryId, name, track_stock }) {
return http('/api/article', { return http('/api/article', {
method: 'POST', method: 'POST',
@@ -75,7 +75,7 @@ export const article = {
* PATCH /api/article/:sku * PATCH /api/article/:sku
* Body: at least one of { name, unitamount, unitSi, track_stock, desc, seo } * Body: at least one of { name, unitamount, unitSi, track_stock, desc, seo }
* unitSi must exist for selected company → 404 Unit not found * unitSi must exist for selected company → 404 Unit not found
* → 200 { article } (same detail shape as GET: includes desc, seo) * → 204 (no body; refetch via getBySku)
*/ */
update(sku, body) { update(sku, body) {
return http(`/api/article/${encodeURIComponent(sku)}`, { return http(`/api/article/${encodeURIComponent(sku)}`, {
@@ -87,7 +87,7 @@ export const article = {
/** /**
* PUT /api/article/:sku/track_stock * PUT /api/article/:sku/track_stock
* Body: { track_stock: boolean } * Body: { track_stock: boolean }
* → 200 { article } * → 204 (no body)
*/ */
setTrackStock(sku, body) { setTrackStock(sku, body) {
const payload = typeof body === 'boolean' ? { track_stock: body } : body; const payload = typeof body === 'boolean' ? { track_stock: body } : body;
@@ -147,7 +147,7 @@ export const article = {
* PUT /api/article/:sku/prices * PUT /api/article/:sku/prices
* Body: { prices: [{ price (net), tax (rate), minmultiplier? }] } * Body: { prices: [{ price (net), tax (rate), minmultiplier? }] }
* Replace-all POS customer group prices. Empty prices clears all POS prices. * Replace-all POS customer group prices. Empty prices clears all POS prices.
* → 200 { article } (same shape as GET by SKU) * → 204 (no body)
*/ */
setPrices(sku, prices) { setPrices(sku, prices) {
return http(`/api/article/${encodeURIComponent(sku)}/prices`, { return http(`/api/article/${encodeURIComponent(sku)}/prices`, {
@@ -158,7 +158,7 @@ export const article = {
/** /**
* PUT /api/article/:sku/weight * PUT /api/article/:sku/weight
* Body: { weight } → 200 { article } * Body: { weight } → 204 (no body)
*/ */
setWeight(sku, body) { setWeight(sku, body) {
return http(`/api/article/${encodeURIComponent(sku)}/weight`, { return http(`/api/article/${encodeURIComponent(sku)}/weight`, {
@@ -171,7 +171,7 @@ export const article = {
* PUT /api/article/:sku/brand * PUT /api/article/:sku/brand
* Body: { brandId: number | null } — null clears the brand. * Body: { brandId: number | null } — null clears the brand.
* brandId must belong to the article's company → 404 Article or brand not found. * brandId must belong to the article's company → 404 Article or brand not found.
* → 200 { article } (same shape as GET by SKU) * → 204 (no body)
*/ */
setBrandIdBySku(sku, brandId) { setBrandIdBySku(sku, brandId) {
return http(`/api/article/${encodeURIComponent(sku)}/brand`, { return http(`/api/article/${encodeURIComponent(sku)}/brand`, {
@@ -184,7 +184,7 @@ export const article = {
* PUT /api/article/:sku/eans * PUT /api/article/:sku/eans
* Body: { eans: string[] } — replace-all. Empty array clears all. * Body: { eans: string[] } — replace-all. Empty array clears all.
* EANs must be non-empty unique strings → 400 Invalid eans. * EANs must be non-empty unique strings → 400 Invalid eans.
* → 200 { article } (same shape as GET by SKU) * → 204 (no body)
*/ */
setEansBySku(sku, eans) { setEansBySku(sku, eans) {
return http(`/api/article/${encodeURIComponent(sku)}/eans`, { return http(`/api/article/${encodeURIComponent(sku)}/eans`, {
@@ -197,7 +197,7 @@ export const article = {
* PUT /api/article/:sku/categories * PUT /api/article/:sku/categories
* Body: { categoryIds: number[] } — replace-all. Empty array clears all. * Body: { categoryIds: number[] } — replace-all. Empty array clears all.
* Categories must belong to the article's company; ids must be unique. * Categories must belong to the article's company; ids must be unique.
* → 200 { article } (same shape as GET by SKU) * → 204 (no body)
*/ */
setCategories(sku, categoryIds) { setCategories(sku, categoryIds) {
return http(`/api/article/${encodeURIComponent(sku)}/categories`, { return http(`/api/article/${encodeURIComponent(sku)}/categories`, {
@@ -342,7 +342,7 @@ export const article = {
/** /**
* POST /api/article/:sku/parent * POST /api/article/:sku/parent
* Body: { isParent: boolean, attributeNameId?: number } * Body: { isParent: boolean, attributeNameId?: number } → 204 (no body)
*/ */
toggleParent(sku, body) { toggleParent(sku, body) {
return http(`/api/article/${encodeURIComponent(sku)}/parent`, { return http(`/api/article/${encodeURIComponent(sku)}/parent`, {
@@ -355,6 +355,7 @@ export const article = {
/** /**
* POST /api/article/:sku/children * POST /api/article/:sku/children
* Body: { attributeValueId?: number, value?: string, name?: string } * Body: { attributeValueId?: number, value?: string, name?: string }
* → 201 { sku }
*/ */
addChild(sku, body) { addChild(sku, body) {
return http(`/api/article/${encodeURIComponent(sku)}/children`, { return http(`/api/article/${encodeURIComponent(sku)}/children`, {

View File

@@ -169,9 +169,8 @@ const actions = {
actions.setArticleName(key, body.name); actions.setArticleName(key, body.name);
} }
try { try {
const res = await articleApi.update(key, body); await articleApi.update(key, body);
actions.setArticle(res.article); return { article: await actions.reloadArticle(key) };
return res;
} catch (err) { } catch (err) {
if (nameChange) { if (nameChange) {
// The optimistic patch was wrong: drop the index entry and refetch. // The optimistic patch was wrong: drop the index entry and refetch.
@@ -192,9 +191,8 @@ const actions = {
* @returns {Promise<object>} Response body containing the fresh `article`. * @returns {Promise<object>} Response body containing the fresh `article`.
*/ */
async setEans(sku, eans) { async setEans(sku, eans) {
const res = await articleApi.setEansBySku(String(sku), eans); await articleApi.setEansBySku(String(sku), eans);
actions.setArticle(res.article); return { article: await actions.reloadArticle(sku) };
return res;
}, },
/** /**
@@ -205,9 +203,8 @@ const actions = {
* @returns {Promise<object>} Response body containing the fresh `article`. * @returns {Promise<object>} Response body containing the fresh `article`.
*/ */
async setBrand(sku, body) { async setBrand(sku, body) {
const res = await articleApi.setBrandIdBySku(String(sku), body?.brandId); await articleApi.setBrandIdBySku(String(sku), body?.brandId);
actions.setArticle(res.article); return { article: await actions.reloadArticle(sku) };
return res;
}, },
/** /**
@@ -218,9 +215,8 @@ const actions = {
* @returns {Promise<object>} Response body containing the fresh `article`. * @returns {Promise<object>} Response body containing the fresh `article`.
*/ */
async setCategories(sku, categoryIds) { async setCategories(sku, categoryIds) {
const res = await articleApi.setCategories(String(sku), categoryIds); await articleApi.setCategories(String(sku), categoryIds);
actions.setArticle(res.article); return { article: await actions.reloadArticle(sku) };
return res;
}, },
/** /**
@@ -231,9 +227,8 @@ const actions = {
* @returns {Promise<object>} Response body containing the fresh `article`. * @returns {Promise<object>} Response body containing the fresh `article`.
*/ */
async setPrices(sku, prices) { async setPrices(sku, prices) {
const res = await articleApi.setPrices(String(sku), prices); await articleApi.setPrices(String(sku), prices);
actions.setArticle(res.article); return { article: await actions.reloadArticle(sku) };
return res;
}, },
/** /**
@@ -244,9 +239,8 @@ const actions = {
* @returns {Promise<object>} Response body containing the fresh `article`. * @returns {Promise<object>} Response body containing the fresh `article`.
*/ */
async setWeight(sku, body) { async setWeight(sku, body) {
const res = await articleApi.setWeight(String(sku), body); await articleApi.setWeight(String(sku), body);
actions.setArticle(res.article); return { article: await actions.reloadArticle(sku) };
return res;
}, },
/** /**
@@ -257,9 +251,8 @@ const actions = {
* @returns {Promise<object>} Response body containing the fresh `article`. * @returns {Promise<object>} Response body containing the fresh `article`.
*/ */
async setTrackStock(sku, body) { async setTrackStock(sku, body) {
const res = await articleApi.setTrackStock(String(sku), body); await articleApi.setTrackStock(String(sku), body);
if (res?.article) actions.setArticle(res.article); return { article: await actions.reloadArticle(sku) };
return res;
}, },
/** /**

View File

@@ -213,8 +213,8 @@ const actions = {
* @param {{ parentId: number|string, name: string }} param0 * @param {{ parentId: number|string, name: string }} param0
*/ */
async createArticle({ parentId, name }) { async createArticle({ parentId, name }) {
const res = await articleApi.create({ categoryId: parentId, name }); const { sku } = await articleApi.create({ categoryId: parentId, name });
const created = res.article; const { article: created } = await articleApi.getBySku(sku);
if (created) appendArticlesToCategoryViews({ categoryId: parentId, articles: [created] }); if (created) appendArticlesToCategoryViews({ categoryId: parentId, articles: [created] });
return created; return created;
}, },
@@ -228,8 +228,9 @@ const actions = {
if (list.length === 0) throw new Error('Keine Namen übergeben.'); if (list.length === 0) throw new Error('Keine Namen übergeben.');
const created = []; const created = [];
for (const name of list) { for (const name of list) {
const res = await articleApi.create({ categoryId: parentId, name }); const { sku } = await articleApi.create({ categoryId: parentId, name });
if (res.article) created.push(res.article); const { article: created1 } = await articleApi.getBySku(sku);
if (created1) created.push(created1);
} }
appendArticlesToCategoryViews({ categoryId: parentId, articles: created }); appendArticlesToCategoryViews({ categoryId: parentId, articles: created });
return created; return created;

View File

@@ -477,10 +477,9 @@ class LieferungNeuPage extends PureComponent {
}); });
requireObject(articleRes, 'POST /api/article'); requireObject(articleRes, 'POST /api/article');
requireObject(articleRes.article, 'article'); requireDefined(articleRes.sku, 'sku');
requireDefined(articleRes.article.sku, 'article.sku');
const internalSku = articleRes.article.sku; const internalSku = articleRes.sku;
const supplierSku = line.sku; const supplierSku = line.sku;
// Add supplier relationship with the supplier's SKU // Add supplier relationship with the supplier's SKU

View File

@@ -144,10 +144,8 @@ async function importRow(row, { ensureCategory, ensureBrand }) {
// Create the article under the leaf category. // Create the article under the leaf category.
const createRes = await article.create({ categoryId: leafCategoryId, name }); const createRes = await article.create({ categoryId: leafCategoryId, name });
requireObject(createRes, 'POST /api/article'); requireObject(createRes, 'POST /api/article');
const created = createRes.article; requireDefined(createRes.sku, 'sku');
requireDefined(created, 'article'); const sku = createRes.sku;
requireDefined(created.sku, 'article.sku');
const sku = created.sku;
const applied = { sku, artNr: row.artNr || null, name }; const applied = { sku, artNr: row.artNr || null, name };