2026-04-06 09:24:22 +02:00
|
|
|
import { apiRequest, getPath } from './client.js';
|
|
|
|
|
|
2026-04-06 10:30:37 +02:00
|
|
|
function unwrapEntryPayload(payload) {
|
|
|
|
|
return payload?.data || payload?.entry || payload?.item || payload;
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-06 09:24:22 +02:00
|
|
|
export async function searchItemDefinitions(store, query) {
|
|
|
|
|
if (query.trim().length <= 2) {
|
|
|
|
|
return [];
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-07 00:41:55 +02:00
|
|
|
const payload = await apiRequest(store, `${getPath('items')}/grouped`, {
|
|
|
|
|
query: { search_name: query, expanded: 0 },
|
2026-04-06 09:24:22 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (Array.isArray(payload)) {
|
|
|
|
|
return payload;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return payload?.data || payload?.items || [];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function listStockEntries(store, filters = {}) {
|
2026-04-10 15:43:39 +02:00
|
|
|
const payload = await apiRequest(store, getPath('items'));
|
2026-04-06 09:24:22 +02:00
|
|
|
|
|
|
|
|
if (Array.isArray(payload)) {
|
|
|
|
|
return payload;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return payload?.data || payload?.entries || payload?.items || [];
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-07 00:41:55 +02:00
|
|
|
export async function listGroupedStockEntries(store) {
|
|
|
|
|
const payload = await apiRequest(store, `${getPath('items')}/grouped`, {
|
|
|
|
|
query: { expanded: 1 },
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (Array.isArray(payload)) {
|
|
|
|
|
return payload;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return payload?.data || payload?.entries || payload?.items || payload?.groups || [];
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-06 09:24:22 +02:00
|
|
|
export async function getStockEntry(store, stockId) {
|
2026-04-10 15:43:39 +02:00
|
|
|
const payload = await apiRequest(store, `${getPath('items')}/${stockId}`);
|
2026-04-06 10:30:37 +02:00
|
|
|
return unwrapEntryPayload(payload);
|
2026-04-06 09:24:22 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function createStockEntry(store, body) {
|
|
|
|
|
const payload = await apiRequest(store, getPath('items'), {
|
|
|
|
|
method: 'POST',
|
|
|
|
|
body,
|
2026-04-07 19:45:16 +02:00
|
|
|
query: { label: 1, print: 1 },
|
2026-04-06 09:24:22 +02:00
|
|
|
});
|
2026-04-06 10:30:37 +02:00
|
|
|
return unwrapEntryPayload(payload);
|
2026-04-06 09:24:22 +02:00
|
|
|
}
|
|
|
|
|
|
2026-04-10 15:43:39 +02:00
|
|
|
function normalizeUpsertResponse(payload) {
|
|
|
|
|
return {
|
|
|
|
|
status: payload?.status || null,
|
|
|
|
|
mode: payload?.mode || null,
|
|
|
|
|
operation: payload?.operation || null,
|
|
|
|
|
matchType: payload?.match_type || null,
|
|
|
|
|
matchedItem: payload?.matched_item || null,
|
|
|
|
|
item: payload?.item || null,
|
|
|
|
|
payload: payload?.payload || null,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-11 02:24:28 +02:00
|
|
|
function normalizeIdentifierLookupResponse(payload) {
|
|
|
|
|
return {
|
|
|
|
|
status: payload?.status || null,
|
|
|
|
|
source: payload?.source || null,
|
|
|
|
|
cacheHit: Boolean(payload?.cache_hit),
|
|
|
|
|
identifierCode: payload?.identifier_code || null,
|
|
|
|
|
identifierType: payload?.identifier_type || null,
|
|
|
|
|
item: payload?.item || null,
|
|
|
|
|
payloadFetchedAt: payload?.payload_fetched_at || null,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-10 15:43:39 +02:00
|
|
|
export async function previewItemUpsert(store, body) {
|
|
|
|
|
const payload = await apiRequest(store, `${getPath('items')}/upsert`, {
|
|
|
|
|
method: 'POST',
|
|
|
|
|
body,
|
|
|
|
|
query: { mode: 'preview' },
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return normalizeUpsertResponse(payload);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function applyItemUpsert(store, body) {
|
|
|
|
|
const payload = await apiRequest(store, `${getPath('items')}/upsert`, {
|
|
|
|
|
method: 'POST',
|
|
|
|
|
body,
|
|
|
|
|
query: { mode: 'apply' },
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return normalizeUpsertResponse(payload);
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-11 02:24:28 +02:00
|
|
|
export async function lookupItemByIdentifier(store, identifierCode) {
|
|
|
|
|
const payload = await apiRequest(store, `${getPath('items')}/lookup`, {
|
|
|
|
|
method: 'POST',
|
|
|
|
|
body: {
|
|
|
|
|
identifier_code: String(identifierCode || '').trim(),
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return normalizeIdentifierLookupResponse(payload);
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-06 09:24:22 +02:00
|
|
|
export async function updateStockItem(store, uuidB64, body) {
|
|
|
|
|
const payload = await apiRequest(store, `${getPath('items')}/${uuidB64}/stock`, {
|
|
|
|
|
method: 'POST',
|
|
|
|
|
body,
|
|
|
|
|
});
|
2026-04-06 10:30:37 +02:00
|
|
|
return unwrapEntryPayload(payload);
|
2026-04-06 09:24:22 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function deleteStockItem(store, uuidB64) {
|
|
|
|
|
const payload = await apiRequest(store, `${getPath('items')}/${uuidB64}`, {
|
|
|
|
|
method: 'DELETE',
|
|
|
|
|
});
|
2026-04-06 10:30:37 +02:00
|
|
|
return unwrapEntryPayload(payload);
|
2026-04-06 09:24:22 +02:00
|
|
|
}
|
|
|
|
|
|
2026-04-10 15:43:39 +02:00
|
|
|
export async function useStockItem(store, uuidB64) {
|
|
|
|
|
try {
|
|
|
|
|
await apiRequest(store, `${getPath('items')}/${uuidB64}/use`, {
|
|
|
|
|
method: 'POST',
|
|
|
|
|
});
|
|
|
|
|
return { status: 'used' };
|
|
|
|
|
} catch (error) {
|
|
|
|
|
const status = error?.status || error?.cause?.status;
|
|
|
|
|
if (status === 409) {
|
|
|
|
|
return { status: 'already_gone' };
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (status === 404 || status === 405) {
|
|
|
|
|
await deleteStockItem(store, uuidB64);
|
|
|
|
|
return { status: 'fallback_delete' };
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
throw error;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-06 09:24:22 +02:00
|
|
|
export async function adjustStockEntry(store, stockId, body) {
|
2026-04-06 10:30:37 +02:00
|
|
|
const payload = await apiRequest(store, `${getPath('items')}/${stockId}/stock`, {
|
|
|
|
|
method: 'POST',
|
|
|
|
|
body,
|
|
|
|
|
});
|
|
|
|
|
return unwrapEntryPayload(payload);
|
2026-04-06 09:24:22 +02:00
|
|
|
}
|
2026-04-10 15:43:39 +02:00
|
|
|
|
|
|
|
|
export async function listKitchenChanges(store, { since, limit = 10 } = {}) {
|
|
|
|
|
const payload = await apiRequest(store, getPath('changes'), {
|
|
|
|
|
query: {
|
|
|
|
|
since,
|
|
|
|
|
limit,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
since: payload?.since || null,
|
|
|
|
|
nextCursor: payload?.next_cursor || null,
|
|
|
|
|
changes: Array.isArray(payload?.changes) ? payload.changes : [],
|
|
|
|
|
};
|
|
|
|
|
}
|