Add grouped stock view with expiration and location filtering

This commit is contained in:
2026-04-07 00:41:55 +02:00
parent a2819f88d2
commit 385cd95aaf
5 changed files with 550 additions and 21 deletions
+26 -1
View File
@@ -1,5 +1,8 @@
import { apiRequest, getPath } from './client.js';
const LOCATION_CACHE_TTL_MS = 5 * 60 * 1000;
const locationCache = new Map();
function flattenNodes(nodes, trail = [], lineage = []) {
return nodes.flatMap((node) => {
const currentTrail = [...trail, node.name];
@@ -23,15 +26,37 @@ function flattenNodes(nodes, trail = [], lineage = []) {
});
}
function getLocationCacheKey(store) {
const baseUrl = store.config.baseUrl || '';
const database = store.config.database || '';
const applicationKey = store.session.applicationKey || '';
return `${baseUrl}::${database}::${applicationKey}`;
}
export async function fetchLocations(store) {
const cacheKey = getLocationCacheKey(store);
const cached = locationCache.get(cacheKey);
const now = Date.now();
if (cached && now - cached.cachedAt < LOCATION_CACHE_TTL_MS) {
return cached.value;
}
const payload = await apiRequest(store, getPath('locations'), {
includeKitchen: false,
});
const tree = Array.isArray(payload)
? payload
: payload?.data || payload?.locations || [];
return {
const value = {
tree,
flat: flattenNodes(tree),
};
locationCache.set(cacheKey, {
cachedAt: now,
value,
});
return value;
}
+15 -2
View File
@@ -9,9 +9,9 @@ export async function searchItemDefinitions(store, query) {
return [];
}
const payload = await apiRequest(store, getPath('items'), {
const payload = await apiRequest(store, `${getPath('items')}/grouped`, {
includeKitchen: false,
query: { search_name: query },
query: { search_name: query, expanded: 0 },
});
if (Array.isArray(payload)) {
@@ -33,6 +33,19 @@ export async function listStockEntries(store, filters = {}) {
return payload?.data || payload?.entries || payload?.items || [];
}
export async function listGroupedStockEntries(store) {
const payload = await apiRequest(store, `${getPath('items')}/grouped`, {
includeKitchen: false,
query: { expanded: 1 },
});
if (Array.isArray(payload)) {
return payload;
}
return payload?.data || payload?.entries || payload?.items || payload?.groups || [];
}
export async function getStockEntry(store, stockId) {
const payload = await apiRequest(store, `${getPath('items')}/${stockId}`, {
includeKitchen: false,