import refreshTokenHelper from "../../../utils/refreshTokenHelper" import forceLogoutHelper from "../../../utils/forceLogoutHelper" import errorHandlingHelper from "../../../utils/errorHandlingHelper" import fetchHelper from "../../../utils/fetchHelper" import { getAmazonAccessToken, resolveMarketplaceId, listFinancialEventGroupsSince } from "../../../utils/amazonSpApi" // Default lookback when the caller doesn't set an explicit `createdSince` — a // single ~100-day window covers ~7 biweekly settlement periods in one fast API // call. An explicit `createdSince` reaches further back via chunked windowing // inside listFinancialEventGroupsSince (Amazon's Finances API has no 90-day // wall like the old Reports-API flow did). const DEFAULT_LOOKBACK_DAYS = 100 // List the available Amazon settlement periods (Finances API financial event // groups) for an order source — populates the period dropdown on the // settlement-browser page. Unlike the old Reports-API-based // GET_V2_SETTLEMENT_REPORT_DATA_FLAT_FILE_V2 report listing (hard-capped by // Amazon at a 90-day createdSince — verified against production: // "RequestedFromDate ... is more than 90 days old"), this reaches back to the // account's actual settlement history. const handleFunc = async (event: any, authToken: any = null) => { const token = authToken ?? await getTokenHelper(event) const query = getQuery(event) const orderSourceId = query.orderSourceId const createdSince = query.createdSince ? String(query.createdSince) : undefined const createdUntil = query.createdUntil ? String(query.createdUntil) : undefined if (!orderSourceId) { return { status: 400, message: 'orderSourceId is required' } } const orderSource: any = await fetchHelper(event, `models/c_ordersource/${orderSourceId}`, 'GET', token, null) if (!orderSource) { return { status: 404, message: 'Order source not found' } } const marketplaceIdentifier = String(orderSource?.Marketplace?.identifier || '').toLowerCase() const isAmazon = marketplaceIdentifier === 'amazon' || String(orderSource?.Marketplace?.id) === '4' || String(orderSource?.marketplace) === '4' if (!isAmazon) { return { status: 400, message: `Order source "${orderSource?.Name || orderSourceId}" is not an Amazon marketplace` } } if (!orderSource?.marketplace_key || !orderSource?.marketplace_secret || !orderSource?.marketplace_token) { return { status: 400, message: 'Order source is missing Amazon SP-API credentials (marketplace_key, marketplace_secret, marketplace_token)' } } // The Finances API isn't marketplace-scoped by parameter (unlike the old // Reports API call), but we still resolve+validate it here as an early, // clearer error for a misconfigured order source. if (!resolveMarketplaceId(orderSource?.Marketplace?.identifier, orderSource?.Description)) { return { status: 400, message: 'Could not resolve an Amazon marketplaceId from the order source' } } const accessToken = await getAmazonAccessToken( orderSource.marketplace_key, orderSource.marketplace_secret, orderSource.marketplace_token ) const since = createdSince || new Date(Date.now() - DEFAULT_LOOKBACK_DAYS * 86400000).toISOString() const groups = await listFinancialEventGroupsSince(accessToken, since, createdUntil) return { status: 200, orderSourceId: Number(orderSourceId), // Field names kept close to the old Reports-API shape (reportId/dataStartTime/ // dataEndTime) so the frontend needed only additive changes — reportId now // holds the Finances API's FinancialEventGroupId, not a Reports-API reportId. reports: groups.map(g => ({ reportId: g.groupId, dataStartTime: g.periodStart, dataEndTime: g.periodEnd, totalAmount: g.totalAmount, currency: g.currency, fundTransferStatus: g.fundTransferStatus, fundTransferDate: g.fundTransferDate })) } } export default defineEventHandler(async (event) => { let data: any = {} try { data = await handleFunc(event) } catch (err: any) { // SP-API errors (e.g. missing Finance & Accounting role) carry a status — // surface them verbatim rather than treating them as an auth failure. if (err?.status && err?.message) { return { status: err.status, message: err.message, spapi: err.spapi } } 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) } } return data })