import refreshTokenHelper from "../../../utils/refreshTokenHelper" import forceLogoutHelper from "../../../utils/forceLogoutHelper" import errorHandlingHelper from "../../../utils/errorHandlingHelper" import getTokenHelper from "../../../utils/getTokenHelper" // Helper function to generate range const generateRange = (from: string, to: string): string[] => { const range: string[] = [] // Check if numeric range (both values are purely numeric) const isNumeric = /^\d+$/.test(from) && /^\d+$/.test(to) // Check if single letter range (both are single A-Z letters) const isSingleLetter = from.length === 1 && to.length === 1 && /^[A-Za-z]$/.test(from) && /^[A-Za-z]$/.test(to) if (isNumeric) { // Numeric range with padding const fromNum = parseInt(from) const toNum = parseInt(to) const padding = Math.max(from.length, to.length) for (let i = fromNum; i <= toNum; i++) { range.push(String(i).padStart(padding, '0')) } } else if (isSingleLetter) { // Single letter alphabetic range (A-Z) const fromChar = from.toUpperCase().charCodeAt(0) const toChar = to.toUpperCase().charCodeAt(0) for (let i = fromChar; i <= toChar; i++) { range.push(String.fromCharCode(i)) } } else { // Multi-character or mixed values - treat as static // If from equals to, it's a single static value if (from === to) { range.push(from) } else { // Different values - return both (no range expansion for complex patterns) range.push(from) range.push(to) } } return range } const handleFunc = async (event: any, authToken: any = null) => { let data: any = { status: 500, message: 'Generation failed', created: 0, skipped: 0 } try { const token = authToken ?? await getTokenHelper(event) const body = await readBody(event) const { warehouseId, organizationId, xFrom, xTo, yFrom, yTo, zFrom, zTo, priorityNo = 50, isActive = true, locatorTypeId = null } = body if(!warehouseId || !organizationId) { return { status: 400, message: 'Warehouse ID and Organization ID are required', created: 0, skipped: 0 } } if(!xFrom || !xTo || !yFrom || !yTo || !zFrom || !zTo) { return { status: 400, message: 'All range fields (X, Y, Z) are required', created: 0, skipped: 0 } } // Generate ranges const xRange = generateRange(xFrom, xTo) const yRange = generateRange(yFrom, yTo) const zRange = generateRange(zFrom, zTo) // Get existing locators const existingRes: any = await event.context.fetch( `models/m_locator?$filter=M_Warehouse_ID eq ${warehouseId}`, 'GET', token, null ) const existingCoords = new Set() if(existingRes?.records) { existingRes.records.forEach((loc: any) => { const coordKey = `${loc.X}|${loc.Y}|${loc.Z}` existingCoords.add(coordKey) }) } let created = 0 let skipped = 0 // Generate all combinations for(const x of xRange) { for(const y of yRange) { for(const z of zRange) { const coordKey = `${x}|${y}|${z}` // Skip if already exists if(existingCoords.has(coordKey)) { skipped++ continue } // Create locator const value = `${x}-${y}-${z}` const createPayload: any = { M_Warehouse_ID: { id: warehouseId }, AD_Org_ID: { id: organizationId }, X: x, Y: y, Z: z, Value: value, PriorityNo: priorityNo, IsActive: isActive, IsDefault: false } // Add locator type if specified if (locatorTypeId) { createPayload.M_LocatorType_ID = { id: locatorTypeId } } const createRes: any = await event.context.fetch( 'models/m_locator', 'POST', token, createPayload ) if(createRes?.id) { created++ existingCoords.add(coordKey) } else { skipped++ } } } } data = { status: 200, message: `Successfully generated ${created} locators, ${skipped} skipped`, created, skipped, totalCombinations: xRange.length * yRange.length * zRange.length } } catch(err: any) { data = { status: err?.status || 500, message: err?.message || 'Error generating locators', created: 0, skipped: 0 } } return data } 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) { data = errorHandlingHelper(err?.data ?? err, error?.data ?? error) forceLogoutHelper(event, data) } } return data })