// NB: alga-js string.urlEncode leaves '+' unencoded → iDempiere reads "C+" as "C ". Use encodeURIComponent. const enc = (v: string) => encodeURIComponent(v) import refreshTokenHelper from "../../../utils/refreshTokenHelper" import forceLogoutHelper from "../../../utils/forceLogoutHelper" import errorHandlingHelper from "../../../utils/errorHandlingHelper" import getTokenHelper from "../../../utils/getTokenHelper" import fetchHelper from "../../../utils/fetchHelper" /** * Mobile reconditioning — target locators of an org (optionally one warehouse), with * the locator-type flags so the picker can mark shippable bins. The org's IsDefault * locator is returned first (the page preselects it). */ const handleFunc = async (event: any, authToken: any = null) => { const token = authToken ?? await getTokenHelper(event) const body = await readBody(event) const orgId = Number(body?.organizationId) const warehouseId = Number(body?.warehouseId) || null if (!(orgId > 0)) { throw createError({ statusCode: 400, statusMessage: 'organizationId is required' }) } let filter = `AD_Org_ID eq ${orgId} AND IsActive eq true` if (warehouseId) filter += ` AND M_Warehouse_ID eq ${warehouseId}` const res: any = await fetchHelper(event, `models/m_locator?$filter=${enc(filter)}&$expand=M_LocatorType_ID` + `&$select=Value,IsDefault,PriorityNo,M_Warehouse_ID,M_LocatorType_ID,X,Y,Z` + `&$orderby=${enc('IsDefault desc, Value asc')}&$top=2000`, 'GET', token, null) const isY = (v: any) => v === true || v === 'Y' const locators = (res?.records || []).map((l: any) => { const lt = l?.M_LocatorType_ID && typeof l.M_LocatorType_ID === 'object' ? l.M_LocatorType_ID : null return { id: l.id, code: l.Value || l.identifier || l.Name || '', isDefault: isY(l.IsDefault), warehouseId: l.M_Warehouse_ID?.id ?? l.M_Warehouse_ID ?? null, locatorTypeId: lt?.id ?? null, locatorType: lt?.Name || lt?.identifier || '', // no locator type = plain bin (treated as shippable, like iDempiere does) isShippable: lt ? isY(lt.IsAvailableForShipping) : true, isReturn: lt ? (!isY(lt.IsAvailableForShipping) && !isY(lt.IsAvailableForReservation) && !isY(lt.IsAvailableForReplenishment)) : false } }) const defaultLocator = locators.find((l: any) => l.isDefault) || null return { organizationId: orgId, warehouseId, defaultLocatorId: defaultLocator?.id ?? null, locators } } export default defineEventHandler(async (event) => { let data: any = {} try { data = await handleFunc(event) } catch (err: any) { if (err?.statusCode === 400) throw err try { const authToken: any = await refreshTokenHelper(event) data = await handleFunc(event, authToken) } catch (error: any) { data = errorHandlingHelper(err?.data ?? err, error?.data ?? error) forceLogoutHelper(event, data) } } return data })