import { string } from 'alga-js' import refreshTokenHelper from "../../utils/refreshTokenHelper" import forceLogoutHelper from "../../utils/forceLogoutHelper" import errorHandlingHelper from "../../utils/errorHandlingHelper" import getTokenHelper from "../../utils/getTokenHelper" const handleFunc = async (event: any, authToken: any = null) => { const token = authToken ?? await getTokenHelper(event) const body = await readBody(event) const locatorValue = body?.locatorValue || '' if (!locatorValue) { throw createError({ statusCode: 400, statusMessage: 'Locator value is required' }) } // Step 1: Find all locators matching the value (across organizations) const locatorFilter = string.urlEncode(`Value eq '${locatorValue}' AND IsActive eq true`) const locatorsRes: any = await event.context.fetch( `models/m_locator?$filter=${locatorFilter}`, 'GET', token, null ) if (!locatorsRes?.records || locatorsRes.records.length === 0) { throw createError({ statusCode: 404, statusMessage: 'Locator not found' }) } const locators = locatorsRes.records // Use a map to group articles by productId + orgId (unique key) const articleMap: Map = new Map() // Step 2: For each locator, fetch storage on hand with expanded product info for (const locator of locators) { const locatorId = locator.id const orgId = locator.AD_Org_ID?.id || locator.AD_Org_ID const orgName = locator.AD_Org_ID?.identifier || locator.AD_Org_ID?.Name || 'Unknown' const warehouseId = locator.M_Warehouse_ID?.id || locator.M_Warehouse_ID const warehouseName = locator.M_Warehouse_ID?.identifier || locator.M_Warehouse_ID?.Name || 'Unknown' // Fetch storage on hand for this locator const storageFilter = string.urlEncode(`M_Locator_ID eq ${locatorId} AND QtyOnHand gt 0`) const storageRes: any = await event.context.fetch( `models/M_StorageOnHand?$filter=${storageFilter}&$expand=${string.urlEncode('M_Product_ID')}`, 'GET', token, null ) if (storageRes?.records && storageRes.records.length > 0) { for (const storage of storageRes.records) { const product = storage.M_Product_ID || {} const qtyOnHand = Number(storage.QtyOnHand) || 0 if (qtyOnHand > 0 && product.id) { // Create unique key: productId + orgId const key = `${product.id}-${orgId}` if (articleMap.has(key)) { // Sum up the quantity const existing = articleMap.get(key) existing.qtyOnHand += qtyOnHand } else { // Add new article entry articleMap.set(key, { // Product info productId: product.id, productName: product.Name || 'Unknown Product', productValue: product.Value || '', productSKU: product.SKU || '', productUPC: product.UPC || '', productWeight: product.Weight || 0, // Strapi info for image strapiProductDocumentId: product.Strapi_Product_documentId || null, // Quantity (will be summed) qtyOnHand: qtyOnHand, // Locator info locatorId: locatorId, locatorValue: locator.Value || '', // Organization info orgId: orgId, orgName: orgName, // Warehouse info warehouseId: warehouseId, warehouseName: warehouseName }) } } } } } // Convert map to array const articles = Array.from(articleMap.values()) // Sort by organization name, then by product name articles.sort((a, b) => { if (a.orgName !== b.orgName) { return a.orgName.localeCompare(b.orgName) } return a.productName.localeCompare(b.productName) }) return { locatorValue: locatorValue, totalArticles: articles.length, articles: articles } } export default defineEventHandler(async (event) => { let data: any = {} try { data = await handleFunc(event) } catch(err: any) { try { let authToken: any = await refreshTokenHelper(event) data = await handleFunc(event, authToken) } catch(error: any) { data = errorHandlingHelper(err?.data ?? err, error?.data ?? error) forceLogoutHelper(event, data) throw createError({ statusCode: err?.statusCode || 500, statusMessage: err?.statusMessage || 'Error fetching locator articles', data: data }) } } return data })