u
This commit is contained in:
@@ -142,10 +142,11 @@ Backend mapping:
|
|||||||
| Method | Signature | Returns |
|
| Method | Signature | Returns |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| `createUnderParent` | `({ googleAuthId, parentId, name })` | `{ id, parentId, name, sku }` |
|
| `createUnderParent` | `({ googleAuthId, parentId, name })` | `{ id, parentId, name, sku }` |
|
||||||
|
| `getBySku` | `(googleAuthId, sku)` | `{ id, sku, name, slug, net, taxRate, optionsCount, articleListCount, childCount, thumbW, thumbH, thumbHash }` |
|
||||||
|
|
||||||
`parentId` is the category id. Creates `article` + `articletext` (company default language) + `categoryarticle` in one transaction. Allocates `sku` via `getnextnumberwithprefixandpadding` (`type` `sku`; creates `numbers` row with empty prefix if missing). Default unit `pc` is ensured if missing (`unitamount` 1, `weight` 0).
|
`parentId` is the category id. Creates `article` + `articletext` (company default language) + `categoryarticle` in one transaction. Allocates `sku` via `getnextnumberwithprefixandpadding` (`type` `sku`; creates `numbers` row with empty prefix if missing). Default unit `pc` is ensured if missing (`unitamount` 1, `weight` 0). Auth via `resolveCategoryAccess(googleAuthId, parentId)` — `Parent not found` / `Not authorized`.
|
||||||
|
|
||||||
Auth via `resolveCategoryAccess(googleAuthId, parentId)` — `Parent not found` / `Not authorized`.
|
Same article shape as `getCategoryArticles` / `getTreeForCompany().articles[]`. Auth via the article's `categoryarticle` category + `resolveCategoryAccess`. Errors: `Article not found`, `Not authorized`.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -162,6 +163,7 @@ Auth via `resolveCategoryAccess(googleAuthId, parentId)` — `Parent not found`
|
|||||||
| `POST /api/category` | `category.createUnderParent({ googleAuthId, parentId, name })` |
|
| `POST /api/category` | `category.createUnderParent({ googleAuthId, parentId, name })` |
|
||||||
| `DELETE /api/category/:id` | `category.delete({ googleAuthId, id })` |
|
| `DELETE /api/category/:id` | `category.delete({ googleAuthId, id })` |
|
||||||
| `POST /api/article` | `article.createUnderParent({ googleAuthId, parentId, name })` |
|
| `POST /api/article` | `article.createUnderParent({ googleAuthId, parentId, name })` |
|
||||||
|
| `GET /api/article/:sku` | `article.getBySku(googleAuthId, sku)` |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -109,6 +109,11 @@ const MENU = {
|
|||||||
label: 'createUnderParent',
|
label: 'createUnderParent',
|
||||||
hint: 'googleAuthId, parentId, name → row',
|
hint: 'googleAuthId, parentId, name → row',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
value: 'article.getBySku',
|
||||||
|
label: 'getBySku',
|
||||||
|
hint: 'googleAuthId, sku → row',
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
companyuser: {
|
companyuser: {
|
||||||
@@ -382,6 +387,18 @@ async function runMethod(client, action) {
|
|||||||
}),
|
}),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
case 'article.getBySku': {
|
||||||
|
const googleAuthId = await askInt('google_auth id');
|
||||||
|
if (googleAuthId == null) return;
|
||||||
|
const sku = await askText('sku', {
|
||||||
|
validate: (v) => (!v?.trim() ? 'Required' : undefined),
|
||||||
|
});
|
||||||
|
if (sku == null) return;
|
||||||
|
return [
|
||||||
|
'result',
|
||||||
|
await client.article.getBySku(Number(googleAuthId), sku),
|
||||||
|
];
|
||||||
|
}
|
||||||
case 'companyuser.add': {
|
case 'companyuser.add': {
|
||||||
const companyId = await askInt('Company id');
|
const companyId = await askInt('Company id');
|
||||||
if (companyId == null) return;
|
if (companyId == null) return;
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import categoryGetCategoryArticles from './store/category/getCategoryArticles.js
|
|||||||
import categoryCreateUnderParent from './store/category/createUnderParent.js';
|
import categoryCreateUnderParent from './store/category/createUnderParent.js';
|
||||||
import categoryDelete from './store/category/delete.js';
|
import categoryDelete from './store/category/delete.js';
|
||||||
import articleCreateUnderParent from './store/article/createUnderParent.js';
|
import articleCreateUnderParent from './store/article/createUnderParent.js';
|
||||||
|
import articleGetBySku from './store/article/getBySku.js';
|
||||||
import langCreate from './store/lang/create.js';
|
import langCreate from './store/lang/create.js';
|
||||||
import langDelete from './store/lang/delete.js';
|
import langDelete from './store/lang/delete.js';
|
||||||
import langList from './store/lang/list.js';
|
import langList from './store/lang/list.js';
|
||||||
@@ -53,6 +54,7 @@ export default class LibDashStore {
|
|||||||
|
|
||||||
this.article = {
|
this.article = {
|
||||||
createUnderParent: articleCreateUnderParent(pool),
|
createUnderParent: articleCreateUnderParent(pool),
|
||||||
|
getBySku: articleGetBySku(pool),
|
||||||
};
|
};
|
||||||
|
|
||||||
this.lang = {
|
this.lang = {
|
||||||
|
|||||||
@@ -1,3 +1,68 @@
|
|||||||
|
export const ARTICLE_LIST_JOINS = `
|
||||||
|
LEFT JOIN articletext at
|
||||||
|
ON at.article_id = a.id AND at.language_id = @languageId
|
||||||
|
LEFT JOIN price pr
|
||||||
|
ON pr.article_id = a.id
|
||||||
|
AND pr.customergroup_id = @posCustomerGroupId
|
||||||
|
AND pr.minmultiplier = 1
|
||||||
|
LEFT JOIN tax t ON t.id = pr.tax_id
|
||||||
|
OUTER APPLY (
|
||||||
|
SELECT TOP 1 ap.pic_id
|
||||||
|
FROM articlepic ap
|
||||||
|
WHERE ap.article_id = a.id
|
||||||
|
ORDER BY ap.sort ASC, ap.id ASC
|
||||||
|
) first_pic
|
||||||
|
LEFT JOIN pic ON pic.id = first_pic.pic_id
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const ARTICLE_LIST_COLUMNS = `
|
||||||
|
a.id,
|
||||||
|
a.sku,
|
||||||
|
at.name,
|
||||||
|
at.slug,
|
||||||
|
pr.net,
|
||||||
|
t.rate AS taxRate,
|
||||||
|
CASE
|
||||||
|
WHEN a.optionslist_id IS NOT NULL THEN (
|
||||||
|
SELECT COUNT(*)
|
||||||
|
FROM optionslistarticle ola
|
||||||
|
WHERE ola.optionslist_id = a.optionslist_id
|
||||||
|
)
|
||||||
|
ELSE 0
|
||||||
|
END AS optionsCount,
|
||||||
|
CASE
|
||||||
|
WHEN a.articlelist_id IS NOT NULL THEN (
|
||||||
|
SELECT COUNT(*)
|
||||||
|
FROM articlelistarticle ala
|
||||||
|
WHERE ala.articlelist_id = a.articlelist_id
|
||||||
|
)
|
||||||
|
ELSE 0
|
||||||
|
END AS articleListCount,
|
||||||
|
(
|
||||||
|
SELECT COUNT(*)
|
||||||
|
FROM article child
|
||||||
|
WHERE child.fatherarticle_id = a.id
|
||||||
|
) AS childCount,
|
||||||
|
pic.thumbw AS thumbW,
|
||||||
|
pic.thumbh AS thumbH,
|
||||||
|
pic.thumbhash AS thumbHash
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const GET_CATEGORY_ID_BY_SKU = `
|
||||||
|
SELECT TOP 1 ca.category_id AS categoryId
|
||||||
|
FROM article a
|
||||||
|
INNER JOIN categoryarticle ca ON ca.article_id = a.id
|
||||||
|
WHERE a.sku = @sku
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const GET_BY_SKU = `
|
||||||
|
SELECT
|
||||||
|
${ARTICLE_LIST_COLUMNS}
|
||||||
|
FROM article a
|
||||||
|
${ARTICLE_LIST_JOINS}
|
||||||
|
WHERE a.sku = @sku
|
||||||
|
`;
|
||||||
|
|
||||||
export const CREATE = `
|
export const CREATE = `
|
||||||
INSERT INTO article (sku, unit_id, unitamount, weight)
|
INSERT INTO article (sku, unit_id, unitamount, weight)
|
||||||
OUTPUT INSERTED.id
|
OUTPUT INSERTED.id
|
||||||
|
|||||||
@@ -31,54 +31,17 @@ LEFT JOIN pic p ON p.id = first_pic.pic_id
|
|||||||
ORDER BY t.sort, t.id
|
ORDER BY t.sort, t.id
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
import {
|
||||||
|
ARTICLE_LIST_COLUMNS,
|
||||||
|
ARTICLE_LIST_JOINS,
|
||||||
|
} from './article.js';
|
||||||
|
|
||||||
export const GET_CATEGORY_ARTICLES = `
|
export const GET_CATEGORY_ARTICLES = `
|
||||||
SELECT
|
SELECT
|
||||||
a.id,
|
${ARTICLE_LIST_COLUMNS}
|
||||||
a.sku,
|
|
||||||
at.name,
|
|
||||||
at.slug,
|
|
||||||
pr.net,
|
|
||||||
t.rate AS taxRate,
|
|
||||||
CASE
|
|
||||||
WHEN a.optionslist_id IS NOT NULL THEN (
|
|
||||||
SELECT COUNT(*)
|
|
||||||
FROM optionslistarticle ola
|
|
||||||
WHERE ola.optionslist_id = a.optionslist_id
|
|
||||||
)
|
|
||||||
ELSE 0
|
|
||||||
END AS optionsCount,
|
|
||||||
CASE
|
|
||||||
WHEN a.articlelist_id IS NOT NULL THEN (
|
|
||||||
SELECT COUNT(*)
|
|
||||||
FROM articlelistarticle ala
|
|
||||||
WHERE ala.articlelist_id = a.articlelist_id
|
|
||||||
)
|
|
||||||
ELSE 0
|
|
||||||
END AS articleListCount,
|
|
||||||
(
|
|
||||||
SELECT COUNT(*)
|
|
||||||
FROM article child
|
|
||||||
WHERE child.fatherarticle_id = a.id
|
|
||||||
) AS childCount,
|
|
||||||
pic.thumbw AS thumbW,
|
|
||||||
pic.thumbh AS thumbH,
|
|
||||||
pic.thumbhash AS thumbHash
|
|
||||||
FROM categoryarticle ca
|
FROM categoryarticle ca
|
||||||
INNER JOIN article a ON a.id = ca.article_id
|
INNER JOIN article a ON a.id = ca.article_id
|
||||||
LEFT JOIN articletext at
|
${ARTICLE_LIST_JOINS}
|
||||||
ON at.article_id = a.id AND at.language_id = @languageId
|
|
||||||
LEFT JOIN price pr
|
|
||||||
ON pr.article_id = a.id
|
|
||||||
AND pr.customergroup_id = @posCustomerGroupId
|
|
||||||
AND pr.minmultiplier = 1
|
|
||||||
LEFT JOIN tax t ON t.id = pr.tax_id
|
|
||||||
OUTER APPLY (
|
|
||||||
SELECT TOP 1 ap.pic_id
|
|
||||||
FROM articlepic ap
|
|
||||||
WHERE ap.article_id = a.id
|
|
||||||
ORDER BY ap.sort ASC, ap.id ASC
|
|
||||||
) first_pic
|
|
||||||
LEFT JOIN pic ON pic.id = first_pic.pic_id
|
|
||||||
WHERE ca.category_id = @categoryId
|
WHERE ca.category_id = @categoryId
|
||||||
ORDER BY a.id
|
ORDER BY a.id
|
||||||
`;
|
`;
|
||||||
|
|||||||
37
src/store/article/getBySku.js
Normal file
37
src/store/article/getBySku.js
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
import { GET_BY_SKU, GET_CATEGORY_ID_BY_SKU } from '../../sql/article.js';
|
||||||
|
import resolveCategoryAccess from '../category/resolveCategoryAccess.js';
|
||||||
|
|
||||||
|
export default function getBySku(pool) {
|
||||||
|
const access = resolveCategoryAccess(pool);
|
||||||
|
|
||||||
|
return async (googleAuthId, sku) => {
|
||||||
|
const categoryLookup = await pool
|
||||||
|
.request()
|
||||||
|
.input('sku', sku)
|
||||||
|
.query(GET_CATEGORY_ID_BY_SKU);
|
||||||
|
|
||||||
|
const categoryId = categoryLookup.recordset[0]?.categoryId;
|
||||||
|
if (!categoryId) {
|
||||||
|
throw new Error('Article not found');
|
||||||
|
}
|
||||||
|
|
||||||
|
const { languageId, posCustomerGroupId } = await access(
|
||||||
|
googleAuthId,
|
||||||
|
categoryId,
|
||||||
|
);
|
||||||
|
|
||||||
|
const result = await pool
|
||||||
|
.request()
|
||||||
|
.input('sku', sku)
|
||||||
|
.input('languageId', languageId)
|
||||||
|
.input('posCustomerGroupId', posCustomerGroupId)
|
||||||
|
.query(GET_BY_SKU);
|
||||||
|
|
||||||
|
const row = result.recordset[0];
|
||||||
|
if (!row) {
|
||||||
|
throw new Error('Article not found');
|
||||||
|
}
|
||||||
|
|
||||||
|
return row;
|
||||||
|
};
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user