import refreshTokenHelper from "../../../utils/refreshTokenHelper"; import errorHandlingHelper from "../../../utils/errorHandlingHelper"; import fetchHelper from "../../../utils/fetchHelper"; // Proxy to JTL-FFN stock adjustments // POST /api/ffn/stocks/adjustments { orderSourceId: string, items: Array } const handleFunc = async (event: any, authToken: any = null) => { const token = authToken ?? await getTokenHelper(event) const body = await readBody(event) const orderSourceId = body?.orderSourceId as string const items = body?.items as any[] if(!orderSourceId) return { status: 400, message: 'orderSourceId is required' } if(!Array.isArray(items) || items.length === 0) return { status: 400, message: 'items array is required' } // Load Order Source const os: any = await fetchHelper(event, `models/c_ordersource/${orderSourceId}`, 'GET', token, null) if(!os) return { status: 404, message: 'Order Source not found' } if(!(os?.Marketplace?.identifier === 'jtl-ffn' || os?.marketplace === '7' || os?.Marketplace?.id === '7')) { return { status: 400, message: 'Selected Order Source is not JTL-FFN' } } const baseUrl: string = os?.marketplace_url || '' if(!baseUrl) return { status: 400, message: 'No marketplace_url configured for this Order Source' } // Headers const headers: any = { 'content-type': 'application/json', 'accept': 'application/json' } if(os?.marketplace_token) { headers['Authorization'] = `ffn ${os.marketplace_token}` headers['x-application-id'] = 'JPCB0XLOGYOU' headers['x-application-version'] = '0.1' } if(os?.marketplace_key) headers['x-api-key'] = os.marketplace_key if(os?.marketplace_secret) headers['x-api-secret'] = os.marketplace_secret if(os?.jtl_merchantID) headers['x-merchant-id'] = os.jtl_merchantID // Send requests sequentially to preserve order; collect results const results: any[] = [] let host = baseUrl.trim() if(!/^https?:\/\//i.test(host)) host = `https://${host}` host = host.replace(/\/$/, '') // Avoid duplicating path segments if marketplace_url already contains /api/v1/fulfiller let endpoint = '/api/v1/fulfiller/stocks/adjustments' if(/\/api\/v1\/fulfiller\/stocks\/adjustments\/?$/i.test(host)) { endpoint = '' } else if(/\/api\/v1\/fulfiller\/?$/i.test(host)) { endpoint = '/stocks/adjustments' } const url = `${host}${endpoint}` for(const payload of items) { try { const resp = await $fetch(url, { method: 'POST', headers, body: payload }) results.push({ ok: true, payload, response: resp }) } catch (err: any) { const e = errorHandlingHelper(err?.data ?? err, err?.data ?? err) const status = Number(e?.status || err?.status || err?.response?.status || 500) const message = e?.message || err?.data?.message || err?.message || 'Failed to send FFN stock adjustment' results.push({ ok: false, payload, error: { status, message } }) } } const failed = results.filter(r => !r.ok) return { status: failed.length ? 207 : 200, message: failed.length ? `${failed.length} adjustment(s) failed` : 'All adjustments sent successfully', results } } export default defineEventHandler(async (event) => { try { return await handleFunc(event) } catch (err: any) { try { const authToken = await refreshTokenHelper(event) return await handleFunc(event, authToken) } catch (error: any) { const data = errorHandlingHelper(err?.data ?? err, error?.data ?? error) if([401, 402, 403, 407].includes(Number(data.status))) { //@ts-ignore setCookie(event, 'user', null) } return data } } })