import refreshTokenHelper from "../../utils/refreshTokenHelper" import forceLogoutHelper from "../../utils/forceLogoutHelper" import errorHandlingHelper from "../../utils/errorHandlingHelper" import fetchHelper from "../../utils/fetchHelper" /** * Import orders from eBay CSV data * This endpoint creates business partners and orders similar to the quick-add pattern */ // Helper function to create a location const createLocation = async (event: any, token: any, locationData: any, orgId: any) => { const payload: any = { AD_Org_ID: { id: orgId, tableName: 'AD_Org' }, isActive: true, address1: locationData.address1 || '', address2: locationData.address2 || '', city: locationData.city || '', postal: locationData.postal || '', regionName: locationData.state || '', isValid: true, tableName: 'C_Location' } // Add country if provided (Germany = 101) if (locationData.countryId) { payload.C_Country_ID = { id: locationData.countryId, tableName: 'C_Country' } } const res = await fetchHelper(event, 'models/c_location', 'POST', token, payload) return res } // Helper function to create a partner location const createPartnerLocation = async (event: any, token: any, partnerId: any, locationId: any, name: string, phone: string, orgId: any, isShipTo: boolean = true) => { const payload: any = { AD_Org_ID: { id: orgId, tableName: 'AD_Org' }, isActive: true, name: name, phone: phone || '', isBillTo: !isShipTo, isShipTo: isShipTo, isPayFrom: false, isRemitTo: false, isPreserveCustomName: false, C_BPartner_ID: { id: partnerId, tableName: 'C_BPartner' }, C_Location_ID: { id: locationId, tableName: 'C_Location' }, tableName: 'C_BPartner_Location' } const res = await fetchHelper(event, 'models/c_bpartner_location', 'POST', token, payload) return res } // Helper function to create a user for the partner const createPartnerUser = async (event: any, token: any, partnerId: any, name: string, email: string, phone: string, orgId: any, isShipTo: boolean = true) => { const payload: any = { AD_Org_ID: { id: orgId, tableName: 'AD_Org' }, isActive: true, name: name, isFullBPAccess: false, isInPayroll: false, isSalesLead: false, isLocked: false, isNoPasswordReset: false, isExpired: false, isAddMailTextAutomatically: false, isNoExpire: false, isSupportUser: false, isShipTo: isShipTo, isBillTo: !isShipTo, isVendorLead: false, phone: phone || '', C_BPartner_ID: { id: partnerId, tableName: 'C_BPartner' }, tableName: 'AD_User' } // Save email to contact if (email) { payload.EMail = email } const res = await fetchHelper(event, 'models/ad_user', 'POST', token, payload) return res } // Helper function to get country ID by name const getCountryId = async (event: any, token: any, countryName: string) => { if (!countryName) return '101' // Default to Germany const countryMap: { [key: string]: string } = { 'Deutschland': '101', 'Germany': '101', 'DE': '101', 'Österreich': '102', 'Austria': '102', 'AT': '102', 'Schweiz': '106', 'Switzerland': '106', 'CH': '106', 'France': '103', 'Frankreich': '103', 'FR': '103', 'Netherlands': '108', 'Niederlande': '108', 'NL': '108', 'Belgium': '107', 'Belgien': '107', 'BE': '107', 'Italy': '104', 'Italien': '104', 'IT': '104', 'Spain': '105', 'Spanien': '105', 'ES': '105', 'Poland': '115', 'Polen': '115', 'PL': '115', 'United Kingdom': '109', 'UK': '109', 'GB': '109', } return countryMap[countryName] || '101' } // Helper function to check if a product is a BOM product const isProductBOM = async (event: any, token: any, productId: string) => { try { const productRes = await fetchHelper( event, `models/m_product/${productId}?$select=m_product_id,IsBOM,Name`, 'GET', token, null ) const isBOM = productRes?.IsBOM === true || productRes?.IsBOM === 'Y' console.log(`[BOM] Product ${productId} IsBOM=${isBOM} (${productRes?.Name || 'unknown'})`) return isBOM } catch (error) { console.error(`[BOM] Error checking IsBOM for product ${productId}:`, error) return false } } // Helper function to fetch BOM components for a product const getBomComponents = async (event: any, token: any, productId: string) => { try { // First, find the BOM header for this product (pp_product_bom where M_Product_ID = productId) const bomHeaderRes = await fetchHelper( event, `models/pp_product_bom?$filter=M_Product_ID eq ${productId} and isActive eq true&$top=1`, 'GET', token, null ) if (!bomHeaderRes?.records?.length) { console.log(`[BOM] No BOM found for product ${productId}`) return [] } const bomId = bomHeaderRes.records[0].id console.log(`[BOM] Found BOM ${bomId} for product ${productId}`) // Then, find the BOM lines for this BOM (pp_product_bomline where PP_Product_BOM_ID = bomId) const bomLinesRes = await fetchHelper( event, `models/pp_product_bomline?$filter=PP_Product_BOM_ID eq ${bomId} and isActive eq true&$orderby=line asc`, 'GET', token, null ) if (bomLinesRes?.records && bomLinesRes.records.length > 0) { console.log(`[BOM] Found ${bomLinesRes.records.length} components for BOM ${bomId}`) // Log the component details for debugging bomLinesRes.records.forEach((comp: any, idx: number) => { console.log(`[BOM] Component ${idx + 1}: M_Product_ID=${comp.M_Product_ID?.id}, QtyBOM=${comp.QtyBOM}`) }) return bomLinesRes.records } return [] } catch (error) { console.error(`[BOM] Error fetching BOM components for product ${productId}:`, error) return [] } } // Helper function to find or create partner by email const findOrCreatePartner = async (event: any, token: any, order: any, orgId: any, partnerGroupId: string, priceListId: string) => { // First, try to find existing partner by email if (order.buyerEmail) { try { const existingPartner = await fetchHelper( event, `models/c_bpartner?$filter=EMail eq '${order.buyerEmail}'`, 'GET', token ) if (existingPartner?.records && existingPartner.records.length > 0) { // Partner exists, return it with its locations const partner = existingPartner.records[0] // Get partner locations const locations = await fetchHelper( event, `models/c_bpartner_location?$filter=C_BPartner_ID eq ${partner.id}`, 'GET', token ) let shipLocation = null let billLocation = null if (locations?.records) { shipLocation = locations.records.find((l: any) => l.IsShipTo === true || l.IsShipTo === 'Y') billLocation = locations.records.find((l: any) => l.IsBillTo === true || l.IsBillTo === 'Y') } // Get partner users (contacts) const users = await fetchHelper( event, `models/ad_user?$filter=C_BPartner_ID eq ${partner.id}`, 'GET', token ) let shipUserId = null let billUserId = null if (users?.records) { const shipUser = users.records.find((u: any) => u.IsShipTo === true || u.IsShipTo === 'Y') const billUser = users.records.find((u: any) => u.IsBillTo === true || u.IsBillTo === 'Y') shipUserId = shipUser?.id || users.records[0]?.id || null billUserId = billUser?.id || users.records[0]?.id || null } return { partner, shipLocation, billLocation, shipUserId, billUserId, isNew: false } } } catch (error) { console.log('Error checking existing partner:', error) } } // Create new partner const partnerPayload: any = { AD_Org_ID: { id: orgId, tableName: 'AD_Org' }, isActive: true, name: order.recipientName || order.buyerName, value: order.buyerEmail || `EBAY_${order.orderNumber}`, isSummary: false, isVendor: false, isCustomer: true, isProspect: false, isEmployee: false, isSalesRep: false, isOneTime: false, isTaxExempt: false, isDiscountPrinted: false, sendEMail: false, isPOTaxExempt: false, isManufacturer: false, is1099Vendor: false, C_BP_Group_ID: { id: partnerGroupId, tableName: 'C_BP_Group' }, M_PriceList_ID: { id: priceListId, tableName: 'M_PriceList' }, AD_Language: { id: 'de_DE', tableName: 'AD_Language' }, tableName: 'C_BPartner' } if (order.buyerEmail) { partnerPayload.EMail = order.buyerEmail } // Save eBay username to MarketplaceUsername if (order.buyerUsername) { partnerPayload.MarketplaceUsername = order.buyerUsername } const partner = await fetchHelper(event, 'models/c_bpartner', 'POST', token, partnerPayload) if (!partner?.id) { throw new Error('Failed to create business partner') } // Create ship location // Combine address1 and address2 into one (eBay splits street and house number) const countryId = await getCountryId(event, token, order.shipCountry) const combinedShipAddress = [order.shipAddress1, order.shipAddress2].filter(Boolean).join(' ') const shipLocationData = { address1: combinedShipAddress, address2: '', city: order.shipCity, postal: order.shipPostal, state: order.shipState, countryId: countryId } const shipLocation = await createLocation(event, token, shipLocationData, orgId) let shipPartnerLocation = null let shipUserId = null if (shipLocation?.id) { shipPartnerLocation = await createPartnerLocation( event, token, partner.id, shipLocation.id, order.recipientName || order.buyerName, order.recipientPhone, orgId, true ) // Create ship user const shipUser = await createPartnerUser( event, token, partner.id, `Ship_${order.recipientName || order.buyerName}`, order.buyerEmail, order.recipientPhone, orgId, true ) shipUserId = shipUser?.id || null } // Create bill location (same as ship for now, or use buyer address if different) // Combine address1 and address2 into one (eBay splits street and house number) const billCountryId = await getCountryId(event, token, order.buyerCountry || order.shipCountry) const combinedBillAddress = [order.buyerAddress1 || order.shipAddress1, order.buyerAddress2 || order.shipAddress2].filter(Boolean).join(' ') const billLocationData = { address1: combinedBillAddress, address2: '', city: order.buyerCity || order.shipCity, postal: order.buyerPostal || order.shipPostal, state: order.buyerState || order.shipState, countryId: billCountryId } const billLocation = await createLocation(event, token, billLocationData, orgId) let billPartnerLocation = null let billUserId = null if (billLocation?.id) { billPartnerLocation = await createPartnerLocation( event, token, partner.id, billLocation.id, order.buyerName || order.recipientName, order.recipientPhone, orgId, false ) // Create bill user const billUser = await createPartnerUser( event, token, partner.id, `Bill_${order.buyerName || order.recipientName}`, order.buyerEmail, order.recipientPhone, orgId, false ) billUserId = billUser?.id || null } return { partner, shipLocation: shipPartnerLocation, billLocation: billPartnerLocation, shipUserId, billUserId, isNew: true } } // Helper function to create an order const createOrder = async ( event: any, token: any, order: any, partnerData: any, orgId: any, orgDefaults: any, defaultTaxId: string | null ) => { const today = new Date().toISOString().split('T')[0] // YYYY-MM-DD format const orderPayload: any = { AD_Org_ID: { id: orgId, tableName: 'AD_Org' }, isActive: true, dateOrdered: today, datePromised: today, isApproved: false, isCreditApproved: false, isDelivered: false, isInvoiced: false, isPrinted: false, isTransferred: false, isSOTrx: true, isDiscountPrinted: false, isTaxIncluded: orgDefaults.isTaxIncluded || false, isSelected: false, sendEMail: false, isSelfService: false, isDropShip: false, isPayScheduleValid: false, isPriviledgedRate: false, C_DocTypeTarget_ID: { id: orgDefaults.docTypeTargetId, tableName: 'C_DocTypeTarget' }, DocStatus: { id: 'DR' }, M_PriceList_ID: { id: orgDefaults.priceListId, tableName: 'M_PriceList' }, M_Warehouse_ID: { id: orgDefaults.warehouseId, tableName: 'M_Warehouse' }, C_BPartner_ID: { id: partnerData.partner.id, tableName: 'C_BPartner' }, Bill_BPartner_ID: { id: partnerData.partner.id, tableName: 'C_BPartner' }, SalesRep_ID: { id: '1000000', tableName: 'AD_User' }, C_Currency_ID: { id: orgDefaults.currencyId, tableName: 'C_Currency' }, PriorityRule: { id: '5' }, DeliveryRule: { id: 'O' }, C_PaymentTerm_ID: { identifier: 'Immediate', tableName: 'C_PaymentTerm' }, PaymentRule: { id: 'D' }, ExternalOrderId: order.orderNumber, GrandTotal: order.grandTotal || 0, tableName: 'C_Order' } // Add partner locations if available if (partnerData.shipLocation?.id) { orderPayload.C_BPartner_Location_ID = { id: partnerData.shipLocation.id, tableName: 'C_BPartner_Location' } } if (partnerData.billLocation?.id) { orderPayload.Bill_Location_ID = { id: partnerData.billLocation.id, tableName: 'C_BPartner_Location' } } // Add user contacts if available if (partnerData.shipUserId) { orderPayload.AD_User_ID = { id: partnerData.shipUserId, tableName: 'AD_User' } } if (partnerData.billUserId) { orderPayload.Bill_User_ID = { id: partnerData.billUserId, tableName: 'AD_User' } } // Add order source if provided if (orgDefaults.orderSourceId) { orderPayload.C_OrderSource_ID = { id: orgDefaults.orderSourceId, tableName: 'C_OrderSource' } } // Add delivery via rule if provided if (orgDefaults.deliveryViaRuleId) { orderPayload.DeliveryViaRule = { id: orgDefaults.deliveryViaRuleId } } // Add shipper if provided if (orgDefaults.shipperId) { orderPayload.M_Shipper_ID = { id: orgDefaults.shipperId, tableName: 'M_Shipper' } } // Add order lines (matching quick-add format) const qty = order.quantity || 1 const price = order.soldFor || 0 const totalPositionPrice = price * qty // Total position amount to preserve const orderLines: any[] = [] // Check if BOM conversion is enabled on order source AND product has IsBOM = true let useBomComponents = false let bomComponents: any[] = [] if (orgDefaults.isBomConvert && order.productId) { // First check if the product has IsBOM = true const productIsBOM = await isProductBOM(event, token, order.productId) if (productIsBOM) { // Product is a BOM, fetch its components bomComponents = await getBomComponents(event, token, order.productId) if (bomComponents.length > 0) { useBomComponents = true console.log(`[BOM] Converting BOM product ${order.productId} to ${bomComponents.length} components`) } else { console.log(`[BOM] Product ${order.productId} has IsBOM=true but no BOM components found`) } } else { console.log(`[BOM] Product ${order.productId} has IsBOM=false, skipping BOM conversion`) } } if (useBomComponents) { // Calculate total BOM quantity to distribute price evenly let totalBomQty = 0 for (const component of bomComponents) { const compQty = (component.QtyBOM || 1) * qty totalBomQty += compQty } // Calculate price per unit so total position amount stays the same // totalPositionPrice / totalBomQty = pricePerUnit const pricePerUnit = totalBomQty > 0 ? totalPositionPrice / totalBomQty : 0 console.log(`[BOM] Total position price: ${totalPositionPrice}, Total BOM qty: ${totalBomQty}, Price per unit: ${pricePerUnit}`) // Create order lines for each BOM component let lineNo = 10 for (const component of bomComponents) { // In pp_product_bomline, M_Product_ID is the component product const componentProductId = component.M_Product_ID?.id const componentQty = (component.QtyBOM || 1) * qty const componentLinePrice = pricePerUnit const componentLineNetAmt = componentLinePrice * componentQty if (!componentProductId) { console.warn('[BOM] Component missing product ID, skipping:', JSON.stringify(component)) continue } console.log(`[BOM] Creating line: productId=${componentProductId}, qty=${componentQty}, price=${componentLinePrice}, lineNet=${componentLineNetAmt}`) const bomLine: any = { AD_Org_ID: { id: orgId, tableName: 'AD_Org' }, line: lineNo, isActive: true, dateOrdered: today, datePromised: today, qtyOrdered: componentQty, qtyEntered: componentQty, qtyReserved: 0, qtyDelivered: 0, qtyInvoiced: 0, qtyLostSales: 0, priceActual: componentLinePrice, priceEntered: componentLinePrice, priceList: componentLinePrice, priceLimit: componentLinePrice, discount: 0, lineNetAmt: componentLineNetAmt, M_Product_ID: { id: componentProductId, tableName: 'M_Product' }, C_BPartner_ID: { id: partnerData.partner.id, tableName: 'C_BPartner' }, M_Warehouse_ID: { id: orgDefaults.warehouseId, tableName: 'M_Warehouse' }, C_Currency_ID: { id: orgDefaults.currencyId, tableName: 'C_Currency' } } if (defaultTaxId) { bomLine.C_Tax_ID = { id: defaultTaxId, tableName: 'C_Tax' } } if (partnerData.shipLocation?.id) { bomLine.C_BPartner_Location_ID = { id: partnerData.shipLocation.id } } orderLines.push(bomLine) lineNo += 10 } } else { // Standard single line order const orderLine: any = { AD_Org_ID: { id: orgId, tableName: 'AD_Org' }, line: 10, isActive: true, dateOrdered: today, datePromised: today, qtyOrdered: qty, qtyEntered: qty, qtyReserved: 0, qtyDelivered: 0, qtyInvoiced: 0, qtyLostSales: 0, priceActual: price, priceEntered: price, priceList: price, priceLimit: price, discount: 0, lineNetAmt: price * qty, M_Product_ID: { id: order.productId, tableName: 'M_Product' }, C_BPartner_ID: { id: partnerData.partner.id, tableName: 'C_BPartner' }, M_Warehouse_ID: { id: orgDefaults.warehouseId, tableName: 'M_Warehouse' }, C_Currency_ID: { id: orgDefaults.currencyId, tableName: 'C_Currency' } } // Add default tax (required for order line) if (defaultTaxId) { orderLine.C_Tax_ID = { id: defaultTaxId, tableName: 'C_Tax' } } else { console.warn('No default tax ID found - order line may fail') } if (partnerData.shipLocation?.id) { orderLine.C_BPartner_Location_ID = { id: partnerData.shipLocation.id } } orderLines.push(orderLine) } orderPayload.C_OrderLine = orderLines // Create the order const createdOrder = await fetchHelper(event, 'models/c_order', 'POST', token, orderPayload) return createdOrder } const handleFunc = async (event: any, authToken: any = null) => { const token = authToken ?? await getTokenHelper(event) const config = useRuntimeConfig() const serviceToken = config.api.idempieretoken const body = await readBody(event) const { organizationId, orderSourceId, marketplace, docStatus, orders } = body if (!organizationId) { return { status: 400, message: 'Organization ID is required' } } if (!orders || !Array.isArray(orders) || orders.length === 0) { return { status: 400, message: 'No orders to import' } } // Get default values from org configuration (same as org-defaults.get.ts) // Use runtime config for docTypeTargetId (same as /partners/partners/add page) let orgDefaults: any = { partnerGroupId: config.public.partnergroupid ?? '103', // Standard priceListId: config.public.pricelistid ?? '101', // Standard docTypeTargetId: config.public.doctypeid ?? '132', // Standard Order warehouseId: '103', // Default warehouse currencyId: '102', // EUR } try { // Fetch organization's linked business partner using the dedicated endpoint const orgBPartnerRes: any = await $fetch(`${config.api.url}/models/ad_org/${organizationId}`, { method: 'GET', headers: { 'Content-Type': 'application/json', Accept: 'application/json', Authorization: 'Bearer ' + serviceToken } }) // Get warehouse from org if (orgBPartnerRes?.M_Warehouse_ID?.id) { orgDefaults.warehouseId = orgBPartnerRes.M_Warehouse_ID.id } const bpartnerId = orgBPartnerRes?.C_BPartner_ID?.id if (bpartnerId) { // Fetch business partner to get default values using service token const bpartnerRes: any = await $fetch(`${config.api.url}/models/c_bpartner/${bpartnerId}`, { method: 'GET', headers: { 'Content-Type': 'application/json', Accept: 'application/json', Authorization: 'Bearer ' + serviceToken } }) console.log('Org BPartner defaults:', bpartnerRes?.DeliveryViaRule, bpartnerRes?.M_Shipper_OrderDefault_ID) // DeliveryViaRule if (bpartnerRes?.DeliveryViaRule?.id) { orgDefaults.deliveryViaRuleId = bpartnerRes.DeliveryViaRule.id } // Shipper - check both possible field names if (bpartnerRes?.M_Shipper_OrderDefault_ID?.id) { orgDefaults.shipperId = bpartnerRes.M_Shipper_OrderDefault_ID.id } else if (bpartnerRes?.M_Shipper_ID?.id) { orgDefaults.shipperId = bpartnerRes.M_Shipper_ID.id } // PriceList from org's bpartner if (bpartnerRes?.M_PriceList_ID?.id) { orgDefaults.priceListId = bpartnerRes.M_PriceList_ID.id } // Partner Group from org's bpartner if (bpartnerRes?.C_BP_Group_ID?.id) { orgDefaults.partnerGroupId = bpartnerRes.C_BP_Group_ID.id } } // Use the orderSourceId passed from the frontend if provided if (orderSourceId) { orgDefaults.orderSourceId = orderSourceId // Fetch order source to get its config (pricelist, warehouse, isBomConvert) try { const orderSourceRes = await fetchHelper( event, `models/c_ordersource/${orderSourceId}`, 'GET', token ) if (orderSourceRes?.M_PriceList_ID?.id) { orgDefaults.priceListId = orderSourceRes.M_PriceList_ID.id } if (orderSourceRes?.M_Warehouse_ID?.id) { orgDefaults.warehouseId = orderSourceRes.M_Warehouse_ID.id } // Check if BOM conversion is enabled if (orderSourceRes?.isBomConvert === true || orderSourceRes?.isBomConvert === 'Y') { orgDefaults.isBomConvert = true console.log('[eBay Import] BOM conversion is enabled for this order source') } // Check if tax is included in prices if (orderSourceRes?.IsTaxIncluded === true || orderSourceRes?.IsTaxIncluded === 'Y') { orgDefaults.isTaxIncluded = true console.log('[eBay Import] Tax included is enabled for this order source') } } catch (osErr) { console.error('Error fetching order source:', osErr) } } console.log('Final org defaults:', orgDefaults) } catch (error) { console.error('Error fetching org defaults:', error) } // Get default sales tax let defaultTaxId: string | null = null try { const taxRes = await fetchHelper( event, 'models/c_tax?$filter=IsDefault eq true AND IsSalesTax eq true AND isActive eq true&$top=1', 'GET', token, null ) if (taxRes?.records?.length > 0) { defaultTaxId = taxRes.records[0].id console.log('Default tax found:', defaultTaxId, taxRes.records[0].Name || taxRes.records[0].identifier) } else { console.warn('No default sales tax found!') } } catch (err) { console.error('Failed to fetch default sales tax:', err) } const results = { success: [] as any[], errors: [] as any[] } // Process each order for (const order of orders) { try { // Check if order already exists by external order ID const existingOrder = await fetchHelper( event, `models/c_order?$filter=ExternalOrderId eq '${order.orderNumber}'`, 'GET', token ) if (existingOrder?.records && existingOrder.records.length > 0) { results.errors.push({ orderNumber: order.orderNumber, error: 'Order already exists', existingOrderId: existingOrder.records[0].id }) continue } // Find or create partner const partnerData = await findOrCreatePartner( event, token, order, organizationId, orgDefaults.partnerGroupId, orgDefaults.priceListId ) // Create order const createdOrder = await createOrder( event, token, order, partnerData, organizationId, orgDefaults, defaultTaxId ) if (createdOrder?.id) { let finalDocStatus = 'DR' // If docStatus is 'CO', process/complete the order if (docStatus === 'CO') { try { const processRes = await fetchHelper( event, `models/c_order/${createdOrder.id}`, 'PUT', token, { 'doc-action': 'CO' } ) if (processRes?.DocStatus === 'CO' || processRes?.DocStatus?.id === 'CO') { finalDocStatus = 'CO' console.log(`[eBay Import] Order ${createdOrder.DocumentNo} completed successfully`) } else { console.warn(`[eBay Import] Order ${createdOrder.DocumentNo} doc-action CO returned:`, processRes?.DocStatus) finalDocStatus = processRes?.DocStatus?.id || processRes?.DocStatus || 'DR' } } catch (processErr) { console.error(`[eBay Import] Error completing order ${createdOrder.DocumentNo}:`, processErr) } } results.success.push({ orderNumber: order.orderNumber, orderId: createdOrder.id, documentNo: createdOrder.DocumentNo, docStatus: finalDocStatus, partnerId: partnerData.partner.id, partnerName: partnerData.partner.Name || partnerData.partner.name, isNewPartner: partnerData.isNew }) } else { results.errors.push({ orderNumber: order.orderNumber, error: 'Failed to create order' }) } } catch (error: any) { console.error(`Error importing order ${order.orderNumber}:`, error) results.errors.push({ orderNumber: order.orderNumber, error: error?.message || 'Unknown error' }) } } return { status: 200, message: `Imported ${results.success.length} orders, ${results.errors.length} failed`, ...results } } 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) } } return data })