export
This commit is contained in:
93
src/store/article/listExport.js
Normal file
93
src/store/article/listExport.js
Normal file
@@ -0,0 +1,93 @@
|
||||
import { GET_ARTICLE_EXPORT, GET_CATEGORY_TREE_FLAT } from '../../sql/article.js';
|
||||
import resolveCompanyAccess from '../companyuser/resolveCompanyAccess.js';
|
||||
import resolveCategoryAccess from '../category/resolveCategoryAccess.js';
|
||||
|
||||
const ROOT_CATEGORY_NAME = 'Home';
|
||||
|
||||
function parseJsonArray(raw) {
|
||||
if (!raw) return [];
|
||||
const arr = typeof raw === 'string' ? JSON.parse(raw) : raw;
|
||||
return Array.isArray(arr) ? arr : [];
|
||||
}
|
||||
|
||||
export default function listExport(pool) {
|
||||
const companyAccess = resolveCompanyAccess(pool);
|
||||
const categoryAccess = resolveCategoryAccess(pool);
|
||||
|
||||
return async (googleAuthId, companyId, categoryId) => {
|
||||
const { languageId, posCustomerGroupId, rootCategoryId } = await companyAccess(
|
||||
googleAuthId,
|
||||
companyId,
|
||||
);
|
||||
|
||||
// Default to the company's root category when no specific category is given.
|
||||
let exportCategoryId = rootCategoryId;
|
||||
|
||||
if (categoryId != null) {
|
||||
// The requested category must be reachable via the selected company's root.
|
||||
const access = await categoryAccess(googleAuthId, categoryId);
|
||||
if (access.rootCategoryId !== rootCategoryId) {
|
||||
throw new Error('Not authorized');
|
||||
}
|
||||
exportCategoryId = categoryId;
|
||||
}
|
||||
|
||||
const [result, treeResult] = await Promise.all([
|
||||
pool
|
||||
.request()
|
||||
.input('categoryId', exportCategoryId)
|
||||
.input('languageId', languageId)
|
||||
.input('posCustomerGroupId', posCustomerGroupId)
|
||||
.query(GET_ARTICLE_EXPORT),
|
||||
pool
|
||||
.request()
|
||||
.input('rootId', rootCategoryId)
|
||||
.input('languageId', languageId)
|
||||
.query(GET_CATEGORY_TREE_FLAT),
|
||||
]);
|
||||
|
||||
// id -> { id, parentId, name } for breadcrumb resolution.
|
||||
const catById = new Map();
|
||||
for (const node of treeResult.recordset) {
|
||||
catById.set(String(node.id), node);
|
||||
}
|
||||
|
||||
// Breadcrumb label for one category id: "Home" for root, else trimmed name.
|
||||
const displayName = (node) =>
|
||||
String(node.id) === String(rootCategoryId) ? ROOT_CATEGORY_NAME : (node.name ?? '').trim();
|
||||
|
||||
const breadcrumb = (categoryId) => {
|
||||
const crumbs = [];
|
||||
const seen = new Set();
|
||||
let id = categoryId;
|
||||
while (id != null && !seen.has(String(id))) {
|
||||
seen.add(String(id));
|
||||
const node = catById.get(String(id));
|
||||
if (!node) break;
|
||||
crumbs.unshift(displayName(node));
|
||||
id = node.parentId;
|
||||
}
|
||||
// A category outside the tree still yields its own label.
|
||||
return crumbs.join('·');
|
||||
};
|
||||
|
||||
return result.recordset.map((row) => ({
|
||||
id: row.id,
|
||||
sku: row.sku,
|
||||
name: row.name,
|
||||
slug: row.slug,
|
||||
unitSi: row.unitSi,
|
||||
unitSymbol: row.unitSymbol,
|
||||
unitamount: row.unitamount,
|
||||
brandName: row.brandName,
|
||||
net: row.net,
|
||||
taxRate: row.taxRate,
|
||||
eans: parseJsonArray(row.eansJson).map((r) => r.ean),
|
||||
categoryIds: parseJsonArray(row.categoryIdsJson).map((r) => r.category_id),
|
||||
categoryBreadcrumbs: parseJsonArray(row.categoryIdsJson)
|
||||
.map((r) => breadcrumb(r.category_id))
|
||||
.filter(Boolean),
|
||||
fullHashes: parseJsonArray(row.fullHashesJson).map((r) => r.hash),
|
||||
}));
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user